summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-03-18 00:01:02 -0700
committerSimone Willett <swillett@nvidia.com>2012-05-21 18:47:20 -0700
commitdc04b051470f72fa3503be2503b8eed002881b1c (patch)
treeac4da616c45a4296f208379aec0cf77eee00afc2 /arch
parenta04b69f8a6241a0bdf2b9c93f2c7b2bca7520d5c (diff)
ARM: tegra: clock: Account for memory BW efficiency
Account for memory efficiency when processing requests from Tegra3 EMC shared bandwidth users. Do not round requests from these users until they are aggregated. The respective debugfs node: /d/tegra_emc/efficiency (in %). Bug 952739 Signed-off-by: Alex Frid <afrid@nvidia.com> (cherry picked from commit 86929087f68c4366d6179101eb9a6a6473a4f084) Change-Id: I4acdd89f44de1401ce5dad8fc4936932df014458 Reviewed-on: http://git-master/r/103499 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Jihoon Bang <jbang@nvidia.com> Reviewed-by: Jon Mayo <jmayo@nvidia.com> GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/tegra3_clocks.c17
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.c22
-rw-r--r--arch/arm/mach-tegra/tegra3_emc.h2
3 files changed, 40 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c
index acb386a5219e..2dfdb1db39b7 100644
--- a/arch/arm/mach-tegra/tegra3_clocks.c
+++ b/arch/arm/mach-tegra/tegra3_clocks.c
@@ -3011,7 +3011,8 @@ static int tegra3_clk_shared_bus_update(struct clk *bus)
(c->u.shared_bus_user.mode == SHARED_CEILING)) {
switch (c->u.shared_bus_user.mode) {
case SHARED_BW:
- bw += c->u.shared_bus_user.rate;
+ if (bw < bus->max_rate)
+ bw += c->u.shared_bus_user.rate;
break;
case SHARED_CEILING:
ceiling = min(c->u.shared_bus_user.rate,
@@ -3024,6 +3025,16 @@ static int tegra3_clk_shared_bus_update(struct clk *bus)
}
}
}
+
+ if (bw) {
+ if (bus->flags & PERIPH_EMC_ENB) {
+ bw = tegra_emc_bw_efficiency ?
+ (bw / tegra_emc_bw_efficiency) : bus->max_rate;
+ bw = (bw < bus->max_rate / 100) ?
+ (bw * 100) : bus->max_rate;
+ }
+ bw = clk_round_rate_locked(bus, bw);
+ }
rate = min(max(rate, bw), ceiling);
old_rate = clk_get_rate_locked(bus);
@@ -3072,6 +3083,10 @@ static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
if (c->u.shared_bus_user.mode == SHARED_AUTO)
rate = 0;
+ /* BW users should not be rounded until aggregated */
+ if (c->u.shared_bus_user.mode == SHARED_BW)
+ return rate;
+
return clk_round_rate(c->parent, rate);
}
diff --git a/arch/arm/mach-tegra/tegra3_emc.c b/arch/arm/mach-tegra/tegra3_emc.c
index 83136e3c08d1..2b19848b04f2 100644
--- a/arch/arm/mach-tegra/tegra3_emc.c
+++ b/arch/arm/mach-tegra/tegra3_emc.c
@@ -45,6 +45,8 @@ static bool emc_enable;
#endif
module_param(emc_enable, bool, 0644);
+u8 tegra_emc_bw_efficiency = 35;
+
#define EMC_MIN_RATE_DDR3 25500000
#define EMC_STATUS_UPDATE_TIMEOUT 100
#define TEGRA_EMC_TABLE_MAX_SIZE 16
@@ -1267,6 +1269,22 @@ static int eack_state_set(void *data, u64 val)
DEFINE_SIMPLE_ATTRIBUTE(eack_state_fops, eack_state_get,
eack_state_set, "%llu\n");
+static int efficiency_get(void *data, u64 *val)
+{
+ *val = tegra_emc_bw_efficiency;
+ return 0;
+}
+static int efficiency_set(void *data, u64 val)
+{
+ tegra_emc_bw_efficiency = (val > 100) ? 100 : val;
+ if (emc)
+ tegra_clk_shared_bus_update(emc);
+
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(efficiency_fops, efficiency_get,
+ efficiency_set, "%llu\n");
+
static int __init tegra_emc_debug_init(void)
{
if (!tegra_emc_table)
@@ -1292,6 +1310,10 @@ static int __init tegra_emc_debug_init(void)
"eack_state", S_IRUGO | S_IWUGO, emc_debugfs_root, NULL, &eack_state_fops))
goto err_out;
+ if (!debugfs_create_file("efficiency", S_IRUGO | S_IWUSR,
+ emc_debugfs_root, NULL, &efficiency_fops))
+ goto err_out;
+
return 0;
err_out:
diff --git a/arch/arm/mach-tegra/tegra3_emc.h b/arch/arm/mach-tegra/tegra3_emc.h
index 03bde19c4a7b..185d77762da2 100644
--- a/arch/arm/mach-tegra/tegra3_emc.h
+++ b/arch/arm/mach-tegra/tegra3_emc.h
@@ -27,6 +27,8 @@
#define TEGRA_EMC_BRIDGE_RATE_MIN 300000000
#define TEGRA_EMC_BRIDGE_MVOLTS_MIN 1200
+extern u8 tegra_emc_bw_efficiency;
+
struct tegra_emc_table {
u8 rev;
unsigned long rate;