aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common/cpufreq.c')
-rw-r--r--arch/blackfin/mach-common/cpufreq.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index 2e6eefd812f4..6e87dc13f6bf 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/clk.h>
13#include <linux/cpufreq.h> 14#include <linux/cpufreq.h>
14#include <linux/fs.h> 15#include <linux/fs.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
@@ -17,6 +18,7 @@
17#include <asm/time.h> 18#include <asm/time.h>
18#include <asm/dpmc.h> 19#include <asm/dpmc.h>
19 20
21
20/* this is the table of CCLK frequencies, in Hz */ 22/* this is the table of CCLK frequencies, in Hz */
21/* .index is the entry in the auxiliary dpm_state_table[] */ 23/* .index is the entry in the auxiliary dpm_state_table[] */
22static struct cpufreq_frequency_table bfin_freq_table[] = { 24static struct cpufreq_frequency_table bfin_freq_table[] = {
@@ -67,12 +69,22 @@ static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk)
67#else 69#else
68 min_cclk = sclk; 70 min_cclk = sclk;
69#endif 71#endif
72
73#ifndef CONFIG_BF60x
70 csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); 74 csel = ((bfin_read_PLL_DIV() & CSEL) >> 4);
75#else
76 csel = bfin_read32(CGU0_DIV) & 0x1F;
77#endif
71 78
72 for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { 79 for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
73 bfin_freq_table[index].frequency = cclk >> index; 80 bfin_freq_table[index].frequency = cclk >> index;
81#ifndef CONFIG_BF60x
74 dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ 82 dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
75 dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; 83 dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1;
84#else
85 dpm_state_table[index].csel = csel;
86 dpm_state_table[index].tscale = TIME_SCALE >> index;
87#endif
76 88
77 pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", 89 pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
78 bfin_freq_table[index].frequency, 90 bfin_freq_table[index].frequency,
@@ -99,14 +111,34 @@ static unsigned int bfin_getfreq_khz(unsigned int cpu)
99 return get_cclk() / 1000; 111 return get_cclk() / 1000;
100} 112}
101 113
114#ifdef CONFIG_BF60x
115unsigned long cpu_set_cclk(int cpu, unsigned long new)
116{
117 struct clk *clk;
118 int ret;
119
120 clk = clk_get(NULL, "CCLK");
121 if (IS_ERR(clk))
122 return -ENODEV;
123
124 ret = clk_set_rate(clk, new);
125 clk_put(clk);
126 return ret;
127}
128#endif
129
102static int bfin_target(struct cpufreq_policy *poli, 130static int bfin_target(struct cpufreq_policy *poli,
103 unsigned int target_freq, unsigned int relation) 131 unsigned int target_freq, unsigned int relation)
104{ 132{
105 unsigned int index, plldiv, cpu; 133#ifndef CONFIG_BF60x
134 unsigned int plldiv;
135#endif
136 unsigned int index, cpu;
106 unsigned long flags, cclk_hz; 137 unsigned long flags, cclk_hz;
107 struct cpufreq_freqs freqs; 138 struct cpufreq_freqs freqs;
108 static unsigned long lpj_ref; 139 static unsigned long lpj_ref;
109 static unsigned int lpj_ref_freq; 140 static unsigned int lpj_ref_freq;
141 int ret = 0;
110 142
111#if defined(CONFIG_CYCLES_CLOCKSOURCE) 143#if defined(CONFIG_CYCLES_CLOCKSOURCE)
112 cycles_t cycles; 144 cycles_t cycles;
@@ -134,9 +166,17 @@ static int bfin_target(struct cpufreq_policy *poli,
134 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 166 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
135 if (cpu == CPUFREQ_CPU) { 167 if (cpu == CPUFREQ_CPU) {
136 flags = hard_local_irq_save(); 168 flags = hard_local_irq_save();
169#ifndef CONFIG_BF60x
137 plldiv = (bfin_read_PLL_DIV() & SSEL) | 170 plldiv = (bfin_read_PLL_DIV() & SSEL) |
138 dpm_state_table[index].csel; 171 dpm_state_table[index].csel;
139 bfin_write_PLL_DIV(plldiv); 172 bfin_write_PLL_DIV(plldiv);
173#else
174 ret = cpu_set_cclk(cpu, freqs.new * 1000);
175 if (ret != 0) {
176 pr_debug("cpufreq set freq failed %d\n", ret);
177 break;
178 }
179#endif
140 on_each_cpu(bfin_adjust_core_timer, &index, 1); 180 on_each_cpu(bfin_adjust_core_timer, &index, 1);
141#if defined(CONFIG_CYCLES_CLOCKSOURCE) 181#if defined(CONFIG_CYCLES_CLOCKSOURCE)
142 cycles = get_cycles(); 182 cycles = get_cycles();
@@ -161,7 +201,7 @@ static int bfin_target(struct cpufreq_policy *poli,
161 } 201 }
162 202
163 pr_debug("cpufreq: done\n"); 203 pr_debug("cpufreq: done\n");
164 return 0; 204 return ret;
165} 205}
166 206
167static int bfin_verify_speed(struct cpufreq_policy *policy) 207static int bfin_verify_speed(struct cpufreq_policy *policy)
@@ -169,7 +209,7 @@ static int bfin_verify_speed(struct cpufreq_policy *policy)
169 return cpufreq_frequency_table_verify(policy, bfin_freq_table); 209 return cpufreq_frequency_table_verify(policy, bfin_freq_table);
170} 210}
171 211
172static int __init __bfin_cpu_init(struct cpufreq_policy *policy) 212static int __bfin_cpu_init(struct cpufreq_policy *policy)
173{ 213{
174 214
175 unsigned long cclk, sclk; 215 unsigned long cclk, sclk;