sync hh.org
[hh.org.git] / arch / arm / mach-pxa / cpu-pxa.c
blobd1e39a246d1bc8f8fed1a77771580a35ec281c21
1 /*
2 * linux/arch/arm/mach-pxa/cpu-pxa.c
4 * Copyright (C) 2002,2003 Intrinsyc Software
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * History:
21 * 31-Jul-2002 : Initial version [FB]
22 * 29-Jan-2003 : added PXA255 support [FB]
23 * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
24 * 11-Jan-2006 : v2.6, support for PXA27x processor up to 624MHz (Bill Reese, Hewlett Packard)
26 * Note:
27 * This driver may change the memory bus clock rate, but will not do any
28 * platform specific access timing changes... for example if you have flash
29 * memory connected to CS0, you will need to register a platform specific
30 * notifier which will adjust the memory access strobes to maintain a
31 * minimum strobe width.
35 #include <linux/kernel.h>
36 #include <linux/module.h>
37 #include <linux/sched.h>
38 #include <linux/init.h>
39 #include <linux/cpufreq.h>
41 #include <asm/hardware.h>
43 #include <asm/arch/pxa-regs.h>
46 * This comes from generic.h in this directory.
48 extern unsigned int get_clk_frequency_khz(int info);
50 #define DEBUG 0
52 #ifdef DEBUG
53 static unsigned int freq_debug = DEBUG;
54 module_param(freq_debug, int, 0644);
55 MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
56 #else
57 #define freq_debug 0
58 #endif
60 typedef struct
62 unsigned int khz; /* CPU frequency */
63 unsigned int membus; /* memory bus frequency */
64 unsigned int cccr; /* new CCLKCFG setting */
65 unsigned int div2; /* alter memory controller settings to divide by 2 */
66 unsigned int cclkcfg; /* new CCLKCFG setting */
67 } pxa_freqs_t;
69 /* Define the refresh period in mSec for the SDRAM and the number of rows */
70 #define SDRAM_TREF 64 /* standard 64ms SDRAM */
71 #if defined(CONFIG_MACH_H4700) || defined(CONFIG_ARCH_H2200)
72 #define SDRAM_ROWS 8192 /* hx4700 uses 2 64Mb DRAMs, 8912 rows */
73 #else
74 #define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
75 #endif
76 #define MDREFR_DRI(x) (((x*SDRAM_TREF/SDRAM_ROWS - 31)/32))
78 #define CCLKCFG_TURBO 0x1
79 #define CCLKCFG_FCS 0x2
80 #define CCLKCFG_HALFTURBO 0x4
81 #define CCLKCFG_FASTBUS 0x8
82 #define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
83 #define MDREFR_DRI_MASK 0xFFF
84 #define PXA25x_CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS
87 * For the PXA27x:
88 * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG.
90 * A = 0 => memory controller clock from table 3-7,
91 * A = 1 => memory controller clock = system bus clock
92 * Run mode frequency = 13 MHz * L
93 * Turbo mode frequency = 13 MHz * L * N
94 * System bus frequency = 13 MHz * L / (B + 1)
95 * System initialized by bootldr to:
97 * In CCCR:
98 * A = 1
99 * L = 16 oscillator to run mode ratio
100 * 2N = 6 2 * (turbo mode to run mode ratio)
102 * In CCLKCFG:
103 * B = 1 Fast bus mode
104 * HT = 0 Half-Turbo mode
105 * T = 1 Turbo mode
107 * For now, just support some of the combinations in table 3-7 of
108 * PXA27x Processor Family Developer's Manual to simplify frequency
109 * change sequences.
111 * Specify 2N in the PXA27x_CCCR macro, not N!
113 #define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L)
114 #define PXA27x_CCLKCFG(B, HT, T) (B << 3 | HT << 2 | CCLKCFG_FCS | T)
117 * Valid frequency assignments
119 static pxa_freqs_t pxa2xx_freqs[] =
121 /* CPU MEMBUS CCCR DIV2*/
122 #if defined(CONFIG_PXA25x)
123 #if defined(CONFIG_PXA25x_ALTERNATE_FREQS)
124 { 99500, 99500, 0x121, 1, PXA25x_CCLKCFG}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
125 {199100, 99500, 0x221, 0, PXA25x_CCLKCFG}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
126 {298500, 99500, 0x321, 0, PXA25x_CCLKCFG}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
127 {298600, 99500, 0x1c1, 0, PXA25x_CCLKCFG}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
128 {398100, 99500, 0x241, 0, PXA25x_CCLKCFG} /* run=199, turbo=398, PXbus=99, SDRAM=99 */
129 #else
130 { 99500, 99500, 0x121, 1, PXA25x_CCLKCFG}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
131 {132700, 132700, 0x123, 1, PXA25x_CCLKCFG}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
132 {199100, 99500, 0x141, 0, PXA25x_CCLKCFG}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
133 {265400, 132700, 0x143, 1, PXA25x_CCLKCFG}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
134 {331800, 165900, 0x145, 1, PXA25x_CCLKCFG}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
135 {398100, 99500, 0x161, 0, PXA25x_CCLKCFG} /* run=398, turbo=398, PXbus=196, SDRAM=99 */
136 #endif
137 #elif defined(CONFIG_PXA27x)
138 {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, PXA27x_CCLKCFG(1, 0, 1)},
139 {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, PXA27x_CCLKCFG(1, 1, 1)},
140 {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, PXA27x_CCLKCFG(0, 0, 1)},
141 {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, PXA27x_CCLKCFG(1, 0, 1)},
142 {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, PXA27x_CCLKCFG(1, 0, 1)},
143 {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, PXA27x_CCLKCFG(1, 0, 1)},
144 {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, PXA27x_CCLKCFG(1, 0, 1)}
145 #endif
147 #define NUM_FREQS (sizeof(pxa2xx_freqs)/sizeof(pxa_freqs_t))
149 static struct cpufreq_frequency_table pxa2xx_freq_table[NUM_FREQS+1];
151 /* find a valid frequency point */
152 static int pxa_verify_policy(struct cpufreq_policy *policy)
154 int ret;
156 ret=cpufreq_frequency_table_verify(policy, pxa2xx_freq_table);
158 if(freq_debug) {
159 printk("Verified CPU policy: %dKhz min to %dKhz max\n",
160 policy->min, policy->max);
163 return ret;
166 static int pxa_set_target(struct cpufreq_policy *policy,
167 unsigned int target_freq,
168 unsigned int relation)
170 int idx;
171 cpumask_t cpus_allowed, allowedcpuset;
172 int cpu = policy->cpu;
173 struct cpufreq_freqs freqs;
174 unsigned long flags;
175 unsigned int unused;
176 unsigned int preset_mdrefr, postset_mdrefr, cclkcfg;
178 if(freq_debug) {
179 printk ("CPU PXA: target freq %d\n", target_freq);
180 printk ("CPU PXA: relation %d\n", relation);
184 * Save this threads cpus_allowed mask.
186 cpus_allowed = current->cpus_allowed;
189 * Bind to the specified CPU. When this call returns,
190 * we should be running on the right CPU.
192 cpus_clear (allowedcpuset);
193 cpu_set (cpu, allowedcpuset);
194 set_cpus_allowed(current, allowedcpuset);
195 BUG_ON(cpu != smp_processor_id());
197 /* Lookup the next frequency */
198 if (cpufreq_frequency_table_target(policy, pxa2xx_freq_table,
199 target_freq, relation, &idx)) {
200 return -EINVAL;
203 freqs.old = policy->cur;
204 freqs.new = pxa2xx_freqs[idx].khz;
205 freqs.cpu = policy->cpu;
206 if(freq_debug) {
207 printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
208 freqs.new/1000, (pxa2xx_freqs[idx].div2) ?
209 (pxa2xx_freqs[idx].membus/2000) :
210 (pxa2xx_freqs[idx].membus/1000));
214 * Tell everyone what we're about to do...
215 * you should add a notify client with any platform specific
216 * Vcc changing capability
218 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
220 /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
221 * we need to preset the smaller DRI before the change. If we're speeding
222 * up we need to set the larger DRI value after the change.
224 preset_mdrefr = postset_mdrefr = MDREFR;
225 if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa2xx_freqs[idx].membus)) {
226 preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
227 MDREFR_DRI(pxa2xx_freqs[idx].membus);
229 postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
230 MDREFR_DRI(pxa2xx_freqs[idx].membus);
232 /* If we're dividing the memory clock by two for the SDRAM clock, this
233 * must be set prior to the change. Clearing the divide must be done
234 * after the change.
236 if(pxa2xx_freqs[idx].div2) {
238 * Potentially speeding up memory clock, so slow down the memory
239 * before speeding up the clock.
241 preset_mdrefr |= MDREFR_DB2_MASK | MDREFR_K0DB4;
242 preset_mdrefr &= ~MDREFR_K0DB2;
244 postset_mdrefr |= MDREFR_DB2_MASK | MDREFR_K0DB4;
245 postset_mdrefr &= ~MDREFR_K0DB2;
246 } else {
248 * Potentially slowing down memory clock. Wait until after the change
249 * to speed up the memory.
251 postset_mdrefr &= ~MDREFR_DB2_MASK;
252 postset_mdrefr &= ~MDREFR_K0DB4;
253 postset_mdrefr |= MDREFR_K0DB2;
256 cclkcfg = pxa2xx_freqs[idx].cclkcfg;
258 if (freq_debug) {
259 printk (KERN_INFO "CPU PXA writing 0x%08x to CCCR\n",
260 pxa2xx_freqs[idx].cccr);
261 printk (KERN_INFO "CPU PXA writing 0x%08x to CCLKCFG\n",
262 pxa2xx_freqs[idx].cclkcfg);
263 printk (KERN_INFO "CPU PXA writing 0x%08x to MDREFR before change\n",
264 preset_mdrefr);
265 printk (KERN_INFO "CPU PXA writing 0x%08x to MDREFR after change\n",
266 postset_mdrefr);
269 local_irq_save(flags);
271 /* Set new the CCCR */
272 CCCR = pxa2xx_freqs[idx].cccr;
275 * Should really set both of PMCR[xIDAE] while changing the core frequency
279 * TODO: On the PXA27x: If we're setting half-turbo mode and changing the
280 * core frequency at the same time we must split it up into two operations.
281 * The current values in the pxa2xx_freqs table don't do this, so the code
282 * is unimplemented.
285 __asm__ __volatile__(" \
286 ldr r4, [%1] ; /* load MDREFR */ \
287 b 2f ; \
288 .align 5 ; \
289 1: \
290 str %3, [%1] ; /* preset the MDREFR */ \
291 mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \
292 str %4, [%1] ; /* postset the MDREFR */ \
294 b 3f ; \
295 2: b 1b ; \
296 3: nop ; \
298 : "=&r" (unused)
299 : "r" (&MDREFR), "r" (cclkcfg), \
300 "r" (preset_mdrefr), "r" (postset_mdrefr)
301 : "r4", "r5");
302 local_irq_restore(flags);
304 if (freq_debug) {
305 printk (KERN_INFO "CPU PXA Frequency change successful\n");
306 printk (KERN_INFO "CPU PXA new CCSR 0x%08x\n", CCSR);
310 * Restore the CPUs allowed mask.
312 set_cpus_allowed(current, cpus_allowed);
315 * Tell everyone what we've just done...
316 * you should add a notify client with any platform specific
317 * SDRAM refresh timer adjustments
319 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
321 return 0;
324 static int pxa_cpufreq_init(struct cpufreq_policy *policy)
326 cpumask_t cpus_allowed, allowedcpuset;
327 unsigned int cpu = policy->cpu;
328 int i;
329 unsigned int cclkcfg;
331 cpus_allowed = current->cpus_allowed;
333 cpus_clear (allowedcpuset);
334 cpu_set (cpu, allowedcpuset);
335 set_cpus_allowed(current, allowedcpuset);
336 BUG_ON(cpu != smp_processor_id());
338 /* set default governor and cpuinfo */
339 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
340 policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
341 policy->cur = get_clk_frequency_khz(0); /* current freq */
343 /* Generate the cpufreq_frequency_table struct */
344 for(i=0;i<NUM_FREQS;i++) {
345 pxa2xx_freq_table[i].frequency = pxa2xx_freqs[i].khz;
346 pxa2xx_freq_table[i].index = i;
348 pxa2xx_freq_table[i].frequency = CPUFREQ_TABLE_END;
351 * Set the policy's minimum and maximum frequencies from the tables
352 * just constructed. This sets cpuinfo.mxx_freq, min and max.
354 cpufreq_frequency_table_cpuinfo (policy, pxa2xx_freq_table);
356 set_cpus_allowed(current, cpus_allowed);
357 printk(KERN_INFO "PXA CPU frequency change support initialized\n");
359 if (freq_debug) {
360 printk (KERN_INFO "PXA CPU initial CCCR 0x%08x\n", CCCR);
361 asm
363 "mrc p14, 0, %0, c6, c0, 0 ; /* read CCLKCFG from CP14 */ "
364 : "=r" (cclkcfg) :
366 printk ("PXA CPU initial CCLKCFG 0x%08x\n", cclkcfg);
367 printk ("PXA CPU initial MDREFR 0x%08x\n", MDREFR);
370 return 0;
373 static struct cpufreq_driver pxa_cpufreq_driver = {
374 .verify = pxa_verify_policy,
375 .target = pxa_set_target,
376 .init = pxa_cpufreq_init,
377 #if defined(CONFIG_PXA25x)
378 .name = "PXA25x",
379 #elif defined(CONFIG_PXA27x)
380 .name = "PXA27x",
381 #endif
384 static int __init pxa_cpu_init(void)
386 return cpufreq_register_driver(&pxa_cpufreq_driver);
389 static void __exit pxa_cpu_exit(void)
391 cpufreq_unregister_driver(&pxa_cpufreq_driver);
395 MODULE_AUTHOR ("Intrinsyc Software Inc.");
396 MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
397 MODULE_LICENSE("GPL");
398 module_init(pxa_cpu_init);
399 module_exit(pxa_cpu_exit);