[Letux-kernel] [PATCH 00/20] A bunch of JZ4730 fixups for letux-kernel

Paul Boddie paul at boddie.org.uk
Sat Dec 5 22:19:01 CET 2020


On Saturday, 5 December 2020 20:27:27 CET H. Nikolaus Schaller wrote:
> Ok, first finding
> 
> So I tried the assumption that memory layout is more similar to the
> JZ475 and JZ4740 than the JZ4780.
> 
> > 	dma: dma at 10020000 {
> > 	
> > 		compatible = "ingenic,jz4730-dma";
> > 		reg = <0x10020000 0x100>, <0x10020300 0x14>;
> 
> Unfortunately it has an effect - which is that boot hangs after
> 
> [    0.009935] Console: colour dummy device 80x25
> [    0.014479] printk: console [tty0] enabled
> [    0.001103] printk: bootconsole [jz4740_uart0] disabled
> 
> Maybe something in the dma driver is hanging.
> 
> Questionable is the 0x100 - but it is usually not a problem to allocate
> a little more as long as there is no overlap.

The 0x100 covers 6 channels each having a bank of 0x20, so it is just a 
rounding up to a more readable amount, and this is probably done everywhere in 
device tree files.

The 0x14 is the control registers. This should actually be something else, as 
discussed below.

> Or does someone have a JZ4730 programmer's manual?

One has never been seen, maybe not even inside Ingenic. :-)

> Probably we also could dig out this from the older kernels or U-Boot.

Yes, it looks like the register layout is different. I missed this when 
powering through the drivers. In particular...

* The descriptor address register is where the other SoCs put the target
  address register (0x04 * channel), but fortunately the driver doesn't use
  the target address register.

* The command register (0x14 * channel) is not provided, but this isn't used
  by the driver, either.

* The global control register is at 0xfc, not 0x300, and it appears to have
  the same layout between the different SoCs.

* The global interrupt pending register is at 0xf8, not 0x304. Although I
  cannot find any particular layout for the JZ4730, it probably uses the same
  scheme mapping channels to bits in the appropriate positions: bit 0 for
  channel 0, and so on.

So, what we might want to provide in the device tree is this:

reg = <0x10020000 0xc0>, <0x100200f8 0x08>;

Then, the global register offsets will appear relative to 0xf8 and in reverse 
order. The channel registers will be mostly the same apart from the descriptor 
address register.

There are a few things in the driver that don't appear to map to anything in 
the JZ4730. Here, I use the offsets relative to 0x300 in the other SoCs, which 
are what the driver uses:

* The doorbell registers (0x08 and 0x0c) which manually initiate transfers.
  So, I wonder how manual descriptor-based transfer would actually work with
  the JZ4730, but maybe the old kernel code provides some clues.

* The clock enable registers (0x10, 0x14 and 0x18) which are apparently
  obsolete and not supported according to the JZ4780 manual.

* The programmable channel register (0x1c), which is merely cleared by the
  driver since it is fancy functionality for the JZ4780 and similar era
  products.

* Various registers from 0x20 onwards, which are also JZ4780-specific.

So, what probably needs to be done is some parameterisation to use the right 
offsets for descriptor address registers and the principal global registers. 
Meanwhile, some investigation into what might be used for the doorbell 
registers might be needed. Where other peripherals manipulate the DMA system, 
I don't think the doorbell mechanism is needed at all, though.

Paul




More information about the Letux-kernel mailing list