diff options
author | Jinyoung Park <jinyoungp@nvidia.com> | 2013-08-20 17:06:28 +0900 |
---|---|---|
committer | Gabby Lee <galee@nvidia.com> | 2013-08-25 04:49:10 -0700 |
commit | 652a0736dbb6b24cc841d70c4ee3e5f3cfcec57b (patch) | |
tree | 0f68d10c676bd3861a3da37d9c21a7556d8281a6 /arch/arm/mach-tegra | |
parent | bdb8424de563a01dd37e53486c2297b4aa183cc7 (diff) |
ARM: tegra: clock: Support EMC freq min/max constraints by PM QoS
Support EMC frequency min/max constraints by PM QoS
Bug 1346293
Change-Id: I6987235c72921fdf8229a2411eb212dd7ffa66f0
Signed-off-by: Jinyoung Park <jinyoungp@nvidia.com>
Reviewed-on: http://git-master/r/263784
GVS: Gerrit_Virtual_Submit
Reviewed-by: Gabby Lee <galee@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/clock.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra11_clocks.c | 8 |
2 files changed, 38 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index 7e0428dc0faa..29de4d14f743 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -32,6 +32,7 @@ #include <linux/bitops.h> #include <linux/io.h> #include <linux/bug.h> +#include <linux/pm_qos.h> #include <trace/events/power.h> #include <mach/clk.h> @@ -988,6 +989,27 @@ static int __init tegra_dfll_cpu_start(void) return 0; } +static int emc_freq_notify(struct notifier_block *nb, unsigned long val, void *p); + +static struct notifier_block min_emc_freq_notifier = { + .notifier_call = emc_freq_notify, +}; +static struct notifier_block max_emc_freq_notifier = { + .notifier_call = emc_freq_notify, +}; + +static int emc_freq_notify(struct notifier_block *nb, unsigned long val, + void *p) +{ + struct clk *c = tegra_get_clock_by_name("emc"); + + pr_debug("%s: PM QoS %s %lu\n", + __func__, nb == &min_emc_freq_notifier ? "min" : "max", val); + tegra_clk_shared_bus_update(c); + + return NOTIFY_OK; +} + static int __init tegra_clk_late_init(void) { tegra_init_disable_boot_clocks(); /* must before dvfs late init */ @@ -995,6 +1017,14 @@ static int __init tegra_clk_late_init(void) tegra_dfll_cpu_start(); /* after successful dvfs init only */ tegra_sync_cpu_clock(); /* after attempt to get dfll ready */ tegra_recalculate_cpu_edp_limits(); + + if (pm_qos_add_notifier(PM_QOS_EMC_FREQ_MIN, &min_emc_freq_notifier)) + WARN(1, "%s: Failed to register min emc freq PM QoS notifier\n", + __func__); + if(pm_qos_add_notifier(PM_QOS_EMC_FREQ_MAX, &max_emc_freq_notifier)) + WARN(1, "%s: Failed to register max emc freq PM QoS notifier\n", + __func__); + return 0; } late_initcall(tegra_clk_late_init); diff --git a/arch/arm/mach-tegra/tegra11_clocks.c b/arch/arm/mach-tegra/tegra11_clocks.c index a3c9cc16a163..a62843716060 100644 --- a/arch/arm/mach-tegra/tegra11_clocks.c +++ b/arch/arm/mach-tegra/tegra11_clocks.c @@ -29,6 +29,7 @@ #include <linux/cpufreq.h> #include <linux/syscore_ops.h> #include <linux/platform_device.h> +#include <linux/pm_qos.h> #include <asm/clkdev.h> @@ -5217,6 +5218,13 @@ static unsigned long tegra11_clk_shared_bus_update(struct clk *bus, unsigned long ceiling = bus->max_rate; u32 usage_flags = 0; + if (bus->flags & PERIPH_EMC_ENB) { + rate = max_t(unsigned long, rate, + pm_qos_request(PM_QOS_EMC_FREQ_MIN) * 1000); + ceiling = min_t(unsigned long, ceiling, + pm_qos_request(PM_QOS_EMC_FREQ_MAX) * 1000); + } + list_for_each_entry(c, &bus->shared_bus_list, u.shared_bus_user.node) { /* |