aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/cpu-tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/cpu-tegra.c')
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index ceb52db1e2f1..627bf0f4262e 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -49,6 +49,8 @@ static struct cpufreq_frequency_table freq_table[] = {
49#define NUM_CPUS 2 49#define NUM_CPUS 2
50 50
51static struct clk *cpu_clk; 51static struct clk *cpu_clk;
52static struct clk *pll_x_clk;
53static struct clk *pll_p_clk;
52static struct clk *emc_clk; 54static struct clk *emc_clk;
53 55
54static unsigned long target_cpu_speed[NUM_CPUS]; 56static unsigned long target_cpu_speed[NUM_CPUS];
@@ -71,6 +73,42 @@ static unsigned int tegra_getspeed(unsigned int cpu)
71 return rate; 73 return rate;
72} 74}
73 75
76static int tegra_cpu_clk_set_rate(unsigned long rate)
77{
78 int ret;
79
80 /*
81 * Take an extra reference to the main pll so it doesn't turn
82 * off when we move the cpu off of it
83 */
84 clk_prepare_enable(pll_x_clk);
85
86 ret = clk_set_parent(cpu_clk, pll_p_clk);
87 if (ret) {
88 pr_err("Failed to switch cpu to clock pll_p\n");
89 goto out;
90 }
91
92 if (rate == clk_get_rate(pll_p_clk))
93 goto out;
94
95 ret = clk_set_rate(pll_x_clk, rate);
96 if (ret) {
97 pr_err("Failed to change pll_x to %lu\n", rate);
98 goto out;
99 }
100
101 ret = clk_set_parent(cpu_clk, pll_x_clk);
102 if (ret) {
103 pr_err("Failed to switch cpu to clock pll_x\n");
104 goto out;
105 }
106
107out:
108 clk_disable_unprepare(pll_x_clk);
109 return ret;
110}
111
74static int tegra_update_cpu_speed(unsigned long rate) 112static int tegra_update_cpu_speed(unsigned long rate)
75{ 113{
76 int ret = 0; 114 int ret = 0;
@@ -101,7 +139,7 @@ static int tegra_update_cpu_speed(unsigned long rate)
101 freqs.old, freqs.new); 139 freqs.old, freqs.new);
102#endif 140#endif
103 141
104 ret = clk_set_rate(cpu_clk, freqs.new * 1000); 142 ret = tegra_cpu_clk_set_rate(freqs.new * 1000);
105 if (ret) { 143 if (ret) {
106 pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n", 144 pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
107 freqs.new); 145 freqs.new);
@@ -183,6 +221,14 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
183 if (IS_ERR(cpu_clk)) 221 if (IS_ERR(cpu_clk))
184 return PTR_ERR(cpu_clk); 222 return PTR_ERR(cpu_clk);
185 223
224 pll_x_clk = clk_get_sys(NULL, "pll_x");
225 if (IS_ERR(pll_x_clk))
226 return PTR_ERR(pll_x_clk);
227
228 pll_p_clk = clk_get_sys(NULL, "pll_p");
229 if (IS_ERR(pll_p_clk))
230 return PTR_ERR(pll_p_clk);
231
186 emc_clk = clk_get_sys("cpu", "emc"); 232 emc_clk = clk_get_sys("cpu", "emc");
187 if (IS_ERR(emc_clk)) { 233 if (IS_ERR(emc_clk)) {
188 clk_put(cpu_clk); 234 clk_put(cpu_clk);