pxa2xx-cpufreq.c (8872B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2002,2003 Intrinsyc Software 4 * 5 * History: 6 * 31-Jul-2002 : Initial version [FB] 7 * 29-Jan-2003 : added PXA255 support [FB] 8 * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) 9 * 10 * Note: 11 * This driver may change the memory bus clock rate, but will not do any 12 * platform specific access timing changes... for example if you have flash 13 * memory connected to CS0, you will need to register a platform specific 14 * notifier which will adjust the memory access strobes to maintain a 15 * minimum strobe width. 16 */ 17 18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 19 20#include <linux/kernel.h> 21#include <linux/module.h> 22#include <linux/sched.h> 23#include <linux/init.h> 24#include <linux/cpufreq.h> 25#include <linux/err.h> 26#include <linux/regulator/consumer.h> 27#include <linux/soc/pxa/cpu.h> 28#include <linux/io.h> 29 30#ifdef DEBUG 31static unsigned int freq_debug; 32module_param(freq_debug, uint, 0); 33MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); 34#else 35#define freq_debug 0 36#endif 37 38static struct regulator *vcc_core; 39 40static unsigned int pxa27x_maxfreq; 41module_param(pxa27x_maxfreq, uint, 0); 42MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz" 43 "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)"); 44 45struct pxa_cpufreq_data { 46 struct clk *clk_core; 47}; 48static struct pxa_cpufreq_data pxa_cpufreq_data; 49 50struct pxa_freqs { 51 unsigned int khz; 52 int vmin; 53 int vmax; 54}; 55 56/* 57 * PXA255 definitions 58 */ 59static const struct pxa_freqs pxa255_run_freqs[] = 60{ 61 /* CPU MEMBUS run turbo PXbus SDRAM */ 62 { 99500, -1, -1}, /* 99, 99, 50, 50 */ 63 {132700, -1, -1}, /* 133, 133, 66, 66 */ 64 {199100, -1, -1}, /* 199, 199, 99, 99 */ 65 {265400, -1, -1}, /* 265, 265, 133, 66 */ 66 {331800, -1, -1}, /* 331, 331, 166, 83 */ 67 {398100, -1, -1}, /* 398, 398, 196, 99 */ 68}; 69 70/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ 71static const struct pxa_freqs pxa255_turbo_freqs[] = 72{ 73 /* CPU run turbo PXbus SDRAM */ 74 { 99500, -1, -1}, /* 99, 99, 50, 50 */ 75 {199100, -1, -1}, /* 99, 199, 50, 99 */ 76 {298500, -1, -1}, /* 99, 287, 50, 99 */ 77 {298600, -1, -1}, /* 199, 287, 99, 99 */ 78 {398100, -1, -1}, /* 199, 398, 99, 99 */ 79}; 80 81#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs) 82#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs) 83 84static struct cpufreq_frequency_table 85 pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1]; 86static struct cpufreq_frequency_table 87 pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1]; 88 89static unsigned int pxa255_turbo_table; 90module_param(pxa255_turbo_table, uint, 0); 91MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table, !0 = turbo table)"); 92 93static struct pxa_freqs pxa27x_freqs[] = { 94 {104000, 900000, 1705000 }, 95 {156000, 1000000, 1705000 }, 96 {208000, 1180000, 1705000 }, 97 {312000, 1250000, 1705000 }, 98 {416000, 1350000, 1705000 }, 99 {520000, 1450000, 1705000 }, 100 {624000, 1550000, 1705000 } 101}; 102 103#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs) 104static struct cpufreq_frequency_table 105 pxa27x_freq_table[NUM_PXA27x_FREQS+1]; 106 107#ifdef CONFIG_REGULATOR 108 109static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) 110{ 111 int ret = 0; 112 int vmin, vmax; 113 114 if (!cpu_is_pxa27x()) 115 return 0; 116 117 vmin = pxa_freq->vmin; 118 vmax = pxa_freq->vmax; 119 if ((vmin == -1) || (vmax == -1)) 120 return 0; 121 122 ret = regulator_set_voltage(vcc_core, vmin, vmax); 123 if (ret) 124 pr_err("Failed to set vcc_core in [%dmV..%dmV]\n", vmin, vmax); 125 return ret; 126} 127 128static void pxa_cpufreq_init_voltages(void) 129{ 130 vcc_core = regulator_get(NULL, "vcc_core"); 131 if (IS_ERR(vcc_core)) { 132 pr_info("Didn't find vcc_core regulator\n"); 133 vcc_core = NULL; 134 } else { 135 pr_info("Found vcc_core regulator\n"); 136 } 137} 138#else 139static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) 140{ 141 return 0; 142} 143 144static void pxa_cpufreq_init_voltages(void) { } 145#endif 146 147static void find_freq_tables(struct cpufreq_frequency_table **freq_table, 148 const struct pxa_freqs **pxa_freqs) 149{ 150 if (cpu_is_pxa25x()) { 151 if (!pxa255_turbo_table) { 152 *pxa_freqs = pxa255_run_freqs; 153 *freq_table = pxa255_run_freq_table; 154 } else { 155 *pxa_freqs = pxa255_turbo_freqs; 156 *freq_table = pxa255_turbo_freq_table; 157 } 158 } else if (cpu_is_pxa27x()) { 159 *pxa_freqs = pxa27x_freqs; 160 *freq_table = pxa27x_freq_table; 161 } else { 162 BUG(); 163 } 164} 165 166static void pxa27x_guess_max_freq(void) 167{ 168 if (!pxa27x_maxfreq) { 169 pxa27x_maxfreq = 416000; 170 pr_info("PXA CPU 27x max frequency not defined (pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n", 171 pxa27x_maxfreq); 172 } else { 173 pxa27x_maxfreq *= 1000; 174 } 175} 176 177static unsigned int pxa_cpufreq_get(unsigned int cpu) 178{ 179 struct pxa_cpufreq_data *data = cpufreq_get_driver_data(); 180 181 return (unsigned int) clk_get_rate(data->clk_core) / 1000; 182} 183 184static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx) 185{ 186 struct cpufreq_frequency_table *pxa_freqs_table; 187 const struct pxa_freqs *pxa_freq_settings; 188 struct pxa_cpufreq_data *data = cpufreq_get_driver_data(); 189 unsigned int new_freq_cpu; 190 int ret = 0; 191 192 /* Get the current policy */ 193 find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); 194 195 new_freq_cpu = pxa_freq_settings[idx].khz; 196 197 if (freq_debug) 198 pr_debug("Changing CPU frequency from %d Mhz to %d Mhz\n", 199 policy->cur / 1000, new_freq_cpu / 1000); 200 201 if (vcc_core && new_freq_cpu > policy->cur) { 202 ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); 203 if (ret) 204 return ret; 205 } 206 207 clk_set_rate(data->clk_core, new_freq_cpu * 1000); 208 209 /* 210 * Even if voltage setting fails, we don't report it, as the frequency 211 * change succeeded. The voltage reduction is not a critical failure, 212 * only power savings will suffer from this. 213 * 214 * Note: if the voltage change fails, and a return value is returned, a 215 * bug is triggered (seems a deadlock). Should anybody find out where, 216 * the "return 0" should become a "return ret". 217 */ 218 if (vcc_core && new_freq_cpu < policy->cur) 219 ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); 220 221 return 0; 222} 223 224static int pxa_cpufreq_init(struct cpufreq_policy *policy) 225{ 226 int i; 227 unsigned int freq; 228 struct cpufreq_frequency_table *pxa255_freq_table; 229 const struct pxa_freqs *pxa255_freqs; 230 231 /* try to guess pxa27x cpu */ 232 if (cpu_is_pxa27x()) 233 pxa27x_guess_max_freq(); 234 235 pxa_cpufreq_init_voltages(); 236 237 /* set default policy and cpuinfo */ 238 policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ 239 240 /* Generate pxa25x the run cpufreq_frequency_table struct */ 241 for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) { 242 pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz; 243 pxa255_run_freq_table[i].driver_data = i; 244 } 245 pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END; 246 247 /* Generate pxa25x the turbo cpufreq_frequency_table struct */ 248 for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) { 249 pxa255_turbo_freq_table[i].frequency = 250 pxa255_turbo_freqs[i].khz; 251 pxa255_turbo_freq_table[i].driver_data = i; 252 } 253 pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; 254 255 pxa255_turbo_table = !!pxa255_turbo_table; 256 257 /* Generate the pxa27x cpufreq_frequency_table struct */ 258 for (i = 0; i < NUM_PXA27x_FREQS; i++) { 259 freq = pxa27x_freqs[i].khz; 260 if (freq > pxa27x_maxfreq) 261 break; 262 pxa27x_freq_table[i].frequency = freq; 263 pxa27x_freq_table[i].driver_data = i; 264 } 265 pxa27x_freq_table[i].driver_data = i; 266 pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; 267 268 /* 269 * Set the policy's minimum and maximum frequencies from the tables 270 * just constructed. This sets cpuinfo.mxx_freq, min and max. 271 */ 272 if (cpu_is_pxa25x()) { 273 find_freq_tables(&pxa255_freq_table, &pxa255_freqs); 274 pr_info("using %s frequency table\n", 275 pxa255_turbo_table ? "turbo" : "run"); 276 277 policy->freq_table = pxa255_freq_table; 278 } 279 else if (cpu_is_pxa27x()) { 280 policy->freq_table = pxa27x_freq_table; 281 } 282 283 pr_info("frequency change support initialized\n"); 284 285 return 0; 286} 287 288static struct cpufreq_driver pxa_cpufreq_driver = { 289 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, 290 .verify = cpufreq_generic_frequency_table_verify, 291 .target_index = pxa_set_target, 292 .init = pxa_cpufreq_init, 293 .get = pxa_cpufreq_get, 294 .name = "PXA2xx", 295 .driver_data = &pxa_cpufreq_data, 296}; 297 298static int __init pxa_cpu_init(void) 299{ 300 int ret = -ENODEV; 301 302 pxa_cpufreq_data.clk_core = clk_get_sys(NULL, "core"); 303 if (IS_ERR(pxa_cpufreq_data.clk_core)) 304 return PTR_ERR(pxa_cpufreq_data.clk_core); 305 306 if (cpu_is_pxa25x() || cpu_is_pxa27x()) 307 ret = cpufreq_register_driver(&pxa_cpufreq_driver); 308 return ret; 309} 310 311static void __exit pxa_cpu_exit(void) 312{ 313 cpufreq_unregister_driver(&pxa_cpufreq_driver); 314} 315 316 317MODULE_AUTHOR("Intrinsyc Software Inc."); 318MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture"); 319MODULE_LICENSE("GPL"); 320module_init(pxa_cpu_init); 321module_exit(pxa_cpu_exit);