Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPI4 : "flip_done timed out" after switching resolution #1357

Open
ajefr opened this issue Mar 26, 2020 · 28 comments
Open

RPI4 : "flip_done timed out" after switching resolution #1357

ajefr opened this issue Mar 26, 2020 · 28 comments

Comments

@ajefr
Copy link

ajefr commented Mar 26, 2020

Hello,
On some applications (retroarch, emulationstation,..), system is hanged if the resolution have been previously changed with command vcgencmd hdmi_timings
dmesg show sometimes this error :
[drm:drm_atomic_helper_wait_for_flip_done [drm_kms_helper]] *ERROR* [CRTC:49:crtc-0] flip_done timed out
or sometimes :
[drm:drm_atomic_helper_wait_for_dependencies [drm_kms_helper]] *ERROR* [CRTC:49:crtc-0] flip_done timed out
Also, vcdbg log msg is giving this error
TV service:host side not connected, dropping notification
to unlock the system, you have to issue a tvservice -s from another console.
Applications are runing fine if resolution have not been changed previously.
RPI4 is configured with vc4-fkms-v3d overlay, monitor connected to the dpi port (no hdmi connected)
Thanks

@JamesH65
Copy link
Contributor

I don't think you should be using vcgencmd to change resolution with FKMS (or any sort of DRM system) as this changes the resolution without DRM knowing it has happened. Same with tvservice - you are pulling the rug out from underneath DRM. Use the correct DRM tools to change resolution. Think it might be arandr? Not sure.

@JamesH65
Copy link
Contributor

@ajefr
Copy link
Author

ajefr commented Mar 26, 2020

Thanks for pointing me to this thread.
But I'm using a crt monitor wired thru dpi interface.
vcgencmd hdmi_timings was added to the firmware to allow changing resolution on the fly for this kind of monitor.
So fkms did not know any video mode of this monitors except the one provided in config.txt and named FIXED_MODE in modetest.
It also allow me to specify all the video timings manually.
So how is it possible to tell drm that mode have changed.
Why vcgencmd did not forward information to drm ? (maybe the "bug" is here)

@JamesH65
Copy link
Contributor

AIUI, on startup the firmware will pass any config.txt data that specifies the screen size to DRM as a sort of EDID with a single entry. So that is how DRM know what resolution to use at startup, so can you use that? Or do you really need to change the resolution on the fly because I do not know how we could do that with DRM. It's not a bug with vcgencmd, it's simply not designed to work that way with DRM.

@JamesH65
Copy link
Contributor

@6by9 might have some ideas.

@ajefr
Copy link
Author

ajefr commented Mar 26, 2020

@JamesH65
Yes, what I want is a proper way to change the resolution while the system is alive. I have thousand of different resolutions that could be use by the system.
I was previously using vcgencmd that was working perfectly : https://github.com/raspberrypi/firmware/issues/637
Maybe a way to send a new EDID to DRM ?
Or a way to send new informations to DRM (from userland) ?

@ajefr
Copy link
Author

ajefr commented Mar 26, 2020

Something I wanted to add.
If I send the exact same timing that in config.txt, I get timeout too

@6by9
Copy link

6by9 commented Mar 28, 2020

If the timings result in timeouts when specified in config.txt then I'd read that as the timings being invalid. What are these magic timing values that you're using? If any of the horizontal timings are odd numbers then I suspect you will get issues as the Pi4 HVS runs at 2 pixels/clock.

libdrm provides the relevant calls to set up new modes - see https://cgit.freedesktop.org/drm/libdrm/tree/xf86drmMode.h
A quick Google would imply that something along the lines of https://github.com/hexiaolong2008/libdrm/blob/master/tests/planetest/modeset.c is what you're after.

@ajefr
Copy link
Author

ajefr commented Mar 28, 2020

Hello,

I may not have been clear enough or my english is not perfect (best option) in my very last messages.
I have a working hdmi_timings in my config.txt
I can launch applications without any problem.
If I send back this values with vcgencmd, I get timeout error.
DRM shouldn't be disturb as the timing/frame buffer is the same ?
I'm pointing this because this is possibly a clue for the first problem.

But it's not exactly my concern, with previous pi/os, I was able to change resolution and use exact timing I wanted with vcgencmd without any problem.
Now I would like a way to use the exact timing I wanted like it was previously possible.

I'm not using X but only CLI

@JamesH65
Copy link
Contributor

It's not possible to have exactly the same functionality as before as we have moved to DRM/KMS/Mesa for the Pi4 (because the VC6 on the Pi4 is different). So you should not be using vcgencmd to change resolution, but an alternative, which is the modeset linked by 6by9 above.

@ajefr
Copy link
Author

ajefr commented Mar 30, 2020

DRM/KMS resolution switch is a real pain....
A simple way to update information in DRM once hdmi_timings have been changed is not possible ?

Update hdmi_timings thru vcgencmd and says woo-hoo, drm, please launch update process as in config.txt

I have many compatibility issue because hdmi_timings is not working as on pi3...

@6by9
Copy link

6by9 commented Mar 30, 2020

If you wish to ignore DRM/KMS then feel free. Remove dtoverlay=vc4-fkms-v3d from /boot/config.txt, and you have a fighting chance that vcgencmd hdmi_timings will work again.
You have then also removed all 3D acceleration, but that is the penalty.

We are moving towards using DRM/KMS by default as it is the Linux standard interface for rendering. Obsolete APIs will be marked as deprecated, and future support is not guaranteed.

@JamesH65
Copy link
Contributor

DRM/KMS resolution switch is a real pain....
A simple way to update information in DRM once hdmi_timings have been changed is not possible ?

Update hdmi_timings thru vcgencmd and says woo-hoo, drm, please launch update process as in config.txt

I have many compatibility issue because hdmi_timings is not working as on pi3...

Did you try the modeset program from the link above? Did it work? If you haven't tried it, why not? It's no different to using vcgencmd (which will NOT be updated to work with DRM, as its a Pi specific API and being slowly deprecated ).

Pi4 != Pi3. A very big change., and moving towards a more standardised API. Now is the time to move to that brave new, standardised, world.

@ajefr
Copy link
Author

ajefr commented Mar 30, 2020

@JamesH65
Yes, yes I tried it ;-) even tried to modify the code to make it do what I want, but it's far for being as easy as a vcgencmd.
Especially because when using dpi, no mode are known by the system except the one called FIXED_MODE :
(report from modetest)

Connectors:
id      encoder status          name            size (mm)       modes   encoders
51      50      connected       DSI-1           0x0             1       50
  modes:
        index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
  #0 FIXED_MODE 75.00 640 656 720 840 480 481 484 500 31500 flags: phsync, pvsync; type: preferred, driver
  props:
        1 EDID:
                flags: immutable blob
                blobs:
(...)

So if you call modeset, you can only switch from FIXED_MODE to FIXED_MODE...
What I want is to have control over all the monitor parameters (sync length, sync position, size, pix clock, ...), that's why vcgencmd was the perfect solution.

I'm ok to switch to the new world, but when things were working fine, why removing them ;-)

@JamesH65
Copy link
Contributor

We haven't removed any code, its just that the vcgencmd only work in legacy graphics mode, and was never intended for use with DRM. It would mean writing a whole bunch of new code to make this work and we won't be doing that. The whole point is to move to a more open standard API, not make even more closed source stuff.

Seems like this is a deficiency in DRM, you cannot pass your own parameters to set up the system at run time? @6by9?

@6by9
Copy link

6by9 commented Mar 30, 2020

modetest is a test app only. Did you look at the underlying library?

drmModeAttachMode - https://cgit.freedesktop.org/mesa/drm/tree/xf86drmMode.h#n475

/**
 * Attaches the given mode to an connector.
 */
extern int drmModeAttachMode(int fd, uint32_t connectorId, drmModeModeInfoPtr mode_info);

with drmModeModeInfoPtr containing the full timing and sync setup that you desire.

Google for drmModeAttachMode gives https://gist.github.com/sigmaris/df6863a64f6f768f5fb0e07c3c5f5d63, which looks like it has a good chance of mode switching as a test app.

Likewise drmModeSetCrtc looks to be an alternate way to (temporarily?) set a new mode with user specified timings. https://cgit.freedesktop.org/mesa/drm/tree/xf86drmMode.h#n425

int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
                   uint32_t x, uint32_t y, uint32_t *connectors, int count,
		   drmModeModeInfoPtr mode);

If running X, then xrandr allows you to add additional modes. This is standard for all DRM implementations therefore the Ubuntu page at https://askubuntu.com/questions/377937/how-to-set-a-custom-resolution is all valid. This is known to work as I've used it on multiple occasions with VGA666 (ie a DPI interface) where there is no EDID.

I had asked what sort of timings values you were setting, ie please provide values. Without that then there will be no investigation as to whether or not things work. Sorry, I'm not going to try second guessing what you're doing.

@ajefr
Copy link
Author

ajefr commented Apr 1, 2020

Hello,
Thanks a lot for your answer.
So, I have made further test with my "modded" modeset software.
Nothing were working until I tried with a real hdmi output and with deactivated dpi mode.
I have found that I were able to change video mode as I want (from VGA to full HD for example) with the hdmi output but when I try the dpi output, video mode is not changed and keep the same as in config.txt
Another trouble is that once program is closed and file descriptor released, the video mode rollback to the default one while vcgencmd were doing a "definitive" change.
Any clue ?

@JamesH65
Copy link
Contributor

JamesH65 commented Apr 2, 2020

There's not much point in continually referring back to vcgencmd. The entire graphics system has changed on the Pi4, so that is where we need to concentrate. We won't be making any changes to vcgencmd in this area. It does sound like there may be an issue with the DPI drivers in DRM so that is what needs investigating.

@ajefr
Copy link
Author

ajefr commented Apr 4, 2020

@JamesH65 As you guessed, this tool was really handy for me. I miss it.
Anyway, if someone could check if dpi driver is working well, I would be pleased.
And by the way, how could I keep the video mode changed after switching it ? As once file descriptor is closed, video mode revert back ?

@blitzcode
Copy link

@JamesH65 @6by9 Has there been any progress on this?

From what I understand neither a command line tool nor an API exists than can adjust DPI/vga666 display timings on the fly on the Pi4?

Seems like the RetroArch folks are now using the DRM APIs instead of vcgencmd to do mode switching:
libretro/RetroArch#11590

...but there still is the issue with the DPI interface not working without additional changes with that approach. @Cpasjuste has developed a custom kernel module + device tree overlay that fixes this:

http://mydedibox.fr/rpi4-custom-modes-on-a-crt-tv-the-holy-grail/
https://github.com/Cpasjuste/rpi-dpidac

Could this be merged/fixed so we don't require a workaround / add-on to have on-the-fly mode switching working with the DPI like it did with the legacy graphics stack?

@6by9
Copy link

6by9 commented Apr 18, 2023

Based on a very quick look at that module, I believe the same can be achieved through the vc4-kms-dpi-generic overlay, which takes all the timing parameters via the overlay (not a secondary file). I'd only have a closer look at it if a PR was generated based on it.

As I've said in #1357 (comment), the DRM/KMS API has always allowed the application to add and select a new mode or timings that aren't propagated from the driver. It's how xrandr --newmode works under X, and drmModeSetCrtc takes a full timing through a drmModeModeInfo structure.
It only applies whilst the app requesting it is the DRM master though, so if you want mode switching then you need to actually use the API rather than using the frame buffer emulation.

@substring
Copy link

@blitzcode I recently made a PR at retroarch to have full KMS modeswitching on OpenGL. I tested it on a specific Pi4 lakka build on both HDMI and DPI with a VGA666, works good. You don't need anything else. Just know that DPI can't do interlaced.

All this to confirm @6by9 words: on KMS you can set any mode timing when creating a CRTC, there is no need for dark magic anywhere

@blitzcode
Copy link

@6by9 @substring Thanks so much for letting me this is supposed to just work now. It is really hard to find any meaningful information about this, all my Google searches just bring up the same old discussions that say this is broken on the Pi4 and will never work. The best I could find after a lot of Googling was the blog post I linked, and even that is very dated information now.

Is there a specific kernel version and also a RA release (v1.10.0 is on the latest RetroPie image) were all those changes would be included?

In terms of configuration, something like this should work on a Pi4 with current firmware, right?

dtoverlay=vc4-kms-v3d
dtoverlay=vga666
enable_dpi_lcd=1
display_default_lcd=1
dpi_group=2
dpi_mode=87
dpi_timings=...

Or should I use dtoverlay=vc4-kms-dpi-generic even with a VGA666 adapter?

The lack of interlaced video output is a hardware limitation, correct?

@6by9
Copy link

6by9 commented Apr 18, 2023

The README documents what all the overlays do.

dtoverlay=vga666 only sets up the GPIO mappings for when using the firmware drivers, hence saying "NOT for use with vc4-kms-v3d."

There is vc4-kms-vga666. It'll default to basic resolutions, but has the option to enable the DDC link using GPIOs 0&1 should you wish to hook up to a genuine VGA monitor with EDID to be read.
Note that it needs level shifters on those GPIOs as they are NOT 5V tolerant.
Also note that vga666 boards have a wiring issue that makes this trickier than you'd expect - fenlogic/vga666#15

vc4-kms-dpi-generic allows you to set up the desired timing from the overlay.

dpi_group/dpi_mode/dpi_timings are going to do nothing.

Interlacing support has issues over how it should be configured from the simplified progressive mode that is passed in. There are options for odd field first or even field first, and what delay should be inserted on the two fields etc. Without a standardised way to interpret that information, there's no way to make a generic solution.

@pelwell
Copy link
Contributor

pelwell commented Apr 18, 2023

And you can read bits of the README with the dtoverlay command, e.g. dtoverlay -h vga666.

@substring
Copy link

@blitzcode Let's not hijack further this issue. Just know that libretro/RetroArch@f24893b is my contribution to Retroarch, you can build it. It will be anyway shipped in RA 1.16. I used the generic vc4-kms-vga666 overlay, but I really preferred using HDMI (because interlaced works there). Getting your pi to boot in 240p will be quite tricky, even more with kernel 6.1, see https://forums.raspberrypi.com/viewtopic.php?t=344246&start=225#p2086061

@popcornmix
Copy link
Contributor

@substring you linked to a post about

Your EDID describes itself as being an analog display, and update_display_info [aborts if it isn't a digital display]

but that was fixed in raspberrypi/linux#5378 (and that fix has reached apt kernels).

@blitzcode
Copy link

Thanks @6by9 / @substring / @pelwell for answering my dumb questions, I'll stop now ;-) It seems even years later for me the best strategy would be just keep waiting for fixes/improvements. I don't think I want to update my kernel, compile my own RetroArch and edit a device tree overlay and then debug whatever tricky issues arise with kernel 6.1 and what else I've missed. It's a shame this has regressed so much from the Pi3 days. I can see why so many people in the CRT gaming community still think this isn't working at all on the Pi4. Seems like the RGBPi/Recalbox folk have figured out a solution a while ago that works for them, but I don't think I'll try to bring my own setup forward to the Pi4 at this point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants