[Letux-kernel] jz4780 read out LCDC setup for HDMI
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
> < 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
> 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.
More information about the Letux-kernel