]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00170938-2 mxc hdmi: Enable HDMI output color space convert
authorSandor Yu <R01008@freescale.com>
Tue, 27 Dec 2011 01:50:46 +0000 (09:50 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:43 +0000 (08:33 +0200)
Enable HDMI output CSC.
Enable HDMI under scan.

Signed-off-by: Sandor Yu <R01008@freescale.com>
drivers/video/mxc_hdmi.c

index 63d3cba82509f9b85cdf10524b9ed39365cf1f27..46d93efb631ee4b79f9f57f3edf5808da4528270 100644 (file)
@@ -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;