From: Zheng Yang Date: Tue, 15 Sep 2015 01:29:05 +0000 (+0800) Subject: video: rockchip: hdmi: support some vesa dmt mode X-Git-Tag: firefly_0821_release~3781 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f6656c7c7f95f10a25123a3243452cf37f76cd4e;p=firefly-linux-kernel-4.4.55.git video: rockchip: hdmi: support some vesa dmt mode Change-Id: I28e935c717ae69fb2b48a7c243f8ce3cc7101a86 Signed-off-by: Zheng Yang --- diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c index 85f7954734c3..3254b39d66af 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-core.c @@ -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); } diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c index d25e99e7b142..f6c321962122 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi-lcdc.c @@ -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; diff --git a/drivers/video/rockchip/hdmi/rockchip-hdmi.h b/drivers/video/rockchip/hdmi/rockchip-hdmi.h index 7e319aed7858..23ea66e426c1 100644 --- a/drivers/video/rockchip/hdmi/rockchip-hdmi.h +++ b/drivers/video/rockchip/hdmi/rockchip-hdmi.h @@ -8,11 +8,9 @@ #include #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 {