summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-02-14 19:14:36 -0800
committerVarun Colbert <vcolbert@nvidia.com>2012-03-13 15:29:49 -0700
commitde3174e91b90058cdf62a30b804d3637046937c9 (patch)
tree12a08353231dd9a596b81742e8d6e7f014ec6b9f
parent57bc87784142f4aa06329b54ca131a70a58417b2 (diff)
ARM: tegra: clock: Disable early-ack during EMC clock change
Bug 935079 Signed-off-by: Alex Frid <afrid@nvidia.com> (cherry picked from commit edf6b3ed22c4f803bf13d1bf6316ffb01c8946dc) Change-Id: Ifd155a66469e9463da89639b6577c1f90972f4ac Reviewed-on: http://git-master/r/89347 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.c18
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.h1
2 files changed, 19 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c
index 1a6dd8194328..e766a3e51e8c 100644
--- a/arch/arm/mach-tegra/tegra3_emc.c
+++ b/arch/arm/mach-tegra/tegra3_emc.c
@@ -30,6 +30,7 @@
#include <linux/seq_file.h>
#include <asm/cputime.h>
+#include <asm/cacheflush.h>
#include <mach/iomap.h>
@@ -302,6 +303,17 @@ static inline void set_mc_arbiter_limits(void)
}
}
+static inline void disable_early_ack(u32 mc_override)
+{
+ static u32 override_val;
+
+ override_val = mc_override & (~MC_EMEM_ARB_OVERRIDE_EACK_MASK);
+ mc_writel(override_val, MC_EMEM_ARB_OVERRIDE);
+ __cpuc_flush_dcache_area(&override_val, sizeof(override_val));
+ outer_clean_range(__pa(&override_val), __pa(&override_val + 1));
+ override_val |= mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK;
+}
+
static inline bool dqs_preset(const struct tegra_emc_table *next_timing,
const struct tegra_emc_table *last_timing)
{
@@ -457,6 +469,7 @@ static noinline void emc_set_clock(const struct tegra_emc_table *next_timing,
int i, dll_change, pre_wait;
bool dyn_sref_enabled, vref_cal_toggle, qrst_used, zcal_long;
+ u32 mc_override = mc_readl(MC_EMEM_ARB_OVERRIDE);
u32 emc_cfg_reg = emc_readl(EMC_CFG);
u32 emc_dbg_reg = emc_readl(EMC_DBG);
@@ -482,6 +495,8 @@ static noinline void emc_set_clock(const struct tegra_emc_table *next_timing,
/* 2.25 update MC arbiter settings */
set_mc_arbiter_limits();
+ if (mc_override & MC_EMEM_ARB_OVERRIDE_EACK_MASK)
+ disable_early_ack(mc_override);
/* 2.5 check dq/dqs vref delay */
if (dqs_preset(next_timing, last_timing)) {
@@ -600,6 +615,9 @@ static noinline void emc_set_clock(const struct tegra_emc_table *next_timing,
/* 18. update restored timing */
udelay(2);
emc_timing_update();
+
+ /* 18.a restore early ACK */
+ mc_writel(mc_override, MC_EMEM_ARB_OVERRIDE);
}
static inline void emc_get_timing(struct tegra_emc_table *timing)
diff --git a/arch/arm/mach-tegra/tegra3_emc.h b/arch/arm/mach-tegra/tegra3_emc.h
index cc0abc680166..f076dcd67714 100644
--- a/arch/arm/mach-tegra/tegra3_emc.h
+++ b/arch/arm/mach-tegra/tegra3_emc.h
@@ -273,6 +273,7 @@ enum {
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
#define MC_EMEM_ARB_OVERRIDE 0xe8
+#define MC_EMEM_ARB_OVERRIDE_EACK_MASK (0x3 << 0)
#define MC_TIMING_CONTROL 0xfc
#define MC_RESERVED_RSV 0x3fc