2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
5 * EXYNOS5430 - EAGLE Core frequency scaling support
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.
12 #include <linux/kernel.h>
13 #include <linux/err.h>
14 #include <linux/clk.h>
16 #include <linux/slab.h>
17 #include <linux/cpufreq.h>
18 #include <linux/clk-private.h>
21 #include <mach/regs-clock.h>
22 #include <mach/regs-clock-exynos5430.h>
23 #include <mach/regs-pmu.h>
24 #include <mach/cpufreq.h>
25 #include <mach/asv-exynos.h>
27 #define CPUFREQ_LEVEL_END_CA15 (L23 + 1)
28 #define L2_LOCAL_PWR_EN 0x7
33 #define EMA_VAL_REG (S5P_VA_CHIPID2 + 0x20)
34 #define EMA_CON1_SHIFT 2
35 #define EMA_CON2_SHIFT 5
36 #define EMA_CON_MASK 0x7
41 #define EMA_VOLT 900000
42 #define EGL_L1_EMA_SHIFT 8
43 #define EGL_L2_EMA_SHIFT 20
44 #define CLK_EGL_EMA_OFFSET 0x0330
46 static int max_support_idx_CA15
;
47 static int min_support_idx_CA15
= (CPUFREQ_LEVEL_END_CA15
- 1);
49 static struct clk
*mout_egl
;
50 static struct clk
*mout_egl_pll
;
51 static struct clk
*sclk_bus_pll
;
52 static struct clk
*mout_bus_pll_user
;
53 static struct clk
*fout_egl_pll
;
54 static unsigned int spd_option_flag
, spd_sel
;
56 static void __iomem
*clk_egl_2_base
;
57 static int egl_ema_con1
;
58 static int egl_ema_con2
;
60 static unsigned int exynos5430_volt_table_CA15
[CPUFREQ_LEVEL_END_CA15
];
61 static unsigned int exynos5430_abb_table_CA15
[CPUFREQ_LEVEL_END_CA15
];
63 static struct cpufreq_frequency_table exynos5430_freq_table_CA15
[] = {
88 {0, CPUFREQ_TABLE_END
},
91 static struct cpufreq_clkdiv exynos5430_clkdiv_table_CA15
[CPUFREQ_LEVEL_END_CA15
];
93 static unsigned int clkdiv_cpu0_5430_CA15
[CPUFREQ_LEVEL_END_CA15
][6] = {
95 * Clock divider value for following
96 * { EGL1, EGL2, ACLK_EGL, PCLK_EGL,
97 * ATCLK, PCLK_DBG_EGL }
101 { 0, 0, 4, 7, 7, 7 },
103 /* ARM L1: 2.4GMHz */
104 { 0, 0, 4, 7, 7, 7 },
106 /* ARM L2: 2.3GMHz */
107 { 0, 0, 4, 7, 7, 7 },
110 { 0, 0, 4, 7, 7, 7 },
113 { 0, 0, 4, 7, 7, 7 },
116 { 0, 0, 4, 7, 7, 7 },
119 { 0, 0, 4, 7, 7, 7 },
122 { 0, 0, 4, 7, 7, 7 },
125 { 0, 0, 4, 7, 7, 7 },
128 { 0, 0, 4, 7, 7, 7 },
130 /* ARM L10: 1.5GHz */
131 { 0, 0, 3, 7, 7, 7 },
133 /* ARM L11: 1.4GHz */
134 { 0, 0, 3, 7, 7, 7 },
136 /* ARM L12: 1.3GHz */
137 { 0, 0, 3, 7, 7, 7 },
139 /* ARM L13: 1.2GHz */
140 { 0, 0, 3, 7, 7, 7 },
142 /* ARM L14: 1.1GHz */
143 { 0, 0, 2, 7, 7, 7 },
145 /* ARM L15: 1.0GHz */
146 { 0, 0, 2, 7, 7, 7 },
148 /* ARM L16: 900MHz */
149 { 0, 0, 2, 7, 7, 7 },
151 /* ARM L17: 800MHz */
152 { 0, 0, 2, 7, 7, 7 },
154 /* ARM L18: 700MHz */
155 { 0, 0, 2, 7, 7, 7 },
157 /* ARM L19: 600MHz */
158 { 0, 0, 2, 7, 7, 7 },
160 /* ARM L20: 500MHz */
161 { 0, 0, 2, 7, 7, 7 },
163 /* ARM L21: 400MHz */
164 { 0, 0, 2, 7, 7, 7 },
166 /* ARM L22: 300MHz */
167 { 0, 0, 2, 7, 7, 7 },
169 /* ARM L23: 200MHz */
170 { 0, 0, 2, 7, 7, 7 },
173 static unsigned int clkdiv_cpu1_5430_CA15
[CPUFREQ_LEVEL_END_CA15
][2] = {
175 * Clock divider value for following
176 * { SCLK_EGL_PLL, SCLK_HPM_EGL }
182 /* ARM L1: 2.4GMHz */
185 /* ARM L2: 2.3GMHz */
209 /* ARM L10: 1.5GHz */
212 /* ARM L11: 1.4GHz */
215 /* ARM L12: 1.3GHz */
218 /* ARM L13: 1.2GHz */
221 /* ARM L14: 1.1GHz */
224 /* ARM L15: 1.0GHz */
227 /* ARM L16: 900MHz */
230 /* ARM L17: 800MHz */
233 /* ARM L18: 700MHz */
236 /* ARM L19: 600MHz */
239 /* ARM L20: 500MHz */
242 /* ARM L21: 400MHz */
245 /* ARM L22: 300MHz */
248 /* ARM L23: 200MHz */
252 static unsigned int exynos5430_egl_pll_pms_table_CA15
[CPUFREQ_LEVEL_END_CA15
] = {
253 /* MDIV | PDIV | SDIV */
254 /* EGL_PLL FOUT L0: 2.5GHz */
255 PLL2450X_PMS(625, 6, 0),
257 /* EGL_PLL FOUT L1: 2.4GHz */
258 PLL2450X_PMS(500, 5, 0),
260 /* EGL_PLL FOUT L2: 2.3GHz */
261 PLL2450X_PMS(575, 6, 0),
263 /* EGL_PLL FOUT L3: 2.2GHz */
264 PLL2450X_PMS(550, 6, 0),
266 /* EGL_PLL FOUT L4: 2.1GHz */
267 PLL2450X_PMS(350, 4, 0),
269 /* EGL_PLL FOUT L5: 2.0GHz */
270 PLL2450X_PMS(500, 6, 0),
272 /* EGL_PLL FOUT L6: 1.9GHz */
273 PLL2450X_PMS(475, 6, 0),
275 /* EGL_PLL FOUT L7: 1.8GHz */
276 PLL2450X_PMS(375, 5, 0),
278 /* EGL_PLL FOUT L8: 1.7GHz */
279 PLL2450X_PMS(425, 6, 0),
281 /* EGL_PLL FOUT L9: 1.6GHz */
282 PLL2450X_PMS(400, 6, 0),
284 /* EGL_PLL FOUT L10: 1.5GHz */
285 PLL2450X_PMS(250, 4, 0),
287 /* EGL_PLL FOUT L11: 1.4GHz */
288 PLL2450X_PMS(350, 6, 0),
290 /* EGL_PLL FOUT L12: 1.3GHz */
291 PLL2450X_PMS(325, 6, 0),
293 /* EGL_PLL FOUT L13: 1.2GHz */
294 PLL2450X_PMS(500, 5, 1),
296 /* EGL_PLL FOUT L14: 1.1GHz */
297 PLL2450X_PMS(550, 6, 1),
299 /* EGL_PLL FOUT L15: 1.0GHz */
300 PLL2450X_PMS(500, 6, 1),
302 /* EGL_PLL FOUT L16: 900MHz */
303 PLL2450X_PMS(375, 5, 1),
305 /* EGL_PLL FOUT L17: 800MHz */
306 PLL2450X_PMS(400, 6, 1),
308 /* EGL_PLL FOUT L18: 700MHz */
309 PLL2450X_PMS(350, 6, 1),
311 /* EGL_PLL FOUT L19: 600MHz */
312 PLL2450X_PMS(500, 5, 2),
314 /* EGL_PLL FOUT L20: 500MHz */
315 PLL2450X_PMS(500, 6, 2),
317 /* EGL_PLL FOUT L21: 400MHz */
318 PLL2450X_PMS(400, 6, 2),
320 /* EGL_PLL FOUT L22: 300MHz */
321 PLL2450X_PMS(500, 5, 3),
323 /* EGL_PLL FOUT L23: 200MHz */
324 PLL2450X_PMS(400, 6, 3),
328 * ASV group voltage table
330 static const unsigned int asv_voltage_5430_CA15
[CPUFREQ_LEVEL_END_CA15
] = {
331 1300000, /* LO 2500 */
332 1300000, /* L1 2400 */
333 1300000, /* L2 2300 */
334 1300000, /* L3 2200 */
335 1300000, /* L4 2100 */
336 1300000, /* L5 2000 */
337 1300000, /* L6 1900 */
338 1300000, /* L7 1800 */
339 1275000, /* L8 1700 */
340 1250000, /* L9 1600 */
341 1225000, /* L10 1500 */
342 1187500, /* L11 1400 */
343 1150000, /* L12 1300 */
344 1125000, /* L13 1200 */
345 1100000, /* L14 1100 */
346 1075000, /* L15 1000 */
347 1050000, /* L16 900 */
348 1025000, /* L17 800 */
349 1025000, /* L18 700 */
350 1000000, /* L19 600 */
351 1000000, /* L20 500 */
352 975000, /* L21 400 */
353 925000, /* L22 300 */
354 925000, /* L23 200 */
357 /* Minimum memory throughput in megabytes per second */
358 static int exynos5430_bus_table_CA15
[CPUFREQ_LEVEL_END_CA15
] = {
359 825000, /* 2.5 GHz */
360 825000, /* 2.4 GHz */
361 825000, /* 2.3 GHz */
362 825000, /* 2.2 GHz */
363 825000, /* 2.1 GHz */
364 825000, /* 2.0 GHz */
365 825000, /* 1.9 GHz */
366 825000, /* 1.8 GHz */
367 633000, /* 1.7 MHz */
368 633000, /* 1.6 GHz */
369 633000, /* 1.5 GHz */
370 633000, /* 1.4 GHz */
371 543000, /* 1.3 GHz */
372 543000, /* 1.2 GHz */
373 413000, /* 1.1 GHz */
374 413000, /* 1.0 GHz */
385 static int exynos5430_ema_valid_check_CA15(int ema_con_val
)
389 switch (ema_con_val
) {
404 static void exynos5430_set_ema_CA15(unsigned int target_volt
)
408 tmp
= __raw_readl(clk_egl_2_base
+ CLK_EGL_EMA_OFFSET
);
410 if (target_volt
> EMA_VOLT
) {
411 if (egl_ema_con1
> 0) {
412 tmp
&= ~((EMA_CON_MASK
<< EGL_L1_EMA_SHIFT
) |
413 (EMA_CON_MASK
<< EGL_L2_EMA_SHIFT
));
414 tmp
|= ((egl_ema_con1
<< EGL_L1_EMA_SHIFT
) |
415 (egl_ema_con1
<< EGL_L2_EMA_SHIFT
));
416 __raw_writel(tmp
, clk_egl_2_base
+ CLK_EGL_EMA_OFFSET
);
419 if (egl_ema_con2
> 0) {
420 tmp
&= ~((EMA_CON_MASK
<< EGL_L1_EMA_SHIFT
) |
421 (EMA_CON_MASK
<< EGL_L2_EMA_SHIFT
));
422 tmp
|= ((egl_ema_con2
<< EGL_L1_EMA_SHIFT
) |
423 (egl_ema_con2
<< EGL_L2_EMA_SHIFT
));
424 __raw_writel(tmp
, clk_egl_2_base
+ CLK_EGL_EMA_OFFSET
);
429 static void exynos5430_set_clkdiv_CA15(unsigned int div_index
)
431 unsigned int tmp
, tmp1
;
433 /* Change Divider - EGL0 */
434 tmp
= exynos5430_clkdiv_table_CA15
[div_index
].clkdiv0
;
436 __raw_writel(tmp
, EXYNOS5430_DIV_EGL0
);
438 while (__raw_readl(EXYNOS5430_DIV_STAT_EGL0
) & 0x111111)
441 /* Change Divider - EGL1 */
442 tmp1
= exynos5430_clkdiv_table_CA15
[div_index
].clkdiv1
;
444 __raw_writel(tmp1
, EXYNOS5430_DIV_EGL1
);
446 while (__raw_readl(EXYNOS5430_DIV_STAT_EGL1
) & 0x11)
450 tmp
= __raw_readl(EXYNOS5430_DIV_EGL0
);
451 tmp1
= __raw_readl(EXYNOS5430_DIV_EGL1
);
453 pr_info("%s: DIV_EGL0[0x%08x], DIV_EGL1[0x%08x]\n",
454 __func__
, tmp
, tmp1
);
458 static void exynos5430_set_egl_pll_CA15(unsigned int new_index
, unsigned int old_index
)
460 unsigned int tmp
, pdiv
;
462 /* 1. before change to BUS_PLL, set div for BUS_PLL output */
463 if ((new_index
< L17
) && (old_index
< L17
))
464 exynos5430_set_clkdiv_CA15(L17
); /* pll_safe_idx of CA15 */
466 /* 2. CLKMUX_SEL_EGL = MOUT_BUS_PLL_USER, EGLCLK uses BUS_PLL_USER for lock time */
467 if (clk_set_parent(mout_egl
, mout_bus_pll_user
))
468 pr_err("Unable to set parent %s of clock %s.\n",
469 mout_bus_pll_user
->name
, mout_egl
->name
);
472 tmp
= __raw_readl(EXYNOS5430_SRC_STAT_EGL2
);
473 tmp
&= EXYNOS5430_SRC_STAT_EGL2_EGL_MASK
;
474 tmp
>>= EXYNOS5430_SRC_STAT_EGL2_EGL_SHIFT
;
475 } while (tmp
!= 0x2);
477 /* 3. Set EGL_PLL Lock time */
478 pdiv
= ((exynos5430_egl_pll_pms_table_CA15
[new_index
] &
479 EXYNOS5430_PLL_PDIV_MASK
) >> EXYNOS5430_PLL_PDIV_SHIFT
);
481 __raw_writel((pdiv
* 150), EXYNOS5430_EGL_PLL_LOCK
);
483 /* 4. Change PLL PMS values */
484 tmp
= __raw_readl(EXYNOS5430_EGL_PLL_CON0
);
485 tmp
&= ~(EXYNOS5430_PLL_MDIV_MASK
|
486 EXYNOS5430_PLL_PDIV_MASK
|
487 EXYNOS5430_PLL_SDIV_MASK
);
488 tmp
|= exynos5430_egl_pll_pms_table_CA15
[new_index
];
489 __raw_writel(tmp
, EXYNOS5430_EGL_PLL_CON0
);
491 /* 5. wait_lock_time */
494 tmp
= __raw_readl(EXYNOS5430_EGL_PLL_CON0
);
495 } while (!(tmp
& (0x1 << EXYNOS5430_EGL_PLL_CON0_LOCKED_SHIFT
)));
497 /* 6. CLKMUX_SEL_EGL = MOUT_EGL_PLL */
498 if (clk_set_parent(mout_egl
, mout_egl_pll
))
499 pr_err("Unable to set parent %s of clock %s.\n",
500 mout_egl_pll
->name
, mout_egl
->name
);
503 tmp
= __raw_readl(EXYNOS5430_SRC_STAT_EGL2
);
504 tmp
&= EXYNOS5430_SRC_STAT_EGL2_EGL_MASK
;
505 tmp
>>= EXYNOS5430_SRC_STAT_EGL2_EGL_SHIFT
;
506 } while (tmp
!= 0x1);
508 /* 7. restore original div value */
509 if ((new_index
< L17
) && (old_index
< L17
))
510 exynos5430_set_clkdiv_CA15(new_index
);
513 static bool exynos5430_pms_change_CA15(unsigned int old_index
,
514 unsigned int new_index
)
516 unsigned int old_pm
= (exynos5430_egl_pll_pms_table_CA15
[old_index
] >>
517 EXYNOS5430_PLL_PDIV_SHIFT
);
518 unsigned int new_pm
= (exynos5430_egl_pll_pms_table_CA15
[new_index
] >>
519 EXYNOS5430_PLL_PDIV_SHIFT
);
521 return (old_pm
== new_pm
) ? 0 : 1;
524 static void exynos5430_set_frequency_CA15(unsigned int old_index
,
525 unsigned int new_index
)
529 if (old_index
> new_index
) {
530 if (!exynos5430_pms_change_CA15(old_index
, new_index
)) {
531 /* 1. Change the system clock divider values */
532 exynos5430_set_clkdiv_CA15(new_index
);
533 /* 2. Change just s value in egl_pll m,p,s value */
534 tmp
= __raw_readl(EXYNOS5430_EGL_PLL_CON0
);
535 tmp
&= ~EXYNOS5430_PLL_SDIV_MASK
;
536 tmp
|= (exynos5430_egl_pll_pms_table_CA15
[new_index
] & EXYNOS5430_PLL_SDIV_MASK
);
537 __raw_writel(tmp
, EXYNOS5430_EGL_PLL_CON0
);
539 /* Clock Configuration Procedure */
540 /* 1. Change the system clock divider values */
541 exynos5430_set_clkdiv_CA15(new_index
);
542 /* 2. Change the egl_pll m,p,s value */
543 exynos5430_set_egl_pll_CA15(new_index
, old_index
);
545 } else if (old_index
< new_index
) {
546 if (!exynos5430_pms_change_CA15(old_index
, new_index
)) {
547 /* 1. Change just s value in egl_pll m,p,s value */
548 tmp
= __raw_readl(EXYNOS5430_EGL_PLL_CON0
);
549 tmp
&= ~EXYNOS5430_PLL_SDIV_MASK
;
550 tmp
|= (exynos5430_egl_pll_pms_table_CA15
[new_index
] & EXYNOS5430_PLL_SDIV_MASK
);
551 __raw_writel(tmp
, EXYNOS5430_EGL_PLL_CON0
);
552 /* 2. Change the system clock divider values */
553 exynos5430_set_clkdiv_CA15(new_index
);
555 /* Clock Configuration Procedure */
556 /* 1. Change the egl_pll m,p,s value */
557 exynos5430_set_egl_pll_CA15(new_index
, old_index
);
558 /* 2. Change the system clock divider values */
559 exynos5430_set_clkdiv_CA15(new_index
);
563 clk_set_rate(fout_egl_pll
, exynos5430_freq_table_CA15
[new_index
].frequency
* 1000);
566 static void __init
set_volt_table_CA15(void)
569 unsigned int asv_volt
= 0;
571 for (i
= 0; i
< CPUFREQ_LEVEL_END_CA15
; i
++) {
572 asv_volt
= get_match_volt(ID_ARM
, exynos5430_freq_table_CA15
[i
].frequency
);
574 exynos5430_volt_table_CA15
[i
] = asv_voltage_5430_CA15
[i
];
576 exynos5430_volt_table_CA15
[i
] = asv_volt
;
578 pr_info("CPUFREQ of CA15 L%d : %d uV\n", i
,
579 exynos5430_volt_table_CA15
[i
]);
581 exynos5430_abb_table_CA15
[i
] =
582 get_match_abb(ID_ARM
, exynos5430_freq_table_CA15
[i
].frequency
);
584 pr_info("CPUFREQ of CA15 L%d : ABB %d\n", i
,
585 exynos5430_abb_table_CA15
[i
]);
588 exynos5430_get_egl_speed_option(&spd_option_flag
, &spd_sel
);
590 if (spd_option_flag
== EGL_DISABLE_SPD_OPTION
) {
591 max_support_idx_CA15
= L13
; /* 1.2 GHz */
593 if (spd_sel
== EGL_SPD_SEL_1500_MHZ
)
594 max_support_idx_CA15
= L10
; /* 1.5 GHz */
595 #if defined(CONFIG_SOC_EXYNOS5430_L)
596 else if (spd_sel
== EGL_SPD_SEL_1700_MHZ
)
597 max_support_idx_CA15
= L8
; /* 1.7 GHz */
598 else if (spd_sel
== EGL_SPD_SEL_1900_MHZ
||
599 spd_sel
== EGL_SPD_SEL_2000_MHZ
||
600 spd_sel
== EGL_SPD_SEL_2100_MHZ
)
601 max_support_idx_CA15
= L7
; /* 1.8 GHz */
603 else if (spd_sel
== EGL_SPD_SEL_1700_MHZ
)
604 max_support_idx_CA15
= L8
; /* 1.7 GHz */
605 else if (spd_sel
== EGL_SPD_SEL_1900_MHZ
)
606 max_support_idx_CA15
= L6
; /* 1.9 GHz */
607 else if (spd_sel
== EGL_SPD_SEL_2000_MHZ
)
608 max_support_idx_CA15
= L5
; /* 2.0 GHz */
609 else if (spd_sel
== EGL_SPD_SEL_2100_MHZ
)
610 max_support_idx_CA15
= L5
; /* 2.0 GHz */
613 panic("can not support speed select (0x%x)\n", spd_sel
);
615 min_support_idx_CA15
= L17
; /* 800 MHz */
617 pr_info("CPUFREQ of CA15 max_freq : L%d %u khz\n", max_support_idx_CA15
,
618 exynos5430_freq_table_CA15
[max_support_idx_CA15
].frequency
);
619 pr_info("CPUFREQ of CA15 min_freq : L%d %u khz\n", min_support_idx_CA15
,
620 exynos5430_freq_table_CA15
[min_support_idx_CA15
].frequency
);
623 static bool exynos5430_is_alive_CA15(void)
627 tmp
= __raw_readl(EXYNOS5430_EGL_PLL_CON1
);
628 tmp
&= EXYNOS5430_PLL_BYPASS_MASK
;
629 tmp
>>= EXYNOS5430_PLL_BYPASS_SHIFT
;
631 return !tmp
? true : false;
634 int __init
exynos5_cpufreq_CA15_init(struct exynos_dvfs_info
*info
)
640 set_volt_table_CA15();
642 mout_egl
= __clk_lookup("mout_egl");
644 pr_err("failed get mout_egl clk\n");
648 mout_egl_pll
= __clk_lookup("mout_egl_pll");
650 pr_err("failed get mout_egl_pll clk\n");
651 goto err_mout_egl_pll
;
654 if (clk_set_parent(mout_egl
, mout_egl_pll
)) {
655 pr_err("Unable to set parent %s of clock %s.\n",
656 mout_egl_pll
->name
, mout_egl
->name
);
657 goto err_clk_set_parent_egl
;
660 sclk_bus_pll
= __clk_lookup("sclk_bus_pll");
662 pr_err("failed get sclk_bus_pll clk\n");
663 goto err_sclk_bus_pll
;
666 mout_bus_pll_user
= __clk_lookup("mout_bus_pll_egl_user");
667 if (!mout_bus_pll_user
) {
668 pr_err("failed get mout_bus_pll_egl_user clk\n");
669 goto err_mout_bus_pll_user
;
672 if (clk_set_parent(mout_bus_pll_user
, sclk_bus_pll
)) {
673 pr_err("Unable to set parent %s of clock %s.\n",
674 sclk_bus_pll
->name
, mout_bus_pll_user
->name
);
675 goto err_clk_set_parent_bus_pll
;
678 rate
= clk_get_rate(mout_bus_pll_user
) / 1000;
680 fout_egl_pll
= __clk_lookup("fout_egl_pll");
682 pr_err("failed get fout_egl_pll clk\n");
683 goto err_fout_egl_pll
;
686 clk_put(sclk_bus_pll
);
688 for (i
= L0
; i
< CPUFREQ_LEVEL_END_CA15
; i
++) {
689 exynos5430_clkdiv_table_CA15
[i
].index
= i
;
692 tmp
= __raw_readl(EXYNOS5430_DIV_EGL0
);
694 tmp
&= ~(EXYNOS5430_DIV_EGL0_EGL1_MASK
|
695 EXYNOS5430_DIV_EGL0_EGL2_MASK
|
696 EXYNOS5430_DIV_EGL0_ACLK_EGL_MASK
|
697 EXYNOS5430_DIV_EGL0_PCLK_EGL_MASK
|
698 EXYNOS5430_DIV_EGL0_ATCLK_EGL_MASK
|
699 EXYNOS5430_DIV_EGL0_PCLK_DBG_EGL_MASK
);
701 tmp
|= ((clkdiv_cpu0_5430_CA15
[i
][0] << EXYNOS5430_DIV_EGL0_EGL1_SHIFT
) |
702 (clkdiv_cpu0_5430_CA15
[i
][1] << EXYNOS5430_DIV_EGL0_EGL2_SHIFT
) |
703 (clkdiv_cpu0_5430_CA15
[i
][2] << EXYNOS5430_DIV_EGL0_ACLK_EGL_SHIFT
) |
704 (clkdiv_cpu0_5430_CA15
[i
][3] << EXYNOS5430_DIV_EGL0_PCLK_EGL_SHIFT
) |
705 (clkdiv_cpu0_5430_CA15
[i
][4] << EXYNOS5430_DIV_EGL0_ATCLK_EGL_SHIFT
) |
706 (clkdiv_cpu0_5430_CA15
[i
][5] << EXYNOS5430_DIV_EGL0_PCLK_DBG_EGL_SHIFT
));
708 exynos5430_clkdiv_table_CA15
[i
].clkdiv0
= tmp
;
711 tmp
= __raw_readl(EXYNOS5430_DIV_EGL1
);
713 tmp
&= ~(EXYNOS5430_DIV_EGL1_EGL_PLL_MASK
|
714 EXYNOS5430_DIV_EGL1_SCLK_HPM_EGL_MASK
);
716 tmp
|= ((clkdiv_cpu1_5430_CA15
[i
][0] << EXYNOS5430_DIV_EGL1_EGL_PLL_SHIFT
) |
717 (clkdiv_cpu1_5430_CA15
[i
][1] << EXYNOS5430_DIV_EGL1_SCLK_HPM_EGL_SHIFT
));
719 exynos5430_clkdiv_table_CA15
[i
].clkdiv1
= tmp
;
722 /* Save EMA control values */
723 tmp
= __raw_readl(EMA_VAL_REG
);
724 egl_ema_con1
= (tmp
>> EMA_CON1_SHIFT
) & EMA_CON_MASK
;
725 egl_ema_con2
= (tmp
>> EMA_CON2_SHIFT
) & EMA_CON_MASK
;
727 egl_ema_con1
= exynos5430_ema_valid_check_CA15(egl_ema_con1
);
728 egl_ema_con2
= exynos5430_ema_valid_check_CA15(egl_ema_con2
);
730 pr_info("%s: ema_con1[%d], ema_con2[%d]\n", __func__
, egl_ema_con1
, egl_ema_con2
);
732 clk_egl_2_base
= ioremap(EXYNOS5430_PA_CMU_EGL2
, SZ_4K
);
733 if (!clk_egl_2_base
) {
734 pr_err("failed to ioremap for EMA\n");
738 info
->mpll_freq_khz
= rate
;
739 info
->pll_safe_idx
= L17
;
740 info
->max_support_idx
= max_support_idx_CA15
;
741 info
->min_support_idx
= min_support_idx_CA15
;
742 if (spd_option_flag
== EGL_DISABLE_SPD_OPTION
) {
743 /* booting frequency is 800MHz */
744 info
->boot_cpu_min_qos
= exynos5430_freq_table_CA15
[L17
].frequency
;
745 info
->boot_cpu_max_qos
= exynos5430_freq_table_CA15
[L17
].frequency
;
747 /* booting frequency is 1.2GHz */
748 info
->boot_cpu_min_qos
= exynos5430_freq_table_CA15
[L13
].frequency
;
749 info
->boot_cpu_max_qos
= exynos5430_freq_table_CA15
[L13
].frequency
;
751 info
->bus_table
= exynos5430_bus_table_CA15
;
752 info
->cpu_clk
= fout_egl_pll
;
754 info
->volt_table
= exynos5430_volt_table_CA15
;
755 info
->abb_table
= exynos5430_abb_table_CA15
;
756 info
->freq_table
= exynos5430_freq_table_CA15
;
757 info
->set_freq
= exynos5430_set_frequency_CA15
;
758 info
->set_ema
= exynos5430_set_ema_CA15
;
759 info
->need_apll_change
= exynos5430_pms_change_CA15
;
760 info
->is_alive
= exynos5430_is_alive_CA15
;
763 /* dividing EGL_CLK to 1/16 */
764 tmp
= __raw_readl(EXYNOS5430_CLKOUT_CMU_EGL
);
767 __raw_writel(tmp
, EXYNOS5430_CLKOUT_CMU_EGL
);
770 __raw_writel(0x00, EXYNOS5430_EGL_STOPCTRL
);
775 clk_put(fout_egl_pll
);
777 err_clk_set_parent_bus_pll
:
778 clk_put(mout_bus_pll_user
);
779 err_mout_bus_pll_user
:
780 clk_put(sclk_bus_pll
);
782 err_clk_set_parent_egl
:
783 clk_put(mout_egl_pll
);
787 pr_debug("%s: failed initialization\n", __func__
);