[PATCH 3/3] drm/edid: parse HF-EEODB CEA extension block

Lee Shawn C shawn.c.lee at intel.com
Tue Feb 22 06:38:19 UTC 2022


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 at linux.intel.com>
Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
Signed-off-by: Lee Shawn C <shawn.c.lee at intel.com>
---
 drivers/gpu/drm/drm_displayid.c |  2 +-
 drivers/gpu/drm/drm_edid.c      | 19 +++++++++++--------
 include/drm/drm_edid.h          |  2 +-
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..ef0dfc9fa6f9 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -37,7 +37,7 @@ 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, edid->extensions, DISPLAYID_EXT, ext_index);
 	const struct displayid_header *base;
 	int ret;
 
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a7391e427d69..9a987c77f203 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3364,23 +3364,23 @@ 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 num_ext_blk, int ext_id, int *ext_index)
 {
 	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 >= num_ext_blk)
 		return NULL;
 
 	/* Find CEA extension */
-	for (i = *ext_index; i < edid->extensions; i++) {
+	for (i = *ext_index; i < num_ext_blk; i++) {
 		edid_ext = (const u8 *)edid + EDID_LENGTH * (i + 1);
 		if (edid_ext[0] == ext_id)
 			break;
 	}
 
-	if (i >= edid->extensions)
+	if (i >= num_ext_blk)
 		return NULL;
 
 	*ext_index = i + 1;
@@ -3397,7 +3397,7 @@ static const u8 *drm_find_cea_extension(const struct edid *edid)
 
 	/* 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);
+	cea = drm_find_edid_extension(edid, edid->extensions, CEA_EXT, &ext_index);
 	if (cea)
 		return cea;
 
@@ -4378,13 +4378,16 @@ 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;
-	u8 dbl, hdmi_len, video_len = 0;
+	u8 dbl, hdmi_len, video_len = 0, num_ext_blk = edid->extensions;
 	int modes = 0, j;
 
 	if (!cea)
 		return 0;
 
-	for (j = (cea - (u8 *)edid) / EDID_LENGTH; j <= edid->extensions;) {
+	if (num_ext_blk && drm_edid_is_hf_eeodb_blk_available(edid))
+		num_ext_blk = drm_edid_read_hf_eeodb_blk_size(edid);
+
+	for (j = (cea - (u8 *)edid) / EDID_LENGTH; j <= num_ext_blk;) {
 		if (cea && cea_revision(cea) >= 3) {
 			int i, start, end;
 
@@ -4427,7 +4430,7 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid)
 		}
 
 		/* move to next CEA extension block */
-		cea = drm_find_edid_extension(edid, CEA_EXT, &j);
+		cea = drm_find_edid_extension(edid, num_ext_blk, CEA_EXT, &j);
 		if (!cea)
 			break;
 	}
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index ba2812432ead..a9c2708b63a1 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 num_ext_blk, int ext_id, int *ext_index);
 
 bool drm_edid_is_hf_eeodb_blk_available(const struct edid *edid);
 u8 drm_edid_read_hf_eeodb_blk_size(const struct edid *edid);
-- 
2.17.1



More information about the dri-devel mailing list