summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/hdmi.c
diff options
context:
space:
mode:
authorJon Mayo <jmayo@nvidia.com>2011-02-10 15:35:38 -0800
committerVarun Colbert <vcolbert@nvidia.com>2011-04-14 21:24:37 -0700
commit3eabf0949204e0b658e57a662abbc326835c89b6 (patch)
tree434a5884846e38e28a858e0be3eac4a31e39b7b5 /drivers/video/tegra/dc/hdmi.c
parent53e48c3449b00dd2b052d09a88a818cd90c24ab7 (diff)
ARM: tegra: dc: hdmi drive strength changes
use pixel clock to configure HDMI interface signaling properties. These options are different depending on which SoC. Bug 786961 Bug 795251 (cherry picked from commit a59e2483a9f85a72186f51c124709401af554eb3) Change-Id: Ie5ef35fe03065d3e77831a0e1a2bbf8319d04125 Reviewed-on: http://git-master/r/27722 Reviewed-by: Jonathan Mayo <jmayo@nvidia.com> Tested-by: Jonathan Mayo <jmayo@nvidia.com> Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Reviewed-by: Jessica Liao <jeliao@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/hdmi.c')
-rw-r--r--drivers/video/tegra/dc/hdmi.c124
1 files changed, 75 insertions, 49 deletions
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c
index 476130f390dc..add3457705ca 100644
--- a/drivers/video/tegra/dc/hdmi.c
+++ b/drivers/video/tegra/dc/hdmi.c
@@ -178,6 +178,62 @@ const struct fb_videomode tegra_dc_hdmi_supported_modes[] = {
#endif
};
+/* table of electrical settings, must be in acending order. */
+struct tdms_config {
+ int pclk;
+ u32 pll0;
+ u32 pll1;
+ u32 pe_current; /* pre-emphasis */
+ u32 drive_current;
+};
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+const struct tdms_config tdms_config[] = {
+ { /* 480p modes */
+ .pclk = 27000000,
+ .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | SOR_PLL_RESISTORSEL |
+ SOR_PLL_VCOCAP(0) | SOR_PLL_TX_REG_LOAD(3),
+ .pll1 = SOR_PLL_TMDS_TERM_ENABLE,
+ .pe_current = PE_CURRENT0(PE_CURRENT_0_0_mA) |
+ PE_CURRENT1(PE_CURRENT_0_0_mA) |
+ PE_CURRENT2(PE_CURRENT_0_0_mA) |
+ PE_CURRENT3(PE_CURRENT_0_0_mA),
+ .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
+ },
+ { /* 720p modes */
+ .pclk = 74250000,
+ .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | SOR_PLL_RESISTORSEL |
+ SOR_PLL_VCOCAP(1) | SOR_PLL_TX_REG_LOAD(3),
+ .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
+ .pe_current = PE_CURRENT0(PE_CURRENT_6_0_mA) |
+ PE_CURRENT1(PE_CURRENT_6_0_mA) |
+ PE_CURRENT2(PE_CURRENT_6_0_mA) |
+ PE_CURRENT3(PE_CURRENT_6_0_mA),
+ .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
+ },
+ { /* 1080p modes */
+ .pclk = INT_MAX,
+ .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) | SOR_PLL_RESISTORSEL |
+ SOR_PLL_VCOCAP(1) | SOR_PLL_TX_REG_LOAD(3),
+ .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
+ .pe_current = PE_CURRENT0(PE_CURRENT_6_0_mA) |
+ PE_CURRENT1(PE_CURRENT_6_0_mA) |
+ PE_CURRENT2(PE_CURRENT_6_0_mA) |
+ PE_CURRENT3(PE_CURRENT_6_0_mA),
+ .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
+ DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
+ },
+};
+#endif
+
struct tegra_hdmi_audio_config {
unsigned pix_clock;
unsigned n;
@@ -976,18 +1032,29 @@ static void tegra_dc_hdmi_setup_audio_infoframe(struct tegra_dc *dc, bool dvi)
HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
}
+static void tegra_dc_hdmi_setup_tdms(struct tegra_dc_hdmi_data *hdmi,
+ const struct tdms_config *tc)
+{
+ tegra_hdmi_writel(hdmi, tc->pll0, HDMI_NV_PDISP_SOR_PLL0);
+ tegra_hdmi_writel(hdmi, tc->pll1, HDMI_NV_PDISP_SOR_PLL1);
+
+ tegra_hdmi_writel(hdmi, tc->pe_current, HDMI_NV_PDISP_PE_CURRENT);
+
+ tegra_hdmi_writel(hdmi,
+ tc->drive_current | DRIVE_CURRENT_FUSE_OVERRIDE,
+ HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
+}
+
static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
{
struct tegra_dc_hdmi_data *hdmi = tegra_dc_get_outdata(dc);
int pulse_start;
int dispclk_div_8_2;
- int pll0;
- int pll1;
- int ds;
int retries;
int rekey;
int err;
unsigned long val;
+ unsigned i;
/* enbale power, clocks, resets, etc. */
@@ -1078,54 +1145,13 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
tegra_dc_hdmi_setup_stereo_infoframe(dc);
/* TMDS CONFIG */
- pll0 = 0x200033f;
- pll1 = 0;
-
- pll0 &= ~SOR_PLL_PWR & ~SOR_PLL_VCOPD & ~SOR_PLL_PDBG & ~SOR_PLL_PDPORT & ~SOR_PLL_PULLDOWN &
- ~SOR_PLL_VCOCAP(~0) & ~SOR_PLL_ICHPMP(~0);
- pll0 |= SOR_PLL_RESISTORSEL;
-
- if (dc->mode.pclk <= 27000000)
- pll0 |= SOR_PLL_VCOCAP(0);
- else if (dc->mode.pclk <= 74250000)
- pll0 |= SOR_PLL_VCOCAP(1);
- else
- pll0 |= SOR_PLL_VCOCAP(3);
-
- if (dc->mode.h_active == 1080) {
- pll0 |= SOR_PLL_ICHPMP(1) | SOR_PLL_TX_REG_LOAD(3) |
- SOR_PLL_TX_REG_LOAD(3) | SOR_PLL_BG_V17_S(3);
- pll1 |= SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN;
- } else {
- pll0 |= SOR_PLL_ICHPMP(2);
- }
-
- tegra_hdmi_writel(hdmi, pll0, HDMI_NV_PDISP_SOR_PLL0);
- tegra_hdmi_writel(hdmi, pll1, HDMI_NV_PDISP_SOR_PLL1);
-
- if (pll1 & SOR_PLL_PE_EN) {
- tegra_hdmi_writel(hdmi,
- PE_CURRENT0(0xf) |
- PE_CURRENT1(0xf) |
- PE_CURRENT2(0xf) |
- PE_CURRENT3(0xf),
- HDMI_NV_PDISP_PE_CURRENT);
+ for (i = 0; i < ARRAY_SIZE(tdms_config); i++) {
+ if (dc->mode.pclk <= tdms_config[i].pclk) {
+ tegra_dc_hdmi_setup_tdms(hdmi, &tdms_config[i]);
+ break;
+ }
}
- /* enable SOR */
- if (dc->mode.h_active == 1080)
- ds = DRIVE_CURRENT_13_500_mA;
- else
- ds = DRIVE_CURRENT_5_250_mA;
-
- tegra_hdmi_writel(hdmi,
- DRIVE_CURRENT_LANE0(ds) |
- DRIVE_CURRENT_LANE1(ds) |
- DRIVE_CURRENT_LANE2(ds) |
- DRIVE_CURRENT_LANE3(ds) |
- DRIVE_CURRENT_FUSE_OVERRIDE,
- HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
-
tegra_hdmi_writel(hdmi,
SOR_SEQ_CTL_PU_PC(0) |
SOR_SEQ_PU_PC_ALT(0) |