12 #include <linux/module.h>
13 #include <linux/kernel.h>
17 #include <linux/slab.h>
21 #include <mach/regs-clock.h>
22 #include <mach/cpufreq.h>
24 #define CPUFREQ_LEVEL_END (L15 + 1)
26 static int max_support_idx;
28 static struct clk *cpu_clk;
29 static struct clk *moutcore;
30 static struct clk *mout_mpll;
31 static struct clk *mout_apll;
68 { 0, 3, 7, 7, 7, 3, 5, 0 },
69 { 0, 3, 7, 7, 7, 1, 4, 0 },
70 { 0, 2, 7, 7, 7, 1, 4, 0 },
71 { 0, 2, 7, 7, 6, 1, 4, 0 },
72 { 0, 2, 7, 7, 6, 1, 3, 0 },
73 { 0, 2, 7, 7, 5, 1, 3, 0 },
74 { 0, 3, 7, 7, 5, 1, 3, 0 },
75 { 0, 1, 7, 7, 4, 1, 2, 0 },
76 { 0, 1, 7, 7, 4, 1, 2, 0 },
77 { 0, 1, 7, 7, 4, 1, 2, 0 },
78 { 0, 1, 7, 7, 3, 1, 1, 0 },
79 { 0, 1, 7, 7, 3, 1, 1, 0 },
80 { 0, 1, 7, 7, 2, 1, 1, 0 },
81 { 0, 1, 7, 7, 2, 1, 1, 0 },
82 { 0, 1, 7, 7, 1, 1, 1, 0 },
83 { 0, 1, 7, 7, 1, 1, 1, 0 },
109 ((425 << 16) | (6 << 8) | 0),
110 ((200 << 16) | (3 << 8) | 0),
111 ((250 << 16) | (4 << 8) | 0),
112 ((175 << 16) | (3 << 8) | 0),
113 ((325 << 16) | (6 << 8) | 0),
114 ((200 << 16) | (4 << 8) | 0),
115 ((275 << 16) | (6 << 8) | 0),
116 ((125 << 16) | (3 << 8) | 0),
117 ((150 << 16) | (4 << 8) | 0),
118 ((100 << 16) | (3 << 8) | 0),
119 ((175 << 16) | (3 << 8) | 1),
120 ((200 << 16) | (4 << 8) | 1),
121 ((125 << 16) | (3 << 8) | 1),
122 ((100 << 16) | (3 << 8) | 1),
123 ((200 << 16) | (4 << 8) | 2),
124 ((100 << 16) | (3 << 8) | 2),
129 1300000, 1250000, 1225000, 1200000, 1150000,
130 1125000, 1100000, 1075000, 1050000, 1025000,
131 1012500, 1000000, 975000, 950000, 937500,
135 static void set_clkdiv(
unsigned int div_index)
141 tmp = exynos5250_clkdiv_table[div_index].clkdiv;
149 tmp = exynos5250_clkdiv_table[div_index].clkdiv1;
157 static void set_apll(
unsigned int new_index,
158 unsigned int old_index)
160 unsigned int tmp, pdiv;
169 }
while (tmp != 0x2);
172 pdiv = ((exynos5_apll_pms_table[new_index] >> 8) & 0x3f);
178 tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
179 tmp |= exynos5_apll_pms_table[new_index];
186 }
while (!(tmp & (0x1 << 29)));
195 }
while (tmp != (0x1 << 16));
201 unsigned int old_pm = (exynos5_apll_pms_table[old_index] >> 8);
202 unsigned int new_pm = (exynos5_apll_pms_table[new_index] >> 8);
204 return (old_pm == new_pm) ? 0 : 1;
207 static void exynos5250_set_frequency(
unsigned int old_index,
208 unsigned int new_index)
212 if (old_index > new_index) {
215 set_clkdiv(new_index);
219 tmp |= (exynos5_apll_pms_table[new_index] & 0x7);
225 set_clkdiv(new_index);
227 set_apll(new_index, old_index);
229 }
else if (old_index < new_index) {
234 tmp |= (exynos5_apll_pms_table[new_index] & 0x7);
237 set_clkdiv(new_index);
241 set_apll(new_index, old_index);
243 set_clkdiv(new_index);
248 static void __init set_volt_table(
void)
252 max_support_idx =
L0;
255 exynos5250_volt_table[i] = asv_voltage_5250[i];
268 return PTR_ERR(cpu_clk);
271 if (IS_ERR(moutcore))
275 if (IS_ERR(mout_mpll))
281 if (IS_ERR(mout_apll))
286 exynos5250_clkdiv_table[
i].index =
i;
290 tmp &= ~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) |
291 (0x7 << 12) | (0x7 << 16) | (0x7 << 20) |
292 (0x7 << 24) | (0x7 << 28));
294 tmp |= ((clkdiv_cpu0_5250[
i][0] << 0) |
295 (clkdiv_cpu0_5250[i][1] << 4) |
296 (clkdiv_cpu0_5250[
i][2] << 8) |
297 (clkdiv_cpu0_5250[i][3] << 12) |
298 (clkdiv_cpu0_5250[
i][4] << 16) |
299 (clkdiv_cpu0_5250[i][5] << 20) |
300 (clkdiv_cpu0_5250[
i][6] << 24) |
301 (clkdiv_cpu0_5250[i][7] << 28));
303 exynos5250_clkdiv_table[
i].clkdiv =
tmp;
307 tmp &= ~((0x7 << 0) | (0x7 << 4));
309 tmp |= ((clkdiv_cpu1_5250[
i][0] << 0) |
310 (clkdiv_cpu1_5250[i][1] << 4));
312 exynos5250_clkdiv_table[
i].clkdiv1 =
tmp;
325 info->
set_freq = exynos5250_set_frequency;
337 pr_err(
"%s: failed initialization\n", __func__);