linux
linux copied to clipboard
VGA666 DPI adapter
Thanks to your recent work on support for the DPI interface, I've been able to use the VGA666 adapter with the open-source vc4 driver. It's a very simplified D/A converter which turns the DPI signal into VGA-like analog video. I'm using it with an arcade CRT monitor that's rather different from the normal VGA monitor - it only supports video modes with 15 or 25kHz horizontal scan rate, i.e. 240p/384p/480i/768i. I had to make what feels like a bit of a hack to get this working and I'm really looking for pointers on how to do it "properly".
There is already a device tree overlay for the VGA666 adapter but I found it needed some additions to enable the vc4 driver to work with it: https://github.com/raspberrypi/linux/compare/rpi-4.4.y...sigmaris:vga666-dpi
I also added a panel_desc
into the kernel code with some supported video modes for my particular monitor. Now I can switch between custom modes on the monitor without a reboot, which I couldn't do with the closed-source VC4 firmware.
But having to add custom modes to the kernel source and recompile seems awkward, since all kinds of monitors could be connected to the VGA666 adapter but my changes are very specific to the non-standard arcade monitor I'm using. Is there a better way to tell the driver what modes are supported without recompiling (device tree parameters?) or a way to set up custom modes after boot (i.e. set the pixel clock, h-sync and v-sync timings, etc)?
I'm glad the DPI stuff is working for you!
If you're using X, you can add modes at runtime with xrandr --newmode, xrandr --addmode, xrandr --addmode, xrandr --mode (yes, this is an overly complicated workflow, but custom modelines are a very unusual use case these days so nobody's made a nicer tool afaik), and that sits on top of standard DRM KMS functionality that any other compositor could use as well.
If you had a standard monitor, we could upstream that, but it doesn't seem like your monitor is normal enough for that to make sense?
Thanks for the tip about xrandr, that's working for me to add custom modes in X.
I also tested a different patch with a more "standard" VGA monitor that supports up to 1280x1024: https://github.com/sigmaris/linux/commit/0fdbb5cf25ca5f590e2bb7c6b5eae0e061c4d8ca. If I define a panel_desc
in panel-simple.c with no modes, then drm_add_modes_noedid()
will populate some standard VESA modes from 640x480 to 1024x768. This seems like a good approach to ensure that the VGA666 adapter works on the Pi at a basic level if just dtoverlay=vga666
is added to config.txt. Beyond that, I can select 1280x1024 using a cmdline argument video=DPI-1:1280x1024M-32@60
. I expect it should be possible to customise this further by using drm_kms_helper.edid_firmware=
to force an EDID. The VGA666 adapter doesn't have any connection for the DDC pins so I don't think there's any way to read the monitor EDID.
I did try omitting the modifications to panel-simple.c completely, and just relying on the Device Tree overlay with compatible = "simple-panel"
, but that didn't seem to work, and there was this error in the kernel log:
[drm:vc4_dpi_encoder_enable [vc4]] *ERROR* Panel failed to prepare
so I guess the panel_desc
is needed. If this is something that'd be suitable / worthwhile to upstream, let me know and I'll prepare a patch.
Yeah, just "simple-panel" won't do anything, as nothing matches that. I think you need panel-simple.c changes, because even with specifying a mode on the command line, you still need the .bus_format, .bpc, and .size fields of panel_desc.
http://www.spinics.net/lists/devicetree/msg145160.html may be an interesting route to go for supporting this.
I wanted to try the approach in your last comment, basing it on your drm-panel-bridge branch since I think that branch allows the DPI to drive bridges as well as panels? tbh I don't know a lot about kernel development or DT so I'm probably doing various things wrong.
I've added a bridge node and VGA connector here - it's only added to bcm283x.dtsi as a hack, eventually this would be in the vga666 DT Overlay. So now I am wondering where is the right place to attach the bus format information, in DT or code? vc4_dpi_encoder_enable()
currently tries to look at dpi->connector->display_info
but dpi->connector
is NULL, so I guess I need to change this (hardcoded it to DPI_FORMAT_18BIT_666_RGB_1
for now)
The dumb-vga-dac assumes that you have DDC for the modes, which vga666 won't get you. DRM also doesn't currently have a way to tell you the bus_format of the next link in the output chain, just the last, so you'll have issues getting it with a bridge setup until we fix that.
I still think you'd be best off with panel-simple changes.
Is there any progress with this? What's needed with a current upstream kernel to make VGA666 work, ideally without changes to the kernel? Note that I'm actually using my own "VGA555" adapter which uses less bits to free up some I/O.
I had another look at porting my changes to newer kernels but still run into a NULL pointer dereference here: https://github.com/anholt/linux/blob/a8e8e632bfaf040c605d55acbf23f76a503d0b7e/drivers/gpu/drm/vc4/vc4_dpi.c#L175
because dpi->connector
is NULL. In fact I can't see where it is initialised anywhere; looks like the code to initialise it was removed in https://github.com/anholt/linux/commit/7b1298e05310f1fe58401f40e5426a558ec5d3ac, so I think this is a bug and no DPI displays (panel or VGA DAC) will work until it is fixed.
Patch at https://lists.freedesktop.org/archives/dri-devel/2018-March/168920.html