0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0019
0020 #include <linux/kernel.h>
0021 #include <linux/module.h>
0022 #include <linux/sched.h>
0023 #include <linux/init.h>
0024 #include <linux/cpufreq.h>
0025 #include <linux/err.h>
0026 #include <linux/regulator/consumer.h>
0027 #include <linux/soc/pxa/cpu.h>
0028 #include <linux/io.h>
0029
0030 #ifdef DEBUG
0031 static unsigned int freq_debug;
0032 module_param(freq_debug, uint, 0);
0033 MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
0034 #else
0035 #define freq_debug 0
0036 #endif
0037
0038 static struct regulator *vcc_core;
0039
0040 static unsigned int pxa27x_maxfreq;
0041 module_param(pxa27x_maxfreq, uint, 0);
0042 MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
0043 "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)");
0044
0045 struct pxa_cpufreq_data {
0046 struct clk *clk_core;
0047 };
0048 static struct pxa_cpufreq_data pxa_cpufreq_data;
0049
0050 struct pxa_freqs {
0051 unsigned int khz;
0052 int vmin;
0053 int vmax;
0054 };
0055
0056
0057
0058
0059 static const struct pxa_freqs pxa255_run_freqs[] =
0060 {
0061
0062 { 99500, -1, -1},
0063 {132700, -1, -1},
0064 {199100, -1, -1},
0065 {265400, -1, -1},
0066 {331800, -1, -1},
0067 {398100, -1, -1},
0068 };
0069
0070
0071 static const struct pxa_freqs pxa255_turbo_freqs[] =
0072 {
0073
0074 { 99500, -1, -1},
0075 {199100, -1, -1},
0076 {298500, -1, -1},
0077 {298600, -1, -1},
0078 {398100, -1, -1},
0079 };
0080
0081 #define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
0082 #define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
0083
0084 static struct cpufreq_frequency_table
0085 pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1];
0086 static struct cpufreq_frequency_table
0087 pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1];
0088
0089 static unsigned int pxa255_turbo_table;
0090 module_param(pxa255_turbo_table, uint, 0);
0091 MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table, !0 = turbo table)");
0092
0093 static struct pxa_freqs pxa27x_freqs[] = {
0094 {104000, 900000, 1705000 },
0095 {156000, 1000000, 1705000 },
0096 {208000, 1180000, 1705000 },
0097 {312000, 1250000, 1705000 },
0098 {416000, 1350000, 1705000 },
0099 {520000, 1450000, 1705000 },
0100 {624000, 1550000, 1705000 }
0101 };
0102
0103 #define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs)
0104 static struct cpufreq_frequency_table
0105 pxa27x_freq_table[NUM_PXA27x_FREQS+1];
0106
0107 #ifdef CONFIG_REGULATOR
0108
0109 static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq)
0110 {
0111 int ret = 0;
0112 int vmin, vmax;
0113
0114 if (!cpu_is_pxa27x())
0115 return 0;
0116
0117 vmin = pxa_freq->vmin;
0118 vmax = pxa_freq->vmax;
0119 if ((vmin == -1) || (vmax == -1))
0120 return 0;
0121
0122 ret = regulator_set_voltage(vcc_core, vmin, vmax);
0123 if (ret)
0124 pr_err("Failed to set vcc_core in [%dmV..%dmV]\n", vmin, vmax);
0125 return ret;
0126 }
0127
0128 static void pxa_cpufreq_init_voltages(void)
0129 {
0130 vcc_core = regulator_get(NULL, "vcc_core");
0131 if (IS_ERR(vcc_core)) {
0132 pr_info("Didn't find vcc_core regulator\n");
0133 vcc_core = NULL;
0134 } else {
0135 pr_info("Found vcc_core regulator\n");
0136 }
0137 }
0138 #else
0139 static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq)
0140 {
0141 return 0;
0142 }
0143
0144 static void pxa_cpufreq_init_voltages(void) { }
0145 #endif
0146
0147 static void find_freq_tables(struct cpufreq_frequency_table **freq_table,
0148 const struct pxa_freqs **pxa_freqs)
0149 {
0150 if (cpu_is_pxa25x()) {
0151 if (!pxa255_turbo_table) {
0152 *pxa_freqs = pxa255_run_freqs;
0153 *freq_table = pxa255_run_freq_table;
0154 } else {
0155 *pxa_freqs = pxa255_turbo_freqs;
0156 *freq_table = pxa255_turbo_freq_table;
0157 }
0158 } else if (cpu_is_pxa27x()) {
0159 *pxa_freqs = pxa27x_freqs;
0160 *freq_table = pxa27x_freq_table;
0161 } else {
0162 BUG();
0163 }
0164 }
0165
0166 static void pxa27x_guess_max_freq(void)
0167 {
0168 if (!pxa27x_maxfreq) {
0169 pxa27x_maxfreq = 416000;
0170 pr_info("PXA CPU 27x max frequency not defined (pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n",
0171 pxa27x_maxfreq);
0172 } else {
0173 pxa27x_maxfreq *= 1000;
0174 }
0175 }
0176
0177 static unsigned int pxa_cpufreq_get(unsigned int cpu)
0178 {
0179 struct pxa_cpufreq_data *data = cpufreq_get_driver_data();
0180
0181 return (unsigned int) clk_get_rate(data->clk_core) / 1000;
0182 }
0183
0184 static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx)
0185 {
0186 struct cpufreq_frequency_table *pxa_freqs_table;
0187 const struct pxa_freqs *pxa_freq_settings;
0188 struct pxa_cpufreq_data *data = cpufreq_get_driver_data();
0189 unsigned int new_freq_cpu;
0190 int ret = 0;
0191
0192
0193 find_freq_tables(&pxa_freqs_table, &pxa_freq_settings);
0194
0195 new_freq_cpu = pxa_freq_settings[idx].khz;
0196
0197 if (freq_debug)
0198 pr_debug("Changing CPU frequency from %d Mhz to %d Mhz\n",
0199 policy->cur / 1000, new_freq_cpu / 1000);
0200
0201 if (vcc_core && new_freq_cpu > policy->cur) {
0202 ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]);
0203 if (ret)
0204 return ret;
0205 }
0206
0207 clk_set_rate(data->clk_core, new_freq_cpu * 1000);
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 if (vcc_core && new_freq_cpu < policy->cur)
0219 ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]);
0220
0221 return 0;
0222 }
0223
0224 static int pxa_cpufreq_init(struct cpufreq_policy *policy)
0225 {
0226 int i;
0227 unsigned int freq;
0228 struct cpufreq_frequency_table *pxa255_freq_table;
0229 const struct pxa_freqs *pxa255_freqs;
0230
0231
0232 if (cpu_is_pxa27x())
0233 pxa27x_guess_max_freq();
0234
0235 pxa_cpufreq_init_voltages();
0236
0237
0238 policy->cpuinfo.transition_latency = 1000;
0239
0240
0241 for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) {
0242 pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
0243 pxa255_run_freq_table[i].driver_data = i;
0244 }
0245 pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
0246
0247
0248 for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) {
0249 pxa255_turbo_freq_table[i].frequency =
0250 pxa255_turbo_freqs[i].khz;
0251 pxa255_turbo_freq_table[i].driver_data = i;
0252 }
0253 pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
0254
0255 pxa255_turbo_table = !!pxa255_turbo_table;
0256
0257
0258 for (i = 0; i < NUM_PXA27x_FREQS; i++) {
0259 freq = pxa27x_freqs[i].khz;
0260 if (freq > pxa27x_maxfreq)
0261 break;
0262 pxa27x_freq_table[i].frequency = freq;
0263 pxa27x_freq_table[i].driver_data = i;
0264 }
0265 pxa27x_freq_table[i].driver_data = i;
0266 pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
0267
0268
0269
0270
0271
0272 if (cpu_is_pxa25x()) {
0273 find_freq_tables(&pxa255_freq_table, &pxa255_freqs);
0274 pr_info("using %s frequency table\n",
0275 pxa255_turbo_table ? "turbo" : "run");
0276
0277 policy->freq_table = pxa255_freq_table;
0278 }
0279 else if (cpu_is_pxa27x()) {
0280 policy->freq_table = pxa27x_freq_table;
0281 }
0282
0283 pr_info("frequency change support initialized\n");
0284
0285 return 0;
0286 }
0287
0288 static struct cpufreq_driver pxa_cpufreq_driver = {
0289 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
0290 .verify = cpufreq_generic_frequency_table_verify,
0291 .target_index = pxa_set_target,
0292 .init = pxa_cpufreq_init,
0293 .get = pxa_cpufreq_get,
0294 .name = "PXA2xx",
0295 .driver_data = &pxa_cpufreq_data,
0296 };
0297
0298 static int __init pxa_cpu_init(void)
0299 {
0300 int ret = -ENODEV;
0301
0302 pxa_cpufreq_data.clk_core = clk_get_sys(NULL, "core");
0303 if (IS_ERR(pxa_cpufreq_data.clk_core))
0304 return PTR_ERR(pxa_cpufreq_data.clk_core);
0305
0306 if (cpu_is_pxa25x() || cpu_is_pxa27x())
0307 ret = cpufreq_register_driver(&pxa_cpufreq_driver);
0308 return ret;
0309 }
0310
0311 static void __exit pxa_cpu_exit(void)
0312 {
0313 cpufreq_unregister_driver(&pxa_cpufreq_driver);
0314 }
0315
0316
0317 MODULE_AUTHOR("Intrinsyc Software Inc.");
0318 MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture");
0319 MODULE_LICENSE("GPL");
0320 module_init(pxa_cpu_init);
0321 module_exit(pxa_cpu_exit);