From 507feeef1ff37762201a82157c39c7e4939b732a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
Date: Wed, 27 May 2020 16:03:08 +0300
Subject: drm/edid: Allow looking for ext blocks starting from a specified
index
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: 8873cfa384055d0348c03161420b1e9b6c1dc5d0
Patch-mainline: v5.9-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322
Apparently EDIDs with multiple DispID ext blocks is a thing, so prepare
for iterating through multiple ext blocks of the same type by
passing the starting ext block index to drm_find_edid_extension(). Well
also have drm_find_edid_extension() update the index to point to the
next ext block on success. Thus we should be able to call
drm_find_edid_extension() in loop.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200527130310.27099-1-ville.syrjala@linux.intel.com
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
drivers/gpu/drm/drm_edid.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 31496b6cfc56..a0800c7b16ab 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3236,7 +3236,8 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
/*
* Search EDID for CEA extension block.
*/
-static u8 *drm_find_edid_extension(const struct edid *edid, int ext_id)
+static u8 *drm_find_edid_extension(const struct edid *edid,
+ int ext_id, int *ext_index)
{
u8 *edid_ext = NULL;
int i;
@@ -3246,23 +3247,26 @@ static u8 *drm_find_edid_extension(const struct edid *edid, int ext_id)
return NULL;
/* Find CEA extension */
- for (i = 0; i < edid->extensions; i++) {
+ for (i = *ext_index; i < edid->extensions; i++) {
edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == ext_id)
break;
}
- if (i == edid->extensions)
+ if (i >= edid->extensions)
return NULL;
+ *ext_index = i + 1;
+
return edid_ext;
}
static u8 *drm_find_displayid_extension(const struct edid *edid,
- int *length, int *idx)
+ int *length, int *idx,
+ int *ext_index)
{
- u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT);
+ u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, ext_index);
struct displayid_hdr *base;
int ret;
@@ -3289,14 +3293,18 @@ static u8 *drm_find_cea_extension(const struct edid *edid)
struct displayid_block *block;
u8 *cea;
u8 *displayid;
+ int ext_index;
/* Look for a top level CEA extension block */
- cea = drm_find_edid_extension(edid, CEA_EXT);
+ ext_index = 0;
+ cea = drm_find_edid_extension(edid, CEA_EXT, &ext_index);
if (cea)
return cea;
/* CEA blocks can also be found embedded in a DisplayID block */
- displayid = drm_find_displayid_extension(edid, &length, &idx);
+ ext_index = 0;
+ displayid = drm_find_displayid_extension(edid, &length, &idx,
+ &ext_index);
if (!displayid)
return NULL;
@@ -5246,8 +5254,10 @@ static int add_displayid_detailed_modes(struct drm_connector *connector,
int length, idx;
struct displayid_block *block;
int num_modes = 0;
+ int ext_index = 0;
- displayid = drm_find_displayid_extension(edid, &length, &idx);
+ displayid = drm_find_displayid_extension(edid, &length, &idx,
+ &ext_index);
if (!displayid)
return 0;
@@ -5922,11 +5932,13 @@ void drm_update_tile_info(struct drm_connector *connector,
const struct edid *edid)
{
const void *displayid = NULL;
+ int ext_index = 0;
int length, idx;
int ret;
connector->has_tile = false;
- displayid = drm_find_displayid_extension(edid, &length, &idx);
+ displayid = drm_find_displayid_extension(edid, &length, &idx,
+ &ext_index);
if (!displayid) {
/* drop reference to any tile group we had */
goto out_drop_ref;
--
2.29.2