ARM: Fix build after memfd_create syscall
[GitHub/LineageOS/android_kernel_samsung_universal7580.git] / drivers / cpufreq / exynos7420-atlas-cpufreq.c
1 /*
2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * EXYNOS7420 - ATLAS Core frequency scaling support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12 #include <linux/kernel.h>
13 #include <linux/err.h>
14 #include <linux/clk.h>
15 #include <linux/io.h>
16 #include <linux/slab.h>
17 #include <linux/cpufreq.h>
18 #include <linux/clk-private.h>
19
20 #include <mach/map.h>
21 #include <mach/regs-clock.h>
22 #include <mach/regs-clock-exynos7420.h>
23 #include <mach/regs-pmu.h>
24 #include <mach/cpufreq.h>
25 #include <mach/asv-exynos.h>
26 #include <linux/of.h>
27
28 #define CPUFREQ_LEVEL_END_CA57 (L23 + 1)
29 #undef PRINT_DIV_VAL
30
31 #define ATLAS_EMA_CON (EXYNOS7420_VA_SYSREG + 0x0138)
32 #define CPU_EMA_REG1 (EXYNOS7420_VA_SYSREG + 0x2908)
33
34 static int max_support_idx_CA57;
35 static int min_support_idx_CA57 = (CPUFREQ_LEVEL_END_CA57 - 1);
36
37 static struct clk *mout_atlas;
38 static struct clk *mout_atlas_pll;
39 static struct clk *mout_bus0_pll_atlas;
40
41 static unsigned int exynos7420_volt_table_CA57[CPUFREQ_LEVEL_END_CA57];
42 static unsigned int exynos7420_abb_table_CA57[CPUFREQ_LEVEL_END_CA57];
43
44 static int en_smpl_warn = 0;
45 static BLOCKING_NOTIFIER_HEAD(exynos_cpufreq_smpl_warn_notifier_list);
46 int exynos_cpufreq_smpl_warn_register_notifier(struct notifier_block *nb)
47 {
48 return blocking_notifier_chain_register(&exynos_cpufreq_smpl_warn_notifier_list, nb);
49 }
50
51 int exynos_cpufreq_smpl_warn_unregister_notifier(struct notifier_block *nb)
52 {
53 return blocking_notifier_chain_unregister(&exynos_cpufreq_smpl_warn_notifier_list, nb);
54 }
55
56 int exynos_cpufreq_smpl_warn_notify_call_chain(void)
57 {
58 int ret = blocking_notifier_call_chain(&exynos_cpufreq_smpl_warn_notifier_list, 0, NULL);
59 return notifier_to_errno(ret);
60 }
61 EXPORT_SYMBOL(exynos_cpufreq_smpl_warn_notify_call_chain);
62
63
64 static struct cpufreq_frequency_table exynos7420_freq_table_CA57[] = {
65 {L0, 2496 * 1000},
66 {L1, 2400 * 1000},
67 {L2, 2304 * 1000},
68 {L3, 2200 * 1000},
69 {L4, 2100 * 1000},
70 {L5, 2000 * 1000},
71 {L6, 1896 * 1000},
72 {L7, 1800 * 1000},
73 {L8, 1704 * 1000},
74 {L9, 1600 * 1000},
75 {L10, 1500 * 1000},
76 {L11, 1400 * 1000},
77 {L12, 1300 * 1000},
78 {L13, 1200 * 1000},
79 {L14, 1100 * 1000},
80 {L15, 1000 * 1000},
81 {L16, 900 * 1000},
82 {L17, 800 * 1000},
83 {L18, 700 * 1000},
84 {L19, 600 * 1000},
85 {L20, 500 * 1000},
86 {L21, 400 * 1000},
87 {L22, 300 * 1000},
88 {L23, 200 * 1000},
89 {0, CPUFREQ_TABLE_END},
90 };
91
92 static struct apll_freq exynos7420_apll_freq_CA57[] = {
93 /*
94 * values:
95 * freq
96 * clock divider for ATLAS1, ATLAS2, ACLK_ATLAS, PCLK_ATLAS, ATCLK, PCLK_DBG_ATLAS,
97 * clock divider for SCLK_ATLAS_PLL, SCLK_HPM_ATLAS, SCLK_CNTCLK
98 * PLL M, P, S values are NOT used, Instead CCF clk_set_rate is used
99 */
100 APLL_ATLAS_FREQ(2496, 0, 0, 2, 6, 6, 6, 1, 5, 6, 208, 2, 0), /* ARM L0: 2.5GHz */
101 APLL_ATLAS_FREQ(2400, 0, 0, 2, 6, 6, 6, 1, 5, 6, 200, 2, 0), /* ARM L1: 2.4GMHz */
102 APLL_ATLAS_FREQ(2304, 0, 0, 2, 6, 6, 6, 1, 5, 6, 192, 2, 0), /* ARM L2: 2.3GMHz */
103 APLL_ATLAS_FREQ(2200, 0, 0, 2, 6, 6, 6, 1, 5, 6, 275, 3, 0), /* ARM L3: 2.2GHz */
104 APLL_ATLAS_FREQ(2100, 0, 0, 2, 6, 6, 6, 1, 5, 6, 175, 2, 0), /* ARM L4: 2.1GHz */
105 APLL_ATLAS_FREQ(2000, 0, 0, 2, 6, 6, 6, 1, 5, 6, 250, 3, 0), /* ARM L5: 2.0GHz */
106 APLL_ATLAS_FREQ(1896, 0, 0, 2, 6, 6, 6, 1, 4, 6, 158, 2, 0), /* ARM L6: 1.9GHz */
107 APLL_ATLAS_FREQ(1800, 0, 0, 2, 6, 6, 6, 1, 4, 6, 150, 2, 0), /* ARM L7: 1.8GHz */
108 APLL_ATLAS_FREQ(1704, 0, 0, 2, 6, 6, 6, 1, 4, 6, 142, 2, 0), /* ARM L8: 1.7GHz */
109 APLL_ATLAS_FREQ(1600, 0, 0, 2, 6, 6, 6, 1, 4, 6, 200, 3, 0), /* ARM L9: 1.6GHz */
110 APLL_ATLAS_FREQ(1500, 0, 0, 2, 6, 6, 6, 1, 4, 6, 250, 2, 1), /* ARM L10: 1.5GHz */
111 APLL_ATLAS_FREQ(1400, 0, 0, 2, 6, 6, 6, 1, 4, 6, 350, 3, 1), /* ARM L11: 1.4GHz */
112 APLL_ATLAS_FREQ(1300, 0, 0, 2, 6, 6, 6, 1, 4, 6, 325, 3, 1), /* ARM L12: 1.3GHz */
113 APLL_ATLAS_FREQ(1200, 0, 0, 1, 6, 6, 6, 1, 3, 6, 200, 2, 1), /* ARM L13: 1.2GHz */
114 APLL_ATLAS_FREQ(1100, 0, 0, 1, 6, 6, 6, 1, 3, 6, 275, 3, 1), /* ARM L14: 1.1GHz */
115 APLL_ATLAS_FREQ(1000, 0, 0, 1, 6, 6, 6, 1, 3, 6, 250, 3, 1), /* ARM L15: 1.0GHz */
116 APLL_ATLAS_FREQ( 900, 0, 0, 1, 6, 6, 6, 1, 3, 6, 150, 2, 1), /* ARM L16: 900MHz */
117 APLL_ATLAS_FREQ( 800, 0, 0, 1, 5, 5, 5, 1, 3, 5, 200, 3, 1), /* ARM L17: 800MHz */
118 APLL_ATLAS_FREQ( 700, 0, 0, 1, 5, 5, 5, 1, 3, 5, 350, 3, 2), /* ARM L18: 700MHz */
119 APLL_ATLAS_FREQ( 600, 0, 0, 1, 4, 4, 4, 1, 3, 4, 200, 2, 2), /* ARM L19: 600MHz */
120 APLL_ATLAS_FREQ( 500, 0, 0, 1, 3, 3, 3, 1, 2, 3, 250, 3, 2), /* ARM L20: 500MHz */
121 APLL_ATLAS_FREQ( 400, 0, 0, 1, 3, 3, 3, 1, 2, 3, 200, 3, 2), /* ARM L21: 400MHz */
122 APLL_ATLAS_FREQ( 300, 0, 0, 1, 3, 3, 3, 1, 2, 3, 200, 2, 3), /* ARM L22: 300MHz */
123 APLL_ATLAS_FREQ( 200, 0, 0, 1, 3, 3, 3, 1, 1, 3, 200, 3, 3), /* ARM L23: 200MHz */
124 };
125
126 /*
127 * ASV group voltage table
128 */
129 static const unsigned int asv_voltage_7420_CA57[CPUFREQ_LEVEL_END_CA57] = {
130 1250000, /* L0 2500 */
131 1250000, /* L1 2400 */
132 1250000, /* L2 2300 */
133 1250000, /* L3 2200 */
134 1250000, /* L4 2100 */
135 1200000, /* L5 2000 */
136 1156250, /* L6 1900 */
137 1118750, /* L7 1800 */
138 1081250, /* L8 1700 */
139 1043750, /* L9 1600 */
140 1012500, /* L10 1500 */
141 981250, /* L11 1400 */
142 950000, /* L12 1300 */
143 925000, /* L13 1200 */
144 900000, /* L14 1100 */
145 875000, /* L15 1000 */
146 850000, /* L16 900 */
147 825000, /* L17 800 */
148 800000, /* L18 700 */
149 775000, /* L19 600 */
150 750000, /* L20 500 */
151 725000, /* L21 400 */
152 700000, /* L22 300 */
153 675000, /* L23 200 */
154 };
155
156 /* minimum memory throughput in megabytes per second */
157 static int exynos7420_bus_table_CA57[CPUFREQ_LEVEL_END_CA57] = {
158 1552000, /* 2.5 GHz */
159 1552000, /* 2.4 GHz */
160 1552000, /* 2.3 GHz */
161 1552000, /* 2.2 GHz */
162 1552000, /* 2.1 GHz */
163 1456000, /* 2.0 GHz */
164 1264000, /* 1.9 GHz */
165 1026000, /* 1.8 GHz */
166 828000, /* 1.7 MHz */
167 828000, /* 1.6 GHz */
168 828000, /* 1.5 GHz */
169 828000, /* 1.4 GHz */
170 828000, /* 1.3 GHz */
171 828000, /* 1.2 GHz */
172 632000, /* 1.1 GHz */
173 543000, /* 1.0 GHz */
174 543000, /* 900 MHz */
175 416000, /* 800 MHz */
176 0, /* 700 MHz */
177 0, /* 600 MHz */
178 0, /* 500 MHz */
179 0, /* 400 MHz */
180 0, /* 300 MHz */
181 0, /* 200 MHz */
182 };
183
184 static int exynos7420_cpufreq_smpl_warn_notifier_call(
185 struct notifier_block *notifer,
186 unsigned long event, void *v)
187 {
188 unsigned int state;
189
190 state = __raw_readl(EXYNOS7420_ATLAS_SMPL_CTRL0);
191 state &= ~0x40;
192 __raw_writel(state, EXYNOS7420_ATLAS_SMPL_CTRL0);
193 state |= 0x40;
194 __raw_writel(state, EXYNOS7420_ATLAS_SMPL_CTRL0);
195
196 pr_info("%s: SMPL_WARN: SMPL_WARN is cleared\n",__func__);
197
198 return NOTIFY_OK;
199 }
200
201 static int exynos7420_check_smpl_CA57(void)
202 {
203 int tmp;
204
205 tmp = __raw_readl(EXYNOS7420_ATLAS_SMPL_CTRL1);
206
207 if (tmp & 0x80) {
208 pr_info("%s: SMPL_WARN HAPPENED!\n", __func__);
209 return 1;
210 }
211
212 return 0;
213 };
214
215 static struct notifier_block exynos7420_cpufreq_smpl_warn_notifier = {
216 .notifier_call = exynos7420_cpufreq_smpl_warn_notifier_call,
217 };
218
219 static void exynos7420_set_clkdiv_CA57(unsigned int div_index)
220 {
221 unsigned int tmp, tmp1;
222
223 /* Change Divider - ATLAS0 */
224 tmp = exynos7420_apll_freq_CA57[div_index].clk_div_cpu0;
225
226 __raw_writel(tmp, EXYNOS7420_DIV_ATLAS0);
227
228 while (__raw_readl(EXYNOS7420_DIV_STAT_ATLAS0) & 0x4101111)
229 cpu_relax();
230
231 /* Change Divider - ATLAS1 */
232 tmp1 = exynos7420_apll_freq_CA57[div_index].clk_div_cpu1;
233
234 __raw_writel(tmp1, EXYNOS7420_DIV_ATLAS1);
235
236 while (__raw_readl(EXYNOS7420_DIV_STAT_ATLAS1) & 0x111)
237 cpu_relax();
238
239 #ifdef PRINT_DIV_VAL
240 tmp = __raw_readl(EXYNOS7420_DIV_ATLAS0);
241 tmp1 = __raw_readl(EXYNOS7420_DIV_ATLAS1);
242
243 pr_info("%s: DIV_ATLAS0[0x%08x], DIV_ATLAS1[0x%08x]\n",
244 __func__, tmp, tmp1);
245 #endif
246 }
247
248 static bool exynos7420_pms_change_CA57(unsigned int old_index,
249 unsigned int new_index)
250 {
251 unsigned int old_pm = (exynos7420_apll_freq_CA57[old_index].mps >>
252 EXYNOS7420_PLL_PDIV_SHIFT);
253 unsigned int new_pm = (exynos7420_apll_freq_CA57[new_index].mps >>
254 EXYNOS7420_PLL_PDIV_SHIFT);
255
256 return (old_pm == new_pm) ? 0 : 1;
257 }
258
259 static void exynos7420_set_atlas_pll_CA57(unsigned int new_index, unsigned int old_index)
260 {
261 unsigned int tmp;
262
263 if (!exynos7420_pms_change_CA57(old_index, new_index)) {
264 /* Change MOUT_ATLAS_PLL frequency
265 When PM value are matching with previous frequency
266 then only S value should be change in this case
267 don't need to change ATLAS_PLL to BUS0_PLL_ATLASO */
268 clk_set_rate(mout_atlas_pll, exynos7420_freq_table_CA57[new_index].frequency * 1000);
269 } else {
270 /* 1. before change to BUS0_PLL, set div for BUS0_PLL output */
271 if ((new_index > L17) && (old_index > L17))
272 exynos7420_set_clkdiv_CA57(L17); /* pll_safe_idx of CA57 */
273
274 /* 2. MUX_SEL_ATLAS = MOUT_BUS0_PLL_ALTAS, ATLASCLK uses BUS0_PLL_ATLAS for lock time */
275 if (clk_set_parent(mout_atlas, mout_bus0_pll_atlas))
276 pr_err("Unable to set parent %s of clock %s.\n",
277 mout_bus0_pll_atlas->name, mout_atlas->name);
278 do {
279 cpu_relax();
280 tmp = __raw_readl(EXYNOS7420_MUX_STAT_ATLAS2);
281 tmp &= EXYNOS7420_MUX_STAT_CORE2_MASK;
282 tmp >>= EXYNOS7420_MUX_STAT_CORE2_SHIFT;
283 } while (tmp != 0x1);
284
285 /* 3. Change MOUT_ATLAS_PLL Frequency */
286 clk_set_rate(mout_atlas_pll, exynos7420_freq_table_CA57[new_index].frequency * 1000);
287
288 /* 4. MUX_SEL_ATLAS = MOUT_ATLAS_PLL */
289 if (clk_set_parent(mout_atlas, mout_atlas_pll))
290 pr_err("Unable to set parent %s of clock %s.\n",
291 mout_atlas_pll->name, mout_atlas->name);
292 do {
293 cpu_relax();
294 tmp = __raw_readl(EXYNOS7420_MUX_STAT_ATLAS2);
295 tmp &= EXYNOS7420_MUX_STAT_CORE2_MASK;
296 tmp >>= EXYNOS7420_MUX_STAT_CORE2_SHIFT;
297 } while (tmp != 0x0);
298
299 /* 5. restore original div value */
300 if ((new_index > L17) && (old_index > L17))
301 exynos7420_set_clkdiv_CA57(new_index);
302 }
303 }
304
305 static void exynos7420_set_frequency_CA57(unsigned int old_index,
306 unsigned int new_index)
307 {
308 if (old_index > new_index) {
309 /* Clock Configuration Procedure */
310 /* 1. Change the system clock divider values */
311 exynos7420_set_clkdiv_CA57(new_index);
312 /* 2. Change the atlas_pll m,p,s value */
313 exynos7420_set_atlas_pll_CA57(new_index, old_index);
314 } else if (old_index < new_index) {
315 /* Clock Configuration Procedure */
316 /* 1. Change the atlas_pll m,p,s value */
317 exynos7420_set_atlas_pll_CA57(new_index, old_index);
318 /* 2. Change the system clock divider values */
319 exynos7420_set_clkdiv_CA57(new_index);
320 }
321
322 pr_debug("[%s] Atlas NewFreq: %d OldFreq: %d\n", __func__, exynos7420_freq_table_CA57[new_index].frequency,
323 exynos7420_freq_table_CA57[old_index].frequency);
324 }
325
326 static void __init set_volt_table_CA57(void)
327 {
328 unsigned int i;
329 unsigned int asv_volt = 0;
330
331 for (i = 0; i < CPUFREQ_LEVEL_END_CA57; i++) {
332 asv_volt = get_match_volt(ID_CL1, exynos7420_freq_table_CA57[i].frequency);
333 if (!asv_volt)
334 exynos7420_volt_table_CA57[i] = asv_voltage_7420_CA57[i];
335 else
336 exynos7420_volt_table_CA57[i] = asv_volt;
337
338 pr_info("CPUFREQ of CA57 L%d : %d uV\n", i,
339 exynos7420_volt_table_CA57[i]);
340
341 exynos7420_abb_table_CA57[i] =
342 get_match_abb(ID_CL1, exynos7420_freq_table_CA57[i].frequency);
343
344 pr_info("CPUFREQ of CA57 L%d : ABB %d\n", i,
345 exynos7420_abb_table_CA57[i]);
346 }
347
348 #if defined(CONFIG_CPU_THERMAL) && defined(CONFIG_EXYNOS5_DYNAMIC_CPU_HOTPLUG)
349 switch (exynos_get_table_ver()) {
350 case 0 :
351 case 1 :
352 case 4 :
353 max_support_idx_CA57 = L7; break; /* 1.8GHz */
354 case 5 :
355 max_support_idx_CA57 = L10; break; /* 1.5GHz */
356 default :
357 max_support_idx_CA57 = L4; /* 2.1GHz */
358 }
359 #else
360 max_support_idx_CA57 = L13; /* 1.2 GHz */
361 #endif
362
363 min_support_idx_CA57 = L17; /* 800 MHz */
364
365 pr_info("CPUFREQ of CA57 max_freq : L%d %u khz\n", max_support_idx_CA57,
366 exynos7420_freq_table_CA57[max_support_idx_CA57].frequency);
367 pr_info("CPUFREQ of CA57 min_freq : L%d %u khz\n", min_support_idx_CA57,
368 exynos7420_freq_table_CA57[min_support_idx_CA57].frequency);
369 }
370 static bool exynos7420_is_alive_CA57(void)
371 {
372 unsigned int tmp;
373
374 tmp = __raw_readl(EXYNOS7420_ATLAS_PLL_CON1);
375 tmp &= EXYNOS7420_PLL_BYPASS_MASK;
376 tmp >>= EXYNOS7420_PLL_BYPASS_SHIFT;
377
378 return !tmp ? true : false;
379 }
380
381 static void exynos7420_set_ema_CA57(unsigned int volt)
382 {
383 exynos_set_ema(ID_CL1, volt);
384 }
385
386 int __init exynos_cpufreq_cluster1_init(struct exynos_dvfs_info *info)
387 {
388 unsigned long rate;
389 struct device_node *pmic_node;
390 int ret, tmp;
391
392 set_volt_table_CA57();
393
394 mout_atlas_pll = clk_get(NULL, "mout_atlas_pll");
395 if (IS_ERR(mout_atlas_pll)) {
396 pr_err("failed get mout_atlas_pll clk\n");
397 goto err_mout_atlas_pll;
398 }
399
400 mout_atlas = clk_get(NULL, "mout_atlas");
401 if (IS_ERR(mout_atlas)) {
402 pr_err("failed get mout_atlas clk\n");
403 goto err_mout_atlas;
404 }
405
406 if (clk_set_parent(mout_atlas, mout_atlas_pll)) {
407 pr_err("Unable to set parent %s of clock %s.\n",
408 mout_atlas_pll->name, mout_atlas->name);
409 goto err_clk_set_parent_atlas;
410 }
411
412 mout_bus0_pll_atlas = clk_get(NULL, "mout_bus0_pll_atlas");
413 if (IS_ERR(mout_bus0_pll_atlas)) {
414 pr_err("failed get mout_bus0_pll_atlas clk\n");
415 goto err_mout_bus0_pll_atlas;
416 }
417
418 if (clk_prepare_enable(mout_atlas_pll) || clk_prepare_enable(mout_atlas)) {
419 pr_err("Unable to enable Atlas clocks \n");
420 goto err_clk_prepare_enable;
421 }
422
423 rate = clk_get_rate(mout_bus0_pll_atlas) / 1000;
424
425 info->mpll_freq_khz = rate;
426 info->pll_safe_idx = L17;
427 info->max_support_idx = max_support_idx_CA57;
428 info->min_support_idx = min_support_idx_CA57;
429
430 /* booting frequency is 1.7GHz */
431 info->boot_cpu_min_qos = exynos7420_freq_table_CA57[L8].frequency;
432 info->boot_cpu_max_qos = exynos7420_freq_table_CA57[L8].frequency;
433 info->bus_table = exynos7420_bus_table_CA57;
434 info->cpu_clk = mout_atlas_pll;
435
436 /* reboot limit frequency is 800MHz */
437 info->reboot_limit_freq = exynos7420_freq_table_CA57[L17].frequency;
438
439 info->volt_table = exynos7420_volt_table_CA57;
440 info->abb_table = NULL; //exynos7420_abb_table_CA57;
441 info->freq_table = exynos7420_freq_table_CA57;
442 info->set_freq = exynos7420_set_frequency_CA57;
443 info->need_apll_change = exynos7420_pms_change_CA57;
444 info->is_alive = exynos7420_is_alive_CA57;
445 info->set_ema = exynos7420_set_ema_CA57;
446
447 pmic_node = of_find_compatible_node(NULL, NULL, "samsung,s2mps15-pmic");
448
449 if (!pmic_node) {
450 pr_err("%s: faile to get pmic dt_node\n", __func__);
451 } else {
452 ret = of_property_read_u32(pmic_node, "smpl_warn_en", &en_smpl_warn);
453 if (ret)
454 pr_err("%s: faile to get Property of smpl_warn_en\n", __func__);
455 }
456
457 if (en_smpl_warn) {
458 info->check_smpl = exynos7420_check_smpl_CA57;
459
460 /* ATLAS_RATIO_SMPL */
461 tmp = __raw_readl(EXYNOS7420_ATLAS_SMPL_CTRL0);
462 tmp &= 0x7F;
463 tmp |= 0x44;
464 __raw_writel(tmp, EXYNOS7420_ATLAS_SMPL_CTRL0);
465 pr_info("%s SMPL_WARN ENABLE (DIV:%d) ", __func__, tmp&0x3F);
466
467 exynos_cpufreq_smpl_warn_register_notifier(&exynos7420_cpufreq_smpl_warn_notifier);
468 }
469
470 return 0;
471
472 err_clk_prepare_enable:
473 err_mout_bus0_pll_atlas:
474 err_clk_set_parent_atlas:
475 clk_put(mout_atlas);
476 err_mout_atlas:
477 clk_put(mout_atlas_pll);
478 err_mout_atlas_pll:
479
480 pr_debug("%s: failed initialization\n", __func__);
481 return -EINVAL;
482 }