HDMI controller drivers will need to figure out the RGB range they need to configure based on a mode and property values. Let's expose that in the HDMI connector state so drivers can just use that value. Signed-off-by: Maxime Ripard <mripard@xxxxxxxxxx> --- drivers/gpu/drm/drm_atomic.c | 4 ++- drivers/gpu/drm/drm_atomic_state_helper.c | 44 +++++++++++++++++++++++++++++++ include/drm/drm_atomic_state_helper.h | 1 + include/drm/drm_connector.h | 6 +++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index b1b56dcaa76b..55cb117cd49a 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1143,9 +1143,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, 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) + 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)); + drm_printf(p, "\tis_full_range=%c\n", state->hdmi.is_full_range ? 'y' : 'n'); + } if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) if (state->writeback_job && state->writeback_job->fb) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 37193c6f9fca..c3f124af64dc 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -31,6 +31,7 @@ #include <drm/drm_connector.h> #include <drm/drm_crtc.h> #include <drm/drm_device.h> +#include <drm/drm_edid.h> #include <drm/drm_framebuffer.h> #include <drm/drm_plane.h> #include <drm/drm_print.h> @@ -622,6 +623,47 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, } EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); +static const struct drm_display_mode * +connector_state_get_mode(const struct drm_connector_state *conn_state) +{ + struct drm_atomic_state *state; + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + + state = conn_state->state; + if (!state) + return NULL; + + crtc = conn_state->crtc; + if (!crtc) + return NULL; + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (!crtc_state) + return NULL; + + return &crtc_state->mode; +} + +static bool hdmi_is_full_range(const struct drm_connector *connector, + const struct drm_connector_state *state) +{ + const struct drm_display_info *display = &connector->display_info; + const struct drm_display_mode *mode = + connector_state_get_mode(state); + + if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL) + return true; + + if (state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED) + return false; + + if (!display->is_hdmi) + return true; + + return drm_default_rgb_quant_range(mode); +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -642,6 +684,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, struct drm_connector_state *new_state = drm_atomic_get_new_connector_state(state, connector); + new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state); + if (old_state->hdmi.broadcast_rgb != new_state->hdmi.broadcast_rgb) { struct drm_crtc *crtc = new_state->crtc; struct drm_crtc_state *crtc_state; diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index d59d2b3aef9a..8072ac18e536 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -88,6 +88,7 @@ void __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, struct drm_connector_state *state); + void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, struct drm_private_state *state); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 168009f588ab..fc1fa754a40d 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1053,6 +1053,12 @@ struct drm_connector_state { * Broadcast RGB selection value. */ enum drm_hdmi_broadcast_rgb broadcast_rgb; + + /** + * @is_full_range: Is the output supposed to use a full + * RGB Quantization Range or not? + */ + bool is_full_range; } hdmi; }; -- 2.41.0