video: rockchip: hdmi: support some vesa dmt mode
authorZheng Yang <zhengyang@rock-chips.com>
Tue, 15 Sep 2015 01:29:05 +0000 (09:29 +0800)
committerGerrit Code Review <gerrit@rock-chips.com>
Tue, 15 Sep 2015 06:08:46 +0000 (14:08 +0800)
Change-Id: I28e935c717ae69fb2b48a7c243f8ce3cc7101a86
Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
drivers/video/rockchip/hdmi/rockchip-hdmi-core.c
drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c
drivers/video/rockchip/hdmi/rockchip-hdmi.h

index 85f7954734c350f1c8695121f4c05bccaecc69b6..3254b39d66af2a2cfaf367060be144eaac70b37d 100644 (file)
@@ -86,8 +86,17 @@ static void hdmi_wq_set_video(struct hdmi *hdmi)
        video->sink_hdmi = hdmi->edid.sink_hdmi;
        video->format_3d = hdmi->mode_3d;
        video->colorimetry = hdmi->colorimetry;
+
+       if (hdmi->autoset)
+               hdmi->vic = hdmi_find_best_mode(hdmi, 0);
+       else
+               hdmi->vic = hdmi_find_best_mode(hdmi, hdmi->vic);
+
+       if (hdmi->vic == 0)
+               hdmi->vic = hdmi->property->defaultmode;
+
        /* For DVI, output RGB */
-       if (hdmi->edid.sink_hdmi == 0) {
+       if (video->sink_hdmi == 0) {
                video->color_output = HDMI_COLOR_RGB_0_255;
        } else {
                if (hdmi->colormode == HDMI_COLOR_AUTO) {
@@ -124,8 +133,14 @@ static void hdmi_wq_set_video(struct hdmi *hdmi)
                else if (video->color_output == HDMI_COLOR_YCBCR420)
                        video->color_input = HDMI_COLOR_YCBCR420;
        }
+
+       if (hdmi->vic & HDMI_VIDEO_DMT) {
+               video->vic = hdmi->vic;
+               video->color_output_depth = 8;
+       } else {
+               video->vic = hdmi->vic & HDMI_VIC_MASK;
+       }
        hdmi_set_lcdc(hdmi);
-       video->vic = hdmi->vic & HDMI_VIC_MASK;
        if (hdmi->ops->setvideo)
                hdmi->ops->setvideo(hdmi, video);
 }
index d25e99e7b1422982399750311224851333a91c30..f6c321962122cdb6e1c2bce793f25e2f5f66e5ad 100644 (file)
@@ -29,11 +29,20 @@ static const struct hdmi_video_timing hdmi_mode[] = {
        { {     "3840x2160p@60Hz",      60,     3840,   2160,   594000000,      296,    176,    72,     8,      88,     10,     FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      97,     HDMI_3840X2160P_60HZ_4_3,       1,      OUT_P888},
        { {     "4096x2160p@50Hz",      50,     4096,   2160,   594000000,      128,    968,    72,     8,      88,     10,     FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      101,    0,                              1,      OUT_P888},
        { {     "4096x2160p@60Hz",      60,     4096,   2160,   594000000,      128,    88,     72,     8,      88,     10,     FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      102,    0,                              1,      OUT_P888},
+       { {     "800x600p@60Hz",        60,     800,    600,    40000000,       88,     40,     23,     1,      128,    4,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      1 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1024x768p@60Hz",       60,     1024,   768,    65000000,       160,    24,     29,     3,      136,    6,                      0,                              0,      0       },      2 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1280x960p@60Hz",       60,     1280,   960,    108000000,      312,    96,     36,     1,      112,    3,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      3 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1280x1024p@60Hz",      60,     1280,   1024,   108000000,      248,    48,     38,     1,      112,    3,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      4 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1360x768p@60Hz",       60,     1360,   768,    85500000,       256,    64,     18,     3,      112,    6,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      5 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1366x768p@60Hz",       60,     1366,   768,    85500000,       213,    70,     24,     3,      143,    3,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      6 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1440x900p@60Hz",       60,     1440,   900,    106500000,      232,    80,     25,     3,      152,    6,              FB_SYNC_VERT_HIGH_ACT,                  0,      0       },      7 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1600x900p@60Hz",       60,     1600,   900,    108000000,      96,     24,     96,     1,      80,     3,      FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,   0,      0       },      8 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
+       { {     "1680x1050@60Hz",       60,     1680,   1050,   146250000,      280,    104,    30,     3,      176,    6,              FB_SYNC_VERT_HIGH_ACT,                  0,      0       },      9 | HDMI_VIDEO_DMT,     0,              1,      OUT_P888},
 };
 
 static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi)
 {
-       int i;
+       int i, vic;
        struct fb_videomode *mode;
 
        if (screen == NULL || hdmi == NULL)
@@ -42,9 +51,13 @@ static int hdmi_set_info(struct rk_screen *screen, struct hdmi *hdmi)
        if (hdmi->vic == 0)
                hdmi->vic = hdmi->property->defaultmode;
 
+       if (hdmi->vic & HDMI_VIDEO_DMT)
+               vic = hdmi->vic;
+       else
+               vic = hdmi->vic & HDMI_VIC_MASK;
        for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
-               if (hdmi_mode[i].vic == (hdmi->vic & HDMI_VIC_MASK) ||
-                   hdmi_mode[i].vic_2nd == (hdmi->vic & HDMI_VIC_MASK))
+               if (hdmi_mode[i].vic == vic ||
+                   hdmi_mode[i].vic_2nd == vic)
                        break;
        }
        if (i == ARRAY_SIZE(hdmi_mode))
@@ -182,14 +195,6 @@ int hdmi_set_lcdc(struct hdmi *hdmi)
        int rc = 0;
        struct rk_screen screen;
 
-       if (hdmi->autoset)
-               hdmi->vic = hdmi_find_best_mode(hdmi, 0);
-       else
-               hdmi->vic = hdmi_find_best_mode(hdmi, hdmi->vic);
-
-       if (hdmi->vic == 0)
-               hdmi->vic = hdmi->property->defaultmode;
-
        rc = hdmi_set_info(&screen, hdmi);
 
        if (rc == 0) {
@@ -257,7 +262,7 @@ int hdmi_add_vic(int vic, struct list_head *head)
        struct display_modelist *modelist;
        int found = 0, v;
 
-/*     DBG("%s vic %d", __FUNCTION__, vic); */
+       /*pr_info("%s vic %d\n", __FUNCTION__, vic);*/
        if (vic == 0)
                return -1;
 
@@ -346,7 +351,14 @@ static void hdmi_sort_modelist(struct hdmi_edid *edid, int feature)
                modelist = list_entry(pos, struct display_modelist, list);
                /*pr_info("%s vic %d\n", __function__, modelist->vic);*/
                for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
-                       vic = modelist->vic & HDMI_VIC_MASK;
+                       if (modelist->vic & HDMI_VIDEO_DMT) {
+                               if (feature & SUPPORT_VESA_DMT)
+                                       vic = modelist->vic;
+                               else
+                                       continue;
+                       } else {
+                               vic = modelist->vic & HDMI_VIC_MASK;
+                       }
                        if (vic == hdmi_mode[i].vic ||
                            vic == hdmi_mode[i].vic_2nd) {
                                if ((feature & SUPPORT_4K) == 0 &&
@@ -484,7 +496,8 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
                                   just list common hdmi foramt. */
                                if (mode->xres > 3840 ||
                                    mode->refresh < 50 ||
-                                   mode->vmode == FB_VMODE_INTERLACED)
+                                   mode->vmode == FB_VMODE_INTERLACED ||
+                                   hdmi_mode[i].vic & HDMI_VIDEO_DMT)
                                        continue;
                        }
                        if ((feature & SUPPORT_TMDS_600M) == 0 &&
@@ -511,7 +524,7 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
                   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];
+                               modedb = &specs->modedb[i];
                                pixclock = hdmi_videomode_to_vic(modedb);
                                if (pixclock)
                                        hdmi_add_vic(pixclock, head);
@@ -531,7 +544,7 @@ int hdmi_ouputmode_select(struct hdmi *hdmi, int edid_ok)
 int hdmi_videomode_to_vic(struct fb_videomode *vmode)
 {
        struct fb_videomode *mode;
-       unsigned char vic = 0;
+       unsigned int vic = 0;
        int i = 0;
 
        for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
@@ -579,14 +592,17 @@ const struct hdmi_video_timing *hdmi_vic2timing(int vic)
  */
 const struct fb_videomode *hdmi_vic_to_videomode(int vic)
 {
-       int i;
+       int i, vid;
 
        if (vic == 0)
                return NULL;
-
+       else if (vic & HDMI_VIDEO_DMT)
+               vid = vic;
+       else
+               vid = vic & HDMI_VIC_MASK;
        for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
-               if (hdmi_mode[i].vic == (vic & HDMI_VIC_MASK) ||
-                   hdmi_mode[i].vic_2nd == (vic & HDMI_VIC_MASK))
+               if (hdmi_mode[i].vic == vid ||
+                   hdmi_mode[i].vic_2nd == vid)
                        return &hdmi_mode[i].mode;
        }
        return NULL;
@@ -607,6 +623,8 @@ void hdmi_init_modelist(struct hdmi *hdmi)
        feature = hdmi->property->feature;
        INIT_LIST_HEAD(&hdmi->edid.modelist);
        for (i = 0; i < ARRAY_SIZE(hdmi_mode); i++) {
+               if (hdmi_mode[i].vic & HDMI_VIDEO_DMT)
+                       continue;
                if ((feature & SUPPORT_TMDS_600M) == 0 &&
                    hdmi_mode[i].mode.pixclock > 340000000)
                        continue;
index 7e319aed78587b3940062fac3b2a4d2e67cf1513..23ea66e426c143fc3de95c9edadcd2fce69b83ec 100644 (file)
@@ -8,11 +8,9 @@
 #include <linux/switch.h>
 #endif
 
-#define HDMI_VIDEO_NORMAL                              (0 << 8)
-#define HDMI_VIDEO_EXT                                 (1 << 8)
-#define HDMI_VIDEO_3D                                  (2 << 8)
-#define HDMI_VIDEO_DVI                                 (3 << 8)
-#define HDMI_VIDEO_YUV420                              (4 << 8)
+#define HDMI_VIDEO_NORMAL                              0
+#define HDMI_VIDEO_DMT                                 (1 << 9)
+#define HDMI_VIDEO_YUV420                              (1 << 10)
 #define HDMI_VIC_MASK                                  (0xFF)
 #define HDMI_TYPE_MASK                                 (0xFF << 8)
 #define HDMI_MAX_ID                                    4
@@ -356,6 +354,7 @@ enum rk_hdmi_feature {
        SUPPORT_HDCP            =       (1 << 10),
        SUPPORT_HDCP2           =       (1 << 11),
        SUPPORT_YCBCR_INPUT     =       (1 << 12),
+       SUPPORT_VESA_DMT        =       (1 << 13)
 };
 
 struct hdmi_property {