On Mon, Jan 15, 2024 at 03:37:20PM +0100, Sebastian Wick wrote: > On Mon, Jan 15, 2024 at 03:33:08PM +0100, Sebastian Wick wrote: > > On Thu, Dec 07, 2023 at 04:49:31PM +0100, Maxime Ripard wrote: > > > The i915 driver has a property to force the RGB range of an HDMI output. > > > The vc4 driver then implemented the same property with the same > > > semantics. KWin has support for it, and a PR for mutter is also there to > > > support it. > > > > > > Both drivers implementing the same property with the same semantics, > > > plus the userspace having support for it, is proof enough that it's > > > pretty much a de-facto standard now and we can provide helpers for it. > > > > > > Let's plumb it into the newly created HDMI connector. > > > > > > Signed-off-by: Maxime Ripard <mrip...@kernel.org> > > > --- > > > Documentation/gpu/kms-properties.csv | 1 - > > > drivers/gpu/drm/drm_atomic.c | 5 + > > > drivers/gpu/drm/drm_atomic_state_helper.c | 17 + > > > drivers/gpu/drm/drm_atomic_uapi.c | 4 + > > > drivers/gpu/drm/drm_connector.c | 76 +++++ > > > drivers/gpu/drm/tests/Makefile | 1 + > > > .../gpu/drm/tests/drm_atomic_state_helper_test.c | 376 > > > +++++++++++++++++++++ > > > drivers/gpu/drm/tests/drm_connector_test.c | 117 ++++++- > > > drivers/gpu/drm/tests/drm_kunit_edid.h | 106 ++++++ > > > include/drm/drm_connector.h | 36 ++ > > > 10 files changed, 737 insertions(+), 2 deletions(-) > > > > > > diff --git a/Documentation/gpu/kms-properties.csv > > > b/Documentation/gpu/kms-properties.csv > > > index 0f9590834829..caef14c532d4 100644 > > > --- a/Documentation/gpu/kms-properties.csv > > > +++ b/Documentation/gpu/kms-properties.csv > > > @@ -17,7 +17,6 @@ Owner Module/Drivers,Group,Property Name,Type,Property > > > Values,Object attached,De > > > ,Virtual GPU,“suggested X”,RANGE,"Min=0, > > > Max=0xffffffff",Connector,property to suggest an X offset for a connector > > > ,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to > > > suggest an Y offset for a connector > > > ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" > > > }",Connector,TDB > > > -i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", > > > ""Limited 16:235"" }",Connector,"When this property is set to Limited > > > 16:235 and CTM is set, the hardware will be programmed with the result of > > > the multiplication of CTM by the limited range matrix to ensure the > > > pixels normally in the range 0..1.0 are remapped to the range > > > 16/255..235/255." > > > ,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" > > > }",Connector,TBD > > > ,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" > > > } etc.",Connector,TBD > > > ,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD > > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > > > index c31fc0b48c31..1465a7f09a0b 100644 > > > --- a/drivers/gpu/drm/drm_atomic.c > > > +++ b/drivers/gpu/drm/drm_atomic.c > > > @@ -1142,6 +1142,11 @@ static void > > > drm_atomic_connector_print_state(struct drm_printer *p, > > > drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc); > > > drm_printf(p, "\tcolorspace=%s\n", > > > drm_get_colorspace_name(state->colorspace)); > > > > > > + if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || > > > + connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) > > > + drm_printf(p, "\tbroadcast_rgb=%s\n", > > > + > > > drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); > > > + > > > if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) > > > if (state->writeback_job && state->writeback_job->fb) > > > drm_printf(p, "\tfb=%d\n", > > > state->writeback_job->fb->base.id); > > > diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c > > > b/drivers/gpu/drm/drm_atomic_state_helper.c > > > index e69c0cc1c6da..10d98620a358 100644 > > > --- a/drivers/gpu/drm/drm_atomic_state_helper.c > > > +++ b/drivers/gpu/drm/drm_atomic_state_helper.c > > > @@ -583,6 +583,7 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); > > > void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector > > > *connector, > > > struct drm_connector_state > > > *new_state) > > > { > > > + new_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO; > > > } > > > EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); > > > > > > @@ -650,6 +651,22 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); > > > int drm_atomic_helper_connector_hdmi_check(struct drm_connector > > > *connector, > > > struct drm_atomic_state *state) > > > { > > > + struct drm_connector_state *old_state = > > > + drm_atomic_get_old_connector_state(state, connector); > > > + struct drm_connector_state *new_state = > > > + drm_atomic_get_new_connector_state(state, connector); > > > + > > > + if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) { > > > + struct drm_crtc *crtc = new_state->crtc; > > > + struct drm_crtc_state *crtc_state; > > > + > > > + crtc_state = drm_atomic_get_crtc_state(state, crtc); > > > + if (IS_ERR(crtc_state)) > > > + return PTR_ERR(crtc_state); > > > + > > > + crtc_state->mode_changed = true; > > > + } > > > + > > > return 0; > > > } > > > EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); > > > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c > > > b/drivers/gpu/drm/drm_atomic_uapi.c > > > index aee4a65d4959..3eb4f4bc8b71 100644 > > > --- a/drivers/gpu/drm/drm_atomic_uapi.c > > > +++ b/drivers/gpu/drm/drm_atomic_uapi.c > > > @@ -818,6 +818,8 @@ static int drm_atomic_connector_set_property(struct > > > drm_connector *connector, > > > state->max_requested_bpc = val; > > > } else if (property == connector->privacy_screen_sw_state_property) { > > > state->privacy_screen_sw_state = val; > > > + } else if (property == connector->broadcast_rgb_property) { > > > + state->hdmi.broadcast_rgb = val; > > > } else if (connector->funcs->atomic_set_property) { > > > return connector->funcs->atomic_set_property(connector, > > > state, property, val); > > > @@ -901,6 +903,8 @@ drm_atomic_connector_get_property(struct > > > drm_connector *connector, > > > *val = state->max_requested_bpc; > > > } else if (property == connector->privacy_screen_sw_state_property) { > > > *val = state->privacy_screen_sw_state; > > > + } else if (property == connector->broadcast_rgb_property) { > > > + *val = state->hdmi.broadcast_rgb; > > > } else if (connector->funcs->atomic_get_property) { > > > return connector->funcs->atomic_get_property(connector, > > > state, property, val); > > > diff --git a/drivers/gpu/drm/drm_connector.c > > > b/drivers/gpu/drm/drm_connector.c > > > index d9961cce8245..929b0a911f62 100644 > > > --- a/drivers/gpu/drm/drm_connector.c > > > +++ b/drivers/gpu/drm/drm_connector.c > > > @@ -1183,6 +1183,29 @@ static const u32 dp_colorspaces = > > > BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) | > > > BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); > > > > > > +static const struct drm_prop_enum_list broadcast_rgb_names[] = { > > > + { DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" }, > > > + { DRM_HDMI_BROADCAST_RGB_FULL, "Full" }, > > > + { DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" }, > > > +}; > > > + > > > +/* > > > + * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI > > > connector RGB broadcast selection > > > + * @broadcast_rgb: Broadcast RGB selection to compute name of > > > + * > > > + * Returns: the name of the Broadcast RGB selection, or NULL if the type > > > + * is not valid. > > > + */ > > > +const char * > > > +drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb > > > broadcast_rgb) > > > +{ > > > + if (broadcast_rgb > DRM_HDMI_BROADCAST_RGB_LIMITED) > > > + return NULL; > > > + > > > + return broadcast_rgb_names[broadcast_rgb].name; > > > +} > > > +EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name); > > > + > > > /** > > > * DOC: standard connector properties > > > * > > > @@ -1655,6 +1678,26 @@ > > > EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property); > > > /** > > > * DOC: HDMI connector properties > > > * > > > + * Broadcast RGB > > > + * Indicates the RGB Quantization Range (Full vs Limited) used. > > > + * Infoframes will be generated according to that value. > > > + * > > > + * The value of this property can be one of the following: > > > + * > > > + * Automatic: > > > + * RGB Range is selected automatically based on the mode > > > + * according to the HDMI specifications. > > > + * > > > + * Full: > > > + * Full RGB Range is forced. > > > + * > > > + * Limited 16:235: > > > + * Limited RGB Range is forced. Unlike the name suggests, > > > + * this works for any number of bits-per-component. > > > + * > > > + * Drivers can set up this property by calling > > > + * drm_connector_attach_broadcast_rgb_property(). > > > + * > > > > This is a good time to document this in more detail. There might be two > > different things being affected: > > > > 1. The signalling (InfoFrame/SDP/...) > > 2. The color pipeline processing > > > > All values of Broadcast RGB always affect the color pipeline processing > > such that a full-range input to the CRTC is converted to either full- or > > limited-range, depending on what the monitor is supposed to accept. > > > > When automatic is selected, does that mean that there is no signalling, > > or that the signalling matches what the monitor is supposed to accept > > according to the spec? Also, is this really HDMI specific? > > > > When full or limited is selected and the monitor doesn't support the > > signalling, what happens? > > Forgot to mention: user-space still has no control over RGB vs YCbCr on > the cable, so is this only affecting RGB? If not, how does it affect > YCbCr? i915 only supports it for RGB indeed: https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/i915/display/intel_hdmi.c#L2150
Maxime
signature.asc
Description: PGP signature