User avatar
dividuum
Posts: 168
Joined: Sun Jun 16, 2013 1:18 pm
Location: Germany
Contact: Website

Relationship between mode set with `tvservice` and DRM

Thu Aug 15, 2019 2:17 pm

If I set a video mode with `tvservice` on a FullHD display, for example like this:

Code: Select all

[email protected]:~# tvservice -e "CEA 4"
Powering on HDMI with explicit settings (CEA mode 4)
[email protected]:~# tvservice -s
state 0xa [HDMI CEA (4) RGB lim 16:9], 1280x720 @ 60.00Hz, progressive
The modetest tool doesn't show that change and still shows 1920x1080:

Code: Select all

Connectors:
id      encoder status          name            size (mm)       modes   encoders
51      50      connected       HDMI-A-1        480x270         38      50
  modes:
        name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
  1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
<..snip...>
CRTCs:
id      fb      pos     size
49      58      (0,0)   (1920x1080)  <--------------- This is the active CRTC configuration for display
  1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
Is that expected? Is there a way to query the true active mode from DRM somehow? What's the easiest way to set up DRM with the currently active mode?
info-beamer hosted - A user and programmer friendly digital signage platform for the Pi: https://info-beamer.com/hosted

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7147
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Relationship between mode set with `tvservice` and DRM

Mon Aug 19, 2019 12:25 pm

DRM is sitting on top of the firmware modesetting. tvservice is an alternate way into the same subsystem.
Using tvservice will cause grief with DRM as DRM has no idea that things have changed (it believes it is master and no one else can change things).

It's the same as DispmanX including being an alternate way to insert extra layers onto the display. It'll work, but don't expect DRM to know about them.

For changing mode, see the modetest tool

Code: Select all

modetest -M vc4 -d -s [email protected]:1280x720-60
selects 720p60 for me and puts up a test pattern. 51 is my connector ID, 49 is the CRTC ID.

For the current resolution, read the properties of the CRTC, same as modetest dumps out from -p

Code: Select all

CRTCs:
id      fb      pos     size
49      60      (0,0)   (1920x1080)
  1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync, 2D; type: preferred, driver
The mode appears to be in (struct) drmModeCrtc mode

Code: Select all

typedef struct _drmModeCrtc {
	uint32_t crtc_id;
	uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */

	uint32_t x, y; /**< Position on the framebuffer */
	uint32_t width, height;
	int mode_valid;
	drmModeModeInfo mode; <<<<<<<<<<<<<<<<<<<<

	int gamma_size; /**< Number of gamma stops */

} drmModeCrtc, *drmModeCrtcPtr;
(see dump_crtc() in modetest.c, and then dump_mode).
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

hjimbens
Posts: 50
Joined: Fri May 24, 2013 9:05 am

Re: Relationship between mode set with `tvservice` and DRM

Tue Aug 20, 2019 10:08 am

After cloning and building https://cgit.freedesktop.org/mesa/drm/t ... s/modetest and calling with

Code: Select all

builddir/tests/modetest/modetest -M vc4 -d -s [email protected]:1920x1080-60
I get

Code: Select all

setting mode [email protected] on connectors 51, crtc 49
failed to set mode: Permission denied
and nothing changes.

User avatar
dividuum
Posts: 168
Joined: Sun Jun 16, 2013 1:18 pm
Location: Germany
Contact: Website

Re: Relationship between mode set with `tvservice` and DRM

Wed Aug 21, 2019 1:02 pm

6by9 wrote:
Mon Aug 19, 2019 12:25 pm
DRM is sitting on top of the firmware modesetting. tvservice is an alternate way into the same subsystem.
Using tvservice will cause grief with DRM as DRM has no idea that things have changed (it believes it is master and no one else can change things).
Thanks for the clarification.
modetest -M vc4 -d -s [email protected]:1280x720-60 selects 720p60 for me and puts up a test pattern. 51 is my connector ID, 49 is the CRTC ID.
Yep. That works. I'm still trying to wrap my head around how the EDID provided values, the possible DMT/CEA settings (from tvservice -m) and now the DRM modes relate. Guess it's time for more code reading.

My confusion mainly stemmed from what I observed Raspbian doing: I forced a 720p mode using hdmi_group/hdmi_mode in /boot/config.txt. The Pi booted with that and then, I guess while doing some frame buffer initialization, it switched back to FullHD. Then switching back with tvservice resulted in the DRM/tvservice mismatch that I now understand.
The mode appears to be in (struct) drmModeCrtc mode <...snip...> (see dump_crtc() in modetest.c, and then dump_mode).
Thanks. I'm using that already to rate the modes returned by connector->modes.
info-beamer hosted - A user and programmer friendly digital signage platform for the Pi: https://info-beamer.com/hosted

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7147
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Relationship between mode set with `tvservice` and DRM

Thu Aug 22, 2019 10:01 am

hjimbens wrote:
Tue Aug 20, 2019 10:08 am
After cloning and building https://cgit.freedesktop.org/mesa/drm/t ... s/modetest and calling with

Code: Select all

builddir/tests/modetest/modetest -M vc4 -d -s [email protected]:1920x1080-60
I get

Code: Select all

setting mode [email protected] on connectors 51, crtc 49
failed to set mode: Permission denied
and nothing changes.
At a guess you're running X rather than booting to the console.
DRM supports a single authorised client at a time, and that will be X if it is running. X supports changing resolution via xrandr, or the more user friendly Screen Configuration tool (a patched version of arandr).

The CRTC and plane IDs are computed dynamically so may change between systems and kernel versions. Running "modetest -M vc4" will dump out the full DRM config, including the IDs of each item within the DRM/KMS subsystem.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7147
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Relationship between mode set with `tvservice` and DRM

Thu Aug 22, 2019 10:32 am

dividuum wrote:
Wed Aug 21, 2019 1:02 pm
Yep. That works. I'm still trying to wrap my head around how the EDID provided values, the possible DMT/CEA settings (from tvservice -m) and now the DRM modes relate. Guess it's time for more code reading.
DRM merges CEA and DMT modes into a single table, and also parses all the detailed timings present in the EDID.

CEA vs DMT has limited implications if overscan isn't supported (CEA may be overscanned by the device, DMT won't be), and beyond the RGB range issue (CEA squashes the range to 16-235, DMT uses 0-255).
The behaviour from a timing perspective is identical, and the kernel DRM API has a magic function called drm_default_rgb_quant_range to deal with the RGB range (it compares the mode against the standard CEA modes, and returns HDMI_QUANTIZATION_RANGE_LIMITED if it matches and isn't VGA).
None of this is relevant to userspace, therefore it can largely be ignored.

EDID parsing is done via drm_add_edid_modes, having read it and added it to the connector properties (https://github.com/raspberrypi/linux/bl ... ms.c#L1322). It walks through the various sections of the EDID adding any modes that are defined within. Once all modes are added, it iterates through the list, removes duplicates, and checks with the driver whether they are supportable (eg 3D modes, YUV420, interlaced, max pixel frequency). The final result is what is advertised to userspace.
dividuum wrote:My confusion mainly stemmed from what I observed Raspbian doing: I forced a 720p mode using hdmi_group/hdmi_mode in /boot/config.txt. The Pi booted with that and then, I guess while doing some frame buffer initialization, it switched back to FullHD. Then switching back with tvservice resulted in the DRM/tvservice mismatch that I now understand.
This is the learning curve I've been working through for the last 4 months or so.
hdmi_group/hdmi_mode only tell the firmware which mode to select for the initial boot. The firmware EDID parsing differs from the kernel one, so can end up with a slightly different list of modes (I'd love to replace the firmware parser, but the risk of regressions is far too great to really entertain it).

The firmware will add to the kernel command line something like "video=HDMI-A-1:[email protected]" (or whatever the firmware has chosen as a mode) in an attempt to make the kernel choose the same mode.
That works fine if that mode is found and active within the EDID. If it isn't, then the kernel ADDS it as a supported mode, but using the VESA Generalized Timing Formula (GTF). Most displays actually want the Coordinated Video Timings (CVT), therefore we get a weird mode that may not even be acceptable to the Pi, let alone the display (GTF typically has a higher pixel clock vs CVT for the same resolution).
This is one of the headaches I'm trying to resolve at the moment, but it's all in common DRM code, therefore it's a case of needing to understand it, make sure it isn't changing with upcoming kernels or being discussed, and making changes in a maintainable manner. (The short term fix is likely to be a way of skipping the firmware adding to the command line at all in the hope that the EDID parsing comes up with something plausible).

Having done all of that, the further fun is that X decides to be independent of any resolution that the firmware may have passed up to the kernel command line, and it parses the DRM modes list and chooses what it wants (generally the highest res). So much of the above is a waste of time for the majority who boot into X :roll:
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

User avatar
dividuum
Posts: 168
Joined: Sun Jun 16, 2013 1:18 pm
Location: Germany
Contact: Website

Re: Relationship between mode set with `tvservice` and DRM

Thu Aug 22, 2019 11:35 am

6by9 wrote:
Thu Aug 22, 2019 10:32 am
The behaviour from a timing perspective is identical, and the kernel DRM API has a magic function called drm_default_rgb_quant_range to deal with the RGB range (it compares the mode against the standard CEA modes, and returns HDMI_QUANTIZATION_RANGE_LIMITED if it matches and isn't VGA).
None of this is relevant to userspace, therefore it can largely be ignored.
Is there a way to query whether or not a mode in connector->modes is full/limited? I don't see anything obvious on either kernel or userland.
The firmware will add to the kernel command line something like "video=HDMI-A-1:[email protected]" (or whatever the firmware has chosen as a mode) in an attempt to make the kernel choose the same mode.
Oh. I didn't notice that. That might come handy. Is the clock rate rounded? How are odd modes with 59.94Hz handled? I guess the video= value is meant to be compared to the drm modes name[] and the vrefresh value? I've found code that calculates the true refresh rate based on clock, htotal and vtotal as vrefresh is always rounded due to it being an uint32_t?
Having done all of that, the further fun is that X decides to be independent of any resolution that the firmware may have passed up to the kernel command line, and it parses the DRM modes list and chooses what it wants (generally the highest res). So much of the above is a waste of time for the majority who boot into X :roll:
I very much appreciate all of that :-)
info-beamer hosted - A user and programmer friendly digital signage platform for the Pi: https://info-beamer.com/hosted

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7147
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Relationship between mode set with `tvservice` and DRM

Thu Aug 22, 2019 12:59 pm

dividuum wrote:
Thu Aug 22, 2019 11:35 am
6by9 wrote:
Thu Aug 22, 2019 10:32 am
The behaviour from a timing perspective is identical, and the kernel DRM API has a magic function called drm_default_rgb_quant_range to deal with the RGB range (it compares the mode against the standard CEA modes, and returns HDMI_QUANTIZATION_RANGE_LIMITED if it matches and isn't VGA).
None of this is relevant to userspace, therefore it can largely be ignored.
Is there a way to query whether or not a mode in connector->modes is full/limited? I don't see anything obvious on either kernel or userland.
No as generally userspace doesn't care.
The source planes are always defined by their properties (eg BT601/709/2020 for YUV frames, and RGB being 0-255). This scaling is done via a colour space conversion block in the HDMI hardware. You can read it back via tvservice via the "lim" in

Code: Select all

[email protected]:~ $ tvservice -s
state 0xa [HDMI CUSTOM RGB lim 16:9], 1920x1080 @ 60.00Hz, progressive
Likewise you can override the setting using the "Broadcast RGB" property, reported by modetest as:

Code: Select all

        56 Broadcast RGB:
                flags: enum
                enums: Automatic=0 Full=1 Limited 16:235=2
                value: 0
That's a clone of how Intel cards add a user override on the RGB HDMI range. I added it as Simon Long's monitor didn't read the HDMI AVI Infoframe to determine the range, and he was then complaining that his carefully chosen shades of grey looked wrong!
dividuum wrote:
The firmware will add to the kernel command line something like "video=HDMI-A-1:[email protected]" (or whatever the firmware has chosen as a mode) in an attempt to make the kernel choose the same mode.
Oh. I didn't notice that. That might come handy. Is the clock rate rounded? How are odd modes with 59.94Hz handled? I guess the video= value is meant to be compared to the drm modes name[] and the vrefresh value? I've found code that calculates the true refresh rate based on clock, htotal and vtotal as vrefresh is always rounded due to it being an uint32_t?
Yes, the refresh rate is rounded. DRM does add the dropframe versions of each mode via add_alternate_cea_modes.
Command line mode processing is done from drm_mode_parse_command_line_for_connector. Docs for the format are at https://github.com/raspberrypi/linux/bl ... modedb.txt
(That's helpful. It's been ported from the fbdev drivers, and I've just noticed thatthat the docs say it should use the CVT formula if you add 'M' in the args. I'd missed that one until now!)
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

User avatar
dividuum
Posts: 168
Joined: Sun Jun 16, 2013 1:18 pm
Location: Germany
Contact: Website

Re: Relationship between mode set with `tvservice` and DRM

Thu Aug 22, 2019 1:26 pm

6by9 wrote:
Thu Aug 22, 2019 12:59 pm
Likewise you can override the setting using the "Broadcast RGB" property, reported by modetest as:
Ah. That it. I'll play around with that eventually as I've also had some color range related complaints in the past. This should help. Thanks!
Yes, the refresh rate is rounded. DRM does add the dropframe versions of each mode via add_alternate_cea_modes.
Command line mode processing is done from drm_mode_parse_command_line_for_connector. Docs for the format are at https://github.com/raspberrypi/linux/bl ... modedb.txt
Thanks.
(That's helpful. It's been ported from the fbdev drivers, and I've just noticed thatthat the docs say it should use the CVT formula if you add 'M' in the args. I'd missed that one until now!)
:D
info-beamer hosted - A user and programmer friendly digital signage platform for the Pi: https://info-beamer.com/hosted

Return to “Graphics programming”