[Lenny400] Some tentative changes to the mainline kernel
paul at boddie.org.uk
Sat Apr 4 02:34:41 CEST 2015
I was recently persuaded (or managed to convince myself) to take a look at
building a kernel for the Letux400, already having a Ben NanoNote and wanting
to see if I could build a mainline kernel for that. It turned out that the
jz4740 support in the mainline is mostly complete, with some additional
patches for the NanoNote still required for successful operation (backlight,
keymap, some NAND stuff). Note that the NanoNote uses the jz4720, but it is
mostly a repackaged jz4740 as I understand it.
So, switching to the jz4730, I had a look at the existing letux-400 2.6 kernel
as well as various datasheets floating around on the Internet. I asked on the
#qi-hardware IRC channel on FreeNode for a bit of advice on the best way to
support the jz4730 in general, as well as pointers to support for other jz47xx
variants. I found the following things:
First of all, none of these things supports the jz4730 as it is just too old
and forgotten for people to bother with, and my impression is that it is also
the "odd one out" in the jz47xx series (Ethernet, PCMCIA, PS/2 support!) with
not even a programming manual floating around on the Internet. However...
(1) attempts to support the jz4770 for the GCW-Zero handheld console. The
opinion on #qi-hardware was that the way the jz4770 is accommodated is "the
wrong way" by adding a mach-jz4770 directory.
(2) attempts to support the MIPS Creator CI20 and the jz4780, which is
apparently done "the right way" by not adding a mach-jz4780 directory. ;-) I
cannot believe, however, that this actually produces a working kernel for that
board given that various essential files are missing.
(3) is actually only accessible from git directly, not via a browser, and
contains the Ingenic-maintained ancient kernel which also doesn't support the
jz4730 and definitely wouldn't be considered "the right way" by anyone
committing stuff for the mainline kernel.
Having looked at all this, I started seeing if I could accommodate the jz4730
within the jz4740 mainline support without creating lots of new files that I
would then have to populate. Although there are some similarities between the
two CPUs, meaning that some details can be shared, there are also some crucial
differences that would probably hinder any kind of success if any of them are
missed or misinterpreted.
For the most part, the two CPUs keep their registers in similar memory
regions, and where a jz4740 region is differently labelled in the 2.6 kernel
for the jz4730, it doesn't seem to be of significance to either kernel. (I
think it was just the region at 0x10002000 but not the critical timer/counter
region at 0x10002010.) The GPIO registers seem to use a different layout,
however, occupying blocks every 48 bytes in the jz4730 instead of every 256
bytes in the jz4740, mostly because the jz4730 seems to employ modifiable
registers instead of the separate read/set/clear registers in the jz4740. This
meant that I had to split the GPIO code in arch/mips/jz4740 into separate
The GPIO/pin definitions do differ between the two CPUs according to the
datasheets, and this is confirmed in the 2.6 kernel when compared to the
mainline jz4740 support. Thus, a separate set of definitions needs to be
provided in arch/mips/include/asm/mach-jz4740 for the jz4730 and jz4740 (which
involves some header file indirection that may not be "the right way"). GPIO
operations in the mainline kernel are apparently done using a framework that
is cleaner but less concise than the #defines found in the jz4730 support from
the Ingenic 2.6 kernel. Here, the different nature of the GPIO registers is
apparent, and the idea is to somehow replicate them in the mainline framework.
Moreover, the 2.6 kernel does some quick-and-dirty initialisation in the board
file for the minipc/Letux400 that is done in part by various frameworks in the
mainline kernel (framebuffer, PWM) but not by everything (USB, I2S).
Interrupt/IRQ definitions also differ between the two CPUs, although I remain
uncertain about things like DMA and what interrupt support there is for that.
In addition, the GPIO register changes impact various IRQ-related operations:
some jz4730 registers appear to combine the functionality of two jz4740
registers. Again, some header file indirection is used to switch to the
appropriate definitions without breaking the drivers needing to know about the
I have the faintest hope that the jz4740 framebuffer support will manage to
handle the jz4730 and the display used by the Letux400. I think it may be
sufficient to configure the structure appropriately and just make sure that
the driver uses the right pins, requiring the correct definitions and also
some minor (and maybe superfluous) changes to the driver. Similarly, the
backlight might be supported by the PWM backlight driver, again given the
appropriate pin definitions. I noticed that PWM is driven via some registers
in the jz4730 that do not appear to be documented for the jz4740 or used by
the mainline kernel code, but it seems possible to use the jz4740 mechanism
instead which employs the timer/counter unit.
Since my patch isn't very large, I intend to send it to this list, although I
suppose I could also push it or share it somewhere. I rather dislike git and
don't have a GitHub account, so I can't claim to be seamlessly interoperable
with those who like both those things, but I will cooperate with anyone who
wants to correct my work and to test it. I also don't tend to work with the
Linux kernel, so you can probably also expect lots of mistakes and bad
I'd like to see the jz4730 supported in the mainline kernel or a close
derivative because it would also give me some confidence that other jz47xx
variants would be sustainable choices for new hardware. For instance, the
EOMA68 initiative intends to produce hardware using the jz4775 that could even
be considered "FSF-endorseable", and it just isn't sustainable to use these
"code drop" ancient kernels that Ingenic seems to provide for the basis of a
software distribution or for anything needing a reasonable period of support.
More information about the Lenny400