diff options
author | Alex Frid <afrid@nvidia.com> | 2012-03-18 00:01:02 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-05-21 18:47:20 -0700 |
commit | dc04b051470f72fa3503be2503b8eed002881b1c (patch) | |
tree | ac4da616c45a4296f208379aec0cf77eee00afc2 /arch | |
parent | a04b69f8a6241a0bdf2b9c93f2c7b2bca7520d5c (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.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_emc.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_emc.h | 2 |
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; |