HDMI: improve EDID parse.
authorZheng Yang <zhengyang@rock-chips.com>
Wed, 6 May 2015 09:15:24 +0000 (17:15 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Wed, 6 May 2015 09:15:24 +0000 (17:15 +0800)
1. For some sink device, there is no available video mode
   in EDID. hdmi driver will crash under such case.
2. There are some video mode is not defined in EDID extend
   block, so we need to check first block data.

Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c

index 8a10edb91bb9c4c855771ee51534690165c443a4..bcf45c87862b14881813dd9b83aa0217c6215e5f 100644 (file)
@@ -508,10 +508,14 @@ static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature)
                }
        }
        fb_destroy_modelist(head);
-
-       edid->modelist = head_new;
-       edid->modelist.prev->next = &edid->modelist;
-       edid->modelist.next->prev = &edid->modelist;
+       if (head_new.next == &head_new) {
+               pr_info("There is no available video mode in EDID.\n");
+               INIT_LIST_HEAD(&edid->modelist);
+       } else {
+               edid->modelist = head_new;
+               edid->modelist.prev->next = &edid->modelist;
+               edid->modelist.next->prev = &edid->modelist;
+       }
 }
 
 /**
@@ -585,6 +589,16 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
                        hdmi_add_videomode(mode, head);
                }
        } else {
+               /* There are some video mode is not defined in EDID extend
+                  block, so we need to check first block data.*/
+               if (specs && specs->modedb_len) {
+                       for (i = 0; i < specs->modedb_len; i++) {
+                               modedb = &specs->modedb[0];
+                               pixclock = hdmi_videomode_to_vic(modedb);
+                               if (pixclock)
+                                       hdmi_add_vic(pixclock, head);
+                       }
+               }
                hdmi_sort_modelist(&hdmi->edid, hdmi->property->feature);
        }
        hdmi_show_sink_info(hdmi);