1cffc96ebSViresh Kumar /* 2cffc96ebSViresh Kumar * Copyright (C) 2002,2003 Intrinsyc Software 3cffc96ebSViresh Kumar * 4cffc96ebSViresh Kumar * This program is free software; you can redistribute it and/or modify 5cffc96ebSViresh Kumar * it under the terms of the GNU General Public License as published by 6cffc96ebSViresh Kumar * the Free Software Foundation; either version 2 of the License, or 7cffc96ebSViresh Kumar * (at your option) any later version. 8cffc96ebSViresh Kumar * 9cffc96ebSViresh Kumar * This program is distributed in the hope that it will be useful, 10cffc96ebSViresh Kumar * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cffc96ebSViresh Kumar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12cffc96ebSViresh Kumar * GNU General Public License for more details. 13cffc96ebSViresh Kumar * 14cffc96ebSViresh Kumar * You should have received a copy of the GNU General Public License 15cffc96ebSViresh Kumar * along with this program; if not, write to the Free Software 16cffc96ebSViresh Kumar * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17cffc96ebSViresh Kumar * 18cffc96ebSViresh Kumar * History: 19cffc96ebSViresh Kumar * 31-Jul-2002 : Initial version [FB] 20cffc96ebSViresh Kumar * 29-Jan-2003 : added PXA255 support [FB] 21cffc96ebSViresh Kumar * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) 22cffc96ebSViresh Kumar * 23cffc96ebSViresh Kumar * Note: 24cffc96ebSViresh Kumar * This driver may change the memory bus clock rate, but will not do any 25cffc96ebSViresh Kumar * platform specific access timing changes... for example if you have flash 26cffc96ebSViresh Kumar * memory connected to CS0, you will need to register a platform specific 27cffc96ebSViresh Kumar * notifier which will adjust the memory access strobes to maintain a 28cffc96ebSViresh Kumar * minimum strobe width. 29cffc96ebSViresh Kumar * 30cffc96ebSViresh Kumar */ 31cffc96ebSViresh Kumar 32cffc96ebSViresh Kumar #include <linux/kernel.h> 33cffc96ebSViresh Kumar #include <linux/module.h> 34cffc96ebSViresh Kumar #include <linux/sched.h> 35cffc96ebSViresh Kumar #include <linux/init.h> 36cffc96ebSViresh Kumar #include <linux/cpufreq.h> 37cffc96ebSViresh Kumar #include <linux/err.h> 38cffc96ebSViresh Kumar #include <linux/regulator/consumer.h> 39cffc96ebSViresh Kumar #include <linux/io.h> 40cffc96ebSViresh Kumar 41cffc96ebSViresh Kumar #include <mach/pxa2xx-regs.h> 42cffc96ebSViresh Kumar #include <mach/smemc.h> 43cffc96ebSViresh Kumar 44cffc96ebSViresh Kumar #ifdef DEBUG 45cffc96ebSViresh Kumar static unsigned int freq_debug; 46cffc96ebSViresh Kumar module_param(freq_debug, uint, 0); 47cffc96ebSViresh Kumar MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); 48cffc96ebSViresh Kumar #else 49cffc96ebSViresh Kumar #define freq_debug 0 50cffc96ebSViresh Kumar #endif 51cffc96ebSViresh Kumar 52cffc96ebSViresh Kumar static struct regulator *vcc_core; 53cffc96ebSViresh Kumar 54cffc96ebSViresh Kumar static unsigned int pxa27x_maxfreq; 55cffc96ebSViresh Kumar module_param(pxa27x_maxfreq, uint, 0); 56cffc96ebSViresh Kumar MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz" 57cffc96ebSViresh Kumar "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)"); 58cffc96ebSViresh Kumar 59cffc96ebSViresh Kumar typedef struct { 60cffc96ebSViresh Kumar unsigned int khz; 61cffc96ebSViresh Kumar unsigned int membus; 62cffc96ebSViresh Kumar unsigned int cccr; 63cffc96ebSViresh Kumar unsigned int div2; 64cffc96ebSViresh Kumar unsigned int cclkcfg; 65cffc96ebSViresh Kumar int vmin; 66cffc96ebSViresh Kumar int vmax; 67cffc96ebSViresh Kumar } pxa_freqs_t; 68cffc96ebSViresh Kumar 69cffc96ebSViresh Kumar /* Define the refresh period in mSec for the SDRAM and the number of rows */ 70cffc96ebSViresh Kumar #define SDRAM_TREF 64 /* standard 64ms SDRAM */ 71cffc96ebSViresh Kumar static unsigned int sdram_rows; 72cffc96ebSViresh Kumar 73cffc96ebSViresh Kumar #define CCLKCFG_TURBO 0x1 74cffc96ebSViresh Kumar #define CCLKCFG_FCS 0x2 75cffc96ebSViresh Kumar #define CCLKCFG_HALFTURBO 0x4 76cffc96ebSViresh Kumar #define CCLKCFG_FASTBUS 0x8 77cffc96ebSViresh Kumar #define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2) 78cffc96ebSViresh Kumar #define MDREFR_DRI_MASK 0xFFF 79cffc96ebSViresh Kumar 80cffc96ebSViresh Kumar #define MDCNFG_DRAC2(mdcnfg) (((mdcnfg) >> 21) & 0x3) 81cffc96ebSViresh Kumar #define MDCNFG_DRAC0(mdcnfg) (((mdcnfg) >> 5) & 0x3) 82cffc96ebSViresh Kumar 83cffc96ebSViresh Kumar /* 84cffc96ebSViresh Kumar * PXA255 definitions 85cffc96ebSViresh Kumar */ 86cffc96ebSViresh Kumar /* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */ 87cffc96ebSViresh Kumar #define CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS 88cffc96ebSViresh Kumar 89cffc96ebSViresh Kumar static pxa_freqs_t pxa255_run_freqs[] = 90cffc96ebSViresh Kumar { 91cffc96ebSViresh Kumar /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ 92cffc96ebSViresh Kumar { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */ 93cffc96ebSViresh Kumar {132700, 132700, 0x123, 1, CCLKCFG, -1, -1}, /* 133, 133, 66, 66 */ 94cffc96ebSViresh Kumar {199100, 99500, 0x141, 0, CCLKCFG, -1, -1}, /* 199, 199, 99, 99 */ 95cffc96ebSViresh Kumar {265400, 132700, 0x143, 1, CCLKCFG, -1, -1}, /* 265, 265, 133, 66 */ 96cffc96ebSViresh Kumar {331800, 165900, 0x145, 1, CCLKCFG, -1, -1}, /* 331, 331, 166, 83 */ 97cffc96ebSViresh Kumar {398100, 99500, 0x161, 0, CCLKCFG, -1, -1}, /* 398, 398, 196, 99 */ 98cffc96ebSViresh Kumar }; 99cffc96ebSViresh Kumar 100cffc96ebSViresh Kumar /* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ 101cffc96ebSViresh Kumar static pxa_freqs_t pxa255_turbo_freqs[] = 102cffc96ebSViresh Kumar { 103cffc96ebSViresh Kumar /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */ 104cffc96ebSViresh Kumar { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */ 105cffc96ebSViresh Kumar {199100, 99500, 0x221, 0, CCLKCFG, -1, -1}, /* 99, 199, 50, 99 */ 106cffc96ebSViresh Kumar {298500, 99500, 0x321, 0, CCLKCFG, -1, -1}, /* 99, 287, 50, 99 */ 107cffc96ebSViresh Kumar {298600, 99500, 0x1c1, 0, CCLKCFG, -1, -1}, /* 199, 287, 99, 99 */ 108cffc96ebSViresh Kumar {398100, 99500, 0x241, 0, CCLKCFG, -1, -1}, /* 199, 398, 99, 99 */ 109cffc96ebSViresh Kumar }; 110cffc96ebSViresh Kumar 111cffc96ebSViresh Kumar #define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs) 112cffc96ebSViresh Kumar #define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs) 113cffc96ebSViresh Kumar 114cffc96ebSViresh Kumar static struct cpufreq_frequency_table 115cffc96ebSViresh Kumar pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1]; 116cffc96ebSViresh Kumar static struct cpufreq_frequency_table 117cffc96ebSViresh Kumar pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1]; 118cffc96ebSViresh Kumar 119cffc96ebSViresh Kumar static unsigned int pxa255_turbo_table; 120cffc96ebSViresh Kumar module_param(pxa255_turbo_table, uint, 0); 121cffc96ebSViresh Kumar MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table, !0 = turbo table)"); 122cffc96ebSViresh Kumar 123cffc96ebSViresh Kumar /* 124cffc96ebSViresh Kumar * PXA270 definitions 125cffc96ebSViresh Kumar * 126cffc96ebSViresh Kumar * For the PXA27x: 127cffc96ebSViresh Kumar * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG. 128cffc96ebSViresh Kumar * 129cffc96ebSViresh Kumar * A = 0 => memory controller clock from table 3-7, 130cffc96ebSViresh Kumar * A = 1 => memory controller clock = system bus clock 131cffc96ebSViresh Kumar * Run mode frequency = 13 MHz * L 132cffc96ebSViresh Kumar * Turbo mode frequency = 13 MHz * L * N 133cffc96ebSViresh Kumar * System bus frequency = 13 MHz * L / (B + 1) 134cffc96ebSViresh Kumar * 135cffc96ebSViresh Kumar * In CCCR: 136cffc96ebSViresh Kumar * A = 1 137cffc96ebSViresh Kumar * L = 16 oscillator to run mode ratio 138cffc96ebSViresh Kumar * 2N = 6 2 * (turbo mode to run mode ratio) 139cffc96ebSViresh Kumar * 140cffc96ebSViresh Kumar * In CCLKCFG: 141cffc96ebSViresh Kumar * B = 1 Fast bus mode 142cffc96ebSViresh Kumar * HT = 0 Half-Turbo mode 143cffc96ebSViresh Kumar * T = 1 Turbo mode 144cffc96ebSViresh Kumar * 145cffc96ebSViresh Kumar * For now, just support some of the combinations in table 3-7 of 146cffc96ebSViresh Kumar * PXA27x Processor Family Developer's Manual to simplify frequency 147cffc96ebSViresh Kumar * change sequences. 148cffc96ebSViresh Kumar */ 149cffc96ebSViresh Kumar #define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L) 150cffc96ebSViresh Kumar #define CCLKCFG2(B, HT, T) \ 151cffc96ebSViresh Kumar (CCLKCFG_FCS | \ 152cffc96ebSViresh Kumar ((B) ? CCLKCFG_FASTBUS : 0) | \ 153cffc96ebSViresh Kumar ((HT) ? CCLKCFG_HALFTURBO : 0) | \ 154cffc96ebSViresh Kumar ((T) ? CCLKCFG_TURBO : 0)) 155cffc96ebSViresh Kumar 156cffc96ebSViresh Kumar static pxa_freqs_t pxa27x_freqs[] = { 157cffc96ebSViresh Kumar {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 }, 158cffc96ebSViresh Kumar {156000, 104000, PXA27x_CCCR(1, 8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 }, 159cffc96ebSViresh Kumar {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 }, 160cffc96ebSViresh Kumar {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 }, 161cffc96ebSViresh Kumar {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 }, 162cffc96ebSViresh Kumar {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1), 1450000, 1705000 }, 163cffc96ebSViresh Kumar {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1), 1550000, 1705000 } 164cffc96ebSViresh Kumar }; 165cffc96ebSViresh Kumar 166cffc96ebSViresh Kumar #define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs) 167cffc96ebSViresh Kumar static struct cpufreq_frequency_table 168cffc96ebSViresh Kumar pxa27x_freq_table[NUM_PXA27x_FREQS+1]; 169cffc96ebSViresh Kumar 170cffc96ebSViresh Kumar extern unsigned get_clk_frequency_khz(int info); 171cffc96ebSViresh Kumar 172cffc96ebSViresh Kumar #ifdef CONFIG_REGULATOR 173cffc96ebSViresh Kumar 174cffc96ebSViresh Kumar static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) 175cffc96ebSViresh Kumar { 176cffc96ebSViresh Kumar int ret = 0; 177cffc96ebSViresh Kumar int vmin, vmax; 178cffc96ebSViresh Kumar 179cffc96ebSViresh Kumar if (!cpu_is_pxa27x()) 180cffc96ebSViresh Kumar return 0; 181cffc96ebSViresh Kumar 182cffc96ebSViresh Kumar vmin = pxa_freq->vmin; 183cffc96ebSViresh Kumar vmax = pxa_freq->vmax; 184cffc96ebSViresh Kumar if ((vmin == -1) || (vmax == -1)) 185cffc96ebSViresh Kumar return 0; 186cffc96ebSViresh Kumar 187cffc96ebSViresh Kumar ret = regulator_set_voltage(vcc_core, vmin, vmax); 188cffc96ebSViresh Kumar if (ret) 189cffc96ebSViresh Kumar pr_err("cpufreq: Failed to set vcc_core in [%dmV..%dmV]\n", 190cffc96ebSViresh Kumar vmin, vmax); 191cffc96ebSViresh Kumar return ret; 192cffc96ebSViresh Kumar } 193cffc96ebSViresh Kumar 194cffc96ebSViresh Kumar static __init void pxa_cpufreq_init_voltages(void) 195cffc96ebSViresh Kumar { 196cffc96ebSViresh Kumar vcc_core = regulator_get(NULL, "vcc_core"); 197cffc96ebSViresh Kumar if (IS_ERR(vcc_core)) { 198cffc96ebSViresh Kumar pr_info("cpufreq: Didn't find vcc_core regulator\n"); 199cffc96ebSViresh Kumar vcc_core = NULL; 200cffc96ebSViresh Kumar } else { 201cffc96ebSViresh Kumar pr_info("cpufreq: Found vcc_core regulator\n"); 202cffc96ebSViresh Kumar } 203cffc96ebSViresh Kumar } 204cffc96ebSViresh Kumar #else 205cffc96ebSViresh Kumar static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) 206cffc96ebSViresh Kumar { 207cffc96ebSViresh Kumar return 0; 208cffc96ebSViresh Kumar } 209cffc96ebSViresh Kumar 210cffc96ebSViresh Kumar static __init void pxa_cpufreq_init_voltages(void) { } 211cffc96ebSViresh Kumar #endif 212cffc96ebSViresh Kumar 213cffc96ebSViresh Kumar static void find_freq_tables(struct cpufreq_frequency_table **freq_table, 214cffc96ebSViresh Kumar pxa_freqs_t **pxa_freqs) 215cffc96ebSViresh Kumar { 216cffc96ebSViresh Kumar if (cpu_is_pxa25x()) { 217cffc96ebSViresh Kumar if (!pxa255_turbo_table) { 218cffc96ebSViresh Kumar *pxa_freqs = pxa255_run_freqs; 219cffc96ebSViresh Kumar *freq_table = pxa255_run_freq_table; 220cffc96ebSViresh Kumar } else { 221cffc96ebSViresh Kumar *pxa_freqs = pxa255_turbo_freqs; 222cffc96ebSViresh Kumar *freq_table = pxa255_turbo_freq_table; 223cffc96ebSViresh Kumar } 224*7264a2bbSArnd Bergmann } else if (cpu_is_pxa27x()) { 225cffc96ebSViresh Kumar *pxa_freqs = pxa27x_freqs; 226cffc96ebSViresh Kumar *freq_table = pxa27x_freq_table; 227*7264a2bbSArnd Bergmann } else { 228*7264a2bbSArnd Bergmann BUG(); 229cffc96ebSViresh Kumar } 230cffc96ebSViresh Kumar } 231cffc96ebSViresh Kumar 232cffc96ebSViresh Kumar static void pxa27x_guess_max_freq(void) 233cffc96ebSViresh Kumar { 234cffc96ebSViresh Kumar if (!pxa27x_maxfreq) { 235cffc96ebSViresh Kumar pxa27x_maxfreq = 416000; 236cffc96ebSViresh Kumar printk(KERN_INFO "PXA CPU 27x max frequency not defined " 237cffc96ebSViresh Kumar "(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n", 238cffc96ebSViresh Kumar pxa27x_maxfreq); 239cffc96ebSViresh Kumar } else { 240cffc96ebSViresh Kumar pxa27x_maxfreq *= 1000; 241cffc96ebSViresh Kumar } 242cffc96ebSViresh Kumar } 243cffc96ebSViresh Kumar 244cffc96ebSViresh Kumar static void init_sdram_rows(void) 245cffc96ebSViresh Kumar { 246cffc96ebSViresh Kumar uint32_t mdcnfg = __raw_readl(MDCNFG); 247cffc96ebSViresh Kumar unsigned int drac2 = 0, drac0 = 0; 248cffc96ebSViresh Kumar 249cffc96ebSViresh Kumar if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3)) 250cffc96ebSViresh Kumar drac2 = MDCNFG_DRAC2(mdcnfg); 251cffc96ebSViresh Kumar 252cffc96ebSViresh Kumar if (mdcnfg & (MDCNFG_DE0 | MDCNFG_DE1)) 253cffc96ebSViresh Kumar drac0 = MDCNFG_DRAC0(mdcnfg); 254cffc96ebSViresh Kumar 255cffc96ebSViresh Kumar sdram_rows = 1 << (11 + max(drac0, drac2)); 256cffc96ebSViresh Kumar } 257cffc96ebSViresh Kumar 258cffc96ebSViresh Kumar static u32 mdrefr_dri(unsigned int freq) 259cffc96ebSViresh Kumar { 260cffc96ebSViresh Kumar u32 interval = freq * SDRAM_TREF / sdram_rows; 261cffc96ebSViresh Kumar 262cffc96ebSViresh Kumar return (interval - (cpu_is_pxa27x() ? 31 : 0)) / 32; 263cffc96ebSViresh Kumar } 264cffc96ebSViresh Kumar 265cffc96ebSViresh Kumar /* find a valid frequency point */ 266cffc96ebSViresh Kumar static int pxa_verify_policy(struct cpufreq_policy *policy) 267cffc96ebSViresh Kumar { 268cffc96ebSViresh Kumar struct cpufreq_frequency_table *pxa_freqs_table; 269cffc96ebSViresh Kumar pxa_freqs_t *pxa_freqs; 270cffc96ebSViresh Kumar int ret; 271cffc96ebSViresh Kumar 272cffc96ebSViresh Kumar find_freq_tables(&pxa_freqs_table, &pxa_freqs); 273cffc96ebSViresh Kumar ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table); 274cffc96ebSViresh Kumar 275cffc96ebSViresh Kumar if (freq_debug) 276cffc96ebSViresh Kumar pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n", 277cffc96ebSViresh Kumar policy->min, policy->max); 278cffc96ebSViresh Kumar 279cffc96ebSViresh Kumar return ret; 280cffc96ebSViresh Kumar } 281cffc96ebSViresh Kumar 282cffc96ebSViresh Kumar static unsigned int pxa_cpufreq_get(unsigned int cpu) 283cffc96ebSViresh Kumar { 284cffc96ebSViresh Kumar return get_clk_frequency_khz(0); 285cffc96ebSViresh Kumar } 286cffc96ebSViresh Kumar 287cffc96ebSViresh Kumar static int pxa_set_target(struct cpufreq_policy *policy, 288cffc96ebSViresh Kumar unsigned int target_freq, 289cffc96ebSViresh Kumar unsigned int relation) 290cffc96ebSViresh Kumar { 291cffc96ebSViresh Kumar struct cpufreq_frequency_table *pxa_freqs_table; 292cffc96ebSViresh Kumar pxa_freqs_t *pxa_freq_settings; 293cffc96ebSViresh Kumar struct cpufreq_freqs freqs; 294cffc96ebSViresh Kumar unsigned int idx; 295cffc96ebSViresh Kumar unsigned long flags; 296cffc96ebSViresh Kumar unsigned int new_freq_cpu, new_freq_mem; 297cffc96ebSViresh Kumar unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; 298cffc96ebSViresh Kumar int ret = 0; 299cffc96ebSViresh Kumar 300cffc96ebSViresh Kumar /* Get the current policy */ 301cffc96ebSViresh Kumar find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); 302cffc96ebSViresh Kumar 303cffc96ebSViresh Kumar /* Lookup the next frequency */ 304cffc96ebSViresh Kumar if (cpufreq_frequency_table_target(policy, pxa_freqs_table, 305cffc96ebSViresh Kumar target_freq, relation, &idx)) { 306cffc96ebSViresh Kumar return -EINVAL; 307cffc96ebSViresh Kumar } 308cffc96ebSViresh Kumar 309cffc96ebSViresh Kumar new_freq_cpu = pxa_freq_settings[idx].khz; 310cffc96ebSViresh Kumar new_freq_mem = pxa_freq_settings[idx].membus; 311cffc96ebSViresh Kumar freqs.old = policy->cur; 312cffc96ebSViresh Kumar freqs.new = new_freq_cpu; 313cffc96ebSViresh Kumar 314cffc96ebSViresh Kumar if (freq_debug) 315cffc96ebSViresh Kumar pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", 316cffc96ebSViresh Kumar freqs.new / 1000, (pxa_freq_settings[idx].div2) ? 317cffc96ebSViresh Kumar (new_freq_mem / 2000) : (new_freq_mem / 1000)); 318cffc96ebSViresh Kumar 319cffc96ebSViresh Kumar if (vcc_core && freqs.new > freqs.old) 320cffc96ebSViresh Kumar ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); 321cffc96ebSViresh Kumar if (ret) 322cffc96ebSViresh Kumar return ret; 323cffc96ebSViresh Kumar /* 324cffc96ebSViresh Kumar * Tell everyone what we're about to do... 325cffc96ebSViresh Kumar * you should add a notify client with any platform specific 326cffc96ebSViresh Kumar * Vcc changing capability 327cffc96ebSViresh Kumar */ 328cffc96ebSViresh Kumar cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 329cffc96ebSViresh Kumar 330cffc96ebSViresh Kumar /* Calculate the next MDREFR. If we're slowing down the SDRAM clock 331cffc96ebSViresh Kumar * we need to preset the smaller DRI before the change. If we're 332cffc96ebSViresh Kumar * speeding up we need to set the larger DRI value after the change. 333cffc96ebSViresh Kumar */ 334cffc96ebSViresh Kumar preset_mdrefr = postset_mdrefr = __raw_readl(MDREFR); 335cffc96ebSViresh Kumar if ((preset_mdrefr & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) { 336cffc96ebSViresh Kumar preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK); 337cffc96ebSViresh Kumar preset_mdrefr |= mdrefr_dri(new_freq_mem); 338cffc96ebSViresh Kumar } 339cffc96ebSViresh Kumar postset_mdrefr = 340cffc96ebSViresh Kumar (postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem); 341cffc96ebSViresh Kumar 342cffc96ebSViresh Kumar /* If we're dividing the memory clock by two for the SDRAM clock, this 343cffc96ebSViresh Kumar * must be set prior to the change. Clearing the divide must be done 344cffc96ebSViresh Kumar * after the change. 345cffc96ebSViresh Kumar */ 346cffc96ebSViresh Kumar if (pxa_freq_settings[idx].div2) { 347cffc96ebSViresh Kumar preset_mdrefr |= MDREFR_DB2_MASK; 348cffc96ebSViresh Kumar postset_mdrefr |= MDREFR_DB2_MASK; 349cffc96ebSViresh Kumar } else { 350cffc96ebSViresh Kumar postset_mdrefr &= ~MDREFR_DB2_MASK; 351cffc96ebSViresh Kumar } 352cffc96ebSViresh Kumar 353cffc96ebSViresh Kumar local_irq_save(flags); 354cffc96ebSViresh Kumar 355cffc96ebSViresh Kumar /* Set new the CCCR and prepare CCLKCFG */ 356cffc96ebSViresh Kumar CCCR = pxa_freq_settings[idx].cccr; 357cffc96ebSViresh Kumar cclkcfg = pxa_freq_settings[idx].cclkcfg; 358cffc96ebSViresh Kumar 359cffc96ebSViresh Kumar asm volatile(" \n\ 360cffc96ebSViresh Kumar ldr r4, [%1] /* load MDREFR */ \n\ 361cffc96ebSViresh Kumar b 2f \n\ 362cffc96ebSViresh Kumar .align 5 \n\ 363cffc96ebSViresh Kumar 1: \n\ 364cffc96ebSViresh Kumar str %3, [%1] /* preset the MDREFR */ \n\ 365cffc96ebSViresh Kumar mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\ 366cffc96ebSViresh Kumar str %4, [%1] /* postset the MDREFR */ \n\ 367cffc96ebSViresh Kumar \n\ 368cffc96ebSViresh Kumar b 3f \n\ 369cffc96ebSViresh Kumar 2: b 1b \n\ 370cffc96ebSViresh Kumar 3: nop \n\ 371cffc96ebSViresh Kumar " 372cffc96ebSViresh Kumar : "=&r" (unused) 373cffc96ebSViresh Kumar : "r" (MDREFR), "r" (cclkcfg), 374cffc96ebSViresh Kumar "r" (preset_mdrefr), "r" (postset_mdrefr) 375cffc96ebSViresh Kumar : "r4", "r5"); 376cffc96ebSViresh Kumar local_irq_restore(flags); 377cffc96ebSViresh Kumar 378cffc96ebSViresh Kumar /* 379cffc96ebSViresh Kumar * Tell everyone what we've just done... 380cffc96ebSViresh Kumar * you should add a notify client with any platform specific 381cffc96ebSViresh Kumar * SDRAM refresh timer adjustments 382cffc96ebSViresh Kumar */ 383cffc96ebSViresh Kumar cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 384cffc96ebSViresh Kumar 385cffc96ebSViresh Kumar /* 386cffc96ebSViresh Kumar * Even if voltage setting fails, we don't report it, as the frequency 387cffc96ebSViresh Kumar * change succeeded. The voltage reduction is not a critical failure, 388cffc96ebSViresh Kumar * only power savings will suffer from this. 389cffc96ebSViresh Kumar * 390cffc96ebSViresh Kumar * Note: if the voltage change fails, and a return value is returned, a 391cffc96ebSViresh Kumar * bug is triggered (seems a deadlock). Should anybody find out where, 392cffc96ebSViresh Kumar * the "return 0" should become a "return ret". 393cffc96ebSViresh Kumar */ 394cffc96ebSViresh Kumar if (vcc_core && freqs.new < freqs.old) 395cffc96ebSViresh Kumar ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); 396cffc96ebSViresh Kumar 397cffc96ebSViresh Kumar return 0; 398cffc96ebSViresh Kumar } 399cffc96ebSViresh Kumar 400cffc96ebSViresh Kumar static int pxa_cpufreq_init(struct cpufreq_policy *policy) 401cffc96ebSViresh Kumar { 402cffc96ebSViresh Kumar int i; 403cffc96ebSViresh Kumar unsigned int freq; 404cffc96ebSViresh Kumar struct cpufreq_frequency_table *pxa255_freq_table; 405cffc96ebSViresh Kumar pxa_freqs_t *pxa255_freqs; 406cffc96ebSViresh Kumar 407cffc96ebSViresh Kumar /* try to guess pxa27x cpu */ 408cffc96ebSViresh Kumar if (cpu_is_pxa27x()) 409cffc96ebSViresh Kumar pxa27x_guess_max_freq(); 410cffc96ebSViresh Kumar 411cffc96ebSViresh Kumar pxa_cpufreq_init_voltages(); 412cffc96ebSViresh Kumar 413cffc96ebSViresh Kumar init_sdram_rows(); 414cffc96ebSViresh Kumar 415cffc96ebSViresh Kumar /* set default policy and cpuinfo */ 416cffc96ebSViresh Kumar policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ 417cffc96ebSViresh Kumar policy->cur = get_clk_frequency_khz(0); /* current freq */ 418cffc96ebSViresh Kumar policy->min = policy->max = policy->cur; 419cffc96ebSViresh Kumar 420cffc96ebSViresh Kumar /* Generate pxa25x the run cpufreq_frequency_table struct */ 421cffc96ebSViresh Kumar for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) { 422cffc96ebSViresh Kumar pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz; 423cffc96ebSViresh Kumar pxa255_run_freq_table[i].index = i; 424cffc96ebSViresh Kumar } 425cffc96ebSViresh Kumar pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END; 426cffc96ebSViresh Kumar 427cffc96ebSViresh Kumar /* Generate pxa25x the turbo cpufreq_frequency_table struct */ 428cffc96ebSViresh Kumar for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) { 429cffc96ebSViresh Kumar pxa255_turbo_freq_table[i].frequency = 430cffc96ebSViresh Kumar pxa255_turbo_freqs[i].khz; 431cffc96ebSViresh Kumar pxa255_turbo_freq_table[i].index = i; 432cffc96ebSViresh Kumar } 433cffc96ebSViresh Kumar pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; 434cffc96ebSViresh Kumar 435cffc96ebSViresh Kumar pxa255_turbo_table = !!pxa255_turbo_table; 436cffc96ebSViresh Kumar 437cffc96ebSViresh Kumar /* Generate the pxa27x cpufreq_frequency_table struct */ 438cffc96ebSViresh Kumar for (i = 0; i < NUM_PXA27x_FREQS; i++) { 439cffc96ebSViresh Kumar freq = pxa27x_freqs[i].khz; 440cffc96ebSViresh Kumar if (freq > pxa27x_maxfreq) 441cffc96ebSViresh Kumar break; 442cffc96ebSViresh Kumar pxa27x_freq_table[i].frequency = freq; 443cffc96ebSViresh Kumar pxa27x_freq_table[i].index = i; 444cffc96ebSViresh Kumar } 445cffc96ebSViresh Kumar pxa27x_freq_table[i].index = i; 446cffc96ebSViresh Kumar pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; 447cffc96ebSViresh Kumar 448cffc96ebSViresh Kumar /* 449cffc96ebSViresh Kumar * Set the policy's minimum and maximum frequencies from the tables 450cffc96ebSViresh Kumar * just constructed. This sets cpuinfo.mxx_freq, min and max. 451cffc96ebSViresh Kumar */ 452cffc96ebSViresh Kumar if (cpu_is_pxa25x()) { 453cffc96ebSViresh Kumar find_freq_tables(&pxa255_freq_table, &pxa255_freqs); 454cffc96ebSViresh Kumar pr_info("PXA255 cpufreq using %s frequency table\n", 455cffc96ebSViresh Kumar pxa255_turbo_table ? "turbo" : "run"); 456cffc96ebSViresh Kumar cpufreq_frequency_table_cpuinfo(policy, pxa255_freq_table); 457cffc96ebSViresh Kumar } 458cffc96ebSViresh Kumar else if (cpu_is_pxa27x()) 459cffc96ebSViresh Kumar cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table); 460cffc96ebSViresh Kumar 461cffc96ebSViresh Kumar printk(KERN_INFO "PXA CPU frequency change support initialized\n"); 462cffc96ebSViresh Kumar 463cffc96ebSViresh Kumar return 0; 464cffc96ebSViresh Kumar } 465cffc96ebSViresh Kumar 466cffc96ebSViresh Kumar static struct cpufreq_driver pxa_cpufreq_driver = { 467cffc96ebSViresh Kumar .verify = pxa_verify_policy, 468cffc96ebSViresh Kumar .target = pxa_set_target, 469cffc96ebSViresh Kumar .init = pxa_cpufreq_init, 470cffc96ebSViresh Kumar .get = pxa_cpufreq_get, 471cffc96ebSViresh Kumar .name = "PXA2xx", 472cffc96ebSViresh Kumar }; 473cffc96ebSViresh Kumar 474cffc96ebSViresh Kumar static int __init pxa_cpu_init(void) 475cffc96ebSViresh Kumar { 476cffc96ebSViresh Kumar int ret = -ENODEV; 477cffc96ebSViresh Kumar if (cpu_is_pxa25x() || cpu_is_pxa27x()) 478cffc96ebSViresh Kumar ret = cpufreq_register_driver(&pxa_cpufreq_driver); 479cffc96ebSViresh Kumar return ret; 480cffc96ebSViresh Kumar } 481cffc96ebSViresh Kumar 482cffc96ebSViresh Kumar static void __exit pxa_cpu_exit(void) 483cffc96ebSViresh Kumar { 484cffc96ebSViresh Kumar cpufreq_unregister_driver(&pxa_cpufreq_driver); 485cffc96ebSViresh Kumar } 486cffc96ebSViresh Kumar 487cffc96ebSViresh Kumar 488cffc96ebSViresh Kumar MODULE_AUTHOR("Intrinsyc Software Inc."); 489cffc96ebSViresh Kumar MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture"); 490cffc96ebSViresh Kumar MODULE_LICENSE("GPL"); 491cffc96ebSViresh Kumar module_init(pxa_cpu_init); 492cffc96ebSViresh Kumar module_exit(pxa_cpu_exit); 493