1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2008 Marvell International Ltd. 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/module.h> 8 #include <linux/sched.h> 9 #include <linux/init.h> 10 #include <linux/cpufreq.h> 11 #include <linux/soc/pxa/cpu.h> 12 #include <linux/clk/pxa.h> 13 #include <linux/slab.h> 14 #include <linux/io.h> 15 16 #define HSS_104M (0) 17 #define HSS_156M (1) 18 #define HSS_208M (2) 19 #define HSS_312M (3) 20 21 #define SMCFS_78M (0) 22 #define SMCFS_104M (2) 23 #define SMCFS_208M (5) 24 25 #define SFLFS_104M (0) 26 #define SFLFS_156M (1) 27 #define SFLFS_208M (2) 28 #define SFLFS_312M (3) 29 30 #define XSPCLK_156M (0) 31 #define XSPCLK_NONE (3) 32 33 #define DMCFS_26M (0) 34 #define DMCFS_260M (3) 35 36 #define ACCR_XPDIS (1 << 31) /* Core PLL Output Disable */ 37 #define ACCR_SPDIS (1 << 30) /* System PLL Output Disable */ 38 #define ACCR_D0CS (1 << 26) /* D0 Mode Clock Select */ 39 #define ACCR_PCCE (1 << 11) /* Power Mode Change Clock Enable */ 40 #define ACCR_DDR_D0CS (1 << 7) /* DDR SDRAM clock frequency in D0CS (PXA31x only) */ 41 42 #define ACCR_SMCFS_MASK (0x7 << 23) /* Static Memory Controller Frequency Select */ 43 #define ACCR_SFLFS_MASK (0x3 << 18) /* Frequency Select for Internal Memory Controller */ 44 #define ACCR_XSPCLK_MASK (0x3 << 16) /* Core Frequency during Frequency Change */ 45 #define ACCR_HSS_MASK (0x3 << 14) /* System Bus-Clock Frequency Select */ 46 #define ACCR_DMCFS_MASK (0x3 << 12) /* Dynamic Memory Controller Clock Frequency Select */ 47 #define ACCR_XN_MASK (0x7 << 8) /* Core PLL Turbo-Mode-to-Run-Mode Ratio */ 48 #define ACCR_XL_MASK (0x1f) /* Core PLL Run-Mode-to-Oscillator Ratio */ 49 50 #define ACCR_SMCFS(x) (((x) & 0x7) << 23) 51 #define ACCR_SFLFS(x) (((x) & 0x3) << 18) 52 #define ACCR_XSPCLK(x) (((x) & 0x3) << 16) 53 #define ACCR_HSS(x) (((x) & 0x3) << 14) 54 #define ACCR_DMCFS(x) (((x) & 0x3) << 12) 55 #define ACCR_XN(x) (((x) & 0x7) << 8) 56 #define ACCR_XL(x) ((x) & 0x1f) 57 58 struct pxa3xx_freq_info { 59 unsigned int cpufreq_mhz; 60 unsigned int core_xl : 5; 61 unsigned int core_xn : 3; 62 unsigned int hss : 2; 63 unsigned int dmcfs : 2; 64 unsigned int smcfs : 3; 65 unsigned int sflfs : 2; 66 unsigned int df_clkdiv : 3; 67 68 int vcc_core; /* in mV */ 69 int vcc_sram; /* in mV */ 70 }; 71 72 #define OP(cpufreq, _xl, _xn, _hss, _dmc, _smc, _sfl, _dfi, vcore, vsram) \ 73 { \ 74 .cpufreq_mhz = cpufreq, \ 75 .core_xl = _xl, \ 76 .core_xn = _xn, \ 77 .hss = HSS_##_hss##M, \ 78 .dmcfs = DMCFS_##_dmc##M, \ 79 .smcfs = SMCFS_##_smc##M, \ 80 .sflfs = SFLFS_##_sfl##M, \ 81 .df_clkdiv = _dfi, \ 82 .vcc_core = vcore, \ 83 .vcc_sram = vsram, \ 84 } 85 86 static struct pxa3xx_freq_info pxa300_freqs[] = { 87 /* CPU XL XN HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */ 88 OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100), /* 104MHz */ 89 OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */ 90 OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */ 91 OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */ 92 }; 93 94 static struct pxa3xx_freq_info pxa320_freqs[] = { 95 /* CPU XL XN HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */ 96 OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100), /* 104MHz */ 97 OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */ 98 OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */ 99 OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */ 100 OP(806, 31, 2, 208, 260, 208, 312, 3, 1400, 1400), /* 806MHz */ 101 }; 102 103 static unsigned int pxa3xx_freqs_num; 104 static struct pxa3xx_freq_info *pxa3xx_freqs; 105 static struct cpufreq_frequency_table *pxa3xx_freqs_table; 106 107 static int setup_freqs_table(struct cpufreq_policy *policy, 108 struct pxa3xx_freq_info *freqs, int num) 109 { 110 struct cpufreq_frequency_table *table; 111 int i; 112 113 table = kcalloc(num + 1, sizeof(*table), GFP_KERNEL); 114 if (table == NULL) 115 return -ENOMEM; 116 117 for (i = 0; i < num; i++) { 118 table[i].driver_data = i; 119 table[i].frequency = freqs[i].cpufreq_mhz * 1000; 120 } 121 table[num].driver_data = i; 122 table[num].frequency = CPUFREQ_TABLE_END; 123 124 pxa3xx_freqs = freqs; 125 pxa3xx_freqs_num = num; 126 pxa3xx_freqs_table = table; 127 128 policy->freq_table = table; 129 130 return 0; 131 } 132 133 static void __update_core_freq(struct pxa3xx_freq_info *info) 134 { 135 u32 mask, disable, enable, xclkcfg; 136 137 mask = ACCR_XN_MASK | ACCR_XL_MASK; 138 disable = mask | ACCR_XSPCLK_MASK; 139 enable = ACCR_XN(info->core_xn) | ACCR_XL(info->core_xl); 140 /* No clock until core PLL is re-locked */ 141 enable |= ACCR_XSPCLK(XSPCLK_NONE); 142 xclkcfg = (info->core_xn == 2) ? 0x3 : 0x2; /* turbo bit */ 143 144 pxa3xx_clk_update_accr(disable, enable, xclkcfg, mask); 145 } 146 147 static void __update_bus_freq(struct pxa3xx_freq_info *info) 148 { 149 u32 mask, disable, enable; 150 151 mask = ACCR_SMCFS_MASK | ACCR_SFLFS_MASK | ACCR_HSS_MASK | 152 ACCR_DMCFS_MASK; 153 disable = mask; 154 enable = ACCR_SMCFS(info->smcfs) | ACCR_SFLFS(info->sflfs) | 155 ACCR_HSS(info->hss) | ACCR_DMCFS(info->dmcfs); 156 157 pxa3xx_clk_update_accr(disable, enable, 0, mask); 158 } 159 160 static unsigned int pxa3xx_cpufreq_get(unsigned int cpu) 161 { 162 return pxa3xx_get_clk_frequency_khz(0); 163 } 164 165 static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, unsigned int index) 166 { 167 struct pxa3xx_freq_info *next; 168 unsigned long flags; 169 170 if (policy->cpu != 0) 171 return -EINVAL; 172 173 next = &pxa3xx_freqs[index]; 174 175 local_irq_save(flags); 176 __update_core_freq(next); 177 __update_bus_freq(next); 178 local_irq_restore(flags); 179 180 return 0; 181 } 182 183 static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) 184 { 185 int ret = -EINVAL; 186 187 /* set default policy and cpuinfo */ 188 policy->min = policy->cpuinfo.min_freq = 104000; 189 policy->max = policy->cpuinfo.max_freq = 190 (cpu_is_pxa320()) ? 806000 : 624000; 191 policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ 192 193 if (cpu_is_pxa300() || cpu_is_pxa310()) 194 ret = setup_freqs_table(policy, pxa300_freqs, 195 ARRAY_SIZE(pxa300_freqs)); 196 197 if (cpu_is_pxa320()) 198 ret = setup_freqs_table(policy, pxa320_freqs, 199 ARRAY_SIZE(pxa320_freqs)); 200 201 if (ret) { 202 pr_err("failed to setup frequency table\n"); 203 return ret; 204 } 205 206 pr_info("CPUFREQ support for PXA3xx initialized\n"); 207 return 0; 208 } 209 210 static struct cpufreq_driver pxa3xx_cpufreq_driver = { 211 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, 212 .verify = cpufreq_generic_frequency_table_verify, 213 .target_index = pxa3xx_cpufreq_set, 214 .init = pxa3xx_cpufreq_init, 215 .get = pxa3xx_cpufreq_get, 216 .name = "pxa3xx-cpufreq", 217 }; 218 219 static int __init cpufreq_init(void) 220 { 221 if (cpu_is_pxa3xx()) 222 return cpufreq_register_driver(&pxa3xx_cpufreq_driver); 223 224 return 0; 225 } 226 module_init(cpufreq_init); 227 228 static void __exit cpufreq_exit(void) 229 { 230 cpufreq_unregister_driver(&pxa3xx_cpufreq_driver); 231 } 232 module_exit(cpufreq_exit); 233 234 MODULE_DESCRIPTION("CPU frequency scaling driver for PXA3xx"); 235 MODULE_LICENSE("GPL"); 236