summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJames Wylder <james.wylder@motorola.com>2011-06-21 12:51:37 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:37:11 -0800
commit1dd8408b6a558eef02cb1c11981e1bb12efeecaa (patch)
treeba2641b5398f59c7de3cedc43ec923dd6abe2e18 /arch
parent3c21ede5c77eb776e7bd528274ab79e30c4bf274 (diff)
ARM: tegra: small optimizations for table lookups
Optimization that primarily addresses when cpu frequency is low but a high memory bandwidth is needed. Change-Id: I4f800c2368191c744aefd9f83eb96e4c108dbcc3 Signed-off-by: James Wylder <james.wylder@motorola.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 3fd81e0e3e01..f1ac82ad5c15 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -41,6 +41,9 @@ static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
static const struct tegra_emc_table *tegra_emc_table;
static int tegra_emc_table_size;
+static unsigned long tegra_emc_max_bus_rate; /* 2 * 1000 * maximum emc_clock rate */
+static unsigned long tegra_emc_min_bus_rate; /* 2 * 1000 * minimum emc_clock rate */
+
static inline void emc_writel(u32 val, unsigned long addr)
{
writel(val, emc + addr);
@@ -142,6 +145,14 @@ long tegra_emc_round_rate(unsigned long rate)
if (!emc_enable)
return -EINVAL;
+ if (rate >= tegra_emc_max_bus_rate) {
+ best = tegra_emc_table_size - 1;
+ goto round_out;
+ } else if (rate <= tegra_emc_min_bus_rate) {
+ best = 0;
+ goto round_out;
+ }
+
pr_debug("%s: %lu\n", __func__, rate);
/*
@@ -160,7 +171,7 @@ long tegra_emc_round_rate(unsigned long rate)
if (best < 0)
return -EINVAL;
-
+round_out:
pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
return tegra_emc_table[best].rate * 2 * 1000;
@@ -188,11 +199,11 @@ int tegra_emc_set_rate(unsigned long rate)
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++)
+ for (i = tegra_emc_table_size - 1; i >= 0; i--)
if (tegra_emc_table[i].rate == rate)
break;
- if (i >= tegra_emc_table_size)
+ if (i < 0)
return -EINVAL;
pr_debug("%s: setting to %lu\n", __func__, rate);
@@ -246,6 +257,10 @@ void tegra_init_emc(const struct tegra_emc_chip *chips, int chips_size)
chips[chip_matched].description);
tegra_emc_table = chips[chip_matched].table;
tegra_emc_table_size = chips[chip_matched].table_size;
+
+ tegra_emc_min_bus_rate = tegra_emc_table[0].rate * 2 * 1000;
+ tegra_emc_max_bus_rate = tegra_emc_table[tegra_emc_table_size - 1].rate * 2 * 1000;
+
} else {
pr_err("%s: Memory not recognized, memory scaling disabled\n",
__func__);