322 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2002,2003 Intrinsyc Software4 *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 any12 * platform specific access timing changes... for example if you have flash13 * memory connected to CS0, you will need to register a platform specific14 * notifier which will adjust the memory access strobes to maintain a15 * minimum strobe width.16 */17 18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt19 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 DEBUG31static 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#else35#define freq_debug 036#endif37 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 definitions58 */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_table85 pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1];86static struct cpufreq_frequency_table87 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_table105 pxa27x_freq_table[NUM_PXA27x_FREQS+1];106 107#ifdef CONFIG_REGULATOR108 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#else139static 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#endif146 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 frequency211 * 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, a215 * 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 tables270 * 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);322