aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-pxa/cpu-pxa.c98
1 files changed, 51 insertions, 47 deletions
diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c
index 4b21479332ae..0f5660200bf9 100644
--- a/arch/arm/mach-pxa/cpu-pxa.c
+++ b/arch/arm/mach-pxa/cpu-pxa.c
@@ -57,29 +57,29 @@ typedef struct {
57} pxa_freqs_t; 57} pxa_freqs_t;
58 58
59/* Define the refresh period in mSec for the SDRAM and the number of rows */ 59/* Define the refresh period in mSec for the SDRAM and the number of rows */
60#define SDRAM_TREF 64 /* standard 64ms SDRAM */ 60#define SDRAM_TREF 64 /* standard 64ms SDRAM */
61#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ 61#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
62#define MDREFR_DRI(x) (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32)) 62#define MDREFR_DRI(x) (((x) * SDRAM_TREF) / (SDRAM_ROWS * 32))
63 63
64#define CCLKCFG_TURBO 0x1 64#define CCLKCFG_TURBO 0x1
65#define CCLKCFG_FCS 0x2 65#define CCLKCFG_FCS 0x2
66#define PXA25x_MIN_FREQ 99500 66#define PXA25x_MIN_FREQ 99500
67#define PXA25x_MAX_FREQ 398100 67#define PXA25x_MAX_FREQ 398100
68#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) 68#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
69#define MDREFR_DRI_MASK 0xFFF 69#define MDREFR_DRI_MASK 0xFFF
70 70
71 71
72/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */ 72/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
73static pxa_freqs_t pxa255_run_freqs[] = 73static pxa_freqs_t pxa255_run_freqs[] =
74{ 74{
75 /* CPU MEMBUS CCCR DIV2*/ 75 /* CPU MEMBUS CCCR DIV2 run turbo PXbus SDRAM */
76 { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */ 76 { 99500, 99500, 0x121, 1}, /* 99, 99, 50, 50 */
77 {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */ 77 {132700, 132700, 0x123, 1}, /* 133, 133, 66, 66 */
78 {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */ 78 {199100, 99500, 0x141, 0}, /* 199, 199, 99, 99 */
79 {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */ 79 {265400, 132700, 0x143, 1}, /* 265, 265, 133, 66 */
80 {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */ 80 {331800, 165900, 0x145, 1}, /* 331, 331, 166, 83 */
81 {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */ 81 {398100, 99500, 0x161, 0}, /* 398, 398, 196, 99 */
82 {0,} 82 {0,}
83}; 83};
84#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs) 84#define NUM_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
85 85
@@ -88,17 +88,18 @@ static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
88/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ 88/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
89static pxa_freqs_t pxa255_turbo_freqs[] = 89static pxa_freqs_t pxa255_turbo_freqs[] =
90{ 90{
91 /* CPU MEMBUS CCCR DIV2*/ 91 /* CPU MEMBUS CCCR DIV2 run turbo PXbus SDRAM */
92 { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */ 92 { 99500, 99500, 0x121, 1}, /* 99, 99, 50, 50 */
93 {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */ 93 {199100, 99500, 0x221, 0}, /* 99, 199, 50, 99 */
94 {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */ 94 {298500, 99500, 0x321, 0}, /* 99, 287, 50, 99 */
95 {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */ 95 {298600, 99500, 0x1c1, 0}, /* 199, 287, 99, 99 */
96 {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */ 96 {398100, 99500, 0x241, 0}, /* 199, 398, 99, 99 */
97 {0,} 97 {0,}
98}; 98};
99#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs) 99#define NUM_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
100 100
101static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1]; 101static struct cpufreq_frequency_table
102 pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
102 103
103extern unsigned get_clk_frequency_khz(int info); 104extern unsigned get_clk_frequency_khz(int info);
104 105
@@ -122,14 +123,14 @@ static int pxa_verify_policy(struct cpufreq_policy *policy)
122 123
123 if (freq_debug) 124 if (freq_debug)
124 pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n", 125 pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
125 policy->min, policy->max); 126 policy->min, policy->max);
126 127
127 return ret; 128 return ret;
128} 129}
129 130
130static int pxa_set_target(struct cpufreq_policy *policy, 131static int pxa_set_target(struct cpufreq_policy *policy,
131 unsigned int target_freq, 132 unsigned int target_freq,
132 unsigned int relation) 133 unsigned int relation)
133{ 134{
134 struct cpufreq_frequency_table *pxa_freqs_table; 135 struct cpufreq_frequency_table *pxa_freqs_table;
135 pxa_freqs_t *pxa_freq_settings; 136 pxa_freqs_t *pxa_freq_settings;
@@ -155,7 +156,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
155 156
156 /* Lookup the next frequency */ 157 /* Lookup the next frequency */
157 if (cpufreq_frequency_table_target(policy, pxa_freqs_table, 158 if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
158 target_freq, relation, &idx)) { 159 target_freq, relation, &idx)) {
159 return -EINVAL; 160 return -EINVAL;
160 } 161 }
161 162
@@ -164,10 +165,11 @@ static int pxa_set_target(struct cpufreq_policy *policy,
164 freqs.cpu = policy->cpu; 165 freqs.cpu = policy->cpu;
165 166
166 if (freq_debug) 167 if (freq_debug)
167 pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", 168 pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, "
168 freqs.new / 1000, (pxa_freq_settings[idx].div2) ? 169 "(SDRAM %d Mhz)\n",
169 (pxa_freq_settings[idx].membus / 2000) : 170 freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
170 (pxa_freq_settings[idx].membus / 1000)); 171 (pxa_freq_settings[idx].membus / 2000) :
172 (pxa_freq_settings[idx].membus / 1000));
171 173
172 /* 174 /*
173 * Tell everyone what we're about to do... 175 * Tell everyone what we're about to do...
@@ -177,16 +179,17 @@ static int pxa_set_target(struct cpufreq_policy *policy,
177 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 179 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
178 180
179 /* Calculate the next MDREFR. If we're slowing down the SDRAM clock 181 /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
180 * we need to preset the smaller DRI before the change. If we're speeding 182 * we need to preset the smaller DRI before the change. If we're
181 * up we need to set the larger DRI value after the change. 183 * speeding up we need to set the larger DRI value after the change.
182 */ 184 */
183 preset_mdrefr = postset_mdrefr = MDREFR; 185 preset_mdrefr = postset_mdrefr = MDREFR;
184 if ((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) { 186 if ((MDREFR & MDREFR_DRI_MASK) >
187 MDREFR_DRI(pxa_freq_settings[idx].membus)) {
185 preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) | 188 preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
186 MDREFR_DRI(pxa_freq_settings[idx].membus); 189 MDREFR_DRI(pxa_freq_settings[idx].membus);
187 } 190 }
188 postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) | 191 postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
189 MDREFR_DRI(pxa_freq_settings[idx].membus); 192 MDREFR_DRI(pxa_freq_settings[idx].membus);
190 193
191 /* If we're dividing the memory clock by two for the SDRAM clock, this 194 /* If we're dividing the memory clock by two for the SDRAM clock, this
192 * must be set prior to the change. Clearing the divide must be done 195 * must be set prior to the change. Clearing the divide must be done
@@ -207,7 +210,7 @@ static int pxa_set_target(struct cpufreq_policy *policy,
207 asm volatile(" \n\ 210 asm volatile(" \n\
208 ldr r4, [%1] /* load MDREFR */ \n\ 211 ldr r4, [%1] /* load MDREFR */ \n\
209 b 2f \n\ 212 b 2f \n\
210 .align 5 \n\ 213 .align 5 \n\
2111: \n\ 2141: \n\
212 str %4, [%1] /* preset the MDREFR */ \n\ 215 str %4, [%1] /* preset the MDREFR */ \n\
213 mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\ 216 mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\
@@ -217,10 +220,10 @@ static int pxa_set_target(struct cpufreq_policy *policy,
2172: b 1b \n\ 2202: b 1b \n\
2183: nop \n\ 2213: nop \n\
219 " 222 "
220 : "=&r" (unused) 223 : "=&r" (unused)
221 : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), 224 : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart),
222 "r" (preset_mdrefr), "r" (postset_mdrefr) 225 "r" (preset_mdrefr), "r" (postset_mdrefr)
223 : "r4", "r5"); 226 : "r4", "r5");
224 local_irq_restore(flags); 227 local_irq_restore(flags);
225 228
226 /* 229 /*
@@ -248,7 +251,7 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
248 policy->cpuinfo.max_freq = PXA25x_MAX_FREQ; 251 policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
249 policy->cpuinfo.min_freq = PXA25x_MIN_FREQ; 252 policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
250 policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ 253 policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
251 policy->cur = get_clk_frequency_khz(0); /* current freq */ 254 policy->cur = get_clk_frequency_khz(0); /* current freq */
252 policy->min = policy->max = policy->cur; 255 policy->min = policy->max = policy->cur;
253 256
254 /* Generate the run cpufreq_frequency_table struct */ 257 /* Generate the run cpufreq_frequency_table struct */
@@ -260,7 +263,8 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
260 pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END; 263 pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
261 /* Generate the turbo cpufreq_frequency_table struct */ 264 /* Generate the turbo cpufreq_frequency_table struct */
262 for (i = 0; i < NUM_TURBO_FREQS; i++) { 265 for (i = 0; i < NUM_TURBO_FREQS; i++) {
263 pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz; 266 pxa255_turbo_freq_table[i].frequency =
267 pxa255_turbo_freqs[i].khz;
264 pxa255_turbo_freq_table[i].index = i; 268 pxa255_turbo_freq_table[i].index = i;
265 } 269 }
266 pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; 270 pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
@@ -293,8 +297,8 @@ static void __exit pxa_cpu_exit(void)
293} 297}
294 298
295 299
296MODULE_AUTHOR ("Intrinsyc Software Inc."); 300MODULE_AUTHOR("Intrinsyc Software Inc.");
297MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture"); 301MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture");
298MODULE_LICENSE("GPL"); 302MODULE_LICENSE("GPL");
299module_init(pxa_cpu_init); 303module_init(pxa_cpu_init);
300module_exit(pxa_cpu_exit); 304module_exit(pxa_cpu_exit);