Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e98c115 authored by Uma Shankar's avatar Uma Shankar Committed by Alistair Delva
Browse files

BACKPORT: drm: Parse HDR metadata info from EDID



HDR metadata block is introduced in CEA-861.3 spec.
Parsing the same to get the panel's HDR metadata.

v2: Rebase and added Ville's POC changes to the patch.

v3: No Change

v4: Addressed Shashank's review comments

v5: Addressed Shashank's comment and added his RB.

v6: Addressed Jonas Karlman review comments.

v7: Adressed Ville's review comments and fixed the issue
with length handling.

v8: Put the length check as per the convention followed in
existing code, as suggested by Ville.

Signed-off-by: default avatarUma Shankar <uma.shankar@intel.com>
Reviewed-by: default avatarShashank Sharma <shashank.sharma@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1558015817-12025-4-git-send-email-uma.shankar@intel.com


(cherry picked from commit e85959d6cbe08521942a6118568a38ac671e8d7f)
Bug: 152417756
Signed-off-by: default avatarAlistair Delva <adelva@google.com>
Change-Id: Ie6a5f4d456109486118d148767239f455e4003c3
parent 4ae8f7c4
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -2902,6 +2902,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
#define VIDEO_BLOCK     0x02
#define VENDOR_BLOCK    0x03
#define SPEAKER_BLOCK	0x04
#define HDR_STATIC_METADATA_BLOCK	0x6
#define USE_EXTENDED_TAG 0x07
#define EXT_VIDEO_CAPABILITY_BLOCK 0x00
#define EXT_VIDEO_DATA_BLOCK_420	0x0E
@@ -3925,6 +3926,54 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode)
	mode->clock = clock;
}

static bool cea_db_is_hdmi_hdr_metadata_block(const u8 *db)
{
	if (cea_db_tag(db) != USE_EXTENDED_TAG)
		return false;

	if (db[1] != HDR_STATIC_METADATA_BLOCK)
		return false;

	if (cea_db_payload_len(db) < 3)
		return false;

	return true;
}

static uint8_t eotf_supported(const u8 *edid_ext)
{
	return edid_ext[2] &
		(BIT(HDMI_EOTF_TRADITIONAL_GAMMA_SDR) |
		 BIT(HDMI_EOTF_TRADITIONAL_GAMMA_HDR) |
		 BIT(HDMI_EOTF_SMPTE_ST2084));
}

static uint8_t hdr_metadata_type(const u8 *edid_ext)
{
	return edid_ext[3] &
		BIT(HDMI_STATIC_METADATA_TYPE1);
}

static void
drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
{
	u16 len;

	len = cea_db_payload_len(db);

	connector->hdr_sink_metadata.hdmi_type1.eotf =
						eotf_supported(db);
	connector->hdr_sink_metadata.hdmi_type1.metadata_type =
						hdr_metadata_type(db);

	if (len >= 4)
		connector->hdr_sink_metadata.hdmi_type1.max_cll = db[4];
	if (len >= 5)
		connector->hdr_sink_metadata.hdmi_type1.max_fall = db[5];
	if (len >= 6)
		connector->hdr_sink_metadata.hdmi_type1.min_cll = db[6];
}

static void
drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db)
{
@@ -4575,6 +4624,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
			drm_parse_hdmi_forum_vsdb(connector, db);
		if (cea_db_is_y420cmdb(db))
			drm_parse_y420cmdb_bitmap(connector, db);
		if (cea_db_is_hdmi_hdr_metadata_block(db))
			drm_parse_hdr_metadata_block(connector, db);
	}
}