ARM: tegra: emc: Place BGBIAS pads in DPD
Alex Waterman [Thu, 27 Jun 2013 00:02:13 +0000 (17:02 -0700)]
This change puts the BGBIAS pad into and out of DPD depending on the
triggering mode for the external IO pads.

Bug 1217312

Reviewed-on: http://git-master/r/242651
(cherry picked from commit e67fcda76e6cfe3e3f3f5b767aab1f60ed425880)
Change-Id: Ibd715fc8a5209d6364bbb6e8ac90016ff3babdaa
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: http://git-master/r/248541
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>

arch/arm/mach-tegra/tegra14_emc.c

index 8bee968..5afc6bb 100644 (file)
@@ -80,6 +80,12 @@ enum {
 #define EMC_CLK_LOW_JITTER_ENABLE      (0x1 << 31)
 #define        EMC_CLK_MC_SAME_FREQ            (0x1 << 16)
 
+#define PMC_IO_DPD2_REQ                        0x1C0
+#define PMC_IO_DPD2_REQ_CODE_SHIFT     30
+#define PMC_IO_DPD2_REQ_CODE_DPD_OFF   0x1
+#define PMC_IO_DPD2_REQ_CODE_DPD_ON    0x2
+#define PMC_IO_DPD2_REQ_DISC_BIAS      (0x1 << 27)
+
 /* FIXME: actual Tegar14 list */
 #define BURST_REG_LIST \
        DEFINE_REG(TEGRA_EMC_BASE, EMC_RC),                     \
@@ -291,6 +297,7 @@ static void __iomem *emc1_base = IO_ADDRESS(TEGRA_EMC1_BASE);
 #endif
 static void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE);
 static void __iomem *clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+static void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
 
 static inline void emc_writel(u32 val, unsigned long addr)
 {
@@ -641,7 +648,7 @@ static noinline void emc_set_clock(const struct tegra14_emc_table *next_timing,
        int i, dll_change, pre_wait;
        bool dyn_sref_enabled, zcal_long;
 
-       u32 dll_override, emc_cfg_dig_dll;
+       u32 dll_override, emc_cfg_dig_dll, pmc_dpd;
        u32 t_start, t_diff;
 
        u32 emc_cfg_reg = emc_readl(EMC_CFG);
@@ -676,6 +683,11 @@ static noinline void emc_set_clock(const struct tegra14_emc_table *next_timing,
        if (dqs_preset(next_timing, last_timing)) {
                if (pre_wait < 30)
                        pre_wait = 30; /* (T148) 30us+ for dqs vref settled */
+               /* Take the DISC pads out of DPD. */
+               pmc_dpd = (PMC_IO_DPD2_REQ_CODE_DPD_OFF <<
+                          PMC_IO_DPD2_REQ_CODE_SHIFT);
+               writel(pmc_dpd | PMC_IO_DPD2_REQ_DISC_BIAS,
+                      pmc_base + PMC_IO_DPD2_REQ);
        }
        emc_timing_update();
        t_start = tegra_read_usec_raw();
@@ -785,6 +797,16 @@ static noinline void emc_set_clock(const struct tegra14_emc_table *next_timing,
                wmb();
        }
 
+       /* 14.3 Check if we are entering schmit mode. If we are, then DPD can
+          be requested for the BG BIAS cells of the DISC pads. */
+       if (~next_timing->burst_regs[EMC_XM2DQSPADCTRL2_INDEX] &
+           EMC_XM2DQSPADCTRL2_RX_FT_REC_ENABLE) {
+               pmc_dpd = (PMC_IO_DPD2_REQ_CODE_DPD_ON <<
+                          PMC_IO_DPD2_REQ_CODE_SHIFT);
+               writel(pmc_dpd | PMC_IO_DPD2_REQ_DISC_BIAS,
+                      pmc_base + PMC_IO_DPD2_REQ);
+       }
+
        /* 15. restore auto-cal. On t148, this is just a reprogramming - its
           already enabled during the clock change itself. */
        emc_writel(next_timing->emc_acal_interval, EMC_AUTO_CAL_INTERVAL);