All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for enhanced edid driver compatibility (rev3)
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
  (?)
@ 2022-03-13 13:45 ` Patchwork
  -1 siblings, 0 replies; 30+ messages in thread
From: Patchwork @ 2022-03-13 13:45 UTC (permalink / raw)
  To: Lee Shawn C; +Cc: intel-gfx

== Series Details ==

Series: enhanced edid driver compatibility (rev3)
URL   : https://patchwork.freedesktop.org/series/101241/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
c049087987bb drm/edid: seek for available CEA and DisplayID block from specific EDID block index
17e8316a3054 drm/edid: parse multiple CEA extension block
39376b26f8e4 drm/edid: read HF-EEODB ext block
84dbfb1659a7 drm/edid: parse HF-EEODB CEA extension block
-:51: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!edid"
#51: FILE: drivers/gpu/drm/drm_edid.c:3371:
+	if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)

total: 0 errors, 0 warnings, 1 checks, 178 lines checked
74f01f274c37 drm/edid: check for HF-SCDB block



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [v7 0/5] enhanced edid driver compatibility
@ 2022-03-13 13:46 ` Lee Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:46 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, ankit.k.nautiyal, Lee Shawn C, intel-gfx

Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

v4: add one more patch to support HF-SCDB
v5: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
    drm_parse_hdmi_forum_vsdb() to parse this packet.
v6: save proper extension block index if CTA data information
    was found in DispalyID block.
v7: using different parameters to store CEA and DisplayID block index.
    configure DisplayID extansion block index before search available
    DisplayID block.

Lee Shawn C (5):
  drm/edid: seek for available CEA and DisplayID block from specific
    EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block
  drm/edid: check for HF-SCDB block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |  15 ++-
 drivers/gpu/drm/drm_edid.c      | 216 +++++++++++++++++++++++++-------
 include/drm/drm_displayid.h     |   4 +-
 include/drm/drm_edid.h          |   3 +-
 5 files changed, 194 insertions(+), 52 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Intel-gfx] [v7 0/5] enhanced edid driver compatibility
@ 2022-03-13 13:46 ` Lee Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:46 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx

Support to parse multiple CEA extension blocks and HF-EEODB to
extend drm edid driver's capability.

v4: add one more patch to support HF-SCDB
v5: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
    drm_parse_hdmi_forum_vsdb() to parse this packet.
v6: save proper extension block index if CTA data information
    was found in DispalyID block.
v7: using different parameters to store CEA and DisplayID block index.
    configure DisplayID extansion block index before search available
    DisplayID block.

Lee Shawn C (5):
  drm/edid: seek for available CEA and DisplayID block from specific
    EDID block index
  drm/edid: parse multiple CEA extension block
  drm/edid: read HF-EEODB ext block
  drm/edid: parse HF-EEODB CEA extension block
  drm/edid: check for HF-SCDB block

 drivers/gpu/drm/drm_connector.c |   8 +-
 drivers/gpu/drm/drm_displayid.c |  15 ++-
 drivers/gpu/drm/drm_edid.c      | 216 +++++++++++++++++++++++++-------
 include/drm/drm_displayid.h     |   4 +-
 include/drm/drm_edid.h          |   3 +-
 5 files changed, 194 insertions(+), 52 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
@ 2022-03-13 13:46   ` Lee Shawn C
  -1 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:46 UTC (permalink / raw)
  To: dri-devel
  Cc: jani.nikula, intel-gfx, Drew Davenport, ankit.k.nautiyal, Lee Shawn C

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@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Drew Davenport <ddavenport@chromium.org>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c.lee@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


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
@ 2022-03-13 13:46   ` Lee Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:46 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Drew Davenport

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@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Drew Davenport <ddavenport@chromium.org>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c.lee@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


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [v7 2/5] drm/edid: parse multiple CEA extension block
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
@ 2022-03-13 13:46   ` Lee Shawn C
  -1 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:46 UTC (permalink / raw)
  To: dri-devel
  Cc: jani.nikula, intel-gfx, Drew Davenport, ankit.k.nautiyal, Lee Shawn C

Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
    in this one.
v3: simplify this patch based on previous change.
v4: refine patch v3.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Drew Davenport <ddavenport@chromium.org>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 78c415aa6889..9fa84881fbba 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4320,16 +4320,22 @@ 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, *db, *hdmi = NULL, *video = NULL;
-	u8 dbl, hdmi_len, video_len = 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) {
+	for (;;) {
+		const u8 *cea, *db, *hdmi = NULL, *video = NULL;
+		u8 dbl, hdmi_len = 0, video_len = 0;
 		int i, start, end;
 
+		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+		if (!cea)
+			break;
+
+		if (cea_revision(cea) < 3)
+			continue;
+
 		if (cea_db_offsets(cea, &start, &end))
-			return 0;
+			continue;
 
 		for_each_cea_db(cea, i, start, end) {
 			db = &cea[i];
@@ -4351,15 +4357,15 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
 							  dbl - 1);
 			}
 		}
-	}
 
-	/*
-	 * We parse the HDMI VSDB after having added the cea modes as we will
-	 * be patching their flags when the sink supports stereo 3D.
-	 */
-	if (hdmi)
-		modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-					    video_len);
+		/*
+		 * We parse the HDMI VSDB after having added the cea modes as we will
+		 * be patching their flags when the sink supports stereo 3D.
+		 */
+		if (hdmi)
+			modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
+						    video_len);
+	}
 
 	return modes;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Intel-gfx] [v7 2/5] drm/edid: parse multiple CEA extension block
@ 2022-03-13 13:46   ` Lee Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:46 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Drew Davenport

Try to find and parse more CEA ext blocks if edid->extensions
is greater than one.

v2: split prvious patch to two. And do CEA block parsing
    in this one.
v3: simplify this patch based on previous change.
v4: refine patch v3.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Drew Davenport <ddavenport@chromium.org>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 78c415aa6889..9fa84881fbba 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4320,16 +4320,22 @@ 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, *db, *hdmi = NULL, *video = NULL;
-	u8 dbl, hdmi_len, video_len = 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) {
+	for (;;) {
+		const u8 *cea, *db, *hdmi = NULL, *video = NULL;
+		u8 dbl, hdmi_len = 0, video_len = 0;
 		int i, start, end;
 
+		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+		if (!cea)
+			break;
+
+		if (cea_revision(cea) < 3)
+			continue;
+
 		if (cea_db_offsets(cea, &start, &end))
-			return 0;
+			continue;
 
 		for_each_cea_db(cea, i, start, end) {
 			db = &cea[i];
@@ -4351,15 +4357,15 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
 							  dbl - 1);
 			}
 		}
-	}
 
-	/*
-	 * We parse the HDMI VSDB after having added the cea modes as we will
-	 * be patching their flags when the sink supports stereo 3D.
-	 */
-	if (hdmi)
-		modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
-					    video_len);
+		/*
+		 * We parse the HDMI VSDB after having added the cea modes as we will
+		 * be patching their flags when the sink supports stereo 3D.
+		 */
+		if (hdmi)
+			modes += do_hdmi_vsdb_modes(connector, hdmi, hdmi_len, video,
+						    video_len);
+	}
 
 	return modes;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [v7 3/5] drm/edid: read HF-EEODB ext block
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
@ 2022-03-13 13:47   ` Lee Shawn C
  -1 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:47 UTC (permalink / raw)
  To: dri-devel
  Cc: jani.nikula, intel-gfx, Drew Davenport, ankit.k.nautiyal, Lee Shawn C

According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
    available block number in drm_edid_read_hf_eeodb_blk_count().

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

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
 				       const struct edid *edid)
 {
 	struct drm_device *dev = connector->dev;
-	size_t size = 0;
+	size_t size = 0, hf_eeodb_blk_count;
 	int ret;
 	const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
 	if (connector->override_edid)
 		return 0;
 
-	if (edid)
+	if (edid) {
 		size = EDID_LENGTH * (1 + edid->extensions);
+		hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+		if (hf_eeodb_blk_count)
+			size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+	}
 
 	/* Set the display info, using edid if available, otherwise
 	 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9fa84881fbba..5ae4e83fa5e3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 {
 	int i, j = 0, valid_extensions = 0;
 	u8 *edid, *new;
+	size_t hf_eeodb_blk_count;
 	struct edid *override;
 
 	override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 		}
 
 		kfree(edid);
+		return (struct edid *)new;
+	}
+
+	hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid *)edid);
+	if (hf_eeodb_blk_count >= 2) {
+		new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, GFP_KERNEL);
+		if (!new)
+			goto out;
 		edid = new;
+
+		valid_extensions = hf_eeodb_blk_count - 1;
+		for (j = 2; j <= hf_eeodb_blk_count; j++) {
+			u8 *block = edid + j * EDID_LENGTH;
+
+			for (i = 0; i < 4; i++) {
+				if (get_edid_block(data, block, j, EDID_LENGTH))
+					goto out;
+				if (drm_edid_block_valid(block, j, false, NULL))
+					break;
+			}
+
+			if (i == 4)
+				valid_extensions--;
+		}
+
+		if (valid_extensions != hf_eeodb_blk_count - 1) {
+			DRM_ERROR("Not able to retrieve proper EDID contain HF-EEODB data.\n");
+			goto out;
+		}
 	}
 
 	return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ 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_CAPABILITY_BLOCK	0x00
+#define HDR_STATIC_METADATA_BLOCK	0x06
+#define USE_EXTENDED_TAG		0x07
 #define EXT_VIDEO_DATA_BLOCK_420	0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
 #define EDID_BASIC_AUDIO	(1 << 6)
 #define EDID_CEA_YCRCB444	(1 << 5)
 #define EDID_CEA_YCRCB422	(1 << 4)
 #define EDID_CEA_VCDB_QS	(1 << 6)
+#define HF_EEODB_LENGTH		2
 
 /*
  * Search EDID for CEA extension block.
@@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
 	return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+	if (cea_db_tag(db) != USE_EXTENDED_TAG)
+		return false;
+
+	if (cea_db_payload_len(db) != HF_EEODB_LENGTH)
+		return false;
+
+	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_EEODB_DATA_BLOCK)
+		return false;
+
+	return true;
+}
+
 #define for_each_cea_db(cea, i, start, end) \
 	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
 
+size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid)
+{
+	const u8 *cea;
+	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
+
+	if (edid->extensions) {
+		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+
+		if (cea && !cea_db_offsets(cea, &start, &end))
+			for_each_cea_db(cea, i, start, end)
+				if (cea_db_is_hdmi_forum_eeodb(&cea[i]))
+					return cea[i + 2];
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(drm_edid_read_hf_eeodb_blk_count);
+
 static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
 				      const u8 *db)
 {
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 144c495b99c4..585f0ed932d4 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -593,5 +593,6 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
 const u8 *drm_find_edid_extension(const struct edid *edid,
 				  int ext_id, int *ext_index);
 
+size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
 
 #endif /* __DRM_EDID_H__ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Intel-gfx] [v7 3/5] drm/edid: read HF-EEODB ext block
@ 2022-03-13 13:47   ` Lee Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:47 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Drew Davenport

According to HDMI 2.1 spec.

"The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
is utilized by Sink Devices to provide an alternate method to
indicate an EDID Extension Block count larger than 1, while
avoiding the need to present a VESA Block Map in the first
E-EDID Extension Block."

It is a mandatory for HDMI 2.1 protocol compliance as well.
This patch help to know how many HF_EEODB blocks report by sink
and read allo HF_EEODB blocks back.

v2: support to find CEA block, check EEODB block format, and return
    available block number in drm_edid_read_hf_eeodb_blk_count().

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

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index a50c82bc2b2f..16011023c12e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
 				       const struct edid *edid)
 {
 	struct drm_device *dev = connector->dev;
-	size_t size = 0;
+	size_t size = 0, hf_eeodb_blk_count;
 	int ret;
 	const struct edid *old_edid;
 
@@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
 	if (connector->override_edid)
 		return 0;
 
-	if (edid)
+	if (edid) {
 		size = EDID_LENGTH * (1 + edid->extensions);
+		hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
+		if (hf_eeodb_blk_count)
+			size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
+	}
 
 	/* Set the display info, using edid if available, otherwise
 	 * resetting the values to defaults. This duplicates the work
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9fa84881fbba..5ae4e83fa5e3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 {
 	int i, j = 0, valid_extensions = 0;
 	u8 *edid, *new;
+	size_t hf_eeodb_blk_count;
 	struct edid *override;
 
 	override = drm_get_override_edid(connector);
@@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
 		}
 
 		kfree(edid);
+		return (struct edid *)new;
+	}
+
+	hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid *)edid);
+	if (hf_eeodb_blk_count >= 2) {
+		new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, GFP_KERNEL);
+		if (!new)
+			goto out;
 		edid = new;
+
+		valid_extensions = hf_eeodb_blk_count - 1;
+		for (j = 2; j <= hf_eeodb_blk_count; j++) {
+			u8 *block = edid + j * EDID_LENGTH;
+
+			for (i = 0; i < 4; i++) {
+				if (get_edid_block(data, block, j, EDID_LENGTH))
+					goto out;
+				if (drm_edid_block_valid(block, j, false, NULL))
+					break;
+			}
+
+			if (i == 4)
+				valid_extensions--;
+		}
+
+		if (valid_extensions != hf_eeodb_blk_count - 1) {
+			DRM_ERROR("Not able to retrieve proper EDID contain HF-EEODB data.\n");
+			goto out;
+		}
 	}
 
 	return (struct edid *)edid;
@@ -3315,15 +3344,17 @@ 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_CAPABILITY_BLOCK	0x00
+#define HDR_STATIC_METADATA_BLOCK	0x06
+#define USE_EXTENDED_TAG		0x07
 #define EXT_VIDEO_DATA_BLOCK_420	0x0E
-#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
+#define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
+#define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
 #define EDID_BASIC_AUDIO	(1 << 6)
 #define EDID_CEA_YCRCB444	(1 << 5)
 #define EDID_CEA_YCRCB422	(1 << 4)
 #define EDID_CEA_VCDB_QS	(1 << 6)
+#define HF_EEODB_LENGTH		2
 
 /*
  * Search EDID for CEA extension block.
@@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
 	return true;
 }
 
+static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
+{
+	if (cea_db_tag(db) != USE_EXTENDED_TAG)
+		return false;
+
+	if (cea_db_payload_len(db) != HF_EEODB_LENGTH)
+		return false;
+
+	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_EEODB_DATA_BLOCK)
+		return false;
+
+	return true;
+}
+
 #define for_each_cea_db(cea, i, start, end) \
 	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
 
+size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid)
+{
+	const u8 *cea;
+	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
+
+	if (edid->extensions) {
+		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+
+		if (cea && !cea_db_offsets(cea, &start, &end))
+			for_each_cea_db(cea, i, start, end)
+				if (cea_db_is_hdmi_forum_eeodb(&cea[i]))
+					return cea[i + 2];
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(drm_edid_read_hf_eeodb_blk_count);
+
 static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
 				      const u8 *db)
 {
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 144c495b99c4..585f0ed932d4 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -593,5 +593,6 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
 const u8 *drm_find_edid_extension(const struct edid *edid,
 				  int ext_id, int *ext_index);
 
+size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
 
 #endif /* __DRM_EDID_H__ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [v7 4/5] drm/edid: parse HF-EEODB CEA extension block
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
@ 2022-03-13 13:47   ` Lee Shawn C
  -1 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:47 UTC (permalink / raw)
  To: dri-devel
  Cc: jani.nikula, intel-gfx, Drew Davenport, ankit.k.nautiyal, Lee Shawn C

While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

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

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 31c3e6d7d549..a769c55146f4 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct edid *edid,
 					      int *length, int *idx,
 					      int *ext_index)
 {
-	const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, ext_index);
+	const u8 *displayid = drm_find_edid_extension(edid,
+						      DISPLAYID_EXT,
+						      ext_index,
+						      edid->extensions);
 	const struct displayid_header *base;
 	int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5ae4e83fa5e3..5de85ba20bdf 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,25 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
-				  int ext_id, int *ext_index)
+				  int ext_id,
+				  int *ext_index,
+				  int ext_blk_num)
 {
 	const u8 *edid_ext = NULL;
 	int i;
 
 	/* No EDID or EDID extensions */
-	if (edid == NULL || edid->extensions == 0)
+	if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
 		return NULL;
 
 	/* Find CEA extension */
-	for (i = *ext_index; i < edid->extensions; i++) {
+	for (i = *ext_index; i < ext_blk_num; i++) {
 		edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
 		if (edid_ext[0] == ext_id)
 			break;
 	}
 
-	if (i >= edid->extensions)
+	if (i >= ext_blk_num)
 		return NULL;
 
 	*ext_index = i + 1;
@@ -3385,14 +3387,19 @@ const u8 *drm_find_edid_extension(const struct edid *edid,
 }
 
 static const u8 *drm_find_cea_extension(const struct edid *edid,
-					int *cea_ext_index, int *displayid_ext_index)
+					int *cea_ext_index,
+					int *displayid_ext_index,
+					int ext_blk_num)
 {
 	const struct displayid_block *block;
 	struct displayid_iter iter;
 	const u8 *cea;
 
 	/* Look for a CEA extension block from ext_index */
-	cea = drm_find_edid_extension(edid, CEA_EXT, cea_ext_index);
+	cea = drm_find_edid_extension(edid,
+				      CEA_EXT,
+				      cea_ext_index,
+				      ext_blk_num);
 	if (cea)
 		return cea;
 
@@ -3676,7 +3683,10 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
 	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, &cea_ext_index, &displayid_ext_index))
+	if (!drm_find_cea_extension(edid,
+				    &cea_ext_index,
+				    &displayid_ext_index,
+				    edid->extensions))
 		return 0;
 
 	/*
@@ -4328,7 +4338,10 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid)
 	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
 
 	if (edid->extensions) {
-		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+		cea = drm_find_cea_extension(edid,
+					     &cea_ext_index,
+					     &displayid_ext_index,
+					     edid->extensions);
 
 		if (cea && !cea_db_offsets(cea, &start, &end))
 			for_each_cea_db(cea, i, start, end)
@@ -4384,13 +4397,20 @@ static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
 	int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
+	int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+	if (!ext_blk_num)
+		ext_blk_num = edid->extensions;
 
 	for (;;) {
 		const u8 *cea, *db, *hdmi = NULL, *video = NULL;
 		u8 dbl, hdmi_len = 0, video_len = 0;
 		int i, start, end;
 
-		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+		cea = drm_find_cea_extension(edid,
+					     &cea_ext_index,
+					     &displayid_ext_index,
+					     ext_blk_num);
 		if (!cea)
 			break;
 
@@ -4640,7 +4660,10 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 	if (!edid)
 		return;
 
-	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	cea = drm_find_cea_extension(edid,
+				     &cea_ext_index,
+				     &displayid_ext_index,
+				     edid->extensions);
 	if (!cea) {
 		DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
 		return;
@@ -4729,7 +4752,10 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 	int cea_ext_index = 0, displayid_ext_index = 0;
 	const u8 *cea;
 
-	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	cea = drm_find_cea_extension(edid,
+				     &cea_ext_index,
+				     &displayid_ext_index,
+				     edid->extensions);
 	if (!cea) {
 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
 		return 0;
@@ -4792,7 +4818,10 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 	int cea_ext_index = 0, displayid_ext_index = 0;
 	const u8 *cea;
 
-	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	cea = drm_find_cea_extension(edid,
+				     &cea_ext_index,
+				     &displayid_ext_index,
+				     edid->extensions);
 	if (!cea) {
 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
 		return 0;
@@ -4888,7 +4917,10 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 	int start_offset, end_offset;
 	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	edid_ext = drm_find_cea_extension(edid,
+					  &cea_ext_index,
+					  &displayid_ext_index,
+					  edid->extensions);
 	if (!edid_ext)
 		return false;
 
@@ -4928,7 +4960,10 @@ bool drm_detect_monitor_audio(struct edid *edid)
 	int start_offset, end_offset;
 	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	edid_ext = drm_find_cea_extension(edid,
+					  &cea_ext_index,
+					  &displayid_ext_index,
+					  edid->extensions);
 	if (!edid_ext)
 		goto end;
 
@@ -5253,7 +5288,10 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
 	int i, start, end;
 	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	edid_ext = drm_find_cea_extension(edid,
+					  &cea_ext_index,
+					  &displayid_ext_index,
+					  edid->extensions);
 	if (!edid_ext)
 		return;
 
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 585f0ed932d4..fa06f9a468c4 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -591,7 +591,7 @@ struct drm_display_mode *
 drm_display_mode_from_cea_vic(struct drm_device *dev,
 			      u8 video_code);
 const u8 *drm_find_edid_extension(const struct edid *edid,
-				  int ext_id, int *ext_index);
+				  int ext_id, int *ext_index, int ext_blk_num);
 
 size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Intel-gfx] [v7 4/5] drm/edid: parse HF-EEODB CEA extension block
@ 2022-03-13 13:47   ` Lee Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:47 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Drew Davenport

While adding CEA modes, try to get available EEODB block
number. Then based on it to parse numbers of ext blocks,
retrieve CEA information and add more CEA modes.

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

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 31c3e6d7d549..a769c55146f4 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,10 @@ static const u8 *drm_find_displayid_extension(const struct edid *edid,
 					      int *length, int *idx,
 					      int *ext_index)
 {
-	const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, ext_index);
+	const u8 *displayid = drm_find_edid_extension(edid,
+						      DISPLAYID_EXT,
+						      ext_index,
+						      edid->extensions);
 	const struct displayid_header *base;
 	int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5ae4e83fa5e3..5de85ba20bdf 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3360,23 +3360,25 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
  * Search EDID for CEA extension block.
  */
 const u8 *drm_find_edid_extension(const struct edid *edid,
-				  int ext_id, int *ext_index)
+				  int ext_id,
+				  int *ext_index,
+				  int ext_blk_num)
 {
 	const u8 *edid_ext = NULL;
 	int i;
 
 	/* No EDID or EDID extensions */
-	if (edid == NULL || edid->extensions == 0)
+	if (edid == NULL || edid->extensions == 0 || *ext_index >= ext_blk_num)
 		return NULL;
 
 	/* Find CEA extension */
-	for (i = *ext_index; i < edid->extensions; i++) {
+	for (i = *ext_index; i < ext_blk_num; i++) {
 		edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
 		if (edid_ext[0] == ext_id)
 			break;
 	}
 
-	if (i >= edid->extensions)
+	if (i >= ext_blk_num)
 		return NULL;
 
 	*ext_index = i + 1;
@@ -3385,14 +3387,19 @@ const u8 *drm_find_edid_extension(const struct edid *edid,
 }
 
 static const u8 *drm_find_cea_extension(const struct edid *edid,
-					int *cea_ext_index, int *displayid_ext_index)
+					int *cea_ext_index,
+					int *displayid_ext_index,
+					int ext_blk_num)
 {
 	const struct displayid_block *block;
 	struct displayid_iter iter;
 	const u8 *cea;
 
 	/* Look for a CEA extension block from ext_index */
-	cea = drm_find_edid_extension(edid, CEA_EXT, cea_ext_index);
+	cea = drm_find_edid_extension(edid,
+				      CEA_EXT,
+				      cea_ext_index,
+				      ext_blk_num);
 	if (cea)
 		return cea;
 
@@ -3676,7 +3683,10 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid)
 	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, &cea_ext_index, &displayid_ext_index))
+	if (!drm_find_cea_extension(edid,
+				    &cea_ext_index,
+				    &displayid_ext_index,
+				    edid->extensions))
 		return 0;
 
 	/*
@@ -4328,7 +4338,10 @@ size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid)
 	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
 
 	if (edid->extensions) {
-		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+		cea = drm_find_cea_extension(edid,
+					     &cea_ext_index,
+					     &displayid_ext_index,
+					     edid->extensions);
 
 		if (cea && !cea_db_offsets(cea, &start, &end))
 			for_each_cea_db(cea, i, start, end)
@@ -4384,13 +4397,20 @@ static int
 add_cea_modes(struct drm_connector *connector, struct edid *edid)
 {
 	int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
+	int ext_blk_num = drm_edid_read_hf_eeodb_blk_count(edid);
+
+	if (!ext_blk_num)
+		ext_blk_num = edid->extensions;
 
 	for (;;) {
 		const u8 *cea, *db, *hdmi = NULL, *video = NULL;
 		u8 dbl, hdmi_len = 0, video_len = 0;
 		int i, start, end;
 
-		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+		cea = drm_find_cea_extension(edid,
+					     &cea_ext_index,
+					     &displayid_ext_index,
+					     ext_blk_num);
 		if (!cea)
 			break;
 
@@ -4640,7 +4660,10 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)
 	if (!edid)
 		return;
 
-	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	cea = drm_find_cea_extension(edid,
+				     &cea_ext_index,
+				     &displayid_ext_index,
+				     edid->extensions);
 	if (!cea) {
 		DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
 		return;
@@ -4729,7 +4752,10 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads)
 	int cea_ext_index = 0, displayid_ext_index = 0;
 	const u8 *cea;
 
-	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	cea = drm_find_cea_extension(edid,
+				     &cea_ext_index,
+				     &displayid_ext_index,
+				     edid->extensions);
 	if (!cea) {
 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
 		return 0;
@@ -4792,7 +4818,10 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 	int cea_ext_index = 0, displayid_ext_index = 0;
 	const u8 *cea;
 
-	cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	cea = drm_find_cea_extension(edid,
+				     &cea_ext_index,
+				     &displayid_ext_index,
+				     edid->extensions);
 	if (!cea) {
 		DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
 		return 0;
@@ -4888,7 +4917,10 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
 	int start_offset, end_offset;
 	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	edid_ext = drm_find_cea_extension(edid,
+					  &cea_ext_index,
+					  &displayid_ext_index,
+					  edid->extensions);
 	if (!edid_ext)
 		return false;
 
@@ -4928,7 +4960,10 @@ bool drm_detect_monitor_audio(struct edid *edid)
 	int start_offset, end_offset;
 	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	edid_ext = drm_find_cea_extension(edid,
+					  &cea_ext_index,
+					  &displayid_ext_index,
+					  edid->extensions);
 	if (!edid_ext)
 		goto end;
 
@@ -5253,7 +5288,10 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
 	int i, start, end;
 	int cea_ext_index = 0, displayid_ext_index = 0;
 
-	edid_ext = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
+	edid_ext = drm_find_cea_extension(edid,
+					  &cea_ext_index,
+					  &displayid_ext_index,
+					  edid->extensions);
 	if (!edid_ext)
 		return;
 
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 585f0ed932d4..fa06f9a468c4 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -591,7 +591,7 @@ struct drm_display_mode *
 drm_display_mode_from_cea_vic(struct drm_device *dev,
 			      u8 video_code);
 const u8 *drm_find_edid_extension(const struct edid *edid,
-				  int ext_id, int *ext_index);
+				  int ext_id, int *ext_index, int ext_blk_num);
 
 size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [v7 5/5] drm/edid: check for HF-SCDB block
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
@ 2022-03-13 13:47   ` Lee Shawn C
  -1 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:47 UTC (permalink / raw)
  To: dri-devel
  Cc: jani.nikula, intel-gfx, Drew Davenport, ankit.k.nautiyal, Lee Shawn C

Find HF-SCDB information in CEA extensions block. And retrieve
Max_TMDS_Character_Rate that support by sink device.

v2: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
    drm_parse_hdmi_forum_vsdb() to parse this packet.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Drew Davenport <ddavenport@chromium.org>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5de85ba20bdf..351a729bddb6 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3350,6 +3350,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
 #define EXT_VIDEO_DATA_BLOCK_420	0x0E
 #define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
 #define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
+#define EXT_VIDEO_HF_SCDB_DATA_BLOCK	0x79
 #define EDID_BASIC_AUDIO	(1 << 6)
 #define EDID_CEA_YCRCB444	(1 << 5)
 #define EDID_CEA_YCRCB422	(1 << 4)
@@ -4287,6 +4288,20 @@ static bool cea_db_is_vcdb(const u8 *db)
 	return true;
 }
 
+static bool cea_db_is_hdmi_forum_scdb(const u8 *db)
+{
+	if (cea_db_tag(db) != USE_EXTENDED_TAG)
+		return false;
+
+	if (cea_db_payload_len(db) < 7)
+		return false;
+
+	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_SCDB_DATA_BLOCK)
+		return false;
+
+	return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
 	if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -5312,7 +5327,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
 
 		if (cea_db_is_hdmi_vsdb(db))
 			drm_parse_hdmi_vsdb_video(connector, db);
-		if (cea_db_is_hdmi_forum_vsdb(db))
+		if (cea_db_is_hdmi_forum_vsdb(db) ||
+		    cea_db_is_hdmi_forum_scdb(db))
 			drm_parse_hdmi_forum_vsdb(connector, db);
 		if (cea_db_is_microsoft_vsdb(db))
 			drm_parse_microsoft_vsdb(connector, db);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Intel-gfx] [v7 5/5] drm/edid: check for HF-SCDB block
@ 2022-03-13 13:47   ` Lee Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee Shawn C @ 2022-03-13 13:47 UTC (permalink / raw)
  To: dri-devel; +Cc: jani.nikula, intel-gfx, Drew Davenport

Find HF-SCDB information in CEA extensions block. And retrieve
Max_TMDS_Character_Rate that support by sink device.

v2: HF-SCDB and HF-VSDBS carry the same SCDS data. Reuse
    drm_parse_hdmi_forum_vsdb() to parse this packet.

Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: Drew Davenport <ddavenport@chromium.org>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5de85ba20bdf..351a729bddb6 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3350,6 +3350,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
 #define EXT_VIDEO_DATA_BLOCK_420	0x0E
 #define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
 #define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
+#define EXT_VIDEO_HF_SCDB_DATA_BLOCK	0x79
 #define EDID_BASIC_AUDIO	(1 << 6)
 #define EDID_CEA_YCRCB444	(1 << 5)
 #define EDID_CEA_YCRCB422	(1 << 4)
@@ -4287,6 +4288,20 @@ static bool cea_db_is_vcdb(const u8 *db)
 	return true;
 }
 
+static bool cea_db_is_hdmi_forum_scdb(const u8 *db)
+{
+	if (cea_db_tag(db) != USE_EXTENDED_TAG)
+		return false;
+
+	if (cea_db_payload_len(db) < 7)
+		return false;
+
+	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_SCDB_DATA_BLOCK)
+		return false;
+
+	return true;
+}
+
 static bool cea_db_is_y420cmdb(const u8 *db)
 {
 	if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -5312,7 +5327,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
 
 		if (cea_db_is_hdmi_vsdb(db))
 			drm_parse_hdmi_vsdb_video(connector, db);
-		if (cea_db_is_hdmi_forum_vsdb(db))
+		if (cea_db_is_hdmi_forum_vsdb(db) ||
+		    cea_db_is_hdmi_forum_scdb(db))
 			drm_parse_hdmi_forum_vsdb(connector, db);
 		if (cea_db_is_microsoft_vsdb(db))
 			drm_parse_microsoft_vsdb(connector, db);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for enhanced edid driver compatibility (rev3)
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
                   ` (6 preceding siblings ...)
  (?)
@ 2022-03-13 13:47 ` Patchwork
  -1 siblings, 0 replies; 30+ messages in thread
From: Patchwork @ 2022-03-13 13:47 UTC (permalink / raw)
  To: Lee Shawn C; +Cc: intel-gfx

== Series Details ==

Series: enhanced edid driver compatibility (rev3)
URL   : https://patchwork.freedesktop.org/series/101241/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:319:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1444:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1444:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1444:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1445:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1445:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1445:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1504:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1504:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1504:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16: error: incompatible types in comparison expression (different type sizes):
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16:    unsigned long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:353:16:    unsigned long long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:295:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:296:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:345:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:596:23:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:598:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:315:49: error: static assertion failed: "amd_sriov_msg_vf2pf



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for enhanced edid driver compatibility (rev3)
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
                   ` (7 preceding siblings ...)
  (?)
@ 2022-03-13 14:18 ` Patchwork
  -1 siblings, 0 replies; 30+ messages in thread
From: Patchwork @ 2022-03-13 14:18 UTC (permalink / raw)
  To: Lee Shawn C; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 4569 bytes --]

== Series Details ==

Series: enhanced edid driver compatibility (rev3)
URL   : https://patchwork.freedesktop.org/series/101241/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_11354 -> Patchwork_22553
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/index.html

Participating hosts (43 -> 39)
------------------------------

  Additional (1): fi-pnv-d510 
  Missing    (5): shard-tglu fi-bsw-cyan shard-rkl shard-dg1 fi-bdw-samus 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_22553:

### IGT changes ###

#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@i915_selftest@live@gt_heartbeat:
    - {bat-rpls-2}:       [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/bat-rpls-2/igt@i915_selftest@live@gt_heartbeat.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/bat-rpls-2/igt@i915_selftest@live@gt_heartbeat.html

  * igt@kms_busy@basic@flip:
    - {bat-adlp-6}:       [PASS][3] -> [DMESG-WARN][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/bat-adlp-6/igt@kms_busy@basic@flip.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/bat-adlp-6/igt@kms_busy@basic@flip.html

  
Known issues
------------

  Here are the changes found in Patchwork_22553 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_huc_copy@huc-copy:
    - fi-pnv-d510:        NOTRUN -> [SKIP][5] ([fdo#109271]) +58 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/fi-pnv-d510/igt@gem_huc_copy@huc-copy.html

  * igt@i915_selftest@live@hangcheck:
    - fi-bdw-5557u:       NOTRUN -> [INCOMPLETE][6] ([i915#3921])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/fi-bdw-5557u/igt@i915_selftest@live@hangcheck.html

  * igt@kms_chamelium@vga-edid-read:
    - fi-bdw-5557u:       NOTRUN -> [SKIP][7] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/fi-bdw-5557u/igt@kms_chamelium@vga-edid-read.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-bdw-5557u:       NOTRUN -> [SKIP][8] ([fdo#109271]) +14 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/fi-bdw-5557u/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@gt_lrc:
    - {bat-rpls-2}:       [DMESG-WARN][9] ([i915#4391]) -> [PASS][10] +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/bat-rpls-2/igt@i915_selftest@live@gt_lrc.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/bat-rpls-2/igt@i915_selftest@live@gt_lrc.html

  * igt@kms_flip@basic-flip-vs-modeset@a-edp1:
    - {bat-adlp-6}:       [DMESG-WARN][11] -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/bat-adlp-6/igt@kms_flip@basic-flip-vs-modeset@a-edp1.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/bat-adlp-6/igt@kms_flip@basic-flip-vs-modeset@a-edp1.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#3921]: https://gitlab.freedesktop.org/drm/intel/issues/3921
  [i915#4391]: https://gitlab.freedesktop.org/drm/intel/issues/4391


Build changes
-------------

  * Linux: CI_DRM_11354 -> Patchwork_22553

  CI-20190529: 20190529
  CI_DRM_11354: 5b1b60c0955083406c4873898fc6dd4fd0e2f450 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6378: 9c79047f49acdb6450368ee13fd8b6d28f3fb8e1 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_22553: 74f01f274c3782a4064190d8e57b9ca95d93a2d9 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

74f01f274c37 drm/edid: check for HF-SCDB block
84dbfb1659a7 drm/edid: parse HF-EEODB CEA extension block
39376b26f8e4 drm/edid: read HF-EEODB ext block
17e8316a3054 drm/edid: parse multiple CEA extension block
c049087987bb drm/edid: seek for available CEA and DisplayID block from specific EDID block index

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/index.html

[-- Attachment #2: Type: text/html, Size: 5557 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Intel-gfx] ✗ Fi.CI.IGT: failure for enhanced edid driver compatibility (rev3)
  2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
                   ` (8 preceding siblings ...)
  (?)
@ 2022-03-13 15:24 ` Patchwork
  -1 siblings, 0 replies; 30+ messages in thread
From: Patchwork @ 2022-03-13 15:24 UTC (permalink / raw)
  To: Lee Shawn C; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 30265 bytes --]

== Series Details ==

Series: enhanced edid driver compatibility (rev3)
URL   : https://patchwork.freedesktop.org/series/101241/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_11354_full -> Patchwork_22553_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_22553_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_22553_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Participating hosts (12 -> 12)
------------------------------

  Additional (1): shard-dg1 
  Missing    (1): pig-kbl-iris 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_22553_full:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_eio@kms:
    - shard-apl:          [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-apl7/igt@gem_eio@kms.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl1/igt@gem_eio@kms.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@gem_ccs@block-copy-inplace:
    - {shard-dg1}:        NOTRUN -> [SKIP][3] +1 similar issue
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-dg1-18/igt@gem_ccs@block-copy-inplace.html

  
Known issues
------------

  Here are the changes found in Patchwork_22553_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_balancer@parallel:
    - shard-kbl:          NOTRUN -> [DMESG-WARN][4] ([i915#5076])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl3/igt@gem_exec_balancer@parallel.html

  * igt@gem_exec_balancer@parallel-contexts:
    - shard-tglb:         NOTRUN -> [DMESG-WARN][5] ([i915#5076])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb5/igt@gem_exec_balancer@parallel-contexts.html

  * igt@gem_exec_fair@basic-none-vip@rcs0:
    - shard-kbl:          [PASS][6] -> [FAIL][7] ([i915#2842])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-kbl6/igt@gem_exec_fair@basic-none-vip@rcs0.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl6/igt@gem_exec_fair@basic-none-vip@rcs0.html

  * igt@gem_exec_suspend@basic-s3@smem:
    - shard-apl:          [PASS][8] -> [DMESG-WARN][9] ([i915#180]) +1 similar issue
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-apl8/igt@gem_exec_suspend@basic-s3@smem.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl6/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@gem_huc_copy@huc-copy:
    - shard-tglb:         [PASS][10] -> [SKIP][11] ([i915#2190])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-tglb3/igt@gem_huc_copy@huc-copy.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb7/igt@gem_huc_copy@huc-copy.html
    - shard-apl:          NOTRUN -> [SKIP][12] ([fdo#109271] / [i915#2190])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@gem_huc_copy@huc-copy.html

  * igt@gem_workarounds@suspend-resume:
    - shard-kbl:          NOTRUN -> [DMESG-WARN][13] ([i915#180])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl6/igt@gem_workarounds@suspend-resume.html

  * igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip:
    - shard-tglb:         NOTRUN -> [SKIP][14] ([i915#5286])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb5/igt@kms_big_fb@4-tiled-max-hw-stride-32bpp-rotate-0-hflip.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
    - shard-kbl:          NOTRUN -> [SKIP][15] ([fdo#109271] / [i915#3777]) +1 similar issue
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl6/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip:
    - shard-skl:          NOTRUN -> [FAIL][16] ([i915#3743])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl7/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip:
    - shard-apl:          NOTRUN -> [SKIP][17] ([fdo#109271] / [i915#3777])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl8/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html
    - shard-skl:          NOTRUN -> [SKIP][18] ([fdo#109271] / [i915#3777])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl7/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html

  * igt@kms_ccs@pipe-a-bad-aux-stride-y_tiled_gen12_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][19] ([i915#3689] / [i915#3886])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb8/igt@kms_ccs@pipe-a-bad-aux-stride-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_gen12_rc_ccs_cc:
    - shard-kbl:          NOTRUN -> [SKIP][20] ([fdo#109271] / [i915#3886]) +2 similar issues
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl3/igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc:
    - shard-apl:          NOTRUN -> [SKIP][21] ([fdo#109271] / [i915#3886]) +3 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-c-bad-aux-stride-y_tiled_gen12_rc_ccs_cc:
    - shard-skl:          NOTRUN -> [SKIP][22] ([fdo#109271] / [i915#3886])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl7/igt@kms_ccs@pipe-c-bad-aux-stride-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-c-missing-ccs-buffer-yf_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][23] ([fdo#111615] / [i915#3689]) +1 similar issue
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb8/igt@kms_ccs@pipe-c-missing-ccs-buffer-yf_tiled_ccs.html

  * igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][24] ([i915#3689])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb8/igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_mc_ccs.html

  * igt@kms_cdclk@mode-transition:
    - shard-apl:          NOTRUN -> [SKIP][25] ([fdo#109271]) +111 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl8/igt@kms_cdclk@mode-transition.html

  * igt@kms_chamelium@dp-audio-edid:
    - shard-tglb:         NOTRUN -> [SKIP][26] ([fdo#109284] / [fdo#111827]) +1 similar issue
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb1/igt@kms_chamelium@dp-audio-edid.html
    - shard-kbl:          NOTRUN -> [SKIP][27] ([fdo#109271] / [fdo#111827]) +2 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl3/igt@kms_chamelium@dp-audio-edid.html

  * igt@kms_chamelium@vga-edid-read:
    - shard-apl:          NOTRUN -> [SKIP][28] ([fdo#109271] / [fdo#111827]) +10 similar issues
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@kms_chamelium@vga-edid-read.html

  * igt@kms_color@pipe-a-legacy-gamma-reset:
    - shard-snb:          [PASS][29] -> [SKIP][30] ([fdo#109271]) +1 similar issue
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-snb5/igt@kms_color@pipe-a-legacy-gamma-reset.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-snb7/igt@kms_color@pipe-a-legacy-gamma-reset.html

  * igt@kms_color_chamelium@pipe-b-ctm-max:
    - shard-skl:          NOTRUN -> [SKIP][31] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl7/igt@kms_color_chamelium@pipe-b-ctm-max.html

  * igt@kms_cursor_crc@pipe-b-cursor-max-size-random:
    - shard-skl:          NOTRUN -> [SKIP][32] ([fdo#109271]) +26 similar issues
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl8/igt@kms_cursor_crc@pipe-b-cursor-max-size-random.html

  * igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-legacy:
    - shard-skl:          NOTRUN -> [FAIL][33] ([i915#2346])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl7/igt@kms_cursor_legacy@flip-vs-cursor-busy-crc-legacy.html

  * igt@kms_cursor_legacy@pipe-d-single-bo:
    - shard-kbl:          NOTRUN -> [SKIP][34] ([fdo#109271] / [i915#533])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl3/igt@kms_cursor_legacy@pipe-d-single-bo.html

  * igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-4tiled:
    - shard-kbl:          NOTRUN -> [SKIP][35] ([fdo#109271]) +60 similar issues
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl3/igt@kms_draw_crc@draw-method-xrgb8888-mmap-wc-4tiled.html

  * igt@kms_fbcon_fbt@psr-suspend:
    - shard-skl:          [PASS][36] -> [INCOMPLETE][37] ([i915#4939])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl4/igt@kms_fbcon_fbt@psr-suspend.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl1/igt@kms_fbcon_fbt@psr-suspend.html

  * igt@kms_flip@2x-flip-vs-modeset-vs-hang:
    - shard-tglb:         NOTRUN -> [SKIP][38] ([fdo#109274] / [fdo#111825])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb8/igt@kms_flip@2x-flip-vs-modeset-vs-hang.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@a-hdmi-a2:
    - shard-glk:          [PASS][39] -> [FAIL][40] ([i915#79])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-glk2/igt@kms_flip@flip-vs-expired-vblank-interruptible@a-hdmi-a2.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-glk4/igt@kms_flip@flip-vs-expired-vblank-interruptible@a-hdmi-a2.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling:
    - shard-iclb:         [PASS][41] -> [SKIP][42] ([i915#3701])
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb7/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling.html

  * igt@kms_force_connector_basic@force-load-detect:
    - shard-tglb:         NOTRUN -> [SKIP][43] ([fdo#109285])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb1/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-pwrite:
    - shard-tglb:         NOTRUN -> [SKIP][44] ([fdo#109280] / [fdo#111825]) +1 similar issue
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb8/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-pri-indfb-draw-pwrite.html

  * igt@kms_hdr@bpc-switch-suspend@bpc-switch-suspend-edp-1-pipe-a:
    - shard-skl:          [PASS][45] -> [FAIL][46] ([i915#1188])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl8/igt@kms_hdr@bpc-switch-suspend@bpc-switch-suspend-edp-1-pipe-a.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl1/igt@kms_hdr@bpc-switch-suspend@bpc-switch-suspend-edp-1-pipe-a.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-kbl:          [PASS][47] -> [DMESG-WARN][48] ([i915#180]) +2 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-kbl7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-opaque-fb:
    - shard-apl:          NOTRUN -> [FAIL][49] ([fdo#108145] / [i915#265])
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@kms_plane_alpha_blend@pipe-a-alpha-opaque-fb.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min:
    - shard-skl:          [PASS][50] -> [FAIL][51] ([fdo#108145] / [i915#265])
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl10/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb:
    - shard-apl:          NOTRUN -> [FAIL][52] ([i915#265])
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb.html

  * igt@kms_psr2_sf@cursor-plane-update-sf:
    - shard-skl:          NOTRUN -> [SKIP][53] ([fdo#109271] / [i915#658])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl8/igt@kms_psr2_sf@cursor-plane-update-sf.html

  * igt@kms_psr2_su@frontbuffer-xrgb8888:
    - shard-kbl:          NOTRUN -> [SKIP][54] ([fdo#109271] / [i915#658])
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl3/igt@kms_psr2_su@frontbuffer-xrgb8888.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-tglb:         NOTRUN -> [SKIP][55] ([i915#1911])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb5/igt@kms_psr2_su@page_flip-p010.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [PASS][56] -> [SKIP][57] ([fdo#109441]) +1 similar issue
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb4/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@kms_rotation_crc@primary-4-tiled-reflect-x-0:
    - shard-tglb:         NOTRUN -> [SKIP][58] ([i915#5289])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb5/igt@kms_rotation_crc@primary-4-tiled-reflect-x-0.html

  * igt@kms_sysfs_edid_timing:
    - shard-apl:          NOTRUN -> [FAIL][59] ([IGT#2])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@kms_sysfs_edid_timing.html

  * igt@kms_vblank@pipe-d-wait-idle:
    - shard-apl:          NOTRUN -> [SKIP][60] ([fdo#109271] / [i915#533]) +1 similar issue
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@kms_vblank@pipe-d-wait-idle.html

  * igt@perf@polling-parameterized:
    - shard-glk:          [PASS][61] -> [FAIL][62] ([i915#1542])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-glk1/igt@perf@polling-parameterized.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-glk2/igt@perf@polling-parameterized.html

  * igt@perf@short-reads:
    - shard-skl:          [PASS][63] -> [FAIL][64] ([i915#51])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl9/igt@perf@short-reads.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl8/igt@perf@short-reads.html

  * igt@sysfs_clients@fair-7:
    - shard-apl:          NOTRUN -> [SKIP][65] ([fdo#109271] / [i915#2994])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@sysfs_clients@fair-7.html

  * igt@sysfs_clients@recycle:
    - shard-kbl:          NOTRUN -> [SKIP][66] ([fdo#109271] / [i915#2994])
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl3/igt@sysfs_clients@recycle.html

  
#### Possible fixes ####

  * igt@fbdev@read:
    - {shard-rkl}:        [SKIP][67] ([i915#2582]) -> [PASS][68]
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@fbdev@read.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@fbdev@read.html

  * igt@gem_exec_capture@pi@bcs0:
    - {shard-tglu}:       [INCOMPLETE][69] ([i915#3371] / [i915#3731]) -> [PASS][70]
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-tglu-3/igt@gem_exec_capture@pi@bcs0.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglu-6/igt@gem_exec_capture@pi@bcs0.html

  * igt@gem_exec_fair@basic-none-share@rcs0:
    - shard-glk:          [FAIL][71] ([i915#2842]) -> [PASS][72]
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-glk4/igt@gem_exec_fair@basic-none-share@rcs0.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-glk3/igt@gem_exec_fair@basic-none-share@rcs0.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - {shard-rkl}:        [FAIL][73] ([i915#2842]) -> [PASS][74]
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-5/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-1/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace@vecs0:
    - shard-kbl:          [FAIL][75] ([i915#2842]) -> [PASS][76] +2 similar issues
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-kbl1/igt@gem_exec_fair@basic-pace@vecs0.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl4/igt@gem_exec_fair@basic-pace@vecs0.html

  * igt@i915_pm_dc@dc5-psr:
    - {shard-rkl}:        [SKIP][77] ([i915#658]) -> [PASS][78]
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@i915_pm_dc@dc5-psr.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@i915_pm_dc@dc5-psr.html

  * igt@i915_pm_sseu@full-enable:
    - shard-skl:          [FAIL][79] -> [PASS][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl6/igt@i915_pm_sseu@full-enable.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl3/igt@i915_pm_sseu@full-enable.html

  * igt@kms_atomic@atomic_plane_damage:
    - {shard-rkl}:        [SKIP][81] ([i915#4098]) -> [PASS][82] +1 similar issue
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_atomic@atomic_plane_damage.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_atomic@atomic_plane_damage.html

  * igt@kms_big_fb@x-tiled-32bpp-rotate-0:
    - shard-glk:          [DMESG-WARN][83] ([i915#118]) -> [PASS][84]
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-glk9/igt@kms_big_fb@x-tiled-32bpp-rotate-0.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-glk5/igt@kms_big_fb@x-tiled-32bpp-rotate-0.html

  * igt@kms_big_fb@x-tiled-32bpp-rotate-180:
    - {shard-tglu}:       [DMESG-WARN][85] ([i915#402]) -> [PASS][86]
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-tglu-3/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglu-4/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html

  * igt@kms_color@pipe-b-ctm-0-75:
    - {shard-rkl}:        ([SKIP][87], [SKIP][88]) ([i915#1149] / [i915#1849] / [i915#4070] / [i915#4098]) -> [PASS][89]
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_color@pipe-b-ctm-0-75.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-4/igt@kms_color@pipe-b-ctm-0-75.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_color@pipe-b-ctm-0-75.html

  * igt@kms_color@pipe-b-ctm-max:
    - {shard-rkl}:        [SKIP][90] ([i915#1149] / [i915#1849] / [i915#4070] / [i915#4098]) -> [PASS][91]
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_color@pipe-b-ctm-max.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_color@pipe-b-ctm-max.html

  * igt@kms_color@pipe-c-invalid-ctm-matrix-sizes:
    - {shard-rkl}:        [SKIP][92] ([i915#4070]) -> [PASS][93]
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-6/igt@kms_color@pipe-c-invalid-ctm-matrix-sizes.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-5/igt@kms_color@pipe-c-invalid-ctm-matrix-sizes.html

  * igt@kms_concurrent@pipe-b:
    - {shard-rkl}:        [SKIP][94] ([i915#1845] / [i915#4070] / [i915#4098]) -> [PASS][95]
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_concurrent@pipe-b.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_concurrent@pipe-b.html

  * igt@kms_cursor_crc@pipe-b-cursor-256x85-random:
    - {shard-rkl}:        [SKIP][96] ([fdo#112022] / [i915#4070]) -> [PASS][97] +2 similar issues
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_cursor_crc@pipe-b-cursor-256x85-random.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_cursor_crc@pipe-b-cursor-256x85-random.html

  * igt@kms_cursor_edge_walk@pipe-b-256x256-right-edge:
    - {shard-rkl}:        [SKIP][98] ([i915#1849] / [i915#4070] / [i915#4098]) -> [PASS][99] +4 similar issues
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_cursor_edge_walk@pipe-b-256x256-right-edge.html
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_cursor_edge_walk@pipe-b-256x256-right-edge.html

  * igt@kms_cursor_legacy@cursora-vs-flipa-legacy:
    - {shard-rkl}:        [SKIP][100] ([fdo#111825] / [i915#4070]) -> [PASS][101]
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_cursor_legacy@cursora-vs-flipa-legacy.html
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_cursor_legacy@cursora-vs-flipa-legacy.html

  * igt@kms_cursor_legacy@pipe-c-torture-move:
    - {shard-rkl}:        ([PASS][102], [SKIP][103]) ([i915#4070]) -> [PASS][104]
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-4/igt@kms_cursor_legacy@pipe-c-torture-move.html
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-6/igt@kms_cursor_legacy@pipe-c-torture-move.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-5/igt@kms_cursor_legacy@pipe-c-torture-move.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-mmap-cpu-ytiled:
    - {shard-rkl}:        [SKIP][105] ([fdo#111314] / [i915#4098] / [i915#4369]) -> [PASS][106] +5 similar issues
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_draw_crc@draw-method-xrgb2101010-mmap-cpu-ytiled.html
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_draw_crc@draw-method-xrgb2101010-mmap-cpu-ytiled.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-apl:          [INCOMPLETE][107] ([i915#180]) -> [PASS][108]
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-apl2/igt@kms_fbcon_fbt@fbc-suspend.html
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl7/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_flip@flip-vs-suspend@a-dp1:
    - shard-apl:          [DMESG-WARN][109] ([i915#180]) -> [PASS][110] +4 similar issues
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-apl1/igt@kms_flip@flip-vs-suspend@a-dp1.html
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-apl8/igt@kms_flip@flip-vs-suspend@a-dp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling:
    - shard-iclb:         [SKIP][111] ([i915#3701]) -> [PASS][112]
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling.html
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb6/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-64bpp-ytile-downscaling.html

  * igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw:
    - {shard-rkl}:        [SKIP][113] ([i915#1849]) -> [PASS][114] +14 similar issues
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_frontbuffer_tracking@fbc-1p-pri-indfb-multidraw.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [DMESG-WARN][115] ([i915#180]) -> [PASS][116] +9 similar issues
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-kbl1/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-kbl6/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-gtt:
    - {shard-rkl}:        ([SKIP][117], [SKIP][118]) ([i915#1849] / [i915#4098]) -> [PASS][119]
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-4/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-gtt.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-gtt.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-gtt.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - {shard-rkl}:        [SKIP][120] ([i915#1849] / [i915#4098]) -> [PASS][121]
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
    - shard-skl:          [INCOMPLETE][122] ([i915#4939]) -> [PASS][123]
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl9/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b.html

  * igt@kms_plane_cursor@pipe-a-overlay-size-64:
    - {shard-rkl}:        [SKIP][124] ([i915#1845] / [i915#4098]) -> [PASS][125] +21 similar issues
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_plane_cursor@pipe-a-overlay-size-64.html
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_plane_cursor@pipe-a-overlay-size-64.html

  * igt@kms_psr@cursor_mmap_gtt:
    - {shard-rkl}:        [SKIP][126] ([i915#1072]) -> [PASS][127] +3 similar issues
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-rkl-1/igt@kms_psr@cursor_mmap_gtt.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-rkl-6/igt@kms_psr@cursor_mmap_gtt.html

  * igt@kms_psr@psr2_suspend:
    - shard-iclb:         [SKIP][128] ([fdo#109441]) -> [PASS][129] +2 similar issues
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb1/igt@kms_psr@psr2_suspend.html
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb2/igt@kms_psr@psr2_suspend.html

  * igt@perf@polling-small-buf:
    - shard-skl:          [FAIL][130] ([i915#1722]) -> [PASS][131]
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl4/igt@perf@polling-small-buf.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl1/igt@perf@polling-small-buf.html

  
#### Warnings ####

  * igt@gem_eio@unwedge-stress:
    - shard-tglb:         [FAIL][132] ([i915#232]) -> [TIMEOUT][133] ([i915#3063] / [i915#3648])
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-tglb3/igt@gem_eio@unwedge-stress.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-tglb7/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_balancer@parallel-keep-in-fence:
    - shard-iclb:         [SKIP][134] ([i915#4525]) -> [DMESG-WARN][135] ([i915#5076])
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb3/igt@gem_exec_balancer@parallel-keep-in-fence.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb1/igt@gem_exec_balancer@parallel-keep-in-fence.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-iclb:         [FAIL][136] ([i915#2849]) -> [FAIL][137] ([i915#2842])
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb5/igt@gem_exec_fair@basic-throttle@rcs0.html
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb3/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-skl:          [FAIL][138] ([i915#1888] / [i915#454]) -> [FAIL][139] ([i915#454])
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl9/igt@i915_pm_dc@dc6-dpms.html
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-skl8/igt@i915_pm_dc@dc6-dpms.html

  * igt@kms_psr2_su@page_flip-nv12:
    - shard-iclb:         [FAIL][140] ([i915#4148]) -> [SKIP][141] ([fdo#109642] / [fdo#111068] / [i915#658])
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb2/igt@kms_psr2_su@page_flip-nv12.html
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb4/igt@kms_psr2_su@page_flip-nv12.html

  * igt@kms_psr2_su@page_flip-p010:
    - shard-iclb:         [SKIP][142] ([fdo#109642] / [fdo#111068] / [i915#658]) -> [FAIL][143] ([i915#4148])
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-iclb1/igt@kms_psr2_su@page_flip-p010.html
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/shard-iclb2/igt@kms_psr2_su@page_flip-p010.html

  * igt@kms_sysfs_edid_timing:
    - shard-skl:          [FAIL][144] ([IGT#2]) -> [FAIL][145] ([IGT#2] / [i915#1888])
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11354/shard-skl6/igt@kms_sysfs_edid_timing.html
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22553/index.html

[-- Attachment #2: Type: text/html, Size: 33288 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
  2022-03-13 13:46   ` [Intel-gfx] " Lee Shawn C
@ 2022-03-14  8:40     ` Jani Nikula
  -1 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2022-03-14  8:40 UTC (permalink / raw)
  To: Lee Shawn C, dri-devel
  Cc: Drew Davenport, ankit.k.nautiyal, Lee Shawn C, intel-gfx

On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> 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@linux.intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> Cc: Drew Davenport <ddavenport@chromium.org>
> Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> Signed-off-by: Lee Shawn C <shawn.c.lee@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)

Please don't do this. This just ruins the clean approach displayid
iterator added.

Instead of making the displayid iterator ugly, and leaking its
abstractions, I'll repeat what I said should be done in reply to the
very first version of this patch series [1]:

"I think we're going to need abstracted EDID iteration similar to what
I've done for DisplayID iteration. We can't have all places
reimplementing the iteration like we have now."

This isn't a problem that should be solved by having all the callers
hold a bunch of local variables and pass them around to all the
functions. Nobody's going to be able to keep track of this anymore. And
this series, as it is, makes it harder to fix this properly later on.


BR,
Jani.


[1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com



>  {
>  	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

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
@ 2022-03-14  8:40     ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2022-03-14  8:40 UTC (permalink / raw)
  To: Lee Shawn C, dri-devel; +Cc: Drew Davenport, intel-gfx

On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> 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@linux.intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> Cc: Drew Davenport <ddavenport@chromium.org>
> Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> Signed-off-by: Lee Shawn C <shawn.c.lee@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)

Please don't do this. This just ruins the clean approach displayid
iterator added.

Instead of making the displayid iterator ugly, and leaking its
abstractions, I'll repeat what I said should be done in reply to the
very first version of this patch series [1]:

"I think we're going to need abstracted EDID iteration similar to what
I've done for DisplayID iteration. We can't have all places
reimplementing the iteration like we have now."

This isn't a problem that should be solved by having all the callers
hold a bunch of local variables and pass them around to all the
functions. Nobody's going to be able to keep track of this anymore. And
this series, as it is, makes it harder to fix this properly later on.


BR,
Jani.


[1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com



>  {
>  	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

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
  2022-03-14  8:40     ` [Intel-gfx] " Jani Nikula
@ 2022-03-14 21:02       ` Drew Davenport
  -1 siblings, 0 replies; 30+ messages in thread
From: Drew Davenport @ 2022-03-14 21:02 UTC (permalink / raw)
  To: Jani Nikula; +Cc: ankit.k.nautiyal, Lee Shawn C, dri-devel, intel-gfx

On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> > 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@linux.intel.com>
> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> > Cc: Drew Davenport <ddavenport@chromium.org>
> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
> 
> Please don't do this. This just ruins the clean approach displayid
> iterator added.
> 
> Instead of making the displayid iterator ugly, and leaking its
> abstractions, I'll repeat what I said should be done in reply to the
> very first version of this patch series [1]:
> 
> "I think we're going to need abstracted EDID iteration similar to what
> I've done for DisplayID iteration. We can't have all places
> reimplementing the iteration like we have now."
> 
> This isn't a problem that should be solved by having all the callers
> hold a bunch of local variables and pass them around to all the
> functions. Nobody's going to be able to keep track of this anymore. And
> this series, as it is, makes it harder to fix this properly later on.

I missed your original review comment, so apologies for repeating what you
said there already.

I'd agree that passing a starting index to the displayid_iter_*
functions is probably not the right direction here. More thoughts below.

> 
> 
> BR,
> Jani.
> 
> 
> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
> 
> 
> 
> >  {
> >  	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)

As discussed above, passing both indices into this function may not be
the best approach here. But I think we need to keep track of some kind
of state in order to know which was the last CEA block that was
returned, and thus this function can return the next one after that,
whether it's in the CEA extension block or DisplayID block.

What do you think of using the pointer returned from this function as
that state? The caller could pass in a u8* that was returned from a
previous call. This function would iterate through the extension blocks
and skip the CEA blocks it finds until it finds the passed in pointer,
and then return the next one after (or NULL).

An alternative might be to create a linked list of ptrs to the edid
extension blocks, and allow a caller to iterate over them in whatever
way they need, but I'm not sure how useful that is elsewhere.

> >  {
> >  	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
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
@ 2022-03-14 21:02       ` Drew Davenport
  0 siblings, 0 replies; 30+ messages in thread
From: Drew Davenport @ 2022-03-14 21:02 UTC (permalink / raw)
  To: Jani Nikula; +Cc: dri-devel, intel-gfx

On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> > 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@linux.intel.com>
> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> > Cc: Drew Davenport <ddavenport@chromium.org>
> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
> 
> Please don't do this. This just ruins the clean approach displayid
> iterator added.
> 
> Instead of making the displayid iterator ugly, and leaking its
> abstractions, I'll repeat what I said should be done in reply to the
> very first version of this patch series [1]:
> 
> "I think we're going to need abstracted EDID iteration similar to what
> I've done for DisplayID iteration. We can't have all places
> reimplementing the iteration like we have now."
> 
> This isn't a problem that should be solved by having all the callers
> hold a bunch of local variables and pass them around to all the
> functions. Nobody's going to be able to keep track of this anymore. And
> this series, as it is, makes it harder to fix this properly later on.

I missed your original review comment, so apologies for repeating what you
said there already.

I'd agree that passing a starting index to the displayid_iter_*
functions is probably not the right direction here. More thoughts below.

> 
> 
> BR,
> Jani.
> 
> 
> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
> 
> 
> 
> >  {
> >  	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)

As discussed above, passing both indices into this function may not be
the best approach here. But I think we need to keep track of some kind
of state in order to know which was the last CEA block that was
returned, and thus this function can return the next one after that,
whether it's in the CEA extension block or DisplayID block.

What do you think of using the pointer returned from this function as
that state? The caller could pass in a u8* that was returned from a
previous call. This function would iterate through the extension blocks
and skip the CEA blocks it finds until it finds the passed in pointer,
and then return the next one after (or NULL).

An alternative might be to create a linked list of ptrs to the edid
extension blocks, and allow a caller to iterate over them in whatever
way they need, but I'm not sure how useful that is elsewhere.

> >  {
> >  	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
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [v7 3/5] drm/edid: read HF-EEODB ext block
  2022-03-13 13:47   ` [Intel-gfx] " Lee Shawn C
@ 2022-03-15 11:03     ` Jani Nikula
  -1 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2022-03-15 11:03 UTC (permalink / raw)
  To: Lee Shawn C, dri-devel
  Cc: Drew Davenport, ankit.k.nautiyal, Lee Shawn C, intel-gfx

On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> According to HDMI 2.1 spec.
>
> "The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
> is utilized by Sink Devices to provide an alternate method to
> indicate an EDID Extension Block count larger than 1, while
> avoiding the need to present a VESA Block Map in the first
> E-EDID Extension Block."
>
> It is a mandatory for HDMI 2.1 protocol compliance as well.
> This patch help to know how many HF_EEODB blocks report by sink
> and read allo HF_EEODB blocks back.
>
> v2: support to find CEA block, check EEODB block format, and return
>     available block number in drm_edid_read_hf_eeodb_blk_count().
>
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> Cc: Drew Davenport <ddavenport@chromium.org>
> Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
> ---
>  drivers/gpu/drm/drm_connector.c |  8 +++-
>  drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
>  include/drm/drm_edid.h          |  1 +
>  3 files changed, 74 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index a50c82bc2b2f..16011023c12e 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>  				       const struct edid *edid)
>  {
>  	struct drm_device *dev = connector->dev;
> -	size_t size = 0;
> +	size_t size = 0, hf_eeodb_blk_count;
>  	int ret;
>  	const struct edid *old_edid;
>  
> @@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>  	if (connector->override_edid)
>  		return 0;
>  
> -	if (edid)
> +	if (edid) {
>  		size = EDID_LENGTH * (1 + edid->extensions);
> +		hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
> +		if (hf_eeodb_blk_count)
> +			size = EDID_LENGTH * (1 + hf_eeodb_blk_count);

This approach does not scale. If the number of extensions and thus the
total EDID size depend on HF-EEODB, this *must* be abstracted.

Consider, for example, drm_edid_duplicate(), which only looks at
edid->extensions. A subsequent HF-EEODB aware access on an EDID
duplicated using drm_edid_duplicate() will access beyond the allocated
buffer.

Yes, it's a lot of work to introduce drm_edid_size() and
drm_edid_extension_count() or similar, and use them everywhere, but this
is what we must do. It's a lot more work to try to take HF-EEODB into
account everywhere. The latter is going to be riddled with bugs with
everyone doing it a little different.

> +	}
>  
>  	/* Set the display info, using edid if available, otherwise
>  	 * resetting the values to defaults. This duplicates the work
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 9fa84881fbba..5ae4e83fa5e3 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  {
>  	int i, j = 0, valid_extensions = 0;
>  	u8 *edid, *new;
> +	size_t hf_eeodb_blk_count;
>  	struct edid *override;
>  
>  	override = drm_get_override_edid(connector);
> @@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  		}
>  
>  		kfree(edid);
> +		return (struct edid *)new;
> +	}
> +
> +	hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid *)edid);
> +	if (hf_eeodb_blk_count >= 2) {
> +		new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, GFP_KERNEL);
> +		if (!new)
> +			goto out;
>  		edid = new;
> +
> +		valid_extensions = hf_eeodb_blk_count - 1;
> +		for (j = 2; j <= hf_eeodb_blk_count; j++) {
> +			u8 *block = edid + j * EDID_LENGTH;
> +
> +			for (i = 0; i < 4; i++) {
> +				if (get_edid_block(data, block, j, EDID_LENGTH))
> +					goto out;
> +				if (drm_edid_block_valid(block, j, false, NULL))
> +					break;
> +			}
> +
> +			if (i == 4)
> +				valid_extensions--;
> +		}
> +
> +		if (valid_extensions != hf_eeodb_blk_count - 1) {
> +			DRM_ERROR("Not able to retrieve proper EDID contain HF-EEODB data.\n");
> +			goto out;
> +		}
>  	}
>  
>  	return (struct edid *)edid;
> @@ -3315,15 +3344,17 @@ 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_CAPABILITY_BLOCK	0x00
> +#define HDR_STATIC_METADATA_BLOCK	0x06
> +#define USE_EXTENDED_TAG		0x07
>  #define EXT_VIDEO_DATA_BLOCK_420	0x0E
> -#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
> +#define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
> +#define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
>  #define EDID_BASIC_AUDIO	(1 << 6)
>  #define EDID_CEA_YCRCB444	(1 << 5)
>  #define EDID_CEA_YCRCB422	(1 << 4)
>  #define EDID_CEA_VCDB_QS	(1 << 6)
> +#define HF_EEODB_LENGTH		2
>  
>  /*
>   * Search EDID for CEA extension block.
> @@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
>  	return true;
>  }
>  
> +static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
> +{
> +	if (cea_db_tag(db) != USE_EXTENDED_TAG)
> +		return false;
> +
> +	if (cea_db_payload_len(db) != HF_EEODB_LENGTH)
> +		return false;
> +
> +	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_EEODB_DATA_BLOCK)
> +		return false;
> +
> +	return true;
> +}
> +
>  #define for_each_cea_db(cea, i, start, end) \
>  	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
>  
> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid)
> +{
> +	const u8 *cea;
> +	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
> +
> +	if (edid->extensions) {
> +		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
> +
> +		if (cea && !cea_db_offsets(cea, &start, &end))
> +			for_each_cea_db(cea, i, start, end)
> +				if (cea_db_is_hdmi_forum_eeodb(&cea[i]))
> +					return cea[i + 2];
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(drm_edid_read_hf_eeodb_blk_count);

This should be static and not exported.

BR,
Jani.

> +
>  static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
>  				      const u8 *db)
>  {
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..585f0ed932d4 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -593,5 +593,6 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  const u8 *drm_find_edid_extension(const struct edid *edid,
>  				  int ext_id, int *ext_index);
>  
> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
>  
>  #endif /* __DRM_EDID_H__ */

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [v7 3/5] drm/edid: read HF-EEODB ext block
@ 2022-03-15 11:03     ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2022-03-15 11:03 UTC (permalink / raw)
  To: Lee Shawn C, dri-devel; +Cc: Drew Davenport, intel-gfx

On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> According to HDMI 2.1 spec.
>
> "The HDMI Forum EDID Extension Override Data Block (HF-EEODB)
> is utilized by Sink Devices to provide an alternate method to
> indicate an EDID Extension Block count larger than 1, while
> avoiding the need to present a VESA Block Map in the first
> E-EDID Extension Block."
>
> It is a mandatory for HDMI 2.1 protocol compliance as well.
> This patch help to know how many HF_EEODB blocks report by sink
> and read allo HF_EEODB blocks back.
>
> v2: support to find CEA block, check EEODB block format, and return
>     available block number in drm_edid_read_hf_eeodb_blk_count().
>
> Cc: Jani Nikula <jani.nikula@linux.intel.com>
> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> Cc: Drew Davenport <ddavenport@chromium.org>
> Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
> ---
>  drivers/gpu/drm/drm_connector.c |  8 +++-
>  drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
>  include/drm/drm_edid.h          |  1 +
>  3 files changed, 74 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index a50c82bc2b2f..16011023c12e 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>  				       const struct edid *edid)
>  {
>  	struct drm_device *dev = connector->dev;
> -	size_t size = 0;
> +	size_t size = 0, hf_eeodb_blk_count;
>  	int ret;
>  	const struct edid *old_edid;
>  
> @@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>  	if (connector->override_edid)
>  		return 0;
>  
> -	if (edid)
> +	if (edid) {
>  		size = EDID_LENGTH * (1 + edid->extensions);
> +		hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
> +		if (hf_eeodb_blk_count)
> +			size = EDID_LENGTH * (1 + hf_eeodb_blk_count);

This approach does not scale. If the number of extensions and thus the
total EDID size depend on HF-EEODB, this *must* be abstracted.

Consider, for example, drm_edid_duplicate(), which only looks at
edid->extensions. A subsequent HF-EEODB aware access on an EDID
duplicated using drm_edid_duplicate() will access beyond the allocated
buffer.

Yes, it's a lot of work to introduce drm_edid_size() and
drm_edid_extension_count() or similar, and use them everywhere, but this
is what we must do. It's a lot more work to try to take HF-EEODB into
account everywhere. The latter is going to be riddled with bugs with
everyone doing it a little different.

> +	}
>  
>  	/* Set the display info, using edid if available, otherwise
>  	 * resetting the values to defaults. This duplicates the work
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 9fa84881fbba..5ae4e83fa5e3 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  {
>  	int i, j = 0, valid_extensions = 0;
>  	u8 *edid, *new;
> +	size_t hf_eeodb_blk_count;
>  	struct edid *override;
>  
>  	override = drm_get_override_edid(connector);
> @@ -2051,7 +2052,35 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>  		}
>  
>  		kfree(edid);
> +		return (struct edid *)new;
> +	}
> +
> +	hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid *)edid);
> +	if (hf_eeodb_blk_count >= 2) {
> +		new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, GFP_KERNEL);
> +		if (!new)
> +			goto out;
>  		edid = new;
> +
> +		valid_extensions = hf_eeodb_blk_count - 1;
> +		for (j = 2; j <= hf_eeodb_blk_count; j++) {
> +			u8 *block = edid + j * EDID_LENGTH;
> +
> +			for (i = 0; i < 4; i++) {
> +				if (get_edid_block(data, block, j, EDID_LENGTH))
> +					goto out;
> +				if (drm_edid_block_valid(block, j, false, NULL))
> +					break;
> +			}
> +
> +			if (i == 4)
> +				valid_extensions--;
> +		}
> +
> +		if (valid_extensions != hf_eeodb_blk_count - 1) {
> +			DRM_ERROR("Not able to retrieve proper EDID contain HF-EEODB data.\n");
> +			goto out;
> +		}
>  	}
>  
>  	return (struct edid *)edid;
> @@ -3315,15 +3344,17 @@ 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_CAPABILITY_BLOCK	0x00
> +#define HDR_STATIC_METADATA_BLOCK	0x06
> +#define USE_EXTENDED_TAG		0x07
>  #define EXT_VIDEO_DATA_BLOCK_420	0x0E
> -#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
> +#define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
> +#define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
>  #define EDID_BASIC_AUDIO	(1 << 6)
>  #define EDID_CEA_YCRCB444	(1 << 5)
>  #define EDID_CEA_YCRCB422	(1 << 4)
>  #define EDID_CEA_VCDB_QS	(1 << 6)
> +#define HF_EEODB_LENGTH		2
>  
>  /*
>   * Search EDID for CEA extension block.
> @@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
>  	return true;
>  }
>  
> +static bool cea_db_is_hdmi_forum_eeodb(const u8 *db)
> +{
> +	if (cea_db_tag(db) != USE_EXTENDED_TAG)
> +		return false;
> +
> +	if (cea_db_payload_len(db) != HF_EEODB_LENGTH)
> +		return false;
> +
> +	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_EEODB_DATA_BLOCK)
> +		return false;
> +
> +	return true;
> +}
> +
>  #define for_each_cea_db(cea, i, start, end) \
>  	for ((i) = (start); (i) < (end) && (i) + cea_db_payload_len(&(cea)[(i)]) < (end); (i) += cea_db_payload_len(&(cea)[(i)]) + 1)
>  
> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid)
> +{
> +	const u8 *cea;
> +	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
> +
> +	if (edid->extensions) {
> +		cea = drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index);
> +
> +		if (cea && !cea_db_offsets(cea, &start, &end))
> +			for_each_cea_db(cea, i, start, end)
> +				if (cea_db_is_hdmi_forum_eeodb(&cea[i]))
> +					return cea[i + 2];
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(drm_edid_read_hf_eeodb_blk_count);

This should be static and not exported.

BR,
Jani.

> +
>  static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
>  				      const u8 *db)
>  {
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index 144c495b99c4..585f0ed932d4 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -593,5 +593,6 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
>  const u8 *drm_find_edid_extension(const struct edid *edid,
>  				  int ext_id, int *ext_index);
>  
> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
>  
>  #endif /* __DRM_EDID_H__ */

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
  2022-03-14 21:02       ` [Intel-gfx] " Drew Davenport
@ 2022-03-15 12:32         ` Jani Nikula
  -1 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2022-03-15 12:32 UTC (permalink / raw)
  To: Drew Davenport; +Cc: ankit.k.nautiyal, Lee Shawn C, dri-devel, intel-gfx

On Mon, 14 Mar 2022, Drew Davenport <ddavenport@chromium.org> wrote:
> On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
>> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
>> > 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@linux.intel.com>
>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>> > Cc: Drew Davenport <ddavenport@chromium.org>
>> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
>> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
>> 
>> Please don't do this. This just ruins the clean approach displayid
>> iterator added.
>> 
>> Instead of making the displayid iterator ugly, and leaking its
>> abstractions, I'll repeat what I said should be done in reply to the
>> very first version of this patch series [1]:
>> 
>> "I think we're going to need abstracted EDID iteration similar to what
>> I've done for DisplayID iteration. We can't have all places
>> reimplementing the iteration like we have now."
>> 
>> This isn't a problem that should be solved by having all the callers
>> hold a bunch of local variables and pass them around to all the
>> functions. Nobody's going to be able to keep track of this anymore. And
>> this series, as it is, makes it harder to fix this properly later on.
>
> I missed your original review comment, so apologies for repeating what you
> said there already.
>
> I'd agree that passing a starting index to the displayid_iter_*
> functions is probably not the right direction here. More thoughts below.
>
>> 
>> 
>> BR,
>> Jani.
>> 
>> 
>> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
>> 
>> 
>> 
>> >  {
>> >  	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)
>
> As discussed above, passing both indices into this function may not be
> the best approach here. But I think we need to keep track of some kind
> of state in order to know which was the last CEA block that was
> returned, and thus this function can return the next one after that,
> whether it's in the CEA extension block or DisplayID block.

Per DisplayID v1.3 Appendix B: DisplayID as an EDID Extension, it's
recommended that DisplayID extensions are exposed after all of the CEA
extensions.

I think it should be fine to first iterate over all CEA extensions
across the EDID, followed by iterating over all the DisplayID
extensions. No need to keep track of the order between CEA and
DisplayID, as the former should precede the latter.

> What do you think of using the pointer returned from this function as
> that state? The caller could pass in a u8* that was returned from a
> previous call. This function would iterate through the extension blocks
> and skip the CEA blocks it finds until it finds the passed in pointer,
> and then return the next one after (or NULL).
>
> An alternative might be to create a linked list of ptrs to the edid
> extension blocks, and allow a caller to iterate over them in whatever
> way they need, but I'm not sure how useful that is elsewhere.

I think the main problem here is trying to hack a for loop around
drm_find_cea_extension() and drm_find_edid_extension(), and duplicating
that all over the place, without adding more structure or abstractions.

Contrast with displayid_iter_edid_begin(), displayid_iter_for_each(),
and displayid_iter_end() and their usage. They hide all the complexity
of looping across DisplayID data blocks inside EDID extensions, and none
of the users need to be aware of that complexity. All the state is
hidden in struct displayid_iter, and the users don't need to look
inside. No allocations, no linked lists.

I think it's particularly bad to have the changes here break the
abstractions in displayid_iter_*, especially because they should be
usable for pure DisplayID 2.0 *without* an EDID block structure. They'll
just need a displayid_iter_begin() for pure DisplayID and some internal
changes.

Looking at the usage, the iteration should probably be done at the CEA
data block level, something like this:

	struct cea_iter iter;
        const struct cea_block *block;

	cea_iter_edid_begin(edid, &iter);
        cea_iter_for_each(block, &iter) {
		/* ... */        
        }
        cea_iter_end(&iter);

This would replace cea_db_offsets() and for_each_cea_db(), and would
iterate across the all CEA and DisplayID extensions in the entire EDID.

This looks usable, and then you'd start figuring out how to implement
that, instead of trying to retrofit all the existing usages to
abstractions that don't cut it. You'll probably need an EDID extension
iterator too, and then use that and __displayid_iter_next() within
cea_iter_for_each() i.e. you'd embed the edid_iter and displayid_iter
within struct cea_iter. Exhaust the former first, and then the latter.


BR,
Jani.


>
>> >  {
>> >  	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
>> 
>> -- 
>> Jani Nikula, Intel Open Source Graphics Center

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
@ 2022-03-15 12:32         ` Jani Nikula
  0 siblings, 0 replies; 30+ messages in thread
From: Jani Nikula @ 2022-03-15 12:32 UTC (permalink / raw)
  To: Drew Davenport; +Cc: dri-devel, intel-gfx

On Mon, 14 Mar 2022, Drew Davenport <ddavenport@chromium.org> wrote:
> On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
>> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
>> > 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@linux.intel.com>
>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>> > Cc: Drew Davenport <ddavenport@chromium.org>
>> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
>> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
>> 
>> Please don't do this. This just ruins the clean approach displayid
>> iterator added.
>> 
>> Instead of making the displayid iterator ugly, and leaking its
>> abstractions, I'll repeat what I said should be done in reply to the
>> very first version of this patch series [1]:
>> 
>> "I think we're going to need abstracted EDID iteration similar to what
>> I've done for DisplayID iteration. We can't have all places
>> reimplementing the iteration like we have now."
>> 
>> This isn't a problem that should be solved by having all the callers
>> hold a bunch of local variables and pass them around to all the
>> functions. Nobody's going to be able to keep track of this anymore. And
>> this series, as it is, makes it harder to fix this properly later on.
>
> I missed your original review comment, so apologies for repeating what you
> said there already.
>
> I'd agree that passing a starting index to the displayid_iter_*
> functions is probably not the right direction here. More thoughts below.
>
>> 
>> 
>> BR,
>> Jani.
>> 
>> 
>> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
>> 
>> 
>> 
>> >  {
>> >  	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)
>
> As discussed above, passing both indices into this function may not be
> the best approach here. But I think we need to keep track of some kind
> of state in order to know which was the last CEA block that was
> returned, and thus this function can return the next one after that,
> whether it's in the CEA extension block or DisplayID block.

Per DisplayID v1.3 Appendix B: DisplayID as an EDID Extension, it's
recommended that DisplayID extensions are exposed after all of the CEA
extensions.

I think it should be fine to first iterate over all CEA extensions
across the EDID, followed by iterating over all the DisplayID
extensions. No need to keep track of the order between CEA and
DisplayID, as the former should precede the latter.

> What do you think of using the pointer returned from this function as
> that state? The caller could pass in a u8* that was returned from a
> previous call. This function would iterate through the extension blocks
> and skip the CEA blocks it finds until it finds the passed in pointer,
> and then return the next one after (or NULL).
>
> An alternative might be to create a linked list of ptrs to the edid
> extension blocks, and allow a caller to iterate over them in whatever
> way they need, but I'm not sure how useful that is elsewhere.

I think the main problem here is trying to hack a for loop around
drm_find_cea_extension() and drm_find_edid_extension(), and duplicating
that all over the place, without adding more structure or abstractions.

Contrast with displayid_iter_edid_begin(), displayid_iter_for_each(),
and displayid_iter_end() and their usage. They hide all the complexity
of looping across DisplayID data blocks inside EDID extensions, and none
of the users need to be aware of that complexity. All the state is
hidden in struct displayid_iter, and the users don't need to look
inside. No allocations, no linked lists.

I think it's particularly bad to have the changes here break the
abstractions in displayid_iter_*, especially because they should be
usable for pure DisplayID 2.0 *without* an EDID block structure. They'll
just need a displayid_iter_begin() for pure DisplayID and some internal
changes.

Looking at the usage, the iteration should probably be done at the CEA
data block level, something like this:

	struct cea_iter iter;
        const struct cea_block *block;

	cea_iter_edid_begin(edid, &iter);
        cea_iter_for_each(block, &iter) {
		/* ... */        
        }
        cea_iter_end(&iter);

This would replace cea_db_offsets() and for_each_cea_db(), and would
iterate across the all CEA and DisplayID extensions in the entire EDID.

This looks usable, and then you'd start figuring out how to implement
that, instead of trying to retrofit all the existing usages to
abstractions that don't cut it. You'll probably need an EDID extension
iterator too, and then use that and __displayid_iter_next() within
cea_iter_for_each() i.e. you'd embed the edid_iter and displayid_iter
within struct cea_iter. Exhaust the former first, and then the latter.


BR,
Jani.


>
>> >  {
>> >  	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
>> 
>> -- 
>> Jani Nikula, Intel Open Source Graphics Center

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [v7 3/5] drm/edid: read HF-EEODB ext block
  2022-03-15 11:03     ` [Intel-gfx] " Jani Nikula
@ 2022-03-15 13:43       ` Lee, Shawn C
  -1 siblings, 0 replies; 30+ messages in thread
From: Lee, Shawn C @ 2022-03-15 13:43 UTC (permalink / raw)
  To: Nikula, Jani, dri-devel; +Cc: Drew Davenport, Nautiyal, Ankit K, intel-gfx

On Tuesday, March 15, 2022 7:03 PM, Nikula, Jani <jani.nikula@intel.com> wrote:
>On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
>> According to HDMI 2.1 spec.
>>
>> "The HDMI Forum EDID Extension Override Data Block (HF-EEODB) is 
>> utilized by Sink Devices to provide an alternate method to indicate an 
>> EDID Extension Block count larger than 1, while avoiding the need to 
>> present a VESA Block Map in the first E-EDID Extension Block."
>>
>> It is a mandatory for HDMI 2.1 protocol compliance as well.
>> This patch help to know how many HF_EEODB blocks report by sink and 
>> read allo HF_EEODB blocks back.
>>
>> v2: support to find CEA block, check EEODB block format, and return
>>     available block number in drm_edid_read_hf_eeodb_blk_count().
>>
>> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>> Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>> Cc: Drew Davenport <ddavenport@chromium.org>
>> Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
>> Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
>> ---
>>  drivers/gpu/drm/drm_connector.c |  8 +++-
>>  drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
>>  include/drm/drm_edid.h          |  1 +
>>  3 files changed, 74 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_connector.c 
>> b/drivers/gpu/drm/drm_connector.c index a50c82bc2b2f..16011023c12e 
>> 100644
>> --- a/drivers/gpu/drm/drm_connector.c
>> +++ b/drivers/gpu/drm/drm_connector.c
>> @@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>>  				       const struct edid *edid)
>>  {
>>  	struct drm_device *dev = connector->dev;
>> -	size_t size = 0;
>> +	size_t size = 0, hf_eeodb_blk_count;
>>  	int ret;
>>  	const struct edid *old_edid;
>>  
>> @@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>>  	if (connector->override_edid)
>>  		return 0;
>>  
>> -	if (edid)
>> +	if (edid) {
>>  		size = EDID_LENGTH * (1 + edid->extensions);
>> +		hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
>> +		if (hf_eeodb_blk_count)
>> +			size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
>
>This approach does not scale. If the number of extensions and thus the total EDID size depend on HF-EEODB, this *must* be abstracted.
>
>Consider, for example, drm_edid_duplicate(), which only looks at
>edid->extensions. A subsequent HF-EEODB aware access on an EDID
>duplicated using drm_edid_duplicate() will access beyond the allocated buffer.
>
>Yes, it's a lot of work to introduce drm_edid_size() and
>drm_edid_extension_count() or similar, and use them everywhere, but this is what we must do. It's a lot more work to try to take HF-EEODB into account everywhere. The latter is going to be riddled with bugs with everyone doing it a little different.
>

As you mentioned, we should have new functions to provide proper EDID byte size or extension counter.
And reuse them to handle/retrieve EDID more accurately in drm driver. Thanks for your comment!

>> +	}
>>  
>>  	/* Set the display info, using edid if available, otherwise
>>  	 * resetting the values to defaults. This duplicates the work diff 
>> --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 
>> 9fa84881fbba..5ae4e83fa5e3 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct 
>> drm_connector *connector,  {
>>  	int i, j = 0, valid_extensions = 0;
>>  	u8 *edid, *new;
>> +	size_t hf_eeodb_blk_count;
>>  	struct edid *override;
>>  
>>  	override = drm_get_override_edid(connector); @@ -2051,7 +2052,35 @@ 
>> struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  		}
>>  
>>  		kfree(edid);
>> +		return (struct edid *)new;
>> +	}
>> +
>> +	hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid *)edid);
>> +	if (hf_eeodb_blk_count >= 2) {
>> +		new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, GFP_KERNEL);
>> +		if (!new)
>> +			goto out;
>>  		edid = new;
>> +
>> +		valid_extensions = hf_eeodb_blk_count - 1;
>> +		for (j = 2; j <= hf_eeodb_blk_count; j++) {
>> +			u8 *block = edid + j * EDID_LENGTH;
>> +
>> +			for (i = 0; i < 4; i++) {
>> +				if (get_edid_block(data, block, j, EDID_LENGTH))
>> +					goto out;
>> +				if (drm_edid_block_valid(block, j, false, NULL))
>> +					break;
>> +			}
>> +
>> +			if (i == 4)
>> +				valid_extensions--;
>> +		}
>> +
>> +		if (valid_extensions != hf_eeodb_blk_count - 1) {
>> +			DRM_ERROR("Not able to retrieve proper EDID contain HF-EEODB data.\n");
>> +			goto out;
>> +		}
>>  	}
>>  
>>  	return (struct edid *)edid;
>> @@ -3315,15 +3344,17 @@ 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_CAPABILITY_BLOCK	0x00
>> +#define HDR_STATIC_METADATA_BLOCK	0x06
>> +#define USE_EXTENDED_TAG		0x07
>>  #define EXT_VIDEO_DATA_BLOCK_420	0x0E
>> -#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
>> +#define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
>> +#define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
>>  #define EDID_BASIC_AUDIO	(1 << 6)
>>  #define EDID_CEA_YCRCB444	(1 << 5)
>>  #define EDID_CEA_YCRCB422	(1 << 4)
>>  #define EDID_CEA_VCDB_QS	(1 << 6)
>> +#define HF_EEODB_LENGTH		2
>>  
>>  /*
>>   * Search EDID for CEA extension block.
>> @@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
>>  	return true;
>>  }
>>  
>> +static bool cea_db_is_hdmi_forum_eeodb(const u8 *db) {
>> +	if (cea_db_tag(db) != USE_EXTENDED_TAG)
>> +		return false;
>> +
>> +	if (cea_db_payload_len(db) != HF_EEODB_LENGTH)
>> +		return false;
>> +
>> +	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_EEODB_DATA_BLOCK)
>> +		return false;
>> +
>> +	return true;
>> +}
>> +
>>  #define for_each_cea_db(cea, i, start, end) \
>>  	for ((i) = (start); (i) < (end) && (i) + 
>> cea_db_payload_len(&(cea)[(i)]) < (end); (i) += 
>> cea_db_payload_len(&(cea)[(i)]) + 1)
>>  
>> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid) {
>> +	const u8 *cea;
>> +	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
>> +
>> +	if (edid->extensions) {
>> +		cea = drm_find_cea_extension(edid, &cea_ext_index, 
>> +&displayid_ext_index);
>> +
>> +		if (cea && !cea_db_offsets(cea, &start, &end))
>> +			for_each_cea_db(cea, i, start, end)
>> +				if (cea_db_is_hdmi_forum_eeodb(&cea[i]))
>> +					return cea[i + 2];
>> +	}
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(drm_edid_read_hf_eeodb_blk_count);
>
>This should be static and not exported.
>
>BR,
>Jani.
>
>> +
>>  static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
>>  				      const u8 *db)
>>  {
>> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 
>> 144c495b99c4..585f0ed932d4 100644
>> --- a/include/drm/drm_edid.h
>> +++ b/include/drm/drm_edid.h
>> @@ -593,5 +593,6 @@ drm_display_mode_from_cea_vic(struct drm_device 
>> *dev,  const u8 *drm_find_edid_extension(const struct edid *edid,
>>  				  int ext_id, int *ext_index);
>>  
>> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
>>  
>>  #endif /* __DRM_EDID_H__ */
>
>--
>Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [v7 3/5] drm/edid: read HF-EEODB ext block
@ 2022-03-15 13:43       ` Lee, Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee, Shawn C @ 2022-03-15 13:43 UTC (permalink / raw)
  To: Nikula, Jani, dri-devel; +Cc: Drew Davenport, intel-gfx

On Tuesday, March 15, 2022 7:03 PM, Nikula, Jani <jani.nikula@intel.com> wrote:
>On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
>> According to HDMI 2.1 spec.
>>
>> "The HDMI Forum EDID Extension Override Data Block (HF-EEODB) is 
>> utilized by Sink Devices to provide an alternate method to indicate an 
>> EDID Extension Block count larger than 1, while avoiding the need to 
>> present a VESA Block Map in the first E-EDID Extension Block."
>>
>> It is a mandatory for HDMI 2.1 protocol compliance as well.
>> This patch help to know how many HF_EEODB blocks report by sink and 
>> read allo HF_EEODB blocks back.
>>
>> v2: support to find CEA block, check EEODB block format, and return
>>     available block number in drm_edid_read_hf_eeodb_blk_count().
>>
>> Cc: Jani Nikula <jani.nikula@linux.intel.com>
>> Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>> Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>> Cc: Drew Davenport <ddavenport@chromium.org>
>> Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
>> Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
>> ---
>>  drivers/gpu/drm/drm_connector.c |  8 +++-
>>  drivers/gpu/drm/drm_edid.c      | 71 +++++++++++++++++++++++++++++++--
>>  include/drm/drm_edid.h          |  1 +
>>  3 files changed, 74 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_connector.c 
>> b/drivers/gpu/drm/drm_connector.c index a50c82bc2b2f..16011023c12e 
>> 100644
>> --- a/drivers/gpu/drm/drm_connector.c
>> +++ b/drivers/gpu/drm/drm_connector.c
>> @@ -2129,7 +2129,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>>  				       const struct edid *edid)
>>  {
>>  	struct drm_device *dev = connector->dev;
>> -	size_t size = 0;
>> +	size_t size = 0, hf_eeodb_blk_count;
>>  	int ret;
>>  	const struct edid *old_edid;
>>  
>> @@ -2137,8 +2137,12 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
>>  	if (connector->override_edid)
>>  		return 0;
>>  
>> -	if (edid)
>> +	if (edid) {
>>  		size = EDID_LENGTH * (1 + edid->extensions);
>> +		hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count(edid);
>> +		if (hf_eeodb_blk_count)
>> +			size = EDID_LENGTH * (1 + hf_eeodb_blk_count);
>
>This approach does not scale. If the number of extensions and thus the total EDID size depend on HF-EEODB, this *must* be abstracted.
>
>Consider, for example, drm_edid_duplicate(), which only looks at
>edid->extensions. A subsequent HF-EEODB aware access on an EDID
>duplicated using drm_edid_duplicate() will access beyond the allocated buffer.
>
>Yes, it's a lot of work to introduce drm_edid_size() and
>drm_edid_extension_count() or similar, and use them everywhere, but this is what we must do. It's a lot more work to try to take HF-EEODB into account everywhere. The latter is going to be riddled with bugs with everyone doing it a little different.
>

As you mentioned, we should have new functions to provide proper EDID byte size or extension counter.
And reuse them to handle/retrieve EDID more accurately in drm driver. Thanks for your comment!

>> +	}
>>  
>>  	/* Set the display info, using edid if available, otherwise
>>  	 * resetting the values to defaults. This duplicates the work diff 
>> --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 
>> 9fa84881fbba..5ae4e83fa5e3 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1992,6 +1992,7 @@ struct edid *drm_do_get_edid(struct 
>> drm_connector *connector,  {
>>  	int i, j = 0, valid_extensions = 0;
>>  	u8 *edid, *new;
>> +	size_t hf_eeodb_blk_count;
>>  	struct edid *override;
>>  
>>  	override = drm_get_override_edid(connector); @@ -2051,7 +2052,35 @@ 
>> struct edid *drm_do_get_edid(struct drm_connector *connector,
>>  		}
>>  
>>  		kfree(edid);
>> +		return (struct edid *)new;
>> +	}
>> +
>> +	hf_eeodb_blk_count = drm_edid_read_hf_eeodb_blk_count((struct edid *)edid);
>> +	if (hf_eeodb_blk_count >= 2) {
>> +		new = krealloc(edid, (hf_eeodb_blk_count + 1) * EDID_LENGTH, GFP_KERNEL);
>> +		if (!new)
>> +			goto out;
>>  		edid = new;
>> +
>> +		valid_extensions = hf_eeodb_blk_count - 1;
>> +		for (j = 2; j <= hf_eeodb_blk_count; j++) {
>> +			u8 *block = edid + j * EDID_LENGTH;
>> +
>> +			for (i = 0; i < 4; i++) {
>> +				if (get_edid_block(data, block, j, EDID_LENGTH))
>> +					goto out;
>> +				if (drm_edid_block_valid(block, j, false, NULL))
>> +					break;
>> +			}
>> +
>> +			if (i == 4)
>> +				valid_extensions--;
>> +		}
>> +
>> +		if (valid_extensions != hf_eeodb_blk_count - 1) {
>> +			DRM_ERROR("Not able to retrieve proper EDID contain HF-EEODB data.\n");
>> +			goto out;
>> +		}
>>  	}
>>  
>>  	return (struct edid *)edid;
>> @@ -3315,15 +3344,17 @@ 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_CAPABILITY_BLOCK	0x00
>> +#define HDR_STATIC_METADATA_BLOCK	0x06
>> +#define USE_EXTENDED_TAG		0x07
>>  #define EXT_VIDEO_DATA_BLOCK_420	0x0E
>> -#define EXT_VIDEO_CAP_BLOCK_Y420CMDB 0x0F
>> +#define EXT_VIDEO_CAP_BLOCK_Y420CMDB	0x0F
>> +#define EXT_VIDEO_HF_EEODB_DATA_BLOCK	0x78
>>  #define EDID_BASIC_AUDIO	(1 << 6)
>>  #define EDID_CEA_YCRCB444	(1 << 5)
>>  #define EDID_CEA_YCRCB422	(1 << 4)
>>  #define EDID_CEA_VCDB_QS	(1 << 6)
>> +#define HF_EEODB_LENGTH		2
>>  
>>  /*
>>   * Search EDID for CEA extension block.
>> @@ -4274,9 +4305,41 @@ static bool cea_db_is_y420vdb(const u8 *db)
>>  	return true;
>>  }
>>  
>> +static bool cea_db_is_hdmi_forum_eeodb(const u8 *db) {
>> +	if (cea_db_tag(db) != USE_EXTENDED_TAG)
>> +		return false;
>> +
>> +	if (cea_db_payload_len(db) != HF_EEODB_LENGTH)
>> +		return false;
>> +
>> +	if (cea_db_extended_tag(db) != EXT_VIDEO_HF_EEODB_DATA_BLOCK)
>> +		return false;
>> +
>> +	return true;
>> +}
>> +
>>  #define for_each_cea_db(cea, i, start, end) \
>>  	for ((i) = (start); (i) < (end) && (i) + 
>> cea_db_payload_len(&(cea)[(i)]) < (end); (i) += 
>> cea_db_payload_len(&(cea)[(i)]) + 1)
>>  
>> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid) {
>> +	const u8 *cea;
>> +	int i, start, end, cea_ext_index = 0, displayid_ext_index = 0;
>> +
>> +	if (edid->extensions) {
>> +		cea = drm_find_cea_extension(edid, &cea_ext_index, 
>> +&displayid_ext_index);
>> +
>> +		if (cea && !cea_db_offsets(cea, &start, &end))
>> +			for_each_cea_db(cea, i, start, end)
>> +				if (cea_db_is_hdmi_forum_eeodb(&cea[i]))
>> +					return cea[i + 2];
>> +	}
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(drm_edid_read_hf_eeodb_blk_count);
>
>This should be static and not exported.
>
>BR,
>Jani.
>
>> +
>>  static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector,
>>  				      const u8 *db)
>>  {
>> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 
>> 144c495b99c4..585f0ed932d4 100644
>> --- a/include/drm/drm_edid.h
>> +++ b/include/drm/drm_edid.h
>> @@ -593,5 +593,6 @@ drm_display_mode_from_cea_vic(struct drm_device 
>> *dev,  const u8 *drm_find_edid_extension(const struct edid *edid,
>>  				  int ext_id, int *ext_index);
>>  
>> +size_t drm_edid_read_hf_eeodb_blk_count(const struct edid *edid);
>>  
>>  #endif /* __DRM_EDID_H__ */
>
>--
>Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
  2022-03-15 12:32         ` [Intel-gfx] " Jani Nikula
@ 2022-03-15 15:21           ` Lee, Shawn C
  -1 siblings, 0 replies; 30+ messages in thread
From: Lee, Shawn C @ 2022-03-15 15:21 UTC (permalink / raw)
  To: Nikula, Jani, Drew Davenport; +Cc: Nautiyal, Ankit K, intel-gfx, dri-devel

On Tuesday, March 15, 2022 8:33 PM, Nikula, Jani <jani.nikula@intel.com> wrote:
>On Mon, 14 Mar 2022, Drew Davenport <ddavenport@chromium.org> wrote:
>> On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
>>> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
>>> > 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@linux.intel.com>
>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>>> > Cc: Drew Davenport <ddavenport@chromium.org>
>>> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
>>> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
>>> 
>>> Please don't do this. This just ruins the clean approach displayid 
>>> iterator added.
>>> 
>>> Instead of making the displayid iterator ugly, and leaking its 
>>> abstractions, I'll repeat what I said should be done in reply to the 
>>> very first version of this patch series [1]:
>>> 
>>> "I think we're going to need abstracted EDID iteration similar to 
>>> what I've done for DisplayID iteration. We can't have all places 
>>> reimplementing the iteration like we have now."
>>> 
>>> This isn't a problem that should be solved by having all the callers 
>>> hold a bunch of local variables and pass them around to all the 
>>> functions. Nobody's going to be able to keep track of this anymore. 
>>> And this series, as it is, makes it harder to fix this properly later on.
>>
>> I missed your original review comment, so apologies for repeating what 
>> you said there already.
>>
>> I'd agree that passing a starting index to the displayid_iter_* 
>> functions is probably not the right direction here. More thoughts below.
>>
>>> 
>>> 
>>> BR,
>>> Jani.
>>> 
>>> 
>>> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
>>> 
>>> 
>>> 
>>> >  {
>>> >  	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)
>>
>> As discussed above, passing both indices into this function may not be 
>> the best approach here. But I think we need to keep track of some kind 
>> of state in order to know which was the last CEA block that was 
>> returned, and thus this function can return the next one after that, 
>> whether it's in the CEA extension block or DisplayID block.
>
>Per DisplayID v1.3 Appendix B: DisplayID as an EDID Extension, it's recommended that DisplayID extensions are exposed after all of the CEA extensions.
>
>I think it should be fine to first iterate over all CEA extensions across the EDID, followed by iterating over all the DisplayID extensions. No need to keep track of the order between CEA and DisplayID, as the former should precede the latter.
>

Refer to "DisplayID extensions are exposed after all of the CEA extensions". It looks to me patch v5 is able to support this. And did not touch DisplayID iterator.
https://patchwork.freedesktop.org/series/100690/#rev5

>> What do you think of using the pointer returned from this function as 
>> that state? The caller could pass in a u8* that was returned from a 
>> previous call. This function would iterate through the extension 
>> blocks and skip the CEA blocks it finds until it finds the passed in 
>> pointer, and then return the next one after (or NULL).
>>
>> An alternative might be to create a linked list of ptrs to the edid 
>> extension blocks, and allow a caller to iterate over them in whatever 
>> way they need, but I'm not sure how useful that is elsewhere.
>
>I think the main problem here is trying to hack a for loop around
>drm_find_cea_extension() and drm_find_edid_extension(), and duplicating that all over the place, without adding more structure or abstractions.
>
>Contrast with displayid_iter_edid_begin(), displayid_iter_for_each(), and displayid_iter_end() and their usage. They hide all the complexity of looping across DisplayID data blocks inside EDID extensions, and none of the users need to be aware of that complexity. All the state is hidden in struct displayid_iter, and the users don't need to look inside. No allocations, no linked lists.
>
>I think it's particularly bad to have the changes here break the abstractions in displayid_iter_*, especially because they should be usable for pure DisplayID 2.0 *without* an EDID block structure. They'll just need a displayid_iter_begin() for pure DisplayID and some internal changes.
>
>Looking at the usage, the iteration should probably be done at the CEA data block level, something like this:
>
>	struct cea_iter iter;
>        const struct cea_block *block;
>
>	cea_iter_edid_begin(edid, &iter);
>        cea_iter_for_each(block, &iter) {
>		/* ... */        
>        }
>        cea_iter_end(&iter);
>
>This would replace cea_db_offsets() and for_each_cea_db(), and would iterate across the all CEA and DisplayID extensions in the entire EDID.
>
>This looks usable, and then you'd start figuring out how to implement that, instead of trying to retrofit all the existing usages to abstractions that don't cut it. You'll probably need an EDID extension iterator too, and then use that and __displayid_iter_next() within
>cea_iter_for_each() i.e. you'd embed the edid_iter and displayid_iter within struct cea_iter. Exhaust the former first, and then the latter.
>
>
>BR,
>Jani.
>

Hi Jani, Drew, thank you all for your comment! Agree that edid driver may need
abstracted EDID iteration similar to what you did for DisplayID iteration.
It will need a lot of code changes in drm driver.

But, we have a tight schedule and have to meet HDMI 2.1 compliance test requirement.
Do you think this series can be a short term solution to pass HDMI CTS test?
And we can have another long term plan to work on your opinion to modify
the iterator and make edid driver more efficient and easier to maintain.

Best regards,
Shawn

>
>>
>>> >  {
>>> >  	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
>>> 
>>> --
>>> Jani Nikula, Intel Open Source Graphics Center
>
>--
>Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
@ 2022-03-15 15:21           ` Lee, Shawn C
  0 siblings, 0 replies; 30+ messages in thread
From: Lee, Shawn C @ 2022-03-15 15:21 UTC (permalink / raw)
  To: Nikula, Jani, Drew Davenport; +Cc: intel-gfx, dri-devel

On Tuesday, March 15, 2022 8:33 PM, Nikula, Jani <jani.nikula@intel.com> wrote:
>On Mon, 14 Mar 2022, Drew Davenport <ddavenport@chromium.org> wrote:
>> On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
>>> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
>>> > 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@linux.intel.com>
>>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
>>> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
>>> > Cc: Drew Davenport <ddavenport@chromium.org>
>>> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
>>> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
>>> 
>>> Please don't do this. This just ruins the clean approach displayid 
>>> iterator added.
>>> 
>>> Instead of making the displayid iterator ugly, and leaking its 
>>> abstractions, I'll repeat what I said should be done in reply to the 
>>> very first version of this patch series [1]:
>>> 
>>> "I think we're going to need abstracted EDID iteration similar to 
>>> what I've done for DisplayID iteration. We can't have all places 
>>> reimplementing the iteration like we have now."
>>> 
>>> This isn't a problem that should be solved by having all the callers 
>>> hold a bunch of local variables and pass them around to all the 
>>> functions. Nobody's going to be able to keep track of this anymore. 
>>> And this series, as it is, makes it harder to fix this properly later on.
>>
>> I missed your original review comment, so apologies for repeating what 
>> you said there already.
>>
>> I'd agree that passing a starting index to the displayid_iter_* 
>> functions is probably not the right direction here. More thoughts below.
>>
>>> 
>>> 
>>> BR,
>>> Jani.
>>> 
>>> 
>>> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
>>> 
>>> 
>>> 
>>> >  {
>>> >  	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)
>>
>> As discussed above, passing both indices into this function may not be 
>> the best approach here. But I think we need to keep track of some kind 
>> of state in order to know which was the last CEA block that was 
>> returned, and thus this function can return the next one after that, 
>> whether it's in the CEA extension block or DisplayID block.
>
>Per DisplayID v1.3 Appendix B: DisplayID as an EDID Extension, it's recommended that DisplayID extensions are exposed after all of the CEA extensions.
>
>I think it should be fine to first iterate over all CEA extensions across the EDID, followed by iterating over all the DisplayID extensions. No need to keep track of the order between CEA and DisplayID, as the former should precede the latter.
>

Refer to "DisplayID extensions are exposed after all of the CEA extensions". It looks to me patch v5 is able to support this. And did not touch DisplayID iterator.
https://patchwork.freedesktop.org/series/100690/#rev5

>> What do you think of using the pointer returned from this function as 
>> that state? The caller could pass in a u8* that was returned from a 
>> previous call. This function would iterate through the extension 
>> blocks and skip the CEA blocks it finds until it finds the passed in 
>> pointer, and then return the next one after (or NULL).
>>
>> An alternative might be to create a linked list of ptrs to the edid 
>> extension blocks, and allow a caller to iterate over them in whatever 
>> way they need, but I'm not sure how useful that is elsewhere.
>
>I think the main problem here is trying to hack a for loop around
>drm_find_cea_extension() and drm_find_edid_extension(), and duplicating that all over the place, without adding more structure or abstractions.
>
>Contrast with displayid_iter_edid_begin(), displayid_iter_for_each(), and displayid_iter_end() and their usage. They hide all the complexity of looping across DisplayID data blocks inside EDID extensions, and none of the users need to be aware of that complexity. All the state is hidden in struct displayid_iter, and the users don't need to look inside. No allocations, no linked lists.
>
>I think it's particularly bad to have the changes here break the abstractions in displayid_iter_*, especially because they should be usable for pure DisplayID 2.0 *without* an EDID block structure. They'll just need a displayid_iter_begin() for pure DisplayID and some internal changes.
>
>Looking at the usage, the iteration should probably be done at the CEA data block level, something like this:
>
>	struct cea_iter iter;
>        const struct cea_block *block;
>
>	cea_iter_edid_begin(edid, &iter);
>        cea_iter_for_each(block, &iter) {
>		/* ... */        
>        }
>        cea_iter_end(&iter);
>
>This would replace cea_db_offsets() and for_each_cea_db(), and would iterate across the all CEA and DisplayID extensions in the entire EDID.
>
>This looks usable, and then you'd start figuring out how to implement that, instead of trying to retrofit all the existing usages to abstractions that don't cut it. You'll probably need an EDID extension iterator too, and then use that and __displayid_iter_next() within
>cea_iter_for_each() i.e. you'd embed the edid_iter and displayid_iter within struct cea_iter. Exhaust the former first, and then the latter.
>
>
>BR,
>Jani.
>

Hi Jani, Drew, thank you all for your comment! Agree that edid driver may need
abstracted EDID iteration similar to what you did for DisplayID iteration.
It will need a lot of code changes in drm driver.

But, we have a tight schedule and have to meet HDMI 2.1 compliance test requirement.
Do you think this series can be a short term solution to pass HDMI CTS test?
And we can have another long term plan to work on your opinion to modify
the iterator and make edid driver more efficient and easier to maintain.

Best regards,
Shawn

>
>>
>>> >  {
>>> >  	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
>>> 
>>> --
>>> Jani Nikula, Intel Open Source Graphics Center
>
>--
>Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
  2022-03-15 15:21           ` [Intel-gfx] " Lee, Shawn C
@ 2022-03-15 17:22             ` Drew Davenport
  -1 siblings, 0 replies; 30+ messages in thread
From: Drew Davenport @ 2022-03-15 17:22 UTC (permalink / raw)
  To: Lee, Shawn C; +Cc: Nikula, Jani, Nautiyal, Ankit K, intel-gfx, dri-devel

On Tue, Mar 15, 2022 at 03:21:05PM +0000, Lee, Shawn C wrote:
> On Tuesday, March 15, 2022 8:33 PM, Nikula, Jani <jani.nikula@intel.com> wrote:
> >On Mon, 14 Mar 2022, Drew Davenport <ddavenport@chromium.org> wrote:
> >> On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
> >>> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> >>> > 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@linux.intel.com>
> >>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> >>> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> >>> > Cc: Drew Davenport <ddavenport@chromium.org>
> >>> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> >>> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
> >>> 
> >>> Please don't do this. This just ruins the clean approach displayid 
> >>> iterator added.
> >>> 
> >>> Instead of making the displayid iterator ugly, and leaking its 
> >>> abstractions, I'll repeat what I said should be done in reply to the 
> >>> very first version of this patch series [1]:
> >>> 
> >>> "I think we're going to need abstracted EDID iteration similar to 
> >>> what I've done for DisplayID iteration. We can't have all places 
> >>> reimplementing the iteration like we have now."
> >>> 
> >>> This isn't a problem that should be solved by having all the callers 
> >>> hold a bunch of local variables and pass them around to all the 
> >>> functions. Nobody's going to be able to keep track of this anymore. 
> >>> And this series, as it is, makes it harder to fix this properly later on.
> >>
> >> I missed your original review comment, so apologies for repeating what 
> >> you said there already.
> >>
> >> I'd agree that passing a starting index to the displayid_iter_* 
> >> functions is probably not the right direction here. More thoughts below.
> >>
> >>> 
> >>> 
> >>> BR,
> >>> Jani.
> >>> 
> >>> 
> >>> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
> >>> 
> >>> 
> >>> 
> >>> >  {
> >>> >  	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)
> >>
> >> As discussed above, passing both indices into this function may not be 
> >> the best approach here. But I think we need to keep track of some kind 
> >> of state in order to know which was the last CEA block that was 
> >> returned, and thus this function can return the next one after that, 
> >> whether it's in the CEA extension block or DisplayID block.
> >
> >Per DisplayID v1.3 Appendix B: DisplayID as an EDID Extension, it's recommended that DisplayID extensions are exposed after all of the CEA extensions.
> >
> >I think it should be fine to first iterate over all CEA extensions across the EDID, followed by iterating over all the DisplayID extensions. No need to keep track of the order between CEA and DisplayID, as the former should precede the latter.
> >
> 
> Refer to "DisplayID extensions are exposed after all of the CEA extensions". It looks to me patch v5 is able to support this. And did not touch DisplayID iterator.
> https://patchwork.freedesktop.org/series/100690/#rev5

Patch v5 does not iterate over all the DisplayID extensions, and it has
the previously mentioned problem about resulting in a possible infinite
loop when depending on ext_index to iterate over the CEA extensions.

> 
> >> What do you think of using the pointer returned from this function as 
> >> that state? The caller could pass in a u8* that was returned from a 
> >> previous call. This function would iterate through the extension 
> >> blocks and skip the CEA blocks it finds until it finds the passed in 
> >> pointer, and then return the next one after (or NULL).
> >>
> >> An alternative might be to create a linked list of ptrs to the edid 
> >> extension blocks, and allow a caller to iterate over them in whatever 
> >> way they need, but I'm not sure how useful that is elsewhere.
> >
> >I think the main problem here is trying to hack a for loop around
> >drm_find_cea_extension() and drm_find_edid_extension(), and duplicating that all over the place, without adding more structure or abstractions.
> >
> >Contrast with displayid_iter_edid_begin(), displayid_iter_for_each(), and displayid_iter_end() and their usage. They hide all the complexity of looping across DisplayID data blocks inside EDID extensions, and none of the users need to be aware of that complexity. All the state is hidden in struct displayid_iter, and the users don't need to look inside. No allocations, no linked lists.
> >
> >I think it's particularly bad to have the changes here break the abstractions in displayid_iter_*, especially because they should be usable for pure DisplayID 2.0 *without* an EDID block structure. They'll just need a displayid_iter_begin() for pure DisplayID and some internal changes.
> >
> >Looking at the usage, the iteration should probably be done at the CEA data block level, something like this:
> >
> >	struct cea_iter iter;
> >        const struct cea_block *block;
> >
> >	cea_iter_edid_begin(edid, &iter);
> >        cea_iter_for_each(block, &iter) {
> >		/* ... */        
> >        }
> >        cea_iter_end(&iter);
> >
> >This would replace cea_db_offsets() and for_each_cea_db(), and would iterate across the all CEA and DisplayID extensions in the entire EDID.
> >
> >This looks usable, and then you'd start figuring out how to implement that, instead of trying to retrofit all the existing usages to abstractions that don't cut it. You'll probably need an EDID extension iterator too, and then use that and __displayid_iter_next() within
> >cea_iter_for_each() i.e. you'd embed the edid_iter and displayid_iter within struct cea_iter. Exhaust the former first, and then the latter.
> >
> >
> >BR,
> >Jani.
> >
> 
> Hi Jani, Drew, thank you all for your comment! Agree that edid driver may need
> abstracted EDID iteration similar to what you did for DisplayID iteration.
> It will need a lot of code changes in drm driver.
> 
> But, we have a tight schedule and have to meet HDMI 2.1 compliance test requirement.
> Do you think this series can be a short term solution to pass HDMI CTS test?
> And we can have another long term plan to work on your opinion to modify
> the iterator and make edid driver more efficient and easier to maintain.
> 
> Best regards,
> Shawn
> 
> >
> >>
> >>> >  {
> >>> >  	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
> >>> 
> >>> --
> >>> Jani Nikula, Intel Open Source Graphics Center
> >
> >--
> >Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Intel-gfx] [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index
@ 2022-03-15 17:22             ` Drew Davenport
  0 siblings, 0 replies; 30+ messages in thread
From: Drew Davenport @ 2022-03-15 17:22 UTC (permalink / raw)
  To: Lee, Shawn C; +Cc: Nikula, Jani, intel-gfx, dri-devel

On Tue, Mar 15, 2022 at 03:21:05PM +0000, Lee, Shawn C wrote:
> On Tuesday, March 15, 2022 8:33 PM, Nikula, Jani <jani.nikula@intel.com> wrote:
> >On Mon, 14 Mar 2022, Drew Davenport <ddavenport@chromium.org> wrote:
> >> On Mon, Mar 14, 2022 at 10:40:47AM +0200, Jani Nikula wrote:
> >>> On Sun, 13 Mar 2022, Lee Shawn C <shawn.c.lee@intel.com> wrote:
> >>> > 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@linux.intel.com>
> >>> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
> >>> > Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> >>> > Cc: Drew Davenport <ddavenport@chromium.org>
> >>> > Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
> >>> > Signed-off-by: Lee Shawn C <shawn.c.lee@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)
> >>> 
> >>> Please don't do this. This just ruins the clean approach displayid 
> >>> iterator added.
> >>> 
> >>> Instead of making the displayid iterator ugly, and leaking its 
> >>> abstractions, I'll repeat what I said should be done in reply to the 
> >>> very first version of this patch series [1]:
> >>> 
> >>> "I think we're going to need abstracted EDID iteration similar to 
> >>> what I've done for DisplayID iteration. We can't have all places 
> >>> reimplementing the iteration like we have now."
> >>> 
> >>> This isn't a problem that should be solved by having all the callers 
> >>> hold a bunch of local variables and pass them around to all the 
> >>> functions. Nobody's going to be able to keep track of this anymore. 
> >>> And this series, as it is, makes it harder to fix this properly later on.
> >>
> >> I missed your original review comment, so apologies for repeating what 
> >> you said there already.
> >>
> >> I'd agree that passing a starting index to the displayid_iter_* 
> >> functions is probably not the right direction here. More thoughts below.
> >>
> >>> 
> >>> 
> >>> BR,
> >>> Jani.
> >>> 
> >>> 
> >>> [1] https://lore.kernel.org/r/87czjf8dik.fsf@intel.com
> >>> 
> >>> 
> >>> 
> >>> >  {
> >>> >  	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)
> >>
> >> As discussed above, passing both indices into this function may not be 
> >> the best approach here. But I think we need to keep track of some kind 
> >> of state in order to know which was the last CEA block that was 
> >> returned, and thus this function can return the next one after that, 
> >> whether it's in the CEA extension block or DisplayID block.
> >
> >Per DisplayID v1.3 Appendix B: DisplayID as an EDID Extension, it's recommended that DisplayID extensions are exposed after all of the CEA extensions.
> >
> >I think it should be fine to first iterate over all CEA extensions across the EDID, followed by iterating over all the DisplayID extensions. No need to keep track of the order between CEA and DisplayID, as the former should precede the latter.
> >
> 
> Refer to "DisplayID extensions are exposed after all of the CEA extensions". It looks to me patch v5 is able to support this. And did not touch DisplayID iterator.
> https://patchwork.freedesktop.org/series/100690/#rev5

Patch v5 does not iterate over all the DisplayID extensions, and it has
the previously mentioned problem about resulting in a possible infinite
loop when depending on ext_index to iterate over the CEA extensions.

> 
> >> What do you think of using the pointer returned from this function as 
> >> that state? The caller could pass in a u8* that was returned from a 
> >> previous call. This function would iterate through the extension 
> >> blocks and skip the CEA blocks it finds until it finds the passed in 
> >> pointer, and then return the next one after (or NULL).
> >>
> >> An alternative might be to create a linked list of ptrs to the edid 
> >> extension blocks, and allow a caller to iterate over them in whatever 
> >> way they need, but I'm not sure how useful that is elsewhere.
> >
> >I think the main problem here is trying to hack a for loop around
> >drm_find_cea_extension() and drm_find_edid_extension(), and duplicating that all over the place, without adding more structure or abstractions.
> >
> >Contrast with displayid_iter_edid_begin(), displayid_iter_for_each(), and displayid_iter_end() and their usage. They hide all the complexity of looping across DisplayID data blocks inside EDID extensions, and none of the users need to be aware of that complexity. All the state is hidden in struct displayid_iter, and the users don't need to look inside. No allocations, no linked lists.
> >
> >I think it's particularly bad to have the changes here break the abstractions in displayid_iter_*, especially because they should be usable for pure DisplayID 2.0 *without* an EDID block structure. They'll just need a displayid_iter_begin() for pure DisplayID and some internal changes.
> >
> >Looking at the usage, the iteration should probably be done at the CEA data block level, something like this:
> >
> >	struct cea_iter iter;
> >        const struct cea_block *block;
> >
> >	cea_iter_edid_begin(edid, &iter);
> >        cea_iter_for_each(block, &iter) {
> >		/* ... */        
> >        }
> >        cea_iter_end(&iter);
> >
> >This would replace cea_db_offsets() and for_each_cea_db(), and would iterate across the all CEA and DisplayID extensions in the entire EDID.
> >
> >This looks usable, and then you'd start figuring out how to implement that, instead of trying to retrofit all the existing usages to abstractions that don't cut it. You'll probably need an EDID extension iterator too, and then use that and __displayid_iter_next() within
> >cea_iter_for_each() i.e. you'd embed the edid_iter and displayid_iter within struct cea_iter. Exhaust the former first, and then the latter.
> >
> >
> >BR,
> >Jani.
> >
> 
> Hi Jani, Drew, thank you all for your comment! Agree that edid driver may need
> abstracted EDID iteration similar to what you did for DisplayID iteration.
> It will need a lot of code changes in drm driver.
> 
> But, we have a tight schedule and have to meet HDMI 2.1 compliance test requirement.
> Do you think this series can be a short term solution to pass HDMI CTS test?
> And we can have another long term plan to work on your opinion to modify
> the iterator and make edid driver more efficient and easier to maintain.
> 
> Best regards,
> Shawn
> 
> >
> >>
> >>> >  {
> >>> >  	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
> >>> 
> >>> --
> >>> Jani Nikula, Intel Open Source Graphics Center
> >
> >--
> >Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2022-03-15 17:22 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-13 13:46 [v7 0/5] enhanced edid driver compatibility Lee Shawn C
2022-03-13 13:46 ` [Intel-gfx] " Lee Shawn C
2022-03-13 13:45 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for enhanced edid driver compatibility (rev3) Patchwork
2022-03-13 13:46 ` [v7 1/5] drm/edid: seek for available CEA and DisplayID block from specific EDID block index Lee Shawn C
2022-03-13 13:46   ` [Intel-gfx] " Lee Shawn C
2022-03-14  8:40   ` Jani Nikula
2022-03-14  8:40     ` [Intel-gfx] " Jani Nikula
2022-03-14 21:02     ` Drew Davenport
2022-03-14 21:02       ` [Intel-gfx] " Drew Davenport
2022-03-15 12:32       ` Jani Nikula
2022-03-15 12:32         ` [Intel-gfx] " Jani Nikula
2022-03-15 15:21         ` Lee, Shawn C
2022-03-15 15:21           ` [Intel-gfx] " Lee, Shawn C
2022-03-15 17:22           ` Drew Davenport
2022-03-15 17:22             ` [Intel-gfx] " Drew Davenport
2022-03-13 13:46 ` [v7 2/5] drm/edid: parse multiple CEA extension block Lee Shawn C
2022-03-13 13:46   ` [Intel-gfx] " Lee Shawn C
2022-03-13 13:47 ` [v7 3/5] drm/edid: read HF-EEODB ext block Lee Shawn C
2022-03-13 13:47   ` [Intel-gfx] " Lee Shawn C
2022-03-15 11:03   ` Jani Nikula
2022-03-15 11:03     ` [Intel-gfx] " Jani Nikula
2022-03-15 13:43     ` Lee, Shawn C
2022-03-15 13:43       ` [Intel-gfx] " Lee, Shawn C
2022-03-13 13:47 ` [v7 4/5] drm/edid: parse HF-EEODB CEA extension block Lee Shawn C
2022-03-13 13:47   ` [Intel-gfx] " Lee Shawn C
2022-03-13 13:47 ` [v7 5/5] drm/edid: check for HF-SCDB block Lee Shawn C
2022-03-13 13:47   ` [Intel-gfx] " Lee Shawn C
2022-03-13 13:47 ` [Intel-gfx] ✗ Fi.CI.SPARSE: warning for enhanced edid driver compatibility (rev3) Patchwork
2022-03-13 14:18 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-03-13 15:24 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.