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. Signed-off-by: Lee Shawn C <shawn.c.lee@xxxxxxxxx> --- drivers/gpu/drm/drm_displayid.c | 5 ++++- drivers/gpu/drm/drm_edid.c | 34 ++++++++++++++++++--------------- include/drm/drm_edid.h | 2 +- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c index 32da557b960f..dc649a9efaa2 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 f8514783d089..bb050d171bb8 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 ext_id, int *ext_index, int num_ext_blk) { 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; @@ -3388,14 +3388,15 @@ const u8 *drm_find_edid_extension(const struct edid *edid, return edid_ext; } -static const u8 *drm_find_cea_extension(const struct edid *edid, int *ext_index) +static const u8 *drm_find_cea_extension(const struct edid *edid, + int *ext_index, int num_ext_blk) { 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, ext_index); + cea = drm_find_edid_extension(edid, CEA_EXT, ext_index, num_ext_blk); if (cea) return cea; @@ -3679,7 +3680,7 @@ add_alternate_cea_modes(struct drm_connector *connector, struct edid *edid) int modes = 0, ext_index = 0; /* Don't add CEA modes if the CEA extension block is missing */ - if (!drm_find_cea_extension(edid, &ext_index)) + if (!drm_find_cea_extension(edid, &ext_index, edid->extensions)) return 0; /* @@ -4376,11 +4377,14 @@ add_cea_modes(struct drm_connector *connector, struct edid *edid) { const u8 *cea = NULL; 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 = 0; + if (num_ext_blk && drm_edid_is_hf_eeodb_blk_available(edid)) + num_ext_blk = drm_edid_read_hf_eeodb_blk_size(edid); + for (;;) { - cea = drm_find_cea_extension(edid, &j); + cea = drm_find_cea_extension(edid, &j, num_ext_blk); if (!cea) break; @@ -4636,7 +4640,7 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) if (!edid) return; - cea = drm_find_cea_extension(edid, &ext_index); + cea = drm_find_cea_extension(edid, &ext_index, edid->extensions); if (!cea) { DRM_DEBUG_KMS("ELD: no CEA Extension found\n"); return; @@ -4724,7 +4728,7 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) int i, start, end, dbl; const u8 *cea; - cea = drm_find_cea_extension(edid, &ext_index); + cea = drm_find_cea_extension(edid, &ext_index, edid->extensions); if (!cea) { DRM_DEBUG_KMS("SAD: no CEA Extension found\n"); return 0; @@ -4786,7 +4790,7 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) int i, start, end, dbl; const u8 *cea; - cea = drm_find_cea_extension(edid, &ext_index); + cea = drm_find_cea_extension(edid, &ext_index, edid->extensions); if (!cea) { DRM_DEBUG_KMS("SAD: no CEA Extension found\n"); return 0; @@ -4881,7 +4885,7 @@ bool drm_detect_hdmi_monitor(struct edid *edid) int i, ext_index = 0; int start_offset, end_offset; - edid_ext = drm_find_cea_extension(edid, &ext_index); + edid_ext = drm_find_cea_extension(edid, &ext_index, edid->extensions); if (!edid_ext) return false; @@ -4920,7 +4924,7 @@ bool drm_detect_monitor_audio(struct edid *edid) bool has_audio = false; int start_offset, end_offset; - edid_ext = drm_find_cea_extension(edid, &ext_index); + edid_ext = drm_find_cea_extension(edid, &ext_index, edid->extensions); if (!edid_ext) goto end; @@ -5232,7 +5236,7 @@ static void drm_parse_cea_ext(struct drm_connector *connector, const u8 *edid_ext; int i, start, end, ext_index = 0; - edid_ext = drm_find_cea_extension(edid, &ext_index); + edid_ext = drm_find_cea_extension(edid, &ext_index, edid->extensions); if (!edid_ext) return; diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index ba2812432ead..4dbfbb531dfd 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 num_ext_blk); 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.31.1