summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-07-04 18:14:09 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-07-04 18:14:09 -0700
commit20e0861617d2104eb68405b7b76b641316ad5ccc (patch)
treee9015bb4bce2ef330110238a8b4dbbf7b1b215b2
parent8267ab99bd282c7ae0ff8eceb01911ef0d67cf9c (diff)
parentf9dd40aaef7e44f492c550907ecc98a097a0a562 (diff)
Merge "drm/msm: add support for parsing YUV 420 deep color"
-rw-r--r--drivers/gpu/drm/msm/sde_edid_parser.c73
-rw-r--r--include/drm/drm_edid.h5
2 files changed, 78 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/sde_edid_parser.c b/drivers/gpu/drm/msm/sde_edid_parser.c
index 69ab367307ea..ca9229ede251 100644
--- a/drivers/gpu/drm/msm/sde_edid_parser.c
+++ b/drivers/gpu/drm/msm/sde_edid_parser.c
@@ -93,6 +93,21 @@ for ((i) = (start); \
(i) < (end) && (i) + sde_cea_db_payload_len(&(cea)[(i)]) < (end); \
(i) += sde_cea_db_payload_len(&(cea)[(i)]) + 1)
+static bool sde_cea_db_is_hdmi_hf_vsdb(const u8 *db)
+{
+ int hdmi_id;
+
+ if (sde_cea_db_tag(db) != VENDOR_SPECIFIC_DATA_BLOCK)
+ return false;
+
+ if (sde_cea_db_payload_len(db) < 7)
+ return false;
+
+ hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16);
+
+ return hdmi_id == HDMI_IEEE_OUI_HF;
+}
+
static u8 *sde_edid_find_extended_tag_block(struct edid *edid, int blk_id)
{
u8 *db = NULL;
@@ -339,6 +354,63 @@ struct drm_connector *connector, struct sde_edid_ctrl *edid_ctrl)
SDE_EDID_DEBUG("%s -\n", __func__);
}
+static void _sde_edid_update_dc_modes(
+struct drm_connector *connector, struct sde_edid_ctrl *edid_ctrl)
+{
+ int i, start, end;
+ u8 *edid_ext, *hdmi;
+ struct drm_display_info *disp_info;
+ u32 hdmi_dc_yuv_modes = 0;
+
+ SDE_EDID_DEBUG("%s +\n", __func__);
+
+ if (!connector || !edid_ctrl) {
+ SDE_ERROR("invalid input\n");
+ return;
+ }
+
+ disp_info = &connector->display_info;
+
+ edid_ext = sde_find_cea_extension(edid_ctrl->edid);
+
+ if (!edid_ext) {
+ SDE_ERROR("no cea extension\n");
+ return;
+ }
+
+ if (sde_cea_db_offsets(edid_ext, &start, &end))
+ return;
+
+ sde_for_each_cea_db(edid_ext, i, start, end) {
+ if (sde_cea_db_is_hdmi_hf_vsdb(&edid_ext[i])) {
+
+ hdmi = &edid_ext[i];
+
+ if (sde_cea_db_payload_len(hdmi) < 7)
+ continue;
+
+ if (hdmi[7] & DRM_EDID_YCBCR420_DC_30) {
+ hdmi_dc_yuv_modes |= DRM_EDID_YCBCR420_DC_30;
+ SDE_EDID_DEBUG("Y420 30-bit supported\n");
+ }
+
+ if (hdmi[7] & DRM_EDID_YCBCR420_DC_36) {
+ hdmi_dc_yuv_modes |= DRM_EDID_YCBCR420_DC_36;
+ SDE_EDID_DEBUG("Y420 36-bit supported\n");
+ }
+
+ if (hdmi[7] & DRM_EDID_YCBCR420_DC_48) {
+ hdmi_dc_yuv_modes |= DRM_EDID_YCBCR420_DC_36;
+ SDE_EDID_DEBUG("Y420 48-bit supported\n");
+ }
+ }
+ }
+
+ disp_info->edid_hdmi_dc_modes |= hdmi_dc_yuv_modes;
+
+ SDE_EDID_DEBUG("%s -\n", __func__);
+}
+
static void _sde_edid_extract_audio_data_blocks(
struct sde_edid_ctrl *edid_ctrl)
{
@@ -476,6 +548,7 @@ int _sde_edid_update_modes(struct drm_connector *connector,
rc = drm_add_edid_modes(connector, edid_ctrl->edid);
sde_edid_set_mode_format(connector, edid_ctrl);
+ _sde_edid_update_dc_modes(connector, edid_ctrl);
SDE_EDID_DEBUG("%s -", __func__);
return rc;
}
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 4317ea41382f..69cb2ba37116 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -209,6 +209,11 @@ struct detailed_timing {
#define DRM_EDID_HDMI_DC_30 (1 << 4)
#define DRM_EDID_HDMI_DC_Y444 (1 << 3)
+/* YCBCR 420 deep color modes */
+#define DRM_EDID_YCBCR420_DC_48 (1 << 2)
+#define DRM_EDID_YCBCR420_DC_36 (1 << 1)
+#define DRM_EDID_YCBCR420_DC_30 (1 << 0)
+
/* ELD Header Block */
#define DRM_ELD_HEADER_BLOCK_SIZE 4