video: tegra: dc: setup HDMI infoframe and VIC
Jon Mayo [Tue, 12 Feb 2013 02:15:34 +0000 (18:15 -0800)]
Changes programming sequence when using the generic infoframe.

bug 1233022

Change-Id: I7108276164a4e97cfe27fcd03c1d03ff3a991909
Signed-off-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-on: http://git-master/r/200078
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit

drivers/video/tegra/dc/hdmi.c
drivers/video/tegra/dc/mode.c

index 85ec9ec..2c0dc77 100644 (file)
@@ -1535,7 +1535,52 @@ static int tegra_dc_find_hdmi_vic(const struct tegra_dc_mode *mode)
        return 0;
 }
 
-static void tegra_dc_hdmi_setup_avi_infoframe(struct tegra_dc *dc, bool dvi)
+static void tegra_dc_hdmi_disable_generic_infoframe(struct tegra_dc *dc)
+{
+       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+       u32 val;
+
+       val  = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+       val &= ~GENERIC_CTRL_ENABLE;
+       tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+}
+
+/* return 1 if generic infoframe is used, 0 if not used */
+static int tegra_dc_hdmi_setup_hdmi_vic_infoframe(struct tegra_dc *dc)
+{
+       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
+       struct hdmi_extres_infoframe extres;
+       int hdmi_vic;
+       u32 val;
+
+       hdmi_vic = tegra_dc_find_hdmi_vic(&dc->mode);
+       if (hdmi_vic <= 0) {
+               tegra_dc_hdmi_disable_generic_infoframe(dc);
+               return 0;
+       }
+
+       memset(&extres, 0x0, sizeof(extres));
+
+       extres.csum = 0;
+       extres.regid0 = 0x03;
+       extres.regid1 = 0x0c;
+       extres.regid2 = 0x00;
+       extres.hdmi_video_format = 1; /* Extended Resolution Format */
+       extres.hdmi_vic = hdmi_vic;
+
+       tegra_dc_hdmi_write_infopack(dc,
+               HDMI_NV_PDISP_HDMI_GENERIC_HEADER,
+               HDMI_INFOFRAME_TYPE_VENDOR, HDMI_VENDOR_VERSION,
+               &extres, 6);
+       val = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+       val |= GENERIC_CTRL_ENABLE;
+       tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+       return 1;
+}
+
+
+/* return 1 if generic infoframe is used, 0 if not used */
+static int tegra_dc_hdmi_setup_avi_infoframe(struct tegra_dc *dc, bool dvi)
 {
        struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
        struct hdmi_avi_infoframe avi;
@@ -1543,7 +1588,7 @@ static void tegra_dc_hdmi_setup_avi_infoframe(struct tegra_dc *dc, bool dvi)
        if (dvi) {
                tegra_hdmi_writel(hdmi, 0x0,
                                  HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
-               return;
+               return 0;
        }
 
        memset(&avi, 0x0, sizeof(avi));
@@ -1559,6 +1604,9 @@ static void tegra_dc_hdmi_setup_avi_infoframe(struct tegra_dc *dc, bool dvi)
        avi.m = dc->mode.avi_m;
        dev_dbg(&dc->ndev->dev, "HDMI AVI vic=%d m=%d\n", avi.vic, avi.m);
 
+       if (!avi.vic) /* Extended resolution format */
+               return tegra_dc_hdmi_setup_hdmi_vic_infoframe(dc);
+
        tegra_dc_hdmi_write_infopack(dc, HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER,
                                     HDMI_INFOFRAME_TYPE_AVI,
                                     HDMI_AVI_VERSION,
@@ -1566,16 +1614,8 @@ static void tegra_dc_hdmi_setup_avi_infoframe(struct tegra_dc *dc, bool dvi)
 
        tegra_hdmi_writel(hdmi, INFOFRAME_CTRL_ENABLE,
                          HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
-}
 
-static void tegra_dc_hdmi_disable_generic_infoframe(struct tegra_dc *dc)
-{
-       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
-       u32 val;
-
-       val  = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
-       val &= ~GENERIC_CTRL_ENABLE;
-       tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
+       return 0;
 }
 
 static void tegra_dc_hdmi_setup_stereo_infoframe(struct tegra_dc *dc)
@@ -1611,37 +1651,6 @@ static void tegra_dc_hdmi_setup_stereo_infoframe(struct tegra_dc *dc)
        tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
 }
 
-static void tegra_dc_hdmi_setup_hdmi_vic_infoframe(struct tegra_dc *dc)
-{
-       struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
-       struct hdmi_extres_infoframe extres;
-       int hdmi_vic;
-       u32 val;
-
-       hdmi_vic = tegra_dc_find_hdmi_vic(&dc->mode);
-       if (hdmi_vic <= 0) {
-               tegra_dc_hdmi_disable_generic_infoframe(dc);
-               return;
-       }
-
-       memset(&extres, 0x0, sizeof(extres));
-
-       extres.csum = 0;
-       extres.regid0 = 0x03;
-       extres.regid1 = 0x0c;
-       extres.regid2 = 0x00;
-       extres.hdmi_video_format = 1; /* Extended Resolution Format */
-       extres.hdmi_vic = hdmi_vic;
-
-       tegra_dc_hdmi_write_infopack(dc,
-               HDMI_NV_PDISP_HDMI_GENERIC_HEADER,
-               HDMI_INFOFRAME_TYPE_VENDOR, HDMI_VENDOR_VERSION,
-               &extres, 6);
-       val = tegra_hdmi_readl(hdmi, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
-       val |= GENERIC_CTRL_ENABLE;
-       tegra_hdmi_writel(hdmi, val, HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
-}
-
 static void tegra_dc_hdmi_setup_audio_infoframe(struct tegra_dc *dc, bool dvi)
 {
        struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
@@ -1703,6 +1712,7 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
        unsigned long val;
        unsigned i;
        unsigned long oldrate;
+       int generic_used;
 
        /* enbale power, clocks, resets, etc. */
 
@@ -1814,14 +1824,12 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
                tegra_hdmi_writel(hdmi, GENERIC_CTRL_AUDIO,
                                  HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
 
-       tegra_dc_hdmi_setup_avi_infoframe(dc, hdmi->dvi);
+       generic_used = tegra_dc_hdmi_setup_avi_infoframe(dc, hdmi->dvi);
        tegra_dc_hdmi_setup_audio_infoframe(dc, hdmi->dvi);
 
        if (dc->mode.stereo_mode)
                tegra_dc_hdmi_setup_stereo_infoframe(dc);
-       else if (dc->mode.avi_m) /* Extended resolution format */
-               tegra_dc_hdmi_setup_hdmi_vic_infoframe(dc);
-       else /* else disable sending of this infoframe */
+       else if (!generic_used) /* else disable sending of this infoframe */
                tegra_dc_hdmi_disable_generic_infoframe(dc);
 
        /* TMDS CONFIG */
index c9812f4..08a9769 100644 (file)
@@ -356,6 +356,7 @@ int tegra_dc_set_fb_mode(struct tegra_dc *dc,
        if (!fbmode->pixclock)
                return -EINVAL;
 
+       memset(&mode, 0, sizeof(mode));
        mode.pclk = PICOS2KHZ(fbmode->pixclock) * 1000;
        mode.h_sync_width = fbmode->hsync_len;
        mode.v_sync_width = fbmode->vsync_len;
@@ -366,6 +367,7 @@ int tegra_dc_set_fb_mode(struct tegra_dc *dc,
        mode.h_front_porch = fbmode->right_margin;
        mode.v_front_porch = fbmode->lower_margin;
        mode.stereo_mode = stereo_mode;
+       mode.avi_m = 0;
        if (fbmode->flag & FB_FLAG_RATIO_16_9)
                mode.avi_m = TEGRA_DC_MODE_AVI_M_16_9;
        else if (fbmode->flag & FB_FLAG_RATIO_4_3)