0001
0002
0003
0004
0005
0006 #include <linux/kernel.h>
0007 #include <linux/module.h>
0008 #include <linux/sched.h>
0009 #include <linux/init.h>
0010 #include <linux/cpufreq.h>
0011 #include <linux/soc/pxa/cpu.h>
0012 #include <linux/clk/pxa.h>
0013 #include <linux/slab.h>
0014 #include <linux/io.h>
0015
0016 #define HSS_104M (0)
0017 #define HSS_156M (1)
0018 #define HSS_208M (2)
0019 #define HSS_312M (3)
0020
0021 #define SMCFS_78M (0)
0022 #define SMCFS_104M (2)
0023 #define SMCFS_208M (5)
0024
0025 #define SFLFS_104M (0)
0026 #define SFLFS_156M (1)
0027 #define SFLFS_208M (2)
0028 #define SFLFS_312M (3)
0029
0030 #define XSPCLK_156M (0)
0031 #define XSPCLK_NONE (3)
0032
0033 #define DMCFS_26M (0)
0034 #define DMCFS_260M (3)
0035
0036 #define ACCR_XPDIS (1 << 31)
0037 #define ACCR_SPDIS (1 << 30)
0038 #define ACCR_D0CS (1 << 26)
0039 #define ACCR_PCCE (1 << 11)
0040 #define ACCR_DDR_D0CS (1 << 7)
0041
0042 #define ACCR_SMCFS_MASK (0x7 << 23)
0043 #define ACCR_SFLFS_MASK (0x3 << 18)
0044 #define ACCR_XSPCLK_MASK (0x3 << 16)
0045 #define ACCR_HSS_MASK (0x3 << 14)
0046 #define ACCR_DMCFS_MASK (0x3 << 12)
0047 #define ACCR_XN_MASK (0x7 << 8)
0048 #define ACCR_XL_MASK (0x1f)
0049
0050 #define ACCR_SMCFS(x) (((x) & 0x7) << 23)
0051 #define ACCR_SFLFS(x) (((x) & 0x3) << 18)
0052 #define ACCR_XSPCLK(x) (((x) & 0x3) << 16)
0053 #define ACCR_HSS(x) (((x) & 0x3) << 14)
0054 #define ACCR_DMCFS(x) (((x) & 0x3) << 12)
0055 #define ACCR_XN(x) (((x) & 0x7) << 8)
0056 #define ACCR_XL(x) ((x) & 0x1f)
0057
0058 struct pxa3xx_freq_info {
0059 unsigned int cpufreq_mhz;
0060 unsigned int core_xl : 5;
0061 unsigned int core_xn : 3;
0062 unsigned int hss : 2;
0063 unsigned int dmcfs : 2;
0064 unsigned int smcfs : 3;
0065 unsigned int sflfs : 2;
0066 unsigned int df_clkdiv : 3;
0067
0068 int vcc_core;
0069 int vcc_sram;
0070 };
0071
0072 #define OP(cpufreq, _xl, _xn, _hss, _dmc, _smc, _sfl, _dfi, vcore, vsram) \
0073 { \
0074 .cpufreq_mhz = cpufreq, \
0075 .core_xl = _xl, \
0076 .core_xn = _xn, \
0077 .hss = HSS_##_hss##M, \
0078 .dmcfs = DMCFS_##_dmc##M, \
0079 .smcfs = SMCFS_##_smc##M, \
0080 .sflfs = SFLFS_##_sfl##M, \
0081 .df_clkdiv = _dfi, \
0082 .vcc_core = vcore, \
0083 .vcc_sram = vsram, \
0084 }
0085
0086 static struct pxa3xx_freq_info pxa300_freqs[] = {
0087
0088 OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100),
0089 OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100),
0090 OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200),
0091 OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400),
0092 };
0093
0094 static struct pxa3xx_freq_info pxa320_freqs[] = {
0095
0096 OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100),
0097 OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100),
0098 OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200),
0099 OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400),
0100 OP(806, 31, 2, 208, 260, 208, 312, 3, 1400, 1400),
0101 };
0102
0103 static unsigned int pxa3xx_freqs_num;
0104 static struct pxa3xx_freq_info *pxa3xx_freqs;
0105 static struct cpufreq_frequency_table *pxa3xx_freqs_table;
0106
0107 static int setup_freqs_table(struct cpufreq_policy *policy,
0108 struct pxa3xx_freq_info *freqs, int num)
0109 {
0110 struct cpufreq_frequency_table *table;
0111 int i;
0112
0113 table = kcalloc(num + 1, sizeof(*table), GFP_KERNEL);
0114 if (table == NULL)
0115 return -ENOMEM;
0116
0117 for (i = 0; i < num; i++) {
0118 table[i].driver_data = i;
0119 table[i].frequency = freqs[i].cpufreq_mhz * 1000;
0120 }
0121 table[num].driver_data = i;
0122 table[num].frequency = CPUFREQ_TABLE_END;
0123
0124 pxa3xx_freqs = freqs;
0125 pxa3xx_freqs_num = num;
0126 pxa3xx_freqs_table = table;
0127
0128 policy->freq_table = table;
0129
0130 return 0;
0131 }
0132
0133 static void __update_core_freq(struct pxa3xx_freq_info *info)
0134 {
0135 u32 mask, disable, enable, xclkcfg;
0136
0137 mask = ACCR_XN_MASK | ACCR_XL_MASK;
0138 disable = mask | ACCR_XSPCLK_MASK;
0139 enable = ACCR_XN(info->core_xn) | ACCR_XL(info->core_xl);
0140
0141 enable |= ACCR_XSPCLK(XSPCLK_NONE);
0142 xclkcfg = (info->core_xn == 2) ? 0x3 : 0x2;
0143
0144 pxa3xx_clk_update_accr(disable, enable, xclkcfg, mask);
0145 }
0146
0147 static void __update_bus_freq(struct pxa3xx_freq_info *info)
0148 {
0149 u32 mask, disable, enable;
0150
0151 mask = ACCR_SMCFS_MASK | ACCR_SFLFS_MASK | ACCR_HSS_MASK |
0152 ACCR_DMCFS_MASK;
0153 disable = mask;
0154 enable = ACCR_SMCFS(info->smcfs) | ACCR_SFLFS(info->sflfs) |
0155 ACCR_HSS(info->hss) | ACCR_DMCFS(info->dmcfs);
0156
0157 pxa3xx_clk_update_accr(disable, enable, 0, mask);
0158 }
0159
0160 static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
0161 {
0162 return pxa3xx_get_clk_frequency_khz(0);
0163 }
0164
0165 static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, unsigned int index)
0166 {
0167 struct pxa3xx_freq_info *next;
0168 unsigned long flags;
0169
0170 if (policy->cpu != 0)
0171 return -EINVAL;
0172
0173 next = &pxa3xx_freqs[index];
0174
0175 local_irq_save(flags);
0176 __update_core_freq(next);
0177 __update_bus_freq(next);
0178 local_irq_restore(flags);
0179
0180 return 0;
0181 }
0182
0183 static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
0184 {
0185 int ret = -EINVAL;
0186
0187
0188 policy->min = policy->cpuinfo.min_freq = 104000;
0189 policy->max = policy->cpuinfo.max_freq =
0190 (cpu_is_pxa320()) ? 806000 : 624000;
0191 policy->cpuinfo.transition_latency = 1000;
0192
0193 if (cpu_is_pxa300() || cpu_is_pxa310())
0194 ret = setup_freqs_table(policy, pxa300_freqs,
0195 ARRAY_SIZE(pxa300_freqs));
0196
0197 if (cpu_is_pxa320())
0198 ret = setup_freqs_table(policy, pxa320_freqs,
0199 ARRAY_SIZE(pxa320_freqs));
0200
0201 if (ret) {
0202 pr_err("failed to setup frequency table\n");
0203 return ret;
0204 }
0205
0206 pr_info("CPUFREQ support for PXA3xx initialized\n");
0207 return 0;
0208 }
0209
0210 static struct cpufreq_driver pxa3xx_cpufreq_driver = {
0211 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
0212 .verify = cpufreq_generic_frequency_table_verify,
0213 .target_index = pxa3xx_cpufreq_set,
0214 .init = pxa3xx_cpufreq_init,
0215 .get = pxa3xx_cpufreq_get,
0216 .name = "pxa3xx-cpufreq",
0217 };
0218
0219 static int __init cpufreq_init(void)
0220 {
0221 if (cpu_is_pxa3xx())
0222 return cpufreq_register_driver(&pxa3xx_cpufreq_driver);
0223
0224 return 0;
0225 }
0226 module_init(cpufreq_init);
0227
0228 static void __exit cpufreq_exit(void)
0229 {
0230 cpufreq_unregister_driver(&pxa3xx_cpufreq_driver);
0231 }
0232 module_exit(cpufreq_exit);
0233
0234 MODULE_DESCRIPTION("CPU frequency scaling driver for PXA3xx");
0235 MODULE_LICENSE("GPL");