|
@@ -51,6 +51,7 @@ static struct cpufreq_frequency_table freq_table[] = {
|
|
|
#define NUM_CPUS 2
|
|
|
|
|
|
static struct clk *cpu_clk;
|
|
|
+static struct clk *emc_clk;
|
|
|
|
|
|
static unsigned long target_cpu_speed[NUM_CPUS];
|
|
|
static DEFINE_MUTEX(tegra_cpu_lock);
|
|
@@ -83,6 +84,17 @@ static int tegra_update_cpu_speed(unsigned long rate)
|
|
|
if (freqs.old == freqs.new)
|
|
|
return ret;
|
|
|
|
|
|
+ /*
|
|
|
+ * Vote on memory bus frequency based on cpu frequency
|
|
|
+ * This sets the minimum frequency, display or avp may request higher
|
|
|
+ */
|
|
|
+ if (rate >= 816000)
|
|
|
+ clk_set_rate(emc_clk, 600000000); /* cpu 816 MHz, emc max */
|
|
|
+ else if (rate >= 456000)
|
|
|
+ clk_set_rate(emc_clk, 300000000); /* cpu 456 MHz, emc 150Mhz */
|
|
|
+ else
|
|
|
+ clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */
|
|
|
+
|
|
|
for_each_online_cpu(freqs.cpu)
|
|
|
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
|
|
|
|
@@ -173,6 +185,13 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
|
|
|
if (IS_ERR(cpu_clk))
|
|
|
return PTR_ERR(cpu_clk);
|
|
|
|
|
|
+ emc_clk = clk_get_sys("cpu", "emc");
|
|
|
+ if (IS_ERR(emc_clk)) {
|
|
|
+ clk_put(cpu_clk);
|
|
|
+ return PTR_ERR(emc_clk);
|
|
|
+ }
|
|
|
+
|
|
|
+ clk_enable(emc_clk);
|
|
|
clk_enable(cpu_clk);
|
|
|
|
|
|
cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
|
@@ -195,6 +214,8 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
|
|
|
static int tegra_cpu_exit(struct cpufreq_policy *policy)
|
|
|
{
|
|
|
cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
|
|
+ clk_disable(emc_clk);
|
|
|
+ clk_put(emc_clk);
|
|
|
clk_put(cpu_clk);
|
|
|
return 0;
|
|
|
}
|