From: Dave Stevenson Date: Fri, 30 Apr 2021 09:44:49 +0000 (+0200) Subject: drm/vc4: Add HDR metadata property to the VC5 HDMI connectors X-Git-Tag: microblaze-v5.15~42^2~28^2~24 X-Git-Url: http://git.monstr.eu/?a=commitdiff_plain;h=bccd5c5102a97d62b6339ebbea5b3f805ba13c14;p=linux-2.6-microblaze.git drm/vc4: Add HDR metadata property to the VC5 HDMI connectors Now that we can export deeper colour depths, add in the signalling for HDR metadata. Signed-off-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210430094451.2145002-3-maxime@cerno.tech --- diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 1fda574579af..a1b18fefa559 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -214,6 +214,31 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) return ret; } +static int vc4_hdmi_connector_atomic_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); + struct drm_crtc *crtc = new_state->crtc; + + if (!crtc) + return 0; + + if (!drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) { + 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; +} + static void vc4_hdmi_connector_reset(struct drm_connector *connector) { struct vc4_hdmi_connector_state *old_state = @@ -263,6 +288,7 @@ static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = { .get_modes = vc4_hdmi_connector_get_modes, + .atomic_check = vc4_hdmi_connector_atomic_check, }; static int vc4_hdmi_connector_init(struct drm_device *dev, @@ -299,6 +325,9 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, connector->interlace_allowed = 1; connector->doublescan_allowed = 0; + if (vc4_hdmi->variant->supports_hdr) + drm_connector_attach_hdr_output_metadata_property(connector); + drm_connector_attach_encoder(connector, encoder); return 0; @@ -432,6 +461,25 @@ static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder) vc4_hdmi_write_infoframe(encoder, &frame); } +static void vc4_hdmi_set_hdr_infoframe(struct drm_encoder *encoder) +{ + struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); + struct drm_connector *connector = &vc4_hdmi->connector; + struct drm_connector_state *conn_state = connector->state; + union hdmi_infoframe frame; + + if (!vc4_hdmi->variant->supports_hdr) + return; + + if (!conn_state->hdr_output_metadata) + return; + + if (drm_hdmi_infoframe_set_hdr_metadata(&frame.drm, conn_state)) + return; + + vc4_hdmi_write_infoframe(encoder, &frame); +} + static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder) { struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); @@ -444,6 +492,8 @@ static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder) */ if (vc4_hdmi->audio.streaming) vc4_hdmi_set_audio_infoframe(encoder); + + vc4_hdmi_set_hdr_infoframe(encoder); } static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder, @@ -2102,6 +2152,7 @@ static const struct vc4_hdmi_variant bcm2835_variant = { .phy_rng_enable = vc4_hdmi_phy_rng_enable, .phy_rng_disable = vc4_hdmi_phy_rng_disable, .channel_map = vc4_hdmi_channel_map, + .supports_hdr = false, }; static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = { @@ -2129,6 +2180,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = { .phy_rng_enable = vc5_hdmi_phy_rng_enable, .phy_rng_disable = vc5_hdmi_phy_rng_disable, .channel_map = vc5_hdmi_channel_map, + .supports_hdr = true, }; static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { @@ -2156,6 +2208,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { .phy_rng_enable = vc5_hdmi_phy_rng_enable, .phy_rng_disable = vc5_hdmi_phy_rng_disable, .channel_map = vc5_hdmi_channel_map, + .supports_hdr = true, }; static const struct of_device_id vc4_hdmi_dt_match[] = { diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 3cebd1fd00fc..060bcaefbeb5 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -99,6 +99,9 @@ struct vc4_hdmi_variant { /* Callback to get channel map */ u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask); + + /* Enables HDR metadata */ + bool supports_hdr; }; /* HDMI audio information */