2 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
5 * Clock support for EXYNOS5 SoCs
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>
15 #include <linux/syscore_ops.h>
17 #include <plat/cpu-freq.h>
18 #include <plat/clock.h>
21 #include <plat/s5p-clock.h>
22 #include <plat/clock-clksrc.h>
26 #include <mach/regs-clock.h>
27 #include <mach/sysmmu.h>
31 #ifdef CONFIG_PM_SLEEP
32 static struct sleep_save exynos5_clock_save
[] = {
33 /* will be implemented */
37 static struct clk exynos5_clk_sclk_dptxphy
= {
41 static struct clk exynos5_clk_sclk_hdmi24m
= {
42 .name
= "sclk_hdmi24m",
46 static struct clk exynos5_clk_sclk_hdmi27m
= {
47 .name
= "sclk_hdmi27m",
51 static struct clk exynos5_clk_sclk_hdmiphy
= {
52 .name
= "sclk_hdmiphy",
55 static struct clk exynos5_clk_sclk_usbphy
= {
56 .name
= "sclk_usbphy",
60 static int exynos5_clksrc_mask_top_ctrl(struct clk
*clk
, int enable
)
62 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP
, clk
, enable
);
65 static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk
*clk
, int enable
)
67 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0
, clk
, enable
);
70 static int exynos5_clksrc_mask_fsys_ctrl(struct clk
*clk
, int enable
)
72 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS
, clk
, enable
);
75 static int exynos5_clksrc_mask_gscl_ctrl(struct clk
*clk
, int enable
)
77 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL
, clk
, enable
);
80 static int exynos5_clksrc_mask_peric0_ctrl(struct clk
*clk
, int enable
)
82 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0
, clk
, enable
);
85 static int exynos5_clk_ip_core_ctrl(struct clk
*clk
, int enable
)
87 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE
, clk
, enable
);
90 static int exynos5_clk_ip_disp1_ctrl(struct clk
*clk
, int enable
)
92 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1
, clk
, enable
);
95 static int exynos5_clk_ip_fsys_ctrl(struct clk
*clk
, int enable
)
97 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS
, clk
, enable
);
100 static int exynos5_clk_block_ctrl(struct clk
*clk
, int enable
)
102 return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK
, clk
, enable
);
105 static int exynos5_clk_ip_gen_ctrl(struct clk
*clk
, int enable
)
107 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN
, clk
, enable
);
110 static int exynos5_clk_ip_gps_ctrl(struct clk
*clk
, int enable
)
112 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GPS
, clk
, enable
);
115 static int exynos5_clk_ip_mfc_ctrl(struct clk
*clk
, int enable
)
117 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC
, clk
, enable
);
120 static int exynos5_clk_ip_peric_ctrl(struct clk
*clk
, int enable
)
122 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC
, clk
, enable
);
125 static int exynos5_clk_ip_peris_ctrl(struct clk
*clk
, int enable
)
127 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS
, clk
, enable
);
130 /* Core list of CMU_CPU side */
132 static struct clksrc_clk exynos5_clk_mout_apll
= {
136 .sources
= &clk_src_apll
,
137 .reg_src
= { .reg
= EXYNOS5_CLKSRC_CPU
, .shift
= 0, .size
= 1 },
140 static struct clksrc_clk exynos5_clk_sclk_apll
= {
143 .parent
= &exynos5_clk_mout_apll
.clk
,
145 .reg_div
= { .reg
= EXYNOS5_CLKDIV_CPU0
, .shift
= 24, .size
= 3 },
148 static struct clksrc_clk exynos5_clk_mout_bpll
= {
152 .sources
= &clk_src_bpll
,
153 .reg_src
= { .reg
= EXYNOS5_CLKSRC_CDREX
, .shift
= 0, .size
= 1 },
156 static struct clk
*exynos5_clk_src_bpll_user_list
[] = {
158 [1] = &exynos5_clk_mout_bpll
.clk
,
161 static struct clksrc_sources exynos5_clk_src_bpll_user
= {
162 .sources
= exynos5_clk_src_bpll_user_list
,
163 .nr_sources
= ARRAY_SIZE(exynos5_clk_src_bpll_user_list
),
166 static struct clksrc_clk exynos5_clk_mout_bpll_user
= {
168 .name
= "mout_bpll_user",
170 .sources
= &exynos5_clk_src_bpll_user
,
171 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP2
, .shift
= 24, .size
= 1 },
174 static struct clksrc_clk exynos5_clk_mout_cpll
= {
178 .sources
= &clk_src_cpll
,
179 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP2
, .shift
= 8, .size
= 1 },
182 static struct clksrc_clk exynos5_clk_mout_epll
= {
186 .sources
= &clk_src_epll
,
187 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP2
, .shift
= 12, .size
= 1 },
190 struct clksrc_clk exynos5_clk_mout_mpll
= {
194 .sources
= &clk_src_mpll
,
195 .reg_src
= { .reg
= EXYNOS5_CLKSRC_CORE1
, .shift
= 8, .size
= 1 },
198 static struct clk
*exynos_clkset_vpllsrc_list
[] = {
200 [1] = &exynos5_clk_sclk_hdmi27m
,
203 static struct clksrc_sources exynos5_clkset_vpllsrc
= {
204 .sources
= exynos_clkset_vpllsrc_list
,
205 .nr_sources
= ARRAY_SIZE(exynos_clkset_vpllsrc_list
),
208 static struct clksrc_clk exynos5_clk_vpllsrc
= {
211 .enable
= exynos5_clksrc_mask_top_ctrl
,
214 .sources
= &exynos5_clkset_vpllsrc
,
215 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP2
, .shift
= 0, .size
= 1 },
218 static struct clk
*exynos5_clkset_sclk_vpll_list
[] = {
219 [0] = &exynos5_clk_vpllsrc
.clk
,
220 [1] = &clk_fout_vpll
,
223 static struct clksrc_sources exynos5_clkset_sclk_vpll
= {
224 .sources
= exynos5_clkset_sclk_vpll_list
,
225 .nr_sources
= ARRAY_SIZE(exynos5_clkset_sclk_vpll_list
),
228 static struct clksrc_clk exynos5_clk_sclk_vpll
= {
232 .sources
= &exynos5_clkset_sclk_vpll
,
233 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP2
, .shift
= 16, .size
= 1 },
236 static struct clksrc_clk exynos5_clk_sclk_pixel
= {
238 .name
= "sclk_pixel",
239 .parent
= &exynos5_clk_sclk_vpll
.clk
,
241 .reg_div
= { .reg
= EXYNOS5_CLKDIV_DISP1_0
, .shift
= 28, .size
= 4 },
244 static struct clk
*exynos5_clkset_sclk_hdmi_list
[] = {
245 [0] = &exynos5_clk_sclk_pixel
.clk
,
246 [1] = &exynos5_clk_sclk_hdmiphy
,
249 static struct clksrc_sources exynos5_clkset_sclk_hdmi
= {
250 .sources
= exynos5_clkset_sclk_hdmi_list
,
251 .nr_sources
= ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list
),
254 static struct clksrc_clk exynos5_clk_sclk_hdmi
= {
257 .enable
= exynos5_clksrc_mask_disp1_0_ctrl
,
258 .ctrlbit
= (1 << 20),
260 .sources
= &exynos5_clkset_sclk_hdmi
,
261 .reg_src
= { .reg
= EXYNOS5_CLKSRC_DISP1_0
, .shift
= 20, .size
= 1 },
264 static struct clksrc_clk
*exynos5_sclk_tv
[] = {
265 &exynos5_clk_sclk_pixel
,
266 &exynos5_clk_sclk_hdmi
,
269 static struct clk
*exynos5_clk_src_mpll_user_list
[] = {
271 [1] = &exynos5_clk_mout_mpll
.clk
,
274 static struct clksrc_sources exynos5_clk_src_mpll_user
= {
275 .sources
= exynos5_clk_src_mpll_user_list
,
276 .nr_sources
= ARRAY_SIZE(exynos5_clk_src_mpll_user_list
),
279 static struct clksrc_clk exynos5_clk_mout_mpll_user
= {
281 .name
= "mout_mpll_user",
283 .sources
= &exynos5_clk_src_mpll_user
,
284 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP2
, .shift
= 20, .size
= 1 },
287 static struct clk
*exynos5_clkset_mout_cpu_list
[] = {
288 [0] = &exynos5_clk_mout_apll
.clk
,
289 [1] = &exynos5_clk_mout_mpll
.clk
,
292 static struct clksrc_sources exynos5_clkset_mout_cpu
= {
293 .sources
= exynos5_clkset_mout_cpu_list
,
294 .nr_sources
= ARRAY_SIZE(exynos5_clkset_mout_cpu_list
),
297 static struct clksrc_clk exynos5_clk_mout_cpu
= {
301 .sources
= &exynos5_clkset_mout_cpu
,
302 .reg_src
= { .reg
= EXYNOS5_CLKSRC_CPU
, .shift
= 16, .size
= 1 },
305 static struct clksrc_clk exynos5_clk_dout_armclk
= {
307 .name
= "dout_armclk",
308 .parent
= &exynos5_clk_mout_cpu
.clk
,
310 .reg_div
= { .reg
= EXYNOS5_CLKDIV_CPU0
, .shift
= 0, .size
= 3 },
313 static struct clksrc_clk exynos5_clk_dout_arm2clk
= {
315 .name
= "dout_arm2clk",
316 .parent
= &exynos5_clk_dout_armclk
.clk
,
318 .reg_div
= { .reg
= EXYNOS5_CLKDIV_CPU0
, .shift
= 28, .size
= 3 },
321 static struct clk exynos5_clk_armclk
= {
323 .parent
= &exynos5_clk_dout_arm2clk
.clk
,
326 /* Core list of CMU_CDREX side */
328 static struct clk
*exynos5_clkset_cdrex_list
[] = {
329 [0] = &exynos5_clk_mout_mpll
.clk
,
330 [1] = &exynos5_clk_mout_bpll
.clk
,
333 static struct clksrc_sources exynos5_clkset_cdrex
= {
334 .sources
= exynos5_clkset_cdrex_list
,
335 .nr_sources
= ARRAY_SIZE(exynos5_clkset_cdrex_list
),
338 static struct clksrc_clk exynos5_clk_cdrex
= {
342 .sources
= &exynos5_clkset_cdrex
,
343 .reg_src
= { .reg
= EXYNOS5_CLKSRC_CDREX
, .shift
= 4, .size
= 1 },
344 .reg_div
= { .reg
= EXYNOS5_CLKDIV_CDREX
, .shift
= 16, .size
= 3 },
347 static struct clksrc_clk exynos5_clk_aclk_acp
= {
350 .parent
= &exynos5_clk_mout_mpll
.clk
,
352 .reg_div
= { .reg
= EXYNOS5_CLKDIV_ACP
, .shift
= 0, .size
= 3 },
355 static struct clksrc_clk exynos5_clk_pclk_acp
= {
358 .parent
= &exynos5_clk_aclk_acp
.clk
,
360 .reg_div
= { .reg
= EXYNOS5_CLKDIV_ACP
, .shift
= 4, .size
= 3 },
363 /* Core list of CMU_TOP side */
365 struct clk
*exynos5_clkset_aclk_top_list
[] = {
366 [0] = &exynos5_clk_mout_mpll_user
.clk
,
367 [1] = &exynos5_clk_mout_bpll_user
.clk
,
370 struct clksrc_sources exynos5_clkset_aclk
= {
371 .sources
= exynos5_clkset_aclk_top_list
,
372 .nr_sources
= ARRAY_SIZE(exynos5_clkset_aclk_top_list
),
375 static struct clksrc_clk exynos5_clk_aclk_400
= {
379 .sources
= &exynos5_clkset_aclk
,
380 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP0
, .shift
= 20, .size
= 1 },
381 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP0
, .shift
= 24, .size
= 3 },
384 struct clk
*exynos5_clkset_aclk_333_166_list
[] = {
385 [0] = &exynos5_clk_mout_cpll
.clk
,
386 [1] = &exynos5_clk_mout_mpll_user
.clk
,
389 struct clksrc_sources exynos5_clkset_aclk_333_166
= {
390 .sources
= exynos5_clkset_aclk_333_166_list
,
391 .nr_sources
= ARRAY_SIZE(exynos5_clkset_aclk_333_166_list
),
394 static struct clksrc_clk exynos5_clk_aclk_333
= {
398 .sources
= &exynos5_clkset_aclk_333_166
,
399 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP0
, .shift
= 16, .size
= 1 },
400 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP0
, .shift
= 20, .size
= 3 },
403 static struct clksrc_clk exynos5_clk_aclk_166
= {
407 .sources
= &exynos5_clkset_aclk_333_166
,
408 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP0
, .shift
= 8, .size
= 1 },
409 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP0
, .shift
= 8, .size
= 3 },
412 static struct clksrc_clk exynos5_clk_aclk_266
= {
415 .parent
= &exynos5_clk_mout_mpll_user
.clk
,
417 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP0
, .shift
= 16, .size
= 3 },
420 static struct clksrc_clk exynos5_clk_aclk_200
= {
424 .sources
= &exynos5_clkset_aclk
,
425 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP0
, .shift
= 12, .size
= 1 },
426 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP0
, .shift
= 12, .size
= 3 },
429 static struct clksrc_clk exynos5_clk_aclk_66_pre
= {
431 .name
= "aclk_66_pre",
432 .parent
= &exynos5_clk_mout_mpll_user
.clk
,
434 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP1
, .shift
= 24, .size
= 3 },
437 static struct clksrc_clk exynos5_clk_aclk_66
= {
440 .parent
= &exynos5_clk_aclk_66_pre
.clk
,
442 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP0
, .shift
= 0, .size
= 3 },
445 static struct clk exynos5_init_clocks_off
[] = {
448 .parent
= &exynos5_clk_aclk_66
.clk
,
449 .enable
= exynos5_clk_ip_peric_ctrl
,
450 .ctrlbit
= (1 << 24),
453 .parent
= &exynos5_clk_aclk_66
.clk
,
454 .enable
= exynos5_clk_ip_peris_ctrl
,
455 .ctrlbit
= (1 << 20),
458 .devname
= "s3c-sdhci.0",
459 .parent
= &exynos5_clk_aclk_200
.clk
,
460 .enable
= exynos5_clk_ip_fsys_ctrl
,
461 .ctrlbit
= (1 << 12),
464 .devname
= "s3c-sdhci.1",
465 .parent
= &exynos5_clk_aclk_200
.clk
,
466 .enable
= exynos5_clk_ip_fsys_ctrl
,
467 .ctrlbit
= (1 << 13),
470 .devname
= "s3c-sdhci.2",
471 .parent
= &exynos5_clk_aclk_200
.clk
,
472 .enable
= exynos5_clk_ip_fsys_ctrl
,
473 .ctrlbit
= (1 << 14),
476 .devname
= "s3c-sdhci.3",
477 .parent
= &exynos5_clk_aclk_200
.clk
,
478 .enable
= exynos5_clk_ip_fsys_ctrl
,
479 .ctrlbit
= (1 << 15),
482 .parent
= &exynos5_clk_aclk_200
.clk
,
483 .enable
= exynos5_clk_ip_fsys_ctrl
,
484 .ctrlbit
= (1 << 16),
488 .enable
= exynos5_clk_ip_fsys_ctrl
,
492 .enable
= exynos5_clk_ip_fsys_ctrl
,
493 .ctrlbit
= (1 << 24),
495 .name
= "sata_phy_i2c",
496 .enable
= exynos5_clk_ip_fsys_ctrl
,
497 .ctrlbit
= (1 << 25),
500 .devname
= "s5p-mfc",
501 .enable
= exynos5_clk_ip_mfc_ctrl
,
505 .devname
= "exynos4-hdmi",
506 .enable
= exynos5_clk_ip_disp1_ctrl
,
510 .devname
= "s5p-mixer",
511 .enable
= exynos5_clk_ip_disp1_ctrl
,
515 .enable
= exynos5_clk_ip_gen_ctrl
,
519 .enable
= exynos5_clk_ip_disp1_ctrl
,
523 .devname
= "samsung-i2s.1",
524 .enable
= exynos5_clk_ip_peric_ctrl
,
525 .ctrlbit
= (1 << 20),
528 .devname
= "samsung-i2s.2",
529 .enable
= exynos5_clk_ip_peric_ctrl
,
530 .ctrlbit
= (1 << 21),
533 .devname
= "samsung-pcm.1",
534 .enable
= exynos5_clk_ip_peric_ctrl
,
535 .ctrlbit
= (1 << 22),
538 .devname
= "samsung-pcm.2",
539 .enable
= exynos5_clk_ip_peric_ctrl
,
540 .ctrlbit
= (1 << 23),
543 .devname
= "samsung-spdif",
544 .enable
= exynos5_clk_ip_peric_ctrl
,
545 .ctrlbit
= (1 << 26),
548 .devname
= "samsung-ac97",
549 .enable
= exynos5_clk_ip_peric_ctrl
,
550 .ctrlbit
= (1 << 27),
553 .enable
= exynos5_clk_ip_fsys_ctrl
,
554 .ctrlbit
= (1 << 18),
557 .enable
= exynos5_clk_ip_fsys_ctrl
,
561 .enable
= exynos5_clk_ip_gps_ctrl
,
562 .ctrlbit
= ((1 << 3) | (1 << 2) | (1 << 0)),
565 .enable
= exynos5_clk_ip_fsys_ctrl
,
566 .ctrlbit
= (1 << 22),
569 .enable
= exynos5_clk_ip_fsys_ctrl
,
570 .ctrlbit
= ((1 << 30) | (1 << 26) | (1 << 23)),
573 .enable
= exynos5_clk_ip_core_ctrl
,
574 .ctrlbit
= ((1 << 21) | (1 << 3)),
577 .enable
= exynos5_clk_ip_fsys_ctrl
,
581 .devname
= "s3c2440-i2c.0",
582 .parent
= &exynos5_clk_aclk_66
.clk
,
583 .enable
= exynos5_clk_ip_peric_ctrl
,
587 .devname
= "s3c2440-i2c.1",
588 .parent
= &exynos5_clk_aclk_66
.clk
,
589 .enable
= exynos5_clk_ip_peric_ctrl
,
593 .devname
= "s3c2440-i2c.2",
594 .parent
= &exynos5_clk_aclk_66
.clk
,
595 .enable
= exynos5_clk_ip_peric_ctrl
,
599 .devname
= "s3c2440-i2c.3",
600 .parent
= &exynos5_clk_aclk_66
.clk
,
601 .enable
= exynos5_clk_ip_peric_ctrl
,
605 .devname
= "s3c2440-i2c.4",
606 .parent
= &exynos5_clk_aclk_66
.clk
,
607 .enable
= exynos5_clk_ip_peric_ctrl
,
608 .ctrlbit
= (1 << 10),
611 .devname
= "s3c2440-i2c.5",
612 .parent
= &exynos5_clk_aclk_66
.clk
,
613 .enable
= exynos5_clk_ip_peric_ctrl
,
614 .ctrlbit
= (1 << 11),
617 .devname
= "s3c2440-i2c.6",
618 .parent
= &exynos5_clk_aclk_66
.clk
,
619 .enable
= exynos5_clk_ip_peric_ctrl
,
620 .ctrlbit
= (1 << 12),
623 .devname
= "s3c2440-i2c.7",
624 .parent
= &exynos5_clk_aclk_66
.clk
,
625 .enable
= exynos5_clk_ip_peric_ctrl
,
626 .ctrlbit
= (1 << 13),
629 .devname
= "s3c2440-hdmiphy-i2c",
630 .parent
= &exynos5_clk_aclk_66
.clk
,
631 .enable
= exynos5_clk_ip_peric_ctrl
,
632 .ctrlbit
= (1 << 14),
636 static struct clk exynos5_init_clocks_on
[] = {
639 .devname
= "s5pv210-uart.0",
640 .enable
= exynos5_clk_ip_peric_ctrl
,
644 .devname
= "s5pv210-uart.1",
645 .enable
= exynos5_clk_ip_peric_ctrl
,
649 .devname
= "s5pv210-uart.2",
650 .enable
= exynos5_clk_ip_peric_ctrl
,
654 .devname
= "s5pv210-uart.3",
655 .enable
= exynos5_clk_ip_peric_ctrl
,
659 .devname
= "s5pv210-uart.4",
660 .enable
= exynos5_clk_ip_peric_ctrl
,
664 .devname
= "s5pv210-uart.5",
665 .enable
= exynos5_clk_ip_peric_ctrl
,
670 static struct clk exynos5_clk_pdma0
= {
672 .devname
= "dma-pl330.0",
673 .enable
= exynos5_clk_ip_fsys_ctrl
,
677 static struct clk exynos5_clk_pdma1
= {
679 .devname
= "dma-pl330.1",
680 .enable
= exynos5_clk_ip_fsys_ctrl
,
684 static struct clk exynos5_clk_mdma1
= {
686 .devname
= "dma-pl330.2",
687 .enable
= exynos5_clk_ip_gen_ctrl
,
691 struct clk
*exynos5_clkset_group_list
[] = {
692 [0] = &clk_ext_xtal_mux
,
694 [2] = &exynos5_clk_sclk_hdmi24m
,
695 [3] = &exynos5_clk_sclk_dptxphy
,
696 [4] = &exynos5_clk_sclk_usbphy
,
697 [5] = &exynos5_clk_sclk_hdmiphy
,
698 [6] = &exynos5_clk_mout_mpll_user
.clk
,
699 [7] = &exynos5_clk_mout_epll
.clk
,
700 [8] = &exynos5_clk_sclk_vpll
.clk
,
701 [9] = &exynos5_clk_mout_cpll
.clk
,
704 struct clksrc_sources exynos5_clkset_group
= {
705 .sources
= exynos5_clkset_group_list
,
706 .nr_sources
= ARRAY_SIZE(exynos5_clkset_group_list
),
709 /* Possible clock sources for aclk_266_gscl_sub Mux */
710 static struct clk
*clk_src_gscl_266_list
[] = {
711 [0] = &clk_ext_xtal_mux
,
712 [1] = &exynos5_clk_aclk_266
.clk
,
715 static struct clksrc_sources clk_src_gscl_266
= {
716 .sources
= clk_src_gscl_266_list
,
717 .nr_sources
= ARRAY_SIZE(clk_src_gscl_266_list
),
720 static struct clksrc_clk exynos5_clk_dout_mmc0
= {
724 .sources
= &exynos5_clkset_group
,
725 .reg_src
= { .reg
= EXYNOS5_CLKSRC_FSYS
, .shift
= 0, .size
= 4 },
726 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS1
, .shift
= 0, .size
= 4 },
729 static struct clksrc_clk exynos5_clk_dout_mmc1
= {
733 .sources
= &exynos5_clkset_group
,
734 .reg_src
= { .reg
= EXYNOS5_CLKSRC_FSYS
, .shift
= 4, .size
= 4 },
735 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS1
, .shift
= 16, .size
= 4 },
738 static struct clksrc_clk exynos5_clk_dout_mmc2
= {
742 .sources
= &exynos5_clkset_group
,
743 .reg_src
= { .reg
= EXYNOS5_CLKSRC_FSYS
, .shift
= 8, .size
= 4 },
744 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS2
, .shift
= 0, .size
= 4 },
747 static struct clksrc_clk exynos5_clk_dout_mmc3
= {
751 .sources
= &exynos5_clkset_group
,
752 .reg_src
= { .reg
= EXYNOS5_CLKSRC_FSYS
, .shift
= 12, .size
= 4 },
753 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS2
, .shift
= 16, .size
= 4 },
756 static struct clksrc_clk exynos5_clk_dout_mmc4
= {
760 .sources
= &exynos5_clkset_group
,
761 .reg_src
= { .reg
= EXYNOS5_CLKSRC_FSYS
, .shift
= 16, .size
= 4 },
762 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS3
, .shift
= 0, .size
= 4 },
765 static struct clksrc_clk exynos5_clk_sclk_uart0
= {
768 .devname
= "exynos4210-uart.0",
769 .enable
= exynos5_clksrc_mask_peric0_ctrl
,
772 .sources
= &exynos5_clkset_group
,
773 .reg_src
= { .reg
= EXYNOS5_CLKSRC_PERIC0
, .shift
= 0, .size
= 4 },
774 .reg_div
= { .reg
= EXYNOS5_CLKDIV_PERIC0
, .shift
= 0, .size
= 4 },
777 static struct clksrc_clk exynos5_clk_sclk_uart1
= {
780 .devname
= "exynos4210-uart.1",
781 .enable
= exynos5_clksrc_mask_peric0_ctrl
,
784 .sources
= &exynos5_clkset_group
,
785 .reg_src
= { .reg
= EXYNOS5_CLKSRC_PERIC0
, .shift
= 4, .size
= 4 },
786 .reg_div
= { .reg
= EXYNOS5_CLKDIV_PERIC0
, .shift
= 4, .size
= 4 },
789 static struct clksrc_clk exynos5_clk_sclk_uart2
= {
792 .devname
= "exynos4210-uart.2",
793 .enable
= exynos5_clksrc_mask_peric0_ctrl
,
796 .sources
= &exynos5_clkset_group
,
797 .reg_src
= { .reg
= EXYNOS5_CLKSRC_PERIC0
, .shift
= 8, .size
= 4 },
798 .reg_div
= { .reg
= EXYNOS5_CLKDIV_PERIC0
, .shift
= 8, .size
= 4 },
801 static struct clksrc_clk exynos5_clk_sclk_uart3
= {
804 .devname
= "exynos4210-uart.3",
805 .enable
= exynos5_clksrc_mask_peric0_ctrl
,
806 .ctrlbit
= (1 << 12),
808 .sources
= &exynos5_clkset_group
,
809 .reg_src
= { .reg
= EXYNOS5_CLKSRC_PERIC0
, .shift
= 12, .size
= 4 },
810 .reg_div
= { .reg
= EXYNOS5_CLKDIV_PERIC0
, .shift
= 12, .size
= 4 },
813 static struct clksrc_clk exynos5_clk_sclk_mmc0
= {
816 .devname
= "s3c-sdhci.0",
817 .parent
= &exynos5_clk_dout_mmc0
.clk
,
818 .enable
= exynos5_clksrc_mask_fsys_ctrl
,
821 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS1
, .shift
= 8, .size
= 8 },
824 static struct clksrc_clk exynos5_clk_sclk_mmc1
= {
827 .devname
= "s3c-sdhci.1",
828 .parent
= &exynos5_clk_dout_mmc1
.clk
,
829 .enable
= exynos5_clksrc_mask_fsys_ctrl
,
832 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS1
, .shift
= 24, .size
= 8 },
835 static struct clksrc_clk exynos5_clk_sclk_mmc2
= {
838 .devname
= "s3c-sdhci.2",
839 .parent
= &exynos5_clk_dout_mmc2
.clk
,
840 .enable
= exynos5_clksrc_mask_fsys_ctrl
,
843 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS2
, .shift
= 8, .size
= 8 },
846 static struct clksrc_clk exynos5_clk_sclk_mmc3
= {
849 .devname
= "s3c-sdhci.3",
850 .parent
= &exynos5_clk_dout_mmc3
.clk
,
851 .enable
= exynos5_clksrc_mask_fsys_ctrl
,
852 .ctrlbit
= (1 << 12),
854 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS2
, .shift
= 24, .size
= 8 },
857 static struct clksrc_clk exynos5_clksrcs
[] = {
860 .name
= "sclk_dwmci",
861 .parent
= &exynos5_clk_dout_mmc4
.clk
,
862 .enable
= exynos5_clksrc_mask_fsys_ctrl
,
863 .ctrlbit
= (1 << 16),
865 .reg_div
= { .reg
= EXYNOS5_CLKDIV_FSYS3
, .shift
= 8, .size
= 8 },
869 .devname
= "s3cfb.1",
870 .enable
= exynos5_clksrc_mask_disp1_0_ctrl
,
873 .sources
= &exynos5_clkset_group
,
874 .reg_src
= { .reg
= EXYNOS5_CLKSRC_DISP1_0
, .shift
= 0, .size
= 4 },
875 .reg_div
= { .reg
= EXYNOS5_CLKDIV_DISP1_0
, .shift
= 0, .size
= 4 },
878 .name
= "aclk_266_gscl",
880 .sources
= &clk_src_gscl_266
,
881 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP3
, .shift
= 8, .size
= 1 },
885 .devname
= "mali-t604.0",
886 .enable
= exynos5_clk_block_ctrl
,
889 .sources
= &exynos5_clkset_aclk
,
890 .reg_src
= { .reg
= EXYNOS5_CLKSRC_TOP0
, .shift
= 20, .size
= 1 },
891 .reg_div
= { .reg
= EXYNOS5_CLKDIV_TOP0
, .shift
= 24, .size
= 3 },
894 .name
= "sclk_gscl_wrap",
895 .devname
= "s5p-mipi-csis.0",
896 .enable
= exynos5_clksrc_mask_gscl_ctrl
,
897 .ctrlbit
= (1 << 24),
899 .sources
= &exynos5_clkset_group
,
900 .reg_src
= { .reg
= EXYNOS5_CLKSRC_GSCL
, .shift
= 24, .size
= 4 },
901 .reg_div
= { .reg
= EXYNOS5_CLKDIV_GSCL
, .shift
= 24, .size
= 4 },
904 .name
= "sclk_gscl_wrap",
905 .devname
= "s5p-mipi-csis.1",
906 .enable
= exynos5_clksrc_mask_gscl_ctrl
,
907 .ctrlbit
= (1 << 28),
909 .sources
= &exynos5_clkset_group
,
910 .reg_src
= { .reg
= EXYNOS5_CLKSRC_GSCL
, .shift
= 28, .size
= 4 },
911 .reg_div
= { .reg
= EXYNOS5_CLKDIV_GSCL
, .shift
= 28, .size
= 4 },
915 .enable
= exynos5_clksrc_mask_gscl_ctrl
,
916 .ctrlbit
= (1 << 16),
918 .sources
= &exynos5_clkset_group
,
919 .reg_src
= { .reg
= EXYNOS5_CLKSRC_GSCL
, .shift
= 16, .size
= 4 },
920 .reg_div
= { .reg
= EXYNOS5_CLKDIV_GSCL
, .shift
= 16, .size
= 4 },
924 .enable
= exynos5_clksrc_mask_gscl_ctrl
,
925 .ctrlbit
= (1 << 20),
927 .sources
= &exynos5_clkset_group
,
928 .reg_src
= { .reg
= EXYNOS5_CLKSRC_GSCL
, .shift
= 20, .size
= 4 },
929 .reg_div
= { .reg
= EXYNOS5_CLKDIV_GSCL
, .shift
= 20, .size
= 4 },
933 .parent
= &exynos5_clk_mout_cpll
.clk
,
935 .reg_div
= { .reg
= EXYNOS5_CLKDIV_GEN
, .shift
= 4, .size
= 3 },
939 /* Clock initialization code */
940 static struct clksrc_clk
*exynos5_sysclks
[] = {
941 &exynos5_clk_mout_apll
,
942 &exynos5_clk_sclk_apll
,
943 &exynos5_clk_mout_bpll
,
944 &exynos5_clk_mout_bpll_user
,
945 &exynos5_clk_mout_cpll
,
946 &exynos5_clk_mout_epll
,
947 &exynos5_clk_mout_mpll
,
948 &exynos5_clk_mout_mpll_user
,
949 &exynos5_clk_vpllsrc
,
950 &exynos5_clk_sclk_vpll
,
951 &exynos5_clk_mout_cpu
,
952 &exynos5_clk_dout_armclk
,
953 &exynos5_clk_dout_arm2clk
,
955 &exynos5_clk_aclk_400
,
956 &exynos5_clk_aclk_333
,
957 &exynos5_clk_aclk_266
,
958 &exynos5_clk_aclk_200
,
959 &exynos5_clk_aclk_166
,
960 &exynos5_clk_aclk_66_pre
,
961 &exynos5_clk_aclk_66
,
962 &exynos5_clk_dout_mmc0
,
963 &exynos5_clk_dout_mmc1
,
964 &exynos5_clk_dout_mmc2
,
965 &exynos5_clk_dout_mmc3
,
966 &exynos5_clk_dout_mmc4
,
967 &exynos5_clk_aclk_acp
,
968 &exynos5_clk_pclk_acp
,
971 static struct clk
*exynos5_clk_cdev
[] = {
977 static struct clksrc_clk
*exynos5_clksrc_cdev
[] = {
978 &exynos5_clk_sclk_uart0
,
979 &exynos5_clk_sclk_uart1
,
980 &exynos5_clk_sclk_uart2
,
981 &exynos5_clk_sclk_uart3
,
982 &exynos5_clk_sclk_mmc0
,
983 &exynos5_clk_sclk_mmc1
,
984 &exynos5_clk_sclk_mmc2
,
985 &exynos5_clk_sclk_mmc3
,
988 static struct clk_lookup exynos5_clk_lookup
[] = {
989 CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0
.clk
),
990 CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1
.clk
),
991 CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2
.clk
),
992 CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3
.clk
),
993 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0
.clk
),
994 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1
.clk
),
995 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2
.clk
),
996 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3
.clk
),
997 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0
),
998 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1
),
999 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1
),
1002 static unsigned long exynos5_epll_get_rate(struct clk
*clk
)
1007 static struct clk
*exynos5_clks
[] __initdata
= {
1008 &exynos5_clk_sclk_hdmi27m
,
1009 &exynos5_clk_sclk_hdmiphy
,
1012 &exynos5_clk_armclk
,
1015 static u32 epll_div
[][6] = {
1016 { 192000000, 0, 48, 3, 1, 0 },
1017 { 180000000, 0, 45, 3, 1, 0 },
1018 { 73728000, 1, 73, 3, 3, 47710 },
1019 { 67737600, 1, 90, 4, 3, 20762 },
1020 { 49152000, 0, 49, 3, 3, 9961 },
1021 { 45158400, 0, 45, 3, 3, 10381 },
1022 { 180633600, 0, 45, 3, 1, 10381 },
1025 static int exynos5_epll_set_rate(struct clk
*clk
, unsigned long rate
)
1027 unsigned int epll_con
, epll_con_k
;
1030 unsigned int epll_rate
;
1031 unsigned int locktime
;
1032 unsigned int lockcnt
;
1034 /* Return if nothing changed */
1035 if (clk
->rate
== rate
)
1039 epll_rate
= clk_get_rate(clk
->parent
);
1041 epll_rate
= clk_ext_xtal_mux
.rate
;
1043 if (epll_rate
!= 24000000) {
1044 pr_err("Invalid Clock : recommended clock is 24MHz.\n");
1048 epll_con
= __raw_readl(EXYNOS5_EPLL_CON0
);
1049 epll_con
&= ~(0x1 << 27 | \
1050 PLL46XX_MDIV_MASK
<< PLL46XX_MDIV_SHIFT
| \
1051 PLL46XX_PDIV_MASK
<< PLL46XX_PDIV_SHIFT
| \
1052 PLL46XX_SDIV_MASK
<< PLL46XX_SDIV_SHIFT
);
1054 for (i
= 0; i
< ARRAY_SIZE(epll_div
); i
++) {
1055 if (epll_div
[i
][0] == rate
) {
1056 epll_con_k
= epll_div
[i
][5] << 0;
1057 epll_con
|= epll_div
[i
][1] << 27;
1058 epll_con
|= epll_div
[i
][2] << PLL46XX_MDIV_SHIFT
;
1059 epll_con
|= epll_div
[i
][3] << PLL46XX_PDIV_SHIFT
;
1060 epll_con
|= epll_div
[i
][4] << PLL46XX_SDIV_SHIFT
;
1065 if (i
== ARRAY_SIZE(epll_div
)) {
1066 printk(KERN_ERR
"%s: Invalid Clock EPLL Frequency\n",
1071 epll_rate
/= 1000000;
1073 /* 3000 max_cycls : specification data */
1074 locktime
= 3000 / epll_rate
* epll_div
[i
][3];
1075 lockcnt
= locktime
* 10000 / (10000 / epll_rate
);
1077 __raw_writel(lockcnt
, EXYNOS5_EPLL_LOCK
);
1079 __raw_writel(epll_con
, EXYNOS5_EPLL_CON0
);
1080 __raw_writel(epll_con_k
, EXYNOS5_EPLL_CON1
);
1083 tmp
= __raw_readl(EXYNOS5_EPLL_CON0
);
1084 } while (!(tmp
& 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT
));
1091 static struct clk_ops exynos5_epll_ops
= {
1092 .get_rate
= exynos5_epll_get_rate
,
1093 .set_rate
= exynos5_epll_set_rate
,
1096 static int xtal_rate
;
1098 static unsigned long exynos5_fout_apll_get_rate(struct clk
*clk
)
1100 return s5p_get_pll35xx(xtal_rate
, __raw_readl(EXYNOS5_APLL_CON0
));
1103 static struct clk_ops exynos5_fout_apll_ops
= {
1104 .get_rate
= exynos5_fout_apll_get_rate
,
1108 static int exynos5_clock_suspend(void)
1110 s3c_pm_do_save(exynos5_clock_save
, ARRAY_SIZE(exynos5_clock_save
));
1115 static void exynos5_clock_resume(void)
1117 s3c_pm_do_restore_core(exynos5_clock_save
, ARRAY_SIZE(exynos5_clock_save
));
1120 #define exynos5_clock_suspend NULL
1121 #define exynos5_clock_resume NULL
1124 struct syscore_ops exynos5_clock_syscore_ops
= {
1125 .suspend
= exynos5_clock_suspend
,
1126 .resume
= exynos5_clock_resume
,
1129 void __init_or_cpufreq
exynos5_setup_clocks(void)
1131 struct clk
*xtal_clk
;
1138 unsigned long vpllsrc
;
1140 unsigned long armclk
;
1141 unsigned long mout_cdrex
;
1142 unsigned long aclk_400
;
1143 unsigned long aclk_333
;
1144 unsigned long aclk_266
;
1145 unsigned long aclk_200
;
1146 unsigned long aclk_166
;
1147 unsigned long aclk_66
;
1150 printk(KERN_DEBUG
"%s: registering clocks\n", __func__
);
1152 xtal_clk
= clk_get(NULL
, "xtal");
1153 BUG_ON(IS_ERR(xtal_clk
));
1155 xtal
= clk_get_rate(xtal_clk
);
1161 printk(KERN_DEBUG
"%s: xtal is %ld\n", __func__
, xtal
);
1163 apll
= s5p_get_pll35xx(xtal
, __raw_readl(EXYNOS5_APLL_CON0
));
1164 bpll
= s5p_get_pll35xx(xtal
, __raw_readl(EXYNOS5_BPLL_CON0
));
1165 cpll
= s5p_get_pll35xx(xtal
, __raw_readl(EXYNOS5_CPLL_CON0
));
1166 mpll
= s5p_get_pll35xx(xtal
, __raw_readl(EXYNOS5_MPLL_CON0
));
1167 epll
= s5p_get_pll36xx(xtal
, __raw_readl(EXYNOS5_EPLL_CON0
),
1168 __raw_readl(EXYNOS5_EPLL_CON1
));
1170 vpllsrc
= clk_get_rate(&exynos5_clk_vpllsrc
.clk
);
1171 vpll
= s5p_get_pll36xx(vpllsrc
, __raw_readl(EXYNOS5_VPLL_CON0
),
1172 __raw_readl(EXYNOS5_VPLL_CON1
));
1174 clk_fout_apll
.ops
= &exynos5_fout_apll_ops
;
1175 clk_fout_bpll
.rate
= bpll
;
1176 clk_fout_cpll
.rate
= cpll
;
1177 clk_fout_mpll
.rate
= mpll
;
1178 clk_fout_epll
.rate
= epll
;
1179 clk_fout_vpll
.rate
= vpll
;
1181 printk(KERN_INFO
"EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
1182 "M=%ld, E=%ld V=%ld",
1183 apll
, bpll
, cpll
, mpll
, epll
, vpll
);
1185 armclk
= clk_get_rate(&exynos5_clk_armclk
);
1186 mout_cdrex
= clk_get_rate(&exynos5_clk_cdrex
.clk
);
1188 aclk_400
= clk_get_rate(&exynos5_clk_aclk_400
.clk
);
1189 aclk_333
= clk_get_rate(&exynos5_clk_aclk_333
.clk
);
1190 aclk_266
= clk_get_rate(&exynos5_clk_aclk_266
.clk
);
1191 aclk_200
= clk_get_rate(&exynos5_clk_aclk_200
.clk
);
1192 aclk_166
= clk_get_rate(&exynos5_clk_aclk_166
.clk
);
1193 aclk_66
= clk_get_rate(&exynos5_clk_aclk_66
.clk
);
1195 printk(KERN_INFO
"EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
1196 "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
1197 "ACLK166=%ld, ACLK66=%ld\n",
1198 armclk
, mout_cdrex
, aclk_400
,
1199 aclk_333
, aclk_266
, aclk_200
,
1203 clk_fout_epll
.ops
= &exynos5_epll_ops
;
1205 if (clk_set_parent(&exynos5_clk_mout_epll
.clk
, &clk_fout_epll
))
1206 printk(KERN_ERR
"Unable to set parent %s of clock %s.\n",
1207 clk_fout_epll
.name
, exynos5_clk_mout_epll
.clk
.name
);
1209 clk_set_rate(&exynos5_clk_sclk_apll
.clk
, 100000000);
1210 clk_set_rate(&exynos5_clk_aclk_266
.clk
, 300000000);
1212 clk_set_rate(&exynos5_clk_aclk_acp
.clk
, 267000000);
1213 clk_set_rate(&exynos5_clk_pclk_acp
.clk
, 134000000);
1215 for (ptr
= 0; ptr
< ARRAY_SIZE(exynos5_clksrcs
); ptr
++)
1216 s3c_set_clksrc(&exynos5_clksrcs
[ptr
], true);
1219 void __init
exynos5_register_clocks(void)
1223 s3c24xx_register_clocks(exynos5_clks
, ARRAY_SIZE(exynos5_clks
));
1225 for (ptr
= 0; ptr
< ARRAY_SIZE(exynos5_sysclks
); ptr
++)
1226 s3c_register_clksrc(exynos5_sysclks
[ptr
], 1);
1228 for (ptr
= 0; ptr
< ARRAY_SIZE(exynos5_sclk_tv
); ptr
++)
1229 s3c_register_clksrc(exynos5_sclk_tv
[ptr
], 1);
1231 for (ptr
= 0; ptr
< ARRAY_SIZE(exynos5_clksrc_cdev
); ptr
++)
1232 s3c_register_clksrc(exynos5_clksrc_cdev
[ptr
], 1);
1234 s3c_register_clksrc(exynos5_clksrcs
, ARRAY_SIZE(exynos5_clksrcs
));
1235 s3c_register_clocks(exynos5_init_clocks_on
, ARRAY_SIZE(exynos5_init_clocks_on
));
1237 s3c24xx_register_clocks(exynos5_clk_cdev
, ARRAY_SIZE(exynos5_clk_cdev
));
1238 for (ptr
= 0; ptr
< ARRAY_SIZE(exynos5_clk_cdev
); ptr
++)
1239 s3c_disable_clocks(exynos5_clk_cdev
[ptr
], 1);
1241 s3c_register_clocks(exynos5_init_clocks_off
, ARRAY_SIZE(exynos5_init_clocks_off
));
1242 s3c_disable_clocks(exynos5_init_clocks_off
, ARRAY_SIZE(exynos5_init_clocks_off
));
1243 clkdev_add_table(exynos5_clk_lookup
, ARRAY_SIZE(exynos5_clk_lookup
));
1245 register_syscore_ops(&exynos5_clock_syscore_ops
);