From 86c3333b60b491d217ba68e697dad1d3231c3c87 Mon Sep 17 00:00:00 2001 From: Sandor Yu Date: Tue, 27 Dec 2011 09:50:46 +0800 Subject: ENGR00170938-2 mxc hdmi: Enable HDMI output color space convert Enable HDMI output CSC. Enable HDMI under scan. Signed-off-by: Sandor Yu --- drivers/video/mxc_hdmi.c | 67 +++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c index b212ad128b7..085bdd85bf4 100644 --- a/drivers/video/mxc_hdmi.c +++ b/drivers/video/mxc_hdmi.c @@ -75,7 +75,7 @@ #define YCBCR444 1 #define YCBCR422_16BITS 2 #define YCBCR422_8BITS 3 -#define XVYCC444 4 +#define XVYCC444 4 /* * We follow a flowchart which is in the "Synopsys DesignWare Courses @@ -264,7 +264,7 @@ static void hdmi_video_sample(struct mxc_hdmi *hdmi) color_format = 0x07; else return; - } else if (hdmi->hdmi_data.enc_in_format == XVYCC444) { + } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { if (hdmi->hdmi_data.enc_color_depth == 8) color_format = 0x09; else if (hdmi->hdmi_data.enc_color_depth == 10) @@ -314,14 +314,14 @@ static int isColorSpaceDecimation(struct mxc_hdmi *hdmi) { return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) && (hdmi->hdmi_data.enc_in_format == RGB || - hdmi->hdmi_data.enc_in_format == XVYCC444)); + hdmi->hdmi_data.enc_in_format == YCBCR444)); } static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi) { return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) && (hdmi->hdmi_data.enc_out_format == RGB - || hdmi->hdmi_data.enc_out_format == XVYCC444)); + || hdmi->hdmi_data.enc_out_format == YCBCR444)); } /*! @@ -502,7 +502,7 @@ static void hdmi_video_csc(struct mxc_hdmi *hdmi) if (isColorSpaceInterpolation(hdmi)) interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; else if (isColorSpaceDecimation(hdmi)) - decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1; + decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; if (hdmi->hdmi_data.enc_color_depth == 8) color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; @@ -826,7 +826,7 @@ static void mxc_hdmi_phy_sel_interface_control(u8 enable) static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep, unsigned char cRes, int cscOn) { - u8 val; + u8 val, clkdis; dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); @@ -846,6 +846,13 @@ static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep, hdmi_writeb(val, HDMI_MC_FLOWCTRL); + /* Enable csc path */ + if (cscOn) { + clkdis = hdmi_readb(HDMI_MC_CLKDIS); + clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; + hdmi_writeb(clkdis, HDMI_MC_CLKDIS); + } + /* gen2 tx power off */ mxc_hdmi_phy_gen2_txpwron(0); @@ -1070,9 +1077,14 @@ static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep, static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi) { int i; + bool cscon = false; dev_dbg(&hdmi->pdev->dev, "%s\n", __func__); + /*check csc whether needed activated in HDMI mode */ + cscon = (isColorSpaceConversion(hdmi) && + !hdmi->hdmi_data.video_mode.mDVI); + /* HDMI Phy spec says to do the phy initialization sequence twice */ for (i = 0 ; i < 2 ; i++) { mxc_hdmi_phy_sel_data_en_pol(1); @@ -1080,8 +1092,8 @@ static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi) mxc_hdmi_phy_enable_tmds(0); mxc_hdmi_phy_enable_power(0); - /* TODO: Enable CSC */ - hdmi_phy_configure(hdmi, 0, 8, false); + /* Enable CSC */ + hdmi_phy_configure(hdmi, 0, 8, cscon); } hdmi->phy_enabled = true; @@ -1117,6 +1129,7 @@ static void hdmi_config_AVI(struct mxc_hdmi *hdmi) { u8 val; u8 pix_fmt; + u8 under_scan; u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry; struct fb_videomode mode; const struct fb_videomode *edid_mode; @@ -1138,21 +1151,25 @@ static void hdmi_config_AVI(struct mxc_hdmi *hdmi) /******************************************** * AVI Data Byte 1 ********************************************/ - if (hdmi->edid_cfg.cea_ycbcr444) + if (hdmi->hdmi_data.enc_out_format == YCBCR444) pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444; - else if (hdmi->edid_cfg.cea_ycbcr422) + else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422; else pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB; + if (hdmi->edid_cfg.cea_underscan) + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN; + else + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA; + /* * Active format identification data is present in the AVI InfoFrame. - * No scan info, no bar data + * Under scan info, no bar data */ - val = pix_fmt | + val = pix_fmt | under_scan | HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT | - HDMI_FC_AVICONF0_BAR_DATA_NO_DATA | - HDMI_FC_AVICONF0_SCAN_INFO_NODATA; + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA; hdmi_writeb(val, HDMI_FC_AVICONF0); @@ -1220,7 +1237,7 @@ static void hdmi_config_AVI(struct mxc_hdmi *hdmi) hdmi_writeb(val, HDMI_FC_PRCONF); /* IT Content and quantization range = don't care */ - val = HDMI_FC_AVICONF2_IT_CONTENT_TYPE_GRAPHICS | + val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS | HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED; hdmi_writeb(val, HDMI_FC_AVICONF3); @@ -1526,10 +1543,12 @@ static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi) FB_VMODE_INTERLACED)) { dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i); dev_dbg(&hdmi->pdev->dev, - "xres = %d, yres = %d, freq = %d\n", + "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n", hdmi->fbi->monspecs.modedb[i].xres, hdmi->fbi->monspecs.modedb[i].yres, - hdmi->fbi->monspecs.modedb[i].refresh); + hdmi->fbi->monspecs.modedb[i].refresh, + hdmi->fbi->monspecs.modedb[i].vmode, + hdmi->fbi->monspecs.modedb[i].flag); fb_add_videomode(&hdmi->fbi->monspecs.modedb[i], &hdmi->fbi->modelist); @@ -1914,12 +1933,14 @@ static void mxc_hdmi_setup(struct mxc_hdmi *hdmi) hdmi->hdmi_data.enc_in_format = RGB; hdmi->hdmi_data.enc_out_format = RGB; - if (hdmi->edid_cfg.hdmi_cap) { - if (hdmi->edid_cfg.cea_ycbcr444) - hdmi->hdmi_data.enc_out_format = YCBCR444; - else if (hdmi->edid_cfg.cea_ycbcr422) - hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS; - } + /*DVI mode not support non-RGB */ + if (!hdmi->hdmi_data.video_mode.mDVI) + if (hdmi->edid_cfg.hdmi_cap) { + if (hdmi->edid_cfg.cea_ycbcr444) + hdmi->hdmi_data.enc_out_format = YCBCR444; + else if (hdmi->edid_cfg.cea_ycbcr422) + hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS; + } hdmi->hdmi_data.enc_color_depth = 8; hdmi->hdmi_data.pix_repet_factor = 0; -- cgit v1.2.3