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@xxxxxxxxxxxxxxx> Cc: Ville Syrjala <ville.syrjala@xxxxxxxxxxxxxxx> Cc: Ankit Nautiyal <ankit.k.nautiyal@xxxxxxxxx> Signed-off-by: Lee Shawn C <shawn.c.lee@xxxxxxxxx> --- 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