Open bit-bash opened 2 years ago
Note on bullseye the default is the kms driver and the firmware doesn't control HDMI (the kernel does). The firmware drivers are deprecated and unlikely to get new features.
You should look at doing this using drm/kms. That means no vcgencmd or tvservice.
I have disabled (commented out) the line dtoverlay=vc4-kms-v3d in /boot/config.txt. tvservice doesn't like the kms driver. And for the lite versions of the Raspbian OS, I don't need any fancy acceleration - I'm just displaying images on the framebuffer directly from Python.
You should look at doing this using drm/kms.
Can you give me a shove in the right direction? Not sure how to do HDMI/framebuffer timing/res changes on-the-fly by the drm/kms method.
I did ask @6by9 about this and:
I've looked through the code. DRM_IOCTL_MODE_SETCRTC takes a struct drm_mode_crtc - https://elixir.free-electrons.com/linux/latest/source/include/uapi/drm/drm_mode.h#L277 That includes a struct drm_mode_modeinfo with the full timings - https://elixir.free-electrons.com/linux/latest/source/include/uapi/drm/drm_mode.h#L242 modetest and xrandr are looking through the list of probed modes and copying the chosen one into the struct drm_mode_crtc. https://gitlab.freedesktop.org/mesa/drm/-/blob/main/tests/modetest/modetest.c#L836 is finding the specified mode in the list, called from https://gitlab.freedesktop.org/mesa/drm/-/blob/main/tests/modetest/modetest.c#L922 which assigns to pipe->mode. https://gitlab.freedesktop.org/mesa/drm/-/blob/main/tests/modetest/modetest.c#L1617 is then calling drmModeSetCrtc to set the mode. So it is largely going to be down to whether restoring the framebuffer resets that mode.
I'm not sure if there is example code that does this.
X does allow custom modes to be specified in Xorg.conf (see modeline, and if you were to dig into that code, you can probably find how it does it (and you could add it to your own application which would run outside of X). It probably is doing this through drmModeSetCrtc
.
Thanks for the great info! I will start looking through that stuff soon. One other thing I noticed, my current method using vcgencmd, tvservice, fbset works ok on the RPi 4 with a single HDMI display. If there are two HDMI displays things go strange and after trying to set the different fb options, sometimes tvservice will hang when asking it to display current settings. I'm also not sure if vcgencmd hdmi_timings tries to set both HDMI ports as I don't think vcgencmd has a option to specify witch HDMI port to set the timings for.
For reference: #637 Please can the ability to modify HDMI timings on the fly (i.e. without having to carry out a reboot) be added to the firmware drivers
I have been trying this with limited success without an fbset workaround. I have tested this on the 2022-04-04 LITE releases of 32-bit buster and 64-bit bullseye on both RPi 3B+ and RPi 4 (no desktop). I want to access /dev/fb0 at different display resolutions at 32 bits/pixel. I have added fbcon=map:2 to /boot/cmdline.txt so the kernel doesn't touch or display on /dev/fb0.
The basic premise is I can boot the RPi and it generally adapts to my HDMI display's preferred settings. Then, if I want to change the resolution to say 800x600, I can do this:
The issue I'm having is the fbset line isn't correctly setting the timings on the HDMI port. My 800x600 image loaded to /dev/fb0 only displays in the top corner of my native display (was 1920x1080).
To make it work the way I want, I have to do this:
fbset 800x600-60 -depth 32
Then I get the correct display timings for 800x600 @ 60Hz.The new issue this creates is that I now need to add any missing mode settings to /etc/fb.modes if they are not present. For example, if I want to change to 1280x720 (CEA mode 4), I can do this:
But then I have to add these lines into /etc/fb.modes:
Before I can do this:
fbset 1280x720-60 -depth 32
What I'm trying to figure out is how did this work before with only setting the -depth for fbset? Of course I can add resolutions to /etc/fb.modes that don't exist in my huge list of hdmi_timings. Am I missing something from the original issue or specifically a framebuffer issue that would have worked before? Thanks!