drm_find_cea_extension() always look for a top level CEA block. Pass
ext_index from caller then this function to search next available
CEA ext block from a specific EDID block pointer.

v2: save proper extension block index if CTA data information
    was found in DispalyID block.
v3: using different parameters to store CEA and DisplayID block index.
    configure DisplayID extansion block index before search available
    DisplayID block.

Cc: Jani Nikula <jani.nik...@linux.intel.com>
Cc: Ville Syrjala <ville.syrj...@linux.intel.com>
Cc: Ankit Nautiyal <ankit.k.nauti...@intel.com>
Cc: Drew Davenport <ddavenp...@chromium.org>
Cc: intel-gfx <intel-gfx@lists.freedesktop.org>
Signed-off-by: Lee Shawn C <shawn.c....@intel.com>
---
 drivers/gpu/drm/drm_displayid.c | 10 +++++--
 drivers/gpu/drm/drm_edid.c      | 53 ++++++++++++++++++---------------
 include/drm/drm_displayid.h     |  4 +--
 3 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 32da557b960f..31c3e6d7d549 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -59,11 +59,14 @@ static const u8 *drm_find_displayid_extension(const struct 
edid *edid,
 }
 
 void displayid_iter_edid_begin(const struct edid *edid,
-                              struct displayid_iter *iter)
+                              struct displayid_iter *iter, int *ext_index)
 {
        memset(iter, 0, sizeof(*iter));
 
        iter->edid = edid;
+
+       if (ext_index)
+               iter->ext_index = *ext_index;
 }
 
 static const struct displayid_block *
@@ -126,7 +129,10 @@ __displayid_iter_next(struct displayid_iter *iter)
        }
 }
 
-void displayid_iter_end(struct displayid_iter *iter)
+void displayid_iter_end(struct displayid_iter *iter, int *ext_index)
 {
+       if (ext_index)
+               *ext_index = iter->ext_index;
+
        memset(iter, 0, sizeof(*iter));
 }
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 561f53831e29..78c415aa6889 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -3353,28 +3353,27 @@ const u8 *drm_find_edid_extension(const struct edid 
*edid,
        return edid_ext;
 }
 
-static const u8 *drm_find_cea_extension(const struct edid *edid)
+static const u8 *drm_find_cea_extension(const struct edid *edid,
+                                       int *cea_ext_index, int 
*displayid_ext_index)
 {
        const struct displayid_block *block;
        struct displayid_iter iter;
        const u8 *cea;
-       int ext_index = 0;
 
-       /* 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);
+       /* Look for a CEA extension block from ext_index */
+       cea = drm_find_edid_extension(edid, CEA_EXT, cea_ext_index);
        if (cea)
                return cea;
 
        /* CEA blocks can also be found embedded in a DisplayID block */
-       displayid_iter_edid_begin(edid, &iter);
+       displayid_iter_edid_begin(edid, &iter, displayid_ext_index);
        displayid_iter_for_each(block, &iter) {
                if (block->tag == DATA_BLOCK_CTA) {
                        cea = (const u8 *)block;
                        break;
                }
        }
-       displayid_iter_end(&iter);
+       displayid_iter_end(&iter, displayid_ext_index);
 
        return cea;
 }
@@ -3643,10 +3642,10 @@ add_alternate_cea_modes(struct drm_connector 
*connector, struct edid *edid)
        struct drm_device *dev = connector->dev;
        struct drm_display_mode *mode, *tmp;
        LIST_HEAD(list);
-       int modes = 0;
+       int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
        /* Don't add CEA modes if the CEA extension block is missing */
-       if (!drm_find_cea_extension(edid))
+       if (!drm_find_cea_extension(edid, &cea_ext_index, &displayid_ext_index))
                return 0;
 
        /*
@@ -4321,11 +4320,11 @@ static void drm_parse_y420cmdb_bitmap(struct 
drm_connector *connector,
 static int
 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;
+       const u8 *cea, *db, *hdmi = NULL, *video = NULL;
        u8 dbl, hdmi_len, video_len = 0;
-       int modes = 0;
+       int modes = 0, cea_ext_index = 0, displayid_ext_index = 0;
 
+       cea = drm_find_cea_extension(edid, &cea_ext_index, 
&displayid_ext_index);
        if (cea && cea_revision(cea) >= 3) {
                int i, start, end;
 
@@ -4563,6 +4562,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
        const u8 *cea;
        const u8 *db;
        int total_sad_count = 0;
+       int cea_ext_index = 0, displayid_ext_index = 0;
        int mnl;
        int dbl;
 
@@ -4571,7 +4571,7 @@ static void drm_edid_to_eld(struct drm_connector 
*connector, struct edid *edid)
        if (!edid)
                return;
 
-       cea = drm_find_cea_extension(edid);
+       cea = drm_find_cea_extension(edid, &cea_ext_index, 
&displayid_ext_index);
        if (!cea) {
                DRM_DEBUG_KMS("ELD: no CEA Extension found\n");
                return;
@@ -4657,9 +4657,10 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad 
**sads)
 {
        int count = 0;
        int i, start, end, dbl;
+       int cea_ext_index = 0, displayid_ext_index = 0;
        const u8 *cea;
 
-       cea = drm_find_cea_extension(edid);
+       cea = drm_find_cea_extension(edid, &cea_ext_index, 
&displayid_ext_index);
        if (!cea) {
                DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
                return 0;
@@ -4719,9 +4720,10 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 
**sadb)
 {
        int count = 0;
        int i, start, end, dbl;
+       int cea_ext_index = 0, displayid_ext_index = 0;
        const u8 *cea;
 
-       cea = drm_find_cea_extension(edid);
+       cea = drm_find_cea_extension(edid, &cea_ext_index, 
&displayid_ext_index);
        if (!cea) {
                DRM_DEBUG_KMS("SAD: no CEA Extension found\n");
                return 0;
@@ -4815,8 +4817,9 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
        const u8 *edid_ext;
        int i;
        int start_offset, end_offset;
+       int cea_ext_index = 0, displayid_ext_index = 0;
 
-       edid_ext = drm_find_cea_extension(edid);
+       edid_ext = drm_find_cea_extension(edid, &cea_ext_index, 
&displayid_ext_index);
        if (!edid_ext)
                return false;
 
@@ -4854,8 +4857,9 @@ bool drm_detect_monitor_audio(struct edid *edid)
        int i, j;
        bool has_audio = false;
        int start_offset, end_offset;
+       int cea_ext_index = 0, displayid_ext_index = 0;
 
-       edid_ext = drm_find_cea_extension(edid);
+       edid_ext = drm_find_cea_extension(edid, &cea_ext_index, 
&displayid_ext_index);
        if (!edid_ext)
                goto end;
 
@@ -5178,8 +5182,9 @@ static void drm_parse_cea_ext(struct drm_connector 
*connector,
        struct drm_display_info *info = &connector->display_info;
        const u8 *edid_ext;
        int i, start, end;
+       int cea_ext_index = 0, displayid_ext_index = 0;
 
-       edid_ext = drm_find_cea_extension(edid);
+       edid_ext = drm_find_cea_extension(edid, &cea_ext_index, 
&displayid_ext_index);
        if (!edid_ext)
                return;
 
@@ -5311,12 +5316,12 @@ static void drm_update_mso(struct drm_connector 
*connector, const struct edid *e
        const struct displayid_block *block;
        struct displayid_iter iter;
 
-       displayid_iter_edid_begin(edid, &iter);
+       displayid_iter_edid_begin(edid, &iter, NULL);
        displayid_iter_for_each(block, &iter) {
                if (block->tag == DATA_BLOCK_2_VENDOR_SPECIFIC)
                        drm_parse_vesa_mso_data(connector, block);
        }
-       displayid_iter_end(&iter);
+       displayid_iter_end(&iter, NULL);
 }
 
 /* A connector has no EDID information, so we've got no EDID to compute quirks 
from. Reset
@@ -5516,13 +5521,13 @@ static int add_displayid_detailed_modes(struct 
drm_connector *connector,
        struct displayid_iter iter;
        int num_modes = 0;
 
-       displayid_iter_edid_begin(edid, &iter);
+       displayid_iter_edid_begin(edid, &iter, NULL);
        displayid_iter_for_each(block, &iter) {
                if (block->tag == DATA_BLOCK_TYPE_1_DETAILED_TIMING ||
                    block->tag == DATA_BLOCK_2_TYPE_7_DETAILED_TIMING)
                        num_modes += add_displayid_detailed_1_modes(connector, 
block);
        }
-       displayid_iter_end(&iter);
+       displayid_iter_end(&iter, NULL);
 
        return num_modes;
 }
@@ -6164,12 +6169,12 @@ void drm_update_tile_info(struct drm_connector 
*connector,
 
        connector->has_tile = false;
 
-       displayid_iter_edid_begin(edid, &iter);
+       displayid_iter_edid_begin(edid, &iter, NULL);
        displayid_iter_for_each(block, &iter) {
                if (block->tag == DATA_BLOCK_TILED_DISPLAY)
                        drm_parse_tiled_block(connector, block);
        }
-       displayid_iter_end(&iter);
+       displayid_iter_end(&iter, NULL);
 
        if (!connector->has_tile && connector->tile_group) {
                drm_mode_put_tile_group(connector->dev, connector->tile_group);
diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
index 7ffbd9f7bfc7..15442a161c11 100644
--- a/include/drm/drm_displayid.h
+++ b/include/drm/drm_displayid.h
@@ -150,11 +150,11 @@ struct displayid_iter {
 };
 
 void displayid_iter_edid_begin(const struct edid *edid,
-                              struct displayid_iter *iter);
+                              struct displayid_iter *iter, int *ext_index);
 const struct displayid_block *
 __displayid_iter_next(struct displayid_iter *iter);
 #define displayid_iter_for_each(__block, __iter) \
        while (((__block) = __displayid_iter_next(__iter)))
-void displayid_iter_end(struct displayid_iter *iter);
+void displayid_iter_end(struct displayid_iter *iter, int *ext_index);
 
 #endif
-- 
2.17.1

Reply via email to