Commit bccd5c51 authored by Dave Stevenson's avatar Dave Stevenson Committed by Maxime Ripard

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: default avatarDave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210430094451.2145002-3-maxime@cerno.tech
parent 72921cdf
...@@ -214,6 +214,31 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) ...@@ -214,6 +214,31 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
return ret; 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) static void vc4_hdmi_connector_reset(struct drm_connector *connector)
{ {
struct vc4_hdmi_connector_state *old_state = struct vc4_hdmi_connector_state *old_state =
...@@ -263,6 +288,7 @@ static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { ...@@ -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 = { static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
.get_modes = vc4_hdmi_connector_get_modes, .get_modes = vc4_hdmi_connector_get_modes,
.atomic_check = vc4_hdmi_connector_atomic_check,
}; };
static int vc4_hdmi_connector_init(struct drm_device *dev, static int vc4_hdmi_connector_init(struct drm_device *dev,
...@@ -299,6 +325,9 @@ 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->interlace_allowed = 1;
connector->doublescan_allowed = 0; connector->doublescan_allowed = 0;
if (vc4_hdmi->variant->supports_hdr)
drm_connector_attach_hdr_output_metadata_property(connector);
drm_connector_attach_encoder(connector, encoder); drm_connector_attach_encoder(connector, encoder);
return 0; return 0;
...@@ -432,6 +461,25 @@ static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder) ...@@ -432,6 +461,25 @@ static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
vc4_hdmi_write_infoframe(encoder, &frame); 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) static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
{ {
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(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) ...@@ -444,6 +492,8 @@ static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
*/ */
if (vc4_hdmi->audio.streaming) if (vc4_hdmi->audio.streaming)
vc4_hdmi_set_audio_infoframe(encoder); vc4_hdmi_set_audio_infoframe(encoder);
vc4_hdmi_set_hdr_infoframe(encoder);
} }
static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *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 = { ...@@ -2102,6 +2152,7 @@ static const struct vc4_hdmi_variant bcm2835_variant = {
.phy_rng_enable = vc4_hdmi_phy_rng_enable, .phy_rng_enable = vc4_hdmi_phy_rng_enable,
.phy_rng_disable = vc4_hdmi_phy_rng_disable, .phy_rng_disable = vc4_hdmi_phy_rng_disable,
.channel_map = vc4_hdmi_channel_map, .channel_map = vc4_hdmi_channel_map,
.supports_hdr = false,
}; };
static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = { static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
...@@ -2129,6 +2180,7 @@ 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_enable = vc5_hdmi_phy_rng_enable,
.phy_rng_disable = vc5_hdmi_phy_rng_disable, .phy_rng_disable = vc5_hdmi_phy_rng_disable,
.channel_map = vc5_hdmi_channel_map, .channel_map = vc5_hdmi_channel_map,
.supports_hdr = true,
}; };
static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
...@@ -2156,6 +2208,7 @@ 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_enable = vc5_hdmi_phy_rng_enable,
.phy_rng_disable = vc5_hdmi_phy_rng_disable, .phy_rng_disable = vc5_hdmi_phy_rng_disable,
.channel_map = vc5_hdmi_channel_map, .channel_map = vc5_hdmi_channel_map,
.supports_hdr = true,
}; };
static const struct of_device_id vc4_hdmi_dt_match[] = { static const struct of_device_id vc4_hdmi_dt_match[] = {
......
...@@ -99,6 +99,9 @@ struct vc4_hdmi_variant { ...@@ -99,6 +99,9 @@ struct vc4_hdmi_variant {
/* Callback to get channel map */ /* Callback to get channel map */
u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask); u32 (*channel_map)(struct vc4_hdmi *vc4_hdmi, u32 channel_mask);
/* Enables HDR metadata */
bool supports_hdr;
}; };
/* HDMI audio information */ /* HDMI audio information */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment