Try to find and parse more CEA ext blocks if edid->extensions is greater than one. 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_edid.c | 75 +++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 12893e7be89b..3d5dbbeca7f9 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -4313,43 +4313,58 @@ 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; - int modes = 0; + int modes = 0, j; - if (cea && cea_revision(cea) >= 3) { - int i, start, end; + if (!cea) + return 0; - if (cea_db_offsets(cea, &start, &end)) - return 0; + for (j = (cea - (u8 *)edid) / EDID_LENGTH; j <= edid->extensions;) { + if (cea && cea_revision(cea) >= 3) { + int i, start, end; - for_each_cea_db(cea, i, start, end) { - db = &cea[i]; - dbl = cea_db_payload_len(db); + if (cea_db_offsets(cea, &start, &end)) + continue; - if (cea_db_tag(db) == VIDEO_BLOCK) { - video = db + 1; - video_len = dbl; - modes += do_cea_modes(connector, video, dbl); - } else if (cea_db_is_hdmi_vsdb(db)) { - hdmi = db; - hdmi_len = dbl; - } else if (cea_db_is_y420vdb(db)) { - const u8 *vdb420 = &db[2]; - - /* Add 4:2:0(only) modes present in EDID */ - modes += do_y420vdb_modes(connector, - vdb420, - dbl - 1); + for_each_cea_db(cea, i, start, end) { + db = &cea[i]; + dbl = cea_db_payload_len(db); + + if (cea_db_tag(db) == VIDEO_BLOCK) { + video = db + 1; + video_len = dbl; + modes += do_cea_modes(connector, video, dbl); + } else if (cea_db_is_hdmi_vsdb(db)) { + hdmi = db; + hdmi_len = dbl; + } else if (cea_db_is_y420vdb(db)) { + const u8 *vdb420 = &db[2]; + + /* Add 4:2:0(only) modes present in EDID */ + modes += do_y420vdb_modes(connector, + vdb420, + 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); + hdmi = NULL; + video = NULL; + hdmi_len = 0; + video_len = 0; + } + + /* move to next CEA extension block */ + cea = drm_find_edid_extension(edid, CEA_EXT, &j); + if (!cea) + break; + } return modes; } -- 2.17.1