diff options
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/mach-common/cpufreq.c | 79 |
1 files changed, 34 insertions, 45 deletions
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index d88bd31319e6..995511e80bef 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c | |||
@@ -127,13 +127,13 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new) | |||
127 | } | 127 | } |
128 | #endif | 128 | #endif |
129 | 129 | ||
130 | static int bfin_target(struct cpufreq_policy *poli, | 130 | static int bfin_target(struct cpufreq_policy *policy, |
131 | unsigned int target_freq, unsigned int relation) | 131 | unsigned int target_freq, unsigned int relation) |
132 | { | 132 | { |
133 | #ifndef CONFIG_BF60x | 133 | #ifndef CONFIG_BF60x |
134 | unsigned int plldiv; | 134 | unsigned int plldiv; |
135 | #endif | 135 | #endif |
136 | unsigned int index, cpu; | 136 | unsigned int index; |
137 | unsigned long cclk_hz; | 137 | unsigned long cclk_hz; |
138 | struct cpufreq_freqs freqs; | 138 | struct cpufreq_freqs freqs; |
139 | static unsigned long lpj_ref; | 139 | static unsigned long lpj_ref; |
@@ -144,59 +144,48 @@ static int bfin_target(struct cpufreq_policy *poli, | |||
144 | cycles_t cycles; | 144 | cycles_t cycles; |
145 | #endif | 145 | #endif |
146 | 146 | ||
147 | for_each_online_cpu(cpu) { | 147 | if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq, |
148 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | 148 | relation, &index)) |
149 | return -EINVAL; | ||
149 | 150 | ||
150 | if (!policy) | 151 | cclk_hz = bfin_freq_table[index].frequency; |
151 | continue; | ||
152 | 152 | ||
153 | if (cpufreq_frequency_table_target(policy, bfin_freq_table, | 153 | freqs.old = bfin_getfreq_khz(0); |
154 | target_freq, relation, &index)) | 154 | freqs.new = cclk_hz; |
155 | return -EINVAL; | ||
156 | 155 | ||
157 | cclk_hz = bfin_freq_table[index].frequency; | 156 | pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n", |
157 | cclk_hz, target_freq, freqs.old); | ||
158 | 158 | ||
159 | freqs.old = bfin_getfreq_khz(0); | 159 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
160 | freqs.new = cclk_hz; | ||
161 | freqs.cpu = cpu; | ||
162 | |||
163 | pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n", | ||
164 | cclk_hz, target_freq, freqs.old); | ||
165 | |||
166 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
167 | if (cpu == CPUFREQ_CPU) { | ||
168 | #ifndef CONFIG_BF60x | 160 | #ifndef CONFIG_BF60x |
169 | plldiv = (bfin_read_PLL_DIV() & SSEL) | | 161 | plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel; |
170 | dpm_state_table[index].csel; | 162 | bfin_write_PLL_DIV(plldiv); |
171 | bfin_write_PLL_DIV(plldiv); | ||
172 | #else | 163 | #else |
173 | ret = cpu_set_cclk(cpu, freqs.new * 1000); | 164 | ret = cpu_set_cclk(policy->cpu, freqs.new * 1000); |
174 | if (ret != 0) { | 165 | if (ret != 0) { |
175 | WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret); | 166 | WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret); |
176 | break; | 167 | return ret; |
177 | } | 168 | } |
178 | #endif | 169 | #endif |
179 | on_each_cpu(bfin_adjust_core_timer, &index, 1); | 170 | on_each_cpu(bfin_adjust_core_timer, &index, 1); |
180 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) | 171 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) |
181 | cycles = get_cycles(); | 172 | cycles = get_cycles(); |
182 | SSYNC(); | 173 | SSYNC(); |
183 | cycles += 10; /* ~10 cycles we lose after get_cycles() */ | 174 | cycles += 10; /* ~10 cycles we lose after get_cycles() */ |
184 | __bfin_cycles_off += | 175 | __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index); |
185 | (cycles << __bfin_cycles_mod) - (cycles << index); | 176 | __bfin_cycles_mod = index; |
186 | __bfin_cycles_mod = index; | ||
187 | #endif | 177 | #endif |
188 | if (!lpj_ref_freq) { | 178 | if (!lpj_ref_freq) { |
189 | lpj_ref = loops_per_jiffy; | 179 | lpj_ref = loops_per_jiffy; |
190 | lpj_ref_freq = freqs.old; | 180 | lpj_ref_freq = freqs.old; |
191 | } | ||
192 | if (freqs.new != freqs.old) { | ||
193 | loops_per_jiffy = cpufreq_scale(lpj_ref, | ||
194 | lpj_ref_freq, freqs.new); | ||
195 | } | ||
196 | } | ||
197 | /* TODO: just test case for cycles clock source, remove later */ | ||
198 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
199 | } | 181 | } |
182 | if (freqs.new != freqs.old) { | ||
183 | loops_per_jiffy = cpufreq_scale(lpj_ref, | ||
184 | lpj_ref_freq, freqs.new); | ||
185 | } | ||
186 | |||
187 | /* TODO: just test case for cycles clock source, remove later */ | ||
188 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
200 | 189 | ||
201 | pr_debug("cpufreq: done\n"); | 190 | pr_debug("cpufreq: done\n"); |
202 | return ret; | 191 | return ret; |