[v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index

Lee Shawn C shawn.c.lee at intel.com
Sun Mar 13 13:46:58 UTC 2022


drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

v2: save proper extension block index if CTA data information
    was found in DispalyID block.
v3: using different parameters to store CEA and DisplayID block index.
    configure DisplayID extansion block index before search available
    DisplayID block.

Cc: Jani Nikula <jani.nikula at linux.intel.com>
Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
Cc: Drew Davenport <ddavenport at chromium.org>
Cc: intel-gfx <intel-gfx at lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c.lee at intel.com>
---
 drivers/gpu/drm/drm_displayid.c | 10 +++++--
 drivers/gpu/drm/drm_edid.c      | 53 ++++++++++++++++++---------------
 include/drm/drm_displayid.h     |  4 +--
 3 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..31c3e6d7d549 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -59,11 +59,14 @@ static const u8 *drm_find_displayid_extension(const struct edid *edid,
 }
 
 void displayid_iter_edid_begin(const struct edid *edid,
-			       struct displayid_iter *iter)
+			       struct displayid_iter *iter, int *ext_index)
 {
 	memset(iter, 0, sizeof(*iter));
 
 	iter->edid = edid;
+
+	if (ext_index)
+		iter->ext_index = *ext_index;
 }
 
 static const struct displayid_block *
@@ -126,7 +129,10 @@ __displayid_iter_next(struct displayid_iter *iter)
 	}
 }
 
-void displayid_iter_end(struct displayid_iter *iter)
+void displayid_iter_end(struct displayid_iter *iter, int *ext_index)
 {
+	if (ext_index)
+		*ext_index = iter->ext_index;
+
 	memset(iter, 0, sizeof(*iter));
 }
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..78c415aa6889 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,28 +3353,27 @@ const u8 *drm_find_edid_extension(const struct edid *edid,
 	return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+					int *cea_ext_index, int *displayid_ext_index)
 {
 	const struct displayid_block *block;
 	struct displayid_iter iter;
 	const u8 *cea;
-	int ext_index = 0;
 
-	/* Look for a top level CEA extension block */
-	/* FIXME: make callers iterate through multiple CEA ext blocks? */
-	cea = drm_find_edid_extension(edid, CEA_EXT, &ext_index);
+	/* Look for a CEA extension block from ext_index */
+	cea = drm_find_edid_extension(edid, CEA_EXT, cea_ext_index);
 	if (cea)
 		return cea;
 
 	/* CEA blocks can also be found embedded in a DisplayID block */
-	displayid_iter_edid_begin(edid, &iter);
+	displayid_iter_edid_begin(edid, &iter, displayid_ext_index);
 	displayid_iter_for_each(block, &iter) {
 		if (block->tag == DATA_BLOCK_CTA) {
 			cea = (const u8 *)block;
 			break;
 		}
 	}
-	displayid_iter_end(&iter);
+	displayid_iter_end(&iter, displayid_ext_index);
 
 	return cea;
 }
@@ -3643,10 +3642,10 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
 	struct drm_device *dev = connector->dev;
 	struct drm_display_mode *mode, *tmp;
 	LIST_HEAD(list);
-	int modes = 0;
+	int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
 	/* Don't add CEA modes if the CEA extension block is missing */
-	if (!drm_find_cea_extension(edid))
+	if (!drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index))
 		return 0;
 
 	/*
@@ -4321,11 +4320,11 @@ static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
 static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
-	const u8 *cea = drm_find_cea_extension(edid);
-	const u8 *db, *hdmi = NULL, *video = NULL;
+	const u8 *cea, *db, *hdmi = NULL, *video = NULL;
 	u8 dbl, hdmi_len, video_len = 0;
-	int modes = 0;
+	int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
+	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
 	if (cea && cea_revision(cea) >= 3) {
 		int i, start, end;
 
@@ -4563,6 +4562,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 	const u8 *cea;
 	const u8 *db;
 	int total_sad_count = 0;
+	int cea_ext_index = 0, displayid_ext_index = 0;
 	int mnl;
 	int dbl;
 
@@ -4571,7 +4571,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 	if (!edid)
 		return;
 
-	cea = drm_find_cea_extension(edid);
+	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
 	if (!cea) {
 		DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
 		return;
@@ -4657,9 +4657,10 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 {
 	int count = 0;
 	int i, start, end, dbl;
+	int cea_ext_index = 0, displayid_ext_index = 0;
 	const u8 *cea;
 
-	cea = drm_find_cea_extension(edid);
+	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
 	if (!cea) {
 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
 		return 0;
@@ -4719,9 +4720,10 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 {
 	int count = 0;
 	int i, start, end, dbl;
+	int cea_ext_index = 0, displayid_ext_index = 0;
 	const u8 *cea;
 
-	cea = drm_find_cea_extension(edid);
+	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
 	if (!cea) {
 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
 		return 0;
@@ -4815,8 +4817,9 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 	const u8 *edid_ext;
 	int i;
 	int start_offset, end_offset;
+	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid);
+	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
 	if (!edid_ext)
 		return false;
 
@@ -4854,8 +4857,9 @@ bool drm_detect_monitor_audio(struct edid *edid)
 	int i, j;
 	bool has_audio = false;
 	int start_offset, end_offset;
+	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid);
+	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
 	if (!edid_ext)
 		goto end;
 
@@ -5178,8 +5182,9 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
 	struct drm_display_info *info = &connector->display_info;
 	const u8 *edid_ext;
 	int i, start, end;
+	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid);
+	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
 	if (!edid_ext)
 		return;
 
@@ -5311,12 +5316,12 @@ static void drm_update_mso(struct drm_connector *connector, const struct edid *e
 	const struct displayid_block *block;
 	struct displayid_iter iter;
 
-	displayid_iter_edid_begin(edid, &iter);
+	displayid_iter_edid_begin(edid, &iter, NULL);
 	displayid_iter_for_each(block, &iter) {
 		if (block->tag == DATA_BLOCK_2_VENDOR_SPECIFIC)
 			drm_parse_vesa_mso_data(connector, block);
 	}
-	displayid_iter_end(&iter);
+	displayid_iter_end(&iter, NULL);
 }
 
 /* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
@@ -5516,13 +5521,13 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
 	struct displayid_iter iter;
 	int num_modes = 0;
 
-	displayid_iter_edid_begin(edid, &iter);
+	displayid_iter_edid_begin(edid, &iter, NULL);
 	displayid_iter_for_each(block, &iter) {
 		if (block->tag == DATA_BLOCK_TYPE_1_DETAILED_TIMING ||
 		    block->tag == DATA_BLOCK_2_TYPE_7_DETAILED_TIMING)
 			num_modes += add_displayid_detailed_1_modes(connector, block);
 	}
-	displayid_iter_end(&iter);
+	displayid_iter_end(&iter, NULL);
 
 	return num_modes;
 }
@@ -6164,12 +6169,12 @@ void drm_update_tile_info(struct drm_connector *connector,
 
 	connector->has_tile = false;
 
-	displayid_iter_edid_begin(edid, &iter);
+	displayid_iter_edid_begin(edid, &iter, NULL);
 	displayid_iter_for_each(block, &iter) {
 		if (block->tag == DATA_BLOCK_TILED_DISPLAY)
 			drm_parse_tiled_block(connector, block);
 	}
-	displayid_iter_end(&iter);
+	displayid_iter_end(&iter, NULL);
 
 	if (!connector->has_tile && connector->tile_group) {
 		drm_mode_put_tile_group(connector->dev, connector->tile_group);
diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
index 7ffbd9f7bfc7..15442a161c11 100644
--- a/include/drm/drm_displayid.h
+++ b/include/drm/drm_displayid.h
@@ -150,11 +150,11 @@ struct displayid_iter {
 };
 
 void displayid_iter_edid_begin(const struct edid *edid,
-			       struct displayid_iter *iter);
+			       struct displayid_iter *iter, int *ext_index);
 const struct displayid_block *
 __displayid_iter_next(struct displayid_iter *iter);
 #define displayid_iter_for_each(__block, __iter) \
 	while (((__block) = __displayid_iter_next(__iter)))
-void displayid_iter_end(struct displayid_iter *iter);
+void displayid_iter_end(struct displayid_iter *iter, int *ext_index);
 
 #endif
-- 
2.17.1



More information about the dri-devel mailing list