From 039158eb3840b731ed479355ba7308b837524e8b Mon Sep 17 00:00:00 2001 From: zwl Date: Wed, 19 Mar 2014 14:56:35 +0800 Subject: [PATCH] HDMI: add 4Kx2K timing define and add config vsi for 4Kx2K at rk3288 hdmi drv --- .../hdmi/chips/rk3288/rk3288_hdmi_hw.c | 54 ++++++++++++++++++- .../hdmi/chips/rk3288/rk3288_hdmi_hw.h | 30 +++++++++++ drivers/video/rockchip/hdmi/rk_hdmi.h | 1 + drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c | 8 ++- drivers/video/rockchip/hdmi/rk_hdmi_task.c | 1 + 5 files changed, 91 insertions(+), 3 deletions(-) diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c index 88d0a86abfeb..f073ce0c9ffc 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.c @@ -206,7 +206,7 @@ static int rk3288_hdmi_video_frameComposer(struct hdmi *hdmi_drv, struct hdmi_vi int h_blank = 0, v_blank = 0; int vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync; int hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync; - int de_pol = hdmi_drv->lcdc->cur_screen->pin_den; + int de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0; struct fb_videomode *mode = NULL; struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver); @@ -504,6 +504,50 @@ static int rk3288_hdmi_config_phy(struct hdmi *hdmi_drv) return 0; } +int rk3288_hdmi_config_vsi(struct hdmi *hdmi_drv, unsigned char vic_3d, unsigned char format, int auto_send) +{ + int i = 0; + unsigned char data[3] = {0}; + int id = 0x000c03; + struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver); + + hdmi_dbg(hdmi_drv->dev, "[%s] vic %d format %d.\n", __FUNCTION__, vic, format); + hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0)); + hdmi_writel(hdmi_dev, FC_VSDIEEEID0, id & 0xff); + hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff); + hdmi_writel(hdmi_dev, FC_VSDIEEEID2, (id >> 16) & 0xff); + + data[0] = format << 5; //PB4 --HDMI_Video_Format + switch(format) + { + case HDMI_VIDEO_FORMAT_4Kx2K: + data[1] = vic_3d; //PB5--HDMI_VIC + data[2] = 0; + break; + case HDMI_VIDEO_FORMAT_3D: + data[1] = vic_3d << 4; //PB5--3D_Structure field + data[2] = 0; //PB6--3D_Ext_Data field + break; + default: + data[1] = 0; + data[2] = 0; + break; + } + + for (i = 0; i < 3; i++) { + hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]); + } + + if (auto_send) { + hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(auto_send)); + } + else { + hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1)); + } + + return 0; +} + static void rk3288_hdmi_config_avi(struct hdmi *hdmi_drv, unsigned char vic, unsigned char output_color) { int clolorimetry, aspect_ratio, y1y0; @@ -675,9 +719,15 @@ int rk3288_hdmi_config_video(struct hdmi *hdmi_drv, struct hdmi_video_para *vpar if (rk3288_hdmi_video_sampler(hdmi_drv, vpara) < 0) return -1; - if(vpara->output_mode == OUTPUT_HDMI) { + if (vpara->output_mode == OUTPUT_HDMI) { rk3288_hdmi_config_avi(hdmi_drv, vpara->vic, vpara->output_color); hdmi_dbg(hdmi_drv->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); + if ( vpara->format_3d != 0) + rk3288_hdmi_config_vsi(hdmi_drv, vpara->format_3d, HDMI_VIDEO_FORMAT_3D, 1); + else if (vpara->vic > 0 && vpara->vic < 5) + rk3288_hdmi_config_vsi(hdmi_drv, vpara->vic, HDMI_VIDEO_FORMAT_4Kx2K, 1); + else + rk3288_hdmi_config_vsi(hdmi_drv, vpara->vic, HDMI_VIDEO_FORMAT_NORMAL, 1); } else { hdmi_dbg(hdmi_drv->dev, "[%s] sucess output DVI.\n", __FUNCTION__); diff --git a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h index 05b5f2f13963..91bcf12f4604 100644 --- a/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h +++ b/drivers/video/rockchip/hdmi/chips/rk3288/rk3288_hdmi_hw.h @@ -23,6 +23,12 @@ enum { CSC_ITU709_TO_RGB, //YCbCr input to RGB output according BT709 }; +/*VIC VIDEO FORMAT*/ +enum { + HDMI_VIDEO_FORMAT_NORMAL = 0, + HDMI_VIDEO_FORMAT_4Kx2K, + HDMI_VIDEO_FORMAT_3D +}; #define HDMI_SCL_RATE (100*1000) #define DDC_I2C_EDID_ADDR 0x50 // 0xA0/2 = 0x50 @@ -567,10 +573,34 @@ enum { #define FC_ISCR1_0 0x1092 #define FC_ISCR1_16 0x1093 //16~1 #define FC_ISCR2_15 0x10a3 //15~0 + #define FC_DATAUTO0 0x10b3 +#define m_SPD_AUTO (1 << 4) +#define v_SPD_AUTO(n) (((n)&0x01) << 4) +#define m_VSD_AUTO (1 << 3) +#define v_VSD_AUTO(n) (((n)&0x01) << 3) +#define m_ISCR2_AUTO (1 << 2) +#define v_ISCR2_AUTO(n) (((n)&0x01) << 2) +#define m_ISCR1_AUTO (1 << 1) +#define v_ISCR1_AUTO(n) (((n)&0x01) << 1) +#define m_ACP_AUTO (1 << 0) +#define v_ACP_AUTO(n) (((n)&0x01) << 0) + #define FC_DATAUTO1 0x10b4 #define FC_DATAUTO2 0x10b5 + #define FC_DATMAN 0x10b6 +#define m_SPD_MAN (1 << 4) +#define v_SPD_MAN(n) (((n)&0x01) << 4) +#define m_VSD_MAN (1 << 3) +#define v_VSD_MAN(n) (((n)&0x01) << 3) +#define m_ISCR2_MAN (1 << 2) +#define v_ISCR2_MAN(n) (((n)&0x01) << 2) +#define m_ISCR1_MAN (1 << 1) +#define v_ISCR1_MAN(n) (((n)&0x01) << 1) +#define m_ACP_MAN (1 << 0) +#define v_ACP_MAN(n) (((n)&0x01) << 0) + #define FC_DATAUTO3 0x10b7 #define FC_RDRB0 0x10b8 #define FC_RDRB1 0x10b9 diff --git a/drivers/video/rockchip/hdmi/rk_hdmi.h b/drivers/video/rockchip/hdmi/rk_hdmi.h index 48e69e41aa15..8fa6345db7a1 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi.h +++ b/drivers/video/rockchip/hdmi/rk_hdmi.h @@ -252,6 +252,7 @@ struct hdmi_video_para { int input_color; //input video color mode int output_mode; //output hdmi or dvi int output_color; //output video color mode + int format_3d; }; struct hdmi { diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c b/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c index adc640596a9a..b0a68006e004 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c +++ b/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c @@ -11,7 +11,7 @@ static struct hdmi *m_hdmi_drv = NULL; static const struct fb_videomode hdmi_mode [] = { - //name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag(used for vic) + //name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag(used for vic) //{ "640x480p@60Hz", 60, 640, 480, 25175000, 48, 16, 33, 10, 96, 2, 0, 0, 1 }, //{ "720x480i@60Hz", 60, 720, 480, 27000000, 114, 38, 15, 4, 124, 3, 0, 1, 6 }, //{ "720x576i@50Hz", 50, 720, 576, 27000000, 138, 24, 19, 2, 126, 3, 0, 1, 21 }, @@ -63,7 +63,13 @@ static const struct fb_videomode hdmi_mode [] = { { "3840x2160p@24Hz", 24, 3840, 2160, 297000000, 296, 1276, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 93 }, { "3840x2160p@25Hz", 25, 3840, 2160, 297000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 94 }, { "3840x2160p@30Hz", 30, 3840, 2160, 297000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 95 }, +{ "3840x2160p@50Hz", 50, 3840, 2160, 594000000, 296, 1056, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 96 }, +{ "3840x2160p@60Hz", 60, 3840, 2160, 594000000, 296, 176, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 97 }, { "4096x2160p@24Hz", 24, 4096, 2160, 297000000, 296, 1020, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 98 }, +{ "4096x2160p@25Hz", 25, 4096, 2160, 297000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 99 }, +{ "4096x2160p@30Hz", 30, 4096, 2160, 297000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 100 }, +{ "4096x2160p@50Hz", 50, 4096, 2160, 594000000, 128, 968, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 101 }, +{ "4096x2160p@60Hz", 60, 4096, 2160, 594000000, 128, 88, 72, 8, 88, 10, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 102 }, }; diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_task.c b/drivers/video/rockchip/hdmi/rk_hdmi_task.c index 2f6c5a4c3e19..4eccf14d7206 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi_task.c +++ b/drivers/video/rockchip/hdmi/rk_hdmi_task.c @@ -252,6 +252,7 @@ void hdmi_work(struct work_struct *work) video.input_mode = VIDEO_INPUT_RGB_YCBCR_444; video.input_color = VIDEO_INPUT_COLOR_RGB;//VIDEO_INPUT_COLOR_YCBCR video.output_mode = hdmi->edid.sink_hdmi; + video.format_3d = 0; //TODO modify read from EDID if(hdmi->edid.ycbcr444) video.output_color = VIDEO_OUTPUT_YCBCR444; -- 2.34.1