From 8f146c3559e181abae1d25d9e40c094fe7bbf7cf Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Fri, 14 Aug 2020 09:18:08 +0800 Subject: [PATCH] drm: rockchip: dw-hdmi: Change HDR_PANEL_METADATA to private property For compatibility with GKI, HDR_PANEL_METADATA can't be a global property. So change HDR_PANEL_METADATA to Rockchip private property. Signed-off-by: Algea Cao Change-Id: I7926683a5dc6274e6cab2151e476344fa897b66c --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 31 ++++++++++++++- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 42 +++++++++++++++++++-- include/drm/bridge/dw_hdmi.h | 2 + 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 4a357aeb368d..619baa44ec76 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2629,6 +2629,35 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); } +static int +dw_hdmi_update_hdr_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, + connector); + void *data = hdmi->plat_data->phy_data; + const struct hdr_static_metadata *metadata = + &connector->hdr_sink_metadata.hdmi_type1; + size_t size = sizeof(*metadata); + struct drm_property *property; + struct drm_property_blob *blob; + int ret; + + if (hdmi->plat_data->get_hdr_property) + property = hdmi->plat_data->get_hdr_property(data); + else + return -EINVAL; + + if (hdmi->plat_data->get_hdr_blob) + blob = hdmi->plat_data->get_hdr_blob(data); + else + return -EINVAL; + + ret = drm_property_replace_global_blob(dev, &blob, size, metadata, + &connector->base, property); + return ret; +} + static int dw_hdmi_connector_get_modes(struct drm_connector *connector) { struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, @@ -2654,7 +2683,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) drm_connector_update_edid_property(connector, edid); cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid); ret = drm_add_edid_modes(connector, edid); - drm_mode_connector_update_hdr_property(connector, metedata); + dw_hdmi_update_hdr_property(connector); kfree(edid); } else { hdmi->sink_is_hdmi = true; diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 356c1840351f..ca9128e86e7f 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -119,6 +119,9 @@ struct rockchip_hdmi { struct drm_property *outputmode_capacity; struct drm_property *colorimetry_property; struct drm_property *quant_range; + struct drm_property *hdr_panel_metadata_property; + + struct drm_property_blob *hdr_panel_blob_ptr; unsigned int colordepth; unsigned int colorimetry; @@ -805,6 +808,22 @@ dw_hdmi_rockchip_get_quant_range(void *data) return hdmi->hdmi_quant_range; } +static struct drm_property * +dw_hdmi_rockchip_get_hdr_property(void *data) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + + return hdmi->hdr_panel_metadata_property; +} + +static struct drm_property_blob * +dw_hdmi_rockchip_get_hdr_blob(void *data) +{ + struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data; + + return hdmi->hdr_panel_blob_ptr; +} + static const struct drm_prop_enum_list color_depth_enum_list[] = { { 0, "Automatic" }, /* Prefer highest color depth */ { 8, "24bit" }, @@ -928,12 +947,19 @@ dw_hdmi_rockchip_attach_properties(struct drm_connector *connector, drm_object_attach_property(&connector->base, prop, 0); } + + prop = drm_property_create(connector->dev, + DRM_MODE_PROP_BLOB | + DRM_MODE_PROP_IMMUTABLE, + "HDR_PANEL_METADATA", 0); + if (prop) { + hdmi->hdr_panel_metadata_property = prop; + drm_object_attach_property(&connector->base, prop, 0); + } + prop = connector->dev->mode_config.hdr_output_metadata_property; if (version >= 0x211a) drm_object_attach_property(&connector->base, prop, 0); - - prop = connector->dev->mode_config.hdr_panel_metadata_property; - drm_object_attach_property(&connector->base, prop, 0); } static void @@ -977,6 +1003,12 @@ dw_hdmi_rockchip_destroy_properties(struct drm_connector *connector, hdmi->colorimetry_property); hdmi->colordepth_capacity = NULL; } + + if (hdmi->hdr_panel_metadata_property) { + drm_property_destroy(connector->dev, + hdmi->hdr_panel_metadata_property); + hdmi->hdr_panel_metadata_property = NULL; + } } static int @@ -1308,6 +1340,10 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, dw_hdmi_rockchip_get_enc_out_encoding; plat_data->get_quant_range = dw_hdmi_rockchip_get_quant_range; + plat_data->get_hdr_property = + dw_hdmi_rockchip_get_hdr_property; + plat_data->get_hdr_blob = + dw_hdmi_rockchip_get_hdr_blob; plat_data->property_ops = &dw_hdmi_rockchip_property_ops; encoder = &hdmi->encoder; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index d7fde7dfe0ba..d8f1082b7fab 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -176,6 +176,8 @@ struct dw_hdmi_plat_data { unsigned long (*get_enc_in_encoding)(void *data); unsigned long (*get_enc_out_encoding)(void *data); unsigned long (*get_quant_range)(void *data); + struct drm_property *(*get_hdr_property)(void *data); + struct drm_property_blob *(*get_hdr_blob)(void *data); /* Vendor Property support */ const struct dw_hdmi_property_ops *property_ops;