summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorSang-Hun Lee <sanlee@nvidia.com>2012-06-20 16:16:57 -0700
committerVarun Wadekar <vwadekar@nvidia.com>2012-07-12 10:12:16 +0530
commita6f1c5312b99deb8b69f7878129f4993f44bd04f (patch)
tree8e3f1eea362ff25a6b7795e742cdafd04aabd702 /arch/arm
parentd4556687b3b5518924e17324c8dd3f2496ec1fd4 (diff)
ARM: tegra: emc: add reference counting to early ack disablement
Bug 995950 Signed-off-by: Sang-Hun Lee <sanlee@nvidia.com> Reviewed-on: http://git-master/r/110190 (cherry picked from commit cbfc31fb126cd651157125d1785135eced6587dd) Change-Id: I44eb889235db82b0efda238b87be5612425afb9d Reviewed-on: http://git-master/r/110978 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h18
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.c39
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.h3
3 files changed, 51 insertions, 9 deletions
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index 6792962e2eca..d5846c548350 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -6,7 +6,7 @@
* Author:
* Erik Gilling <konkers@google.com>
*
- * Copyright (C) 2010-2011 NVIDIA Corporation
+ * Copyright (C) 2010-2012 NVIDIA Corporation
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -41,7 +41,23 @@ void tegra_periph_reset_assert(struct clk *c);
int tegra_dvfs_set_rate(struct clk *c, unsigned long rate);
unsigned long clk_get_rate_all_locked(struct clk *c);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
+
+static inline int tegra_emc_enable_eack(void) {
+ return 0;
+}
+
+static inline int tegra_emc_disable_eack(void) {
+ return 0;
+}
+#else
+static inline void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
+{
+}
+int tegra_emc_enable_eack(void);
+int tegra_emc_disable_eack(void);
+#endif
int tegra_dvfs_rail_disable_by_name(const char *reg_id);
int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
int tegra_register_clk_rate_notifier(struct clk *c, struct notifier_block *nb);
diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c
index c8bbafe368f9..cfe7e9d8ed34 100644
--- a/arch/arm/mach-tegra/tegra3_emc.c
+++ b/arch/arm/mach-tegra/tegra3_emc.c
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/tegra3_emc.c
*
- * Copyright (C) 2011 NVIDIA Corporation
+ * Copyright (C) 2012 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1172,24 +1172,51 @@ int tegra_emc_set_over_temp_state(unsigned long state)
return 0;
}
-int tegra_emc_set_eack_state(unsigned long state)
+/* non-zero state value will reduce eack_disable_refcnt */
+static int tegra_emc_set_eack_state(unsigned long state)
{
unsigned long flags;
u32 mc_override;
+ static int eack_disable_refcnt = 0;
spin_lock_irqsave(&emc_access_lock, flags);
- mc_override = mc_readl(MC_EMEM_ARB_OVERRIDE);
-
- if (state)
+ /*
+ * refcnt > 0 implies there is at least one client requiring eack
+ * disabled. refcnt of 0 implies eack is enabled
+ */
+ if (eack_disable_refcnt == 1 && state) {
+ mc_override = mc_readl(MC_EMEM_ARB_OVERRIDE);
enable_early_ack(mc_override);
- else
+ } else if (eack_disable_refcnt == 0 && !state) {
+ mc_override = mc_readl(MC_EMEM_ARB_OVERRIDE);
disable_early_ack(mc_override);
+ }
+
+ if (state) {
+ if (likely(eack_disable_refcnt > 0)) {
+ --eack_disable_refcnt;
+ } else {
+ pr_err("%s: Ignored a request to underflow eack "
+ "disable reference counter\n",__func__);
+ dump_stack();
+ }
+ } else {
+ ++eack_disable_refcnt;
+ }
spin_unlock_irqrestore(&emc_access_lock, flags);
return 0;
}
+int tegra_emc_enable_eack(void) {
+ return tegra_emc_set_eack_state(1);
+}
+
+int tegra_emc_disable_eack(void) {
+ return tegra_emc_set_eack_state(0);
+}
+
#ifdef CONFIG_DEBUG_FS
static struct dentry *emc_debugfs_root;
diff --git a/arch/arm/mach-tegra/tegra3_emc.h b/arch/arm/mach-tegra/tegra3_emc.h
index 185d77762da2..f59654295ba4 100644
--- a/arch/arm/mach-tegra/tegra3_emc.h
+++ b/arch/arm/mach-tegra/tegra3_emc.h
@@ -1,7 +1,7 @@
/*
* arch/arm/mach-tegra/tegra3_emc.h
*
- * Copyright (C) 2011 NVIDIA Corporation
+ * Copyright (C) 2012 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -61,7 +61,6 @@ void tegra_emc_dram_type_init(struct clk *c);
int tegra_emc_get_dram_type(void);
int tegra_emc_get_dram_temperature(void);
int tegra_emc_set_over_temp_state(unsigned long state);
-int tegra_emc_set_eack_state(unsigned long state);
#ifdef CONFIG_PM_SLEEP
void tegra_mc_timing_restore(void);