Re: Linux AMBA-CLCD driver no longer works with Qemu versatilepb target. What to do?

2024-02-09 Thread Christopher Davies
On Fri, Feb 9, 2024 at 5:18 PM Peter Maydell 
wrote:

> Are we talking something other than drivers/gpu/drm/pl111/ ?
>
>
This is the older fbdev driver that used to live at
drivers/video/fbdev/amba-clcd.c but was removed in Linux 6.8. I actually
haven't tested if the DRM driver works since it isn't really relevant to my
use case.


> Generally QEMU goes with "behave as the hardware does", though
> for these old boards that gets kind of tricky. My gut feeling is
> "this is a guest kernel bug that should be fixed in the guest
> kernel".
>

 I guess it was a long shot getting some sort of command line switch
accepted for probably just one user. I'm guessing the kernel driver only
ever really got tested with vexpress boards or something, so maybe it never
even worked on real versatilepb hardware. The fact that the switch is there
at all though suggests someone at one point ran it on something with a
PL110. I guess there's not much to be done but create my own private kernel
patchset.


Linux AMBA-CLCD driver no longer works with Qemu versatilepb target. What to do?

2024-02-09 Thread Christopher Davies
I've been down a bit of a rabbit hole trying to get the Linux AMBA-CLCD
driver for versatilepb target's graphics to work with modern Linux kernels.
After a good deal of reading of both the Linux kernel code and the qemu
code, I discovered why it won't work and why it probably has never worked
since the transition to devicetree in the kernel about a decade ago.

The driver chooses between PL110 and PL111 mode by taking the identifier
from the AMBA bus:

if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) {
fb->off_ienb = CLCD_PL111_IENB;
fb->off_cntl = CLCD_PL111_CNTL;
} else {
fb->off_ienb = CLCD_PL110_IENB;
fb->off_cntl = CLCD_PL110_CNTL;
}

While Qemu thinks that the PL110_versatile ought to have the PL110 device
ID, but the PL111 behaviour.

static const unsigned char *idregs[] = {
pl110_id,
/* The ARM documentation (DDI0224C) says the CLCDC on the Versatile
board
 * has a different ID (0x93, 0x10, 0x04, 0x00, ...). However the
hardware
 * itself has the same ID values as a stock PL110, and guests (in
 * particular Linux) rely on this. We emulate what the hardware does,
 * rather than what the docs claim it ought to do.
 */
pl110_id,
pl111_id
};

So the Linux driver writes the wrong control register and the device is
never enabled.

I'm at a loss to know what to do about this. This hardware emulation worked
with pre-devicetree kernels, and possibly making this change will break
that, I really don't know. I also don't own the real hardware so I can't
observe what the real behaviour is.

I'm possibly the only person to actually care about this in about a decade,
and the CLCD driver has recently been removed from Linux. I only care about
it because I'm trying to run some old software unmodified.

I'm happy to write a patch for Qemu if anyone can suggest an approach to
fixing this, anyone have any ideas?