mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
drm/rockchip: dw_hdmi: Support get hdr10 plus vsdb
Add drm property HDR10_PLUS_VSDB that hdr10 plus data
in edid:
struct hdr10_plus_vsdb {
u8 application_version;
u8 full_frame_peak_luminance_index;
u8 peak_luminance_index;
};
Change-Id: I464cb67e0d9784df905bf34fd8472f80a6b98296
Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
@@ -2770,6 +2770,8 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
|
||||
hdmi->plat_data->get_colorimetry(data, edid);
|
||||
if (hdmi->plat_data->get_yuv422_format)
|
||||
hdmi->plat_data->get_yuv422_format(connector, edid);
|
||||
if (hdmi->plat_data->get_hdr10_plus_vsdb)
|
||||
hdmi->plat_data->get_hdr10_plus_vsdb(data, edid, connector);
|
||||
dw_hdmi_update_hdr_property(connector);
|
||||
if (ret > 0 && hdmi->plat_data->split_mode) {
|
||||
struct dw_hdmi_qp *secondary = NULL;
|
||||
|
||||
@@ -314,11 +314,13 @@ struct rockchip_hdmi {
|
||||
struct drm_property *mode_color_capacity;
|
||||
struct drm_property *hdr_panel_dovi_vsdb;
|
||||
struct drm_property *vsif_data;
|
||||
struct drm_property *hdr10_plus_vsdb;
|
||||
|
||||
struct drm_property_blob *mode_color_caps_ptr;
|
||||
struct drm_property_blob *hdr_panel_blob_ptr;
|
||||
struct drm_property_blob *hdr_panel_dovi_vsdb_ptr;
|
||||
struct drm_property_blob *vsif_data_ptr;
|
||||
struct drm_property_blob *hdr10_plus_vsdb_ptr;
|
||||
|
||||
unsigned int colordepth;
|
||||
unsigned int colorimetry;
|
||||
@@ -335,6 +337,7 @@ struct rockchip_hdmi {
|
||||
u8 edid_colorimetry;
|
||||
u8 hdcp_status;
|
||||
u8 dovi_vsdb[DOVI_VSDB_LEN];
|
||||
struct hdr10_plus_vsdb hdr10_plus_data;
|
||||
struct rockchip_drm_dsc_cap dsc_cap;
|
||||
struct dw_hdmi_link_config link_cfg;
|
||||
struct gpio_desc *enable_gpio;
|
||||
@@ -2867,6 +2870,31 @@ dw_hdmi_rockchip_get_edid_dsc_info(void *data, const struct edid *edid)
|
||||
&hdmi->max_lanes, &hdmi->add_func, edid);
|
||||
}
|
||||
|
||||
static int
|
||||
dw_hdmi_rockchip_get_hdr10_plus_vsdb(void *data, const struct edid *edid,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
int ret;
|
||||
struct rockchip_hdmi *hdmi = (struct rockchip_hdmi *)data;
|
||||
struct drm_property *property = hdmi->hdr10_plus_vsdb;
|
||||
u8 hdr10_plus;
|
||||
|
||||
if (!edid || !connector)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr10_plus = rockchip_drm_parse_hdr10_plus_vsdb(edid);
|
||||
|
||||
hdmi->hdr10_plus_data.application_version = hdr10_plus & 0x3;
|
||||
hdmi->hdr10_plus_data.full_frame_peak_luminance_index = hdr10_plus & 0xc;
|
||||
hdmi->hdr10_plus_data.peak_luminance_index = hdr10_plus & 0xf0;
|
||||
|
||||
ret = drm_property_replace_global_blob(connector->dev, &hdmi->hdr10_plus_vsdb_ptr,
|
||||
3, &hdmi->hdr10_plus_data, &connector->base,
|
||||
property);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dw_hdmi_rockchip_get_dovi_data(void *data, const struct edid *edid,
|
||||
struct drm_connector *connector)
|
||||
@@ -3418,6 +3446,15 @@ dw_hdmi_rockchip_attach_properties(struct drm_connector *connector,
|
||||
drm_object_attach_property(&connector->base, prop, 0);
|
||||
}
|
||||
hdmi->enable_allm = allm_en;
|
||||
|
||||
prop = drm_property_create(connector->dev,
|
||||
DRM_MODE_PROP_BLOB |
|
||||
DRM_MODE_PROP_IMMUTABLE,
|
||||
"HDR10_PLUS_VSDB", 0);
|
||||
if (prop) {
|
||||
hdmi->hdr10_plus_vsdb = prop;
|
||||
drm_object_attach_property(&connector->base, prop, 0);
|
||||
}
|
||||
}
|
||||
|
||||
prop = drm_property_create_enum(connector->dev, 0,
|
||||
@@ -3572,6 +3609,11 @@ dw_hdmi_rockchip_destroy_properties(struct drm_connector *connector,
|
||||
drm_property_destroy(connector->dev, hdmi->vsif_data);
|
||||
hdmi->vsif_data = NULL;
|
||||
}
|
||||
|
||||
if (hdmi->hdr10_plus_vsdb) {
|
||||
drm_property_destroy(connector->dev, hdmi->hdr10_plus_vsdb);
|
||||
hdmi->hdr10_plus_vsdb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -3652,6 +3694,8 @@ dw_hdmi_rockchip_set_property(struct drm_connector *connector,
|
||||
&hdmi->vsif_data_ptr,
|
||||
val, -1, -1, &replaced);
|
||||
return ret;
|
||||
} else if (property == hdmi->hdr10_plus_vsdb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DRM_ERROR("Unknown property [PROP:%d:%s]\n",
|
||||
@@ -3744,6 +3788,9 @@ dw_hdmi_rockchip_get_property(struct drm_connector *connector,
|
||||
} else if (property == hdmi->vsif_data) {
|
||||
*val = (hdmi->vsif_data_ptr) ? hdmi->vsif_data_ptr->base.id : 0;
|
||||
return 0;
|
||||
} else if (property == hdmi->hdr10_plus_vsdb) {
|
||||
*val = (hdmi->hdr10_plus_vsdb_ptr) ? hdmi->hdr10_plus_vsdb_ptr->base.id : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DRM_ERROR("Unknown property [PROP:%d:%s]\n",
|
||||
@@ -4445,6 +4492,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
|
||||
dw_hdmi_rockchip_get_colorimetry;
|
||||
plat_data->get_dovi_vsif =
|
||||
dw_hdmi_rockchip_get_vsif_data;
|
||||
plat_data->get_hdr10_plus_vsdb =
|
||||
dw_hdmi_rockchip_get_hdr10_plus_vsdb;
|
||||
plat_data->get_link_cfg = dw_hdmi_rockchip_get_link_cfg;
|
||||
plat_data->set_hdcp2_enable = rockchip_set_hdcp2_enable;
|
||||
plat_data->set_hdcp_status = rockchip_set_hdcp_status;
|
||||
|
||||
@@ -1179,6 +1179,50 @@ rockchip_drm_parse_colorimetry_data_block(u8 *colorimetry, const struct edid *ed
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_drm_parse_colorimetry_data_block);
|
||||
|
||||
#define HDR10_PLUS_OUI 0x90848b
|
||||
|
||||
static bool cea_db_is_hdr10_plus_block(const u8 *db)
|
||||
{
|
||||
unsigned int oui;
|
||||
|
||||
if (cea_db_tag(db) != CTA_DB_EXTENDED_TAG)
|
||||
return false;
|
||||
|
||||
if (cea_db_payload_len(db) < 5)
|
||||
return false;
|
||||
|
||||
oui = db[4] << 16 | db[3] << 8 | db[2];
|
||||
return oui == HDR10_PLUS_OUI;
|
||||
}
|
||||
|
||||
u8 rockchip_drm_parse_hdr10_plus_vsdb(const struct edid *edid)
|
||||
{
|
||||
const u8 *edid_ext;
|
||||
int i, start, end;
|
||||
u8 hdr10_plus = 0;
|
||||
|
||||
if (!edid)
|
||||
return 0;
|
||||
|
||||
edid_ext = find_cea_extension(edid);
|
||||
if (!edid_ext)
|
||||
return 0;
|
||||
|
||||
if (cea_db_offsets(edid_ext, &start, &end))
|
||||
return 0;
|
||||
|
||||
for_each_cea_db(edid_ext, i, start, end) {
|
||||
const u8 *db = &edid_ext[i];
|
||||
|
||||
if (cea_db_is_hdr10_plus_block(db))
|
||||
/* As per CEA 861-G spec */
|
||||
hdr10_plus = db[5];
|
||||
}
|
||||
|
||||
return hdr10_plus;
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_drm_parse_hdr10_plus_vsdb);
|
||||
|
||||
/*
|
||||
* Attach a (component) device to the shared drm dma mapping from master drm
|
||||
* device. This is used by the VOPs to map GEM buffers to a common DMA
|
||||
|
||||
@@ -669,6 +669,7 @@ int rockchip_drm_parse_cea_ext(struct rockchip_drm_dsc_cap *dsc_cap,
|
||||
const struct edid *edid);
|
||||
int rockchip_drm_parse_dovi(u8 *sink_data, const struct edid *edid);
|
||||
int rockchip_drm_parse_colorimetry_data_block(u8 *colorimetry, const struct edid *edid);
|
||||
u8 rockchip_drm_parse_hdr10_plus_vsdb(const struct edid *edid);
|
||||
struct dma_buf *rockchip_drm_gem_prime_export(struct drm_gem_object *obj, int flags);
|
||||
long rockchip_drm_dclk_round_rate(u32 version, struct clk *dclk, unsigned long rate);
|
||||
int rockchip_drm_dclk_set_rate(u32 version, struct clk *dclk, unsigned long rate);
|
||||
|
||||
@@ -148,6 +148,12 @@ struct dovi_vsif_data {
|
||||
u8 pb[28];
|
||||
};
|
||||
|
||||
struct hdr10_plus_vsdb {
|
||||
u8 application_version;
|
||||
u8 full_frame_peak_luminance_index;
|
||||
u8 peak_luminance_index;
|
||||
};
|
||||
|
||||
struct dw_hdmi_phy_ops {
|
||||
int (*init)(struct dw_hdmi *hdmi, void *data,
|
||||
const struct drm_display_info *display,
|
||||
@@ -286,6 +292,8 @@ struct dw_hdmi_plat_data {
|
||||
void *data);
|
||||
void (*crtc_pre_disable)(void *data, struct drm_crtc *crtc);
|
||||
void (*crtc_post_enable)(void *data, struct drm_crtc *crtc);
|
||||
int (*get_hdr10_plus_vsdb)(void *data, const struct edid *edid,
|
||||
struct drm_connector *connector);
|
||||
|
||||
/* Vendor Property support */
|
||||
const struct dw_hdmi_property_ops *property_ops;
|
||||
|
||||
Reference in New Issue
Block a user