[Letux-kernel] jz4780 read out LCDC setup for HDMI

Paul Boddie paul at boddie.org.uk
Fri Jun 5 22:48:13 CEST 2020


[CC'ing Paul since he had been in contact with me and might be interested.]

On Friday 5. June 2020 07.17.27 H. Nikolaus Schaller wrote:
> 
> Still there are big differences between the 3.0.8 kernel and the 5.7
> for the same hdmi monitor.
> 
> diff hdmi-3.0.8.txt hdmi-5.7.txt | fgrep JZ_REG
> < 0x13050000 12f00440 JZ_REG_LCD_CFG
> < 0x13050004 00000005 JZ_REG_LCD_VSYNC
> < 0x13050008 0000002c JZ_REG_LCD_HSYNC
> < 0x1305000c 08980465 JZ_REG_LCD_VAT
> < 0x13050010 00c00840 JZ_REG_LCD_DAH
> < 0x13050014 00290461 JZ_REG_LCD_DAV
> 
> > 0x13050000 00f00840 JZ_REG_LCD_CFG
> > 0x13050004 00000003 JZ_REG_LCD_VSYNC
> > 0x13050008 0000000d JZ_REG_LCD_HSYNC
> > 0x1305000c 0520026e JZ_REG_LCD_VAT
> > 0x13050010 011b051b JZ_REG_LCD_DAH
> > 0x13050014 0014026c JZ_REG_LCD_DAV

The sync pulse differences are a bit strange, and the dimensions are quite 
different, but perhaps a different resolution has made its way to the DRM 
driver instead of the one you would expect.

> < 0x13050030 4000080d JZ_REG_LCD_CTRL
> < 0x13050034 00000024 JZ_REG_LCD_STATE
> 
> > 0x13050030 24002008 JZ_REG_LCD_CTRL
> > 0x13050034 00000004 JZ_REG_LCD_STATE

The state no longer shows end-of-frame interrupts. Generally, I would not 
expect the control or config registers to work in the 5.7 kernel. I can say 
this with confidence because I finally got a picture on the screen in my L4Re 
test environment, so there are some things that seem to be necessary that are 
not being done in the upstream DRM driver. More on this below.

> I have now also studied the differences in the HDMI_PHY registers and there
> are some:
> 
> < 0x1018c000 000000ce HDMI_PHY_CONF0
> > 0x1018c000 0000000e HDMI_PHY_CONF0

The difference is the lack of PDZ and ENTMDS bits, which are what I call 
"powerdown disable" and "enable TMDS". This indicates that the signal is not 
active.

> < 0x1018c018 000000f1 HDMI_PHY_MASK0
> < 0x1018c01c 000000f1 HDMI_PHY_POL0
> 
> > 0x1018c018 00000001 HDMI_PHY_MASK0
> > 0x1018c01c 00000000 HDMI_PHY_POL0

Here, it seems that in the older kernel, only the hotplug interrupt is enabled 
(PHY_MASK0 has bit 1 clear). In the newer kernel, all the "rx sense" 
interrupts are enabled as well, presumably to sense activity initiated by the 
other device on the cable.

> So there is different CONF. And what I have found is a patch like
> this:
> 
> https://lists.denx.de/pipermail/u-boot/2012-October/136234.html
> 
> where people set the HDMI_PHY_CONF0_PDZ_MASK and HDMI_PHY_CONF0_ENTMDS_MASK
> like I did find with the 3.0.8 kernel but not with 5.7.
> 
> Also the MASK (lane mask?) and POL (polarity?) differ.
> 
> So we may not only have a problem with initializing the LCDC but also the
> HDMI PHY.

The U-Boot patch is interesting because I wouldn't have expected support for 
this peripheral in U-Boot given that Imagination/Ingenic didn't include it in 
their U-Boot version, but perhaps it was a distraction, not entirely necessary 
given that debugging can be done over the UART, and once U-Boot can boot Linux 
you can leave it to the driver there to do all the work.

> I am tempted to try to write all the 3.0.8 register values through
> devmem2... i.e. override the setup done by the kernel drivers.
> 
> But maybe I should study the TILCDC (BeagleBone) driver which seems to have
> a comparable structure (except that it has no vblank). This might help to
> better understand the (broken) call chain for initialization.

I haven't looked at the Linux kernel mechanics for a while, but I can now be 
quite sure that the HDMI initialisation in the kernel should be able to work 
because I borrowed a lot of the details for my L4Re implementation. This 
involved the initialisation of interrupt handling to detect hotplugging, the 
use of I2C for retrieving the EDID, the use of some other I2C registers for 
communication with the PHY, facilitating PHY initialisation, then the 
initialisation of various different functional blocks.

Indeed, my L4Re implementation actually only supports DVI mode, which works 
with my VGA- and DVI-capable monitor, but I think it should probably work even 
on HDMI-capable monitors due to the heritage of the technology. This has 
allowed me to ignore various HDMI details but also to establish the minimum 
functionality to get this working. Also, I have ignored audio altogether 
because I don't have the Ingenic I2S peripheral supported at the moment.

The tricky part of all this has actually been the LCD controller. I did make a 
couple of stupid mistakes, and this is where your register dumps helped a lot 
because they made me check what I had written to the config register and I saw 
that I had written bit numbers (25, 28) instead of shifted bits (1 << 25, 1 << 
28) to the register, which are easy enough to make when tired and distracted 
by lots of details. Fixing this explained a problem with the signal not being 
generated when using these JZ4780-specific bits.

However, there do seem to be some important elements to producing a signal for 
the HDMI peripheral. Reviewing your register dumps made me consider the role 
of the second DMA descriptor. This seemed to be superfluous, and in the 3.0.8 
kernel driver some commentary suggests that it isn't needed (or used) after 
being set up. But then I understood that it still needs to be set up because 
the LCD controller (or the OSD functionality) still expects something to be 
present at the address found in the descriptor address register. And making 
sure that a flag is cleared in the command word of the descriptor probably 
ensures that the DMA channel doesn't do anything and that the LCD/OSD 
functionality remains happy.

(I will actually test without the "new" descriptors and OSD, if possible, just 
to see what the dependencies are on these things.)

So, what we probably need to do is to make sure that the descriptors are set 
up, mostly as they are in 3.18. We also need to deal with the issue of 
encodings and formats. Since I took various shortcuts with the HDMI 
functionality, effectively asserting RGB data for input and output, with this 
working just fine, I think that finding a way of doing that (at least for 
input from the LCD controller) will configure everything appropriately.

One obstacle previously mentioned was that of end-of-frame interrupts. Having 
configured those in my test environment, I can indeed receive these interrupts 
(or at least some kind of interrupt condition) at a frequency that suggests 
that the end-of-frame condition is causing interrupts to be delivered. In 
other words, I can count 60 of them every second or so. Therefore, it should 
be possible to get the LCD controller into an appropriate state to pass the 
"vblank" test, although I imagine that the initialisation sequencing still 
remains a challenge: the HDMI peripheral may need to be active first, but 
there may be expectations of an input signal being available before the HDMI 
peripheral is activated; something will need to short-circuit any such logic.

Anyway, those are my findings right now. I guess I will try and see if I can 
translate them to further progress, however.

Thanks once again for the register dumps! They proved valuable in getting me 
to check my work.

Paul


More information about the Letux-kernel mailing list