diff options
Diffstat (limited to 'arch/arm/mach-pxa/cpufreq-pxa2xx.c')
-rw-r--r-- | arch/arm/mach-pxa/cpufreq-pxa2xx.c | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 1f272ea83f36..771dd4eac935 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c | |||
@@ -64,7 +64,7 @@ typedef struct { | |||
64 | 64 | ||
65 | /* Define the refresh period in mSec for the SDRAM and the number of rows */ | 65 | /* Define the refresh period in mSec for the SDRAM and the number of rows */ |
66 | #define SDRAM_TREF 64 /* standard 64ms SDRAM */ | 66 | #define SDRAM_TREF 64 /* standard 64ms SDRAM */ |
67 | #define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */ | 67 | static unsigned int sdram_rows; |
68 | 68 | ||
69 | #define CCLKCFG_TURBO 0x1 | 69 | #define CCLKCFG_TURBO 0x1 |
70 | #define CCLKCFG_FCS 0x2 | 70 | #define CCLKCFG_FCS 0x2 |
@@ -73,6 +73,9 @@ typedef struct { | |||
73 | #define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) | 73 | #define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) |
74 | #define MDREFR_DRI_MASK 0xFFF | 74 | #define MDREFR_DRI_MASK 0xFFF |
75 | 75 | ||
76 | #define MDCNFG_DRAC2(mdcnfg) (((mdcnfg) >> 21) & 0x3) | ||
77 | #define MDCNFG_DRAC0(mdcnfg) (((mdcnfg) >> 5) & 0x3) | ||
78 | |||
76 | /* | 79 | /* |
77 | * PXA255 definitions | 80 | * PXA255 definitions |
78 | */ | 81 | */ |
@@ -109,6 +112,10 @@ static struct cpufreq_frequency_table | |||
109 | static struct cpufreq_frequency_table | 112 | static struct cpufreq_frequency_table |
110 | pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1]; | 113 | pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1]; |
111 | 114 | ||
115 | static unsigned int pxa255_turbo_table; | ||
116 | module_param(pxa255_turbo_table, uint, 0); | ||
117 | MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table, !0 = turbo table)"); | ||
118 | |||
112 | /* | 119 | /* |
113 | * PXA270 definitions | 120 | * PXA270 definitions |
114 | * | 121 | * |
@@ -158,22 +165,16 @@ static struct cpufreq_frequency_table | |||
158 | 165 | ||
159 | extern unsigned get_clk_frequency_khz(int info); | 166 | extern unsigned get_clk_frequency_khz(int info); |
160 | 167 | ||
161 | static void find_freq_tables(struct cpufreq_policy *policy, | 168 | static void find_freq_tables(struct cpufreq_frequency_table **freq_table, |
162 | struct cpufreq_frequency_table **freq_table, | ||
163 | pxa_freqs_t **pxa_freqs) | 169 | pxa_freqs_t **pxa_freqs) |
164 | { | 170 | { |
165 | if (cpu_is_pxa25x()) { | 171 | if (cpu_is_pxa25x()) { |
166 | if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { | 172 | if (!pxa255_turbo_table) { |
167 | *pxa_freqs = pxa255_run_freqs; | 173 | *pxa_freqs = pxa255_run_freqs; |
168 | *freq_table = pxa255_run_freq_table; | 174 | *freq_table = pxa255_run_freq_table; |
169 | } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { | 175 | } else { |
170 | *pxa_freqs = pxa255_turbo_freqs; | 176 | *pxa_freqs = pxa255_turbo_freqs; |
171 | *freq_table = pxa255_turbo_freq_table; | 177 | *freq_table = pxa255_turbo_freq_table; |
172 | } else { | ||
173 | printk("CPU PXA: Unknown policy found. " | ||
174 | "Using CPUFREQ_POLICY_PERFORMANCE\n"); | ||
175 | *pxa_freqs = pxa255_run_freqs; | ||
176 | *freq_table = pxa255_run_freq_table; | ||
177 | } | 178 | } |
178 | } | 179 | } |
179 | if (cpu_is_pxa27x()) { | 180 | if (cpu_is_pxa27x()) { |
@@ -194,14 +195,28 @@ static void pxa27x_guess_max_freq(void) | |||
194 | } | 195 | } |
195 | } | 196 | } |
196 | 197 | ||
198 | static void init_sdram_rows(void) | ||
199 | { | ||
200 | uint32_t mdcnfg = MDCNFG; | ||
201 | unsigned int drac2 = 0, drac0 = 0; | ||
202 | |||
203 | if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3)) | ||
204 | drac2 = MDCNFG_DRAC2(mdcnfg); | ||
205 | |||
206 | if (mdcnfg & (MDCNFG_DE0 | MDCNFG_DE1)) | ||
207 | drac0 = MDCNFG_DRAC0(mdcnfg); | ||
208 | |||
209 | sdram_rows = 1 << (11 + max(drac0, drac2)); | ||
210 | } | ||
211 | |||
197 | static u32 mdrefr_dri(unsigned int freq) | 212 | static u32 mdrefr_dri(unsigned int freq) |
198 | { | 213 | { |
199 | u32 dri = 0; | 214 | u32 dri = 0; |
200 | 215 | ||
201 | if (cpu_is_pxa25x()) | 216 | if (cpu_is_pxa25x()) |
202 | dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS * 32)); | 217 | dri = ((freq * SDRAM_TREF) / (sdram_rows * 32)); |
203 | if (cpu_is_pxa27x()) | 218 | if (cpu_is_pxa27x()) |
204 | dri = ((freq * SDRAM_TREF) / (SDRAM_ROWS - 31)) / 32; | 219 | dri = ((freq * SDRAM_TREF) / (sdram_rows - 31)) / 32; |
205 | return dri; | 220 | return dri; |
206 | } | 221 | } |
207 | 222 | ||
@@ -212,7 +227,7 @@ static int pxa_verify_policy(struct cpufreq_policy *policy) | |||
212 | pxa_freqs_t *pxa_freqs; | 227 | pxa_freqs_t *pxa_freqs; |
213 | int ret; | 228 | int ret; |
214 | 229 | ||
215 | find_freq_tables(policy, &pxa_freqs_table, &pxa_freqs); | 230 | find_freq_tables(&pxa_freqs_table, &pxa_freqs); |
216 | ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table); | 231 | ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table); |
217 | 232 | ||
218 | if (freq_debug) | 233 | if (freq_debug) |
@@ -240,7 +255,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
240 | unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; | 255 | unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; |
241 | 256 | ||
242 | /* Get the current policy */ | 257 | /* Get the current policy */ |
243 | find_freq_tables(policy, &pxa_freqs_table, &pxa_freq_settings); | 258 | find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); |
244 | 259 | ||
245 | /* Lookup the next frequency */ | 260 | /* Lookup the next frequency */ |
246 | if (cpufreq_frequency_table_target(policy, pxa_freqs_table, | 261 | if (cpufreq_frequency_table_target(policy, pxa_freqs_table, |
@@ -329,11 +344,15 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
329 | { | 344 | { |
330 | int i; | 345 | int i; |
331 | unsigned int freq; | 346 | unsigned int freq; |
347 | struct cpufreq_frequency_table *pxa255_freq_table; | ||
348 | pxa_freqs_t *pxa255_freqs; | ||
332 | 349 | ||
333 | /* try to guess pxa27x cpu */ | 350 | /* try to guess pxa27x cpu */ |
334 | if (cpu_is_pxa27x()) | 351 | if (cpu_is_pxa27x()) |
335 | pxa27x_guess_max_freq(); | 352 | pxa27x_guess_max_freq(); |
336 | 353 | ||
354 | init_sdram_rows(); | ||
355 | |||
337 | /* set default policy and cpuinfo */ | 356 | /* set default policy and cpuinfo */ |
338 | policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ | 357 | policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ |
339 | policy->cur = get_clk_frequency_khz(0); /* current freq */ | 358 | policy->cur = get_clk_frequency_khz(0); /* current freq */ |
@@ -354,6 +373,8 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
354 | } | 373 | } |
355 | pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; | 374 | pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; |
356 | 375 | ||
376 | pxa255_turbo_table = !!pxa255_turbo_table; | ||
377 | |||
357 | /* Generate the pxa27x cpufreq_frequency_table struct */ | 378 | /* Generate the pxa27x cpufreq_frequency_table struct */ |
358 | for (i = 0; i < NUM_PXA27x_FREQS; i++) { | 379 | for (i = 0; i < NUM_PXA27x_FREQS; i++) { |
359 | freq = pxa27x_freqs[i].khz; | 380 | freq = pxa27x_freqs[i].khz; |
@@ -368,8 +389,12 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
368 | * Set the policy's minimum and maximum frequencies from the tables | 389 | * Set the policy's minimum and maximum frequencies from the tables |
369 | * just constructed. This sets cpuinfo.mxx_freq, min and max. | 390 | * just constructed. This sets cpuinfo.mxx_freq, min and max. |
370 | */ | 391 | */ |
371 | if (cpu_is_pxa25x()) | 392 | if (cpu_is_pxa25x()) { |
372 | cpufreq_frequency_table_cpuinfo(policy, pxa255_run_freq_table); | 393 | find_freq_tables(&pxa255_freq_table, &pxa255_freqs); |
394 | pr_info("PXA255 cpufreq using %s frequency table\n", | ||
395 | pxa255_turbo_table ? "turbo" : "run"); | ||
396 | cpufreq_frequency_table_cpuinfo(policy, pxa255_freq_table); | ||
397 | } | ||
373 | else if (cpu_is_pxa27x()) | 398 | else if (cpu_is_pxa27x()) |
374 | cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table); | 399 | cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table); |
375 | 400 | ||