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_acp_ctrl(struct clk *clk, int enable)
87 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable);
90 static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
92 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable);
95 static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable)
97 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable);
100 static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable)
102 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable);
105 static int exynos5_clk_block_ctrl(struct clk *clk, int enable)
107 return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable);
110 static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable)
112 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable);
115 static int exynos5_clk_ip_gps_ctrl(struct clk *clk, int enable)
117 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GPS, clk, enable);
120 static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable)
122 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable);
125 static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable)
127 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable);
130 static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable)
132 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
135 static int exynos5_clk_ip_gscl_ctrl(struct clk *clk, int enable)
137 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GSCL, clk, enable);
140 static int exynos5_clk_ip_isp0_ctrl(struct clk *clk, int enable)
142 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP0, clk, enable);
145 static int exynos5_clk_ip_isp1_ctrl(struct clk *clk, int enable)
147 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP1, clk, enable);
150 /* Core list of CMU_CPU side */
152 static struct clksrc_clk exynos5_clk_mout_apll = {
156 .sources = &clk_src_apll,
157 .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 },
160 static struct clksrc_clk exynos5_clk_sclk_apll = {
163 .parent = &exynos5_clk_mout_apll.clk,
165 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
168 static struct clksrc_clk exynos5_clk_mout_bpll = {
172 .sources = &clk_src_bpll,
173 .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
176 static struct clk *exynos5_clk_src_bpll_user_list[] = {
178 [1] = &exynos5_clk_mout_bpll.clk,
181 static struct clksrc_sources exynos5_clk_src_bpll_user = {
182 .sources = exynos5_clk_src_bpll_user_list,
183 .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_user_list),
186 static struct clksrc_clk exynos5_clk_mout_bpll_user = {
188 .name = "mout_bpll_user",
190 .sources = &exynos5_clk_src_bpll_user,
191 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 },
194 static struct clksrc_clk exynos5_clk_mout_cpll = {
198 .sources = &clk_src_cpll,
199 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 },
202 static struct clksrc_clk exynos5_clk_mout_epll = {
206 .sources = &clk_src_epll,
207 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
210 struct clksrc_clk exynos5_clk_mout_mpll = {
214 .sources = &clk_src_mpll,
215 .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
218 static struct clk *exynos_clkset_vpllsrc_list[] = {
220 [1] = &exynos5_clk_sclk_hdmi27m,
223 static struct clksrc_sources exynos5_clkset_vpllsrc = {
224 .sources = exynos_clkset_vpllsrc_list,
225 .nr_sources = ARRAY_SIZE(exynos_clkset_vpllsrc_list),
228 static struct clksrc_clk exynos5_clk_vpllsrc = {
231 .enable = exynos5_clksrc_mask_top_ctrl,
234 .sources = &exynos5_clkset_vpllsrc,
235 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 },
238 static struct clk *exynos5_clkset_sclk_vpll_list[] = {
239 [0] = &exynos5_clk_vpllsrc.clk,
240 [1] = &clk_fout_vpll,
243 static struct clksrc_sources exynos5_clkset_sclk_vpll = {
244 .sources = exynos5_clkset_sclk_vpll_list,
245 .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_vpll_list),
248 static struct clksrc_clk exynos5_clk_sclk_vpll = {
252 .sources = &exynos5_clkset_sclk_vpll,
253 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 },
256 static struct clksrc_clk exynos5_clk_sclk_pixel = {
258 .name = "sclk_pixel",
259 .parent = &exynos5_clk_sclk_vpll.clk,
261 .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 },
264 static struct clk *exynos5_clkset_sclk_hdmi_list[] = {
265 [0] = &exynos5_clk_sclk_pixel.clk,
266 [1] = &exynos5_clk_sclk_hdmiphy,
269 static struct clksrc_sources exynos5_clkset_sclk_hdmi = {
270 .sources = exynos5_clkset_sclk_hdmi_list,
271 .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list),
274 static struct clksrc_clk exynos5_clk_sclk_hdmi = {
277 .enable = exynos5_clksrc_mask_disp1_0_ctrl,
278 .ctrlbit = (1 << 20),
280 .sources = &exynos5_clkset_sclk_hdmi,
281 .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 },
284 static struct clksrc_clk *exynos5_sclk_tv[] = {
285 &exynos5_clk_sclk_pixel,
286 &exynos5_clk_sclk_hdmi,
289 static struct clk *exynos5_clk_src_mpll_user_list[] = {
291 [1] = &exynos5_clk_mout_mpll.clk,
294 static struct clksrc_sources exynos5_clk_src_mpll_user = {
295 .sources = exynos5_clk_src_mpll_user_list,
296 .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_user_list),
299 static struct clksrc_clk exynos5_clk_mout_mpll_user = {
301 .name = "mout_mpll_user",
303 .sources = &exynos5_clk_src_mpll_user,
304 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 },
307 static struct clk *exynos5_clkset_mout_cpu_list[] = {
308 [0] = &exynos5_clk_mout_apll.clk,
309 [1] = &exynos5_clk_mout_mpll.clk,
312 static struct clksrc_sources exynos5_clkset_mout_cpu = {
313 .sources = exynos5_clkset_mout_cpu_list,
314 .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_cpu_list),
317 static struct clksrc_clk exynos5_clk_mout_cpu = {
321 .sources = &exynos5_clkset_mout_cpu,
322 .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 },
325 static struct clksrc_clk exynos5_clk_dout_armclk = {
327 .name = "dout_armclk",
328 .parent = &exynos5_clk_mout_cpu.clk,
330 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 },
333 static struct clksrc_clk exynos5_clk_dout_arm2clk = {
335 .name = "dout_arm2clk",
336 .parent = &exynos5_clk_dout_armclk.clk,
338 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 },
341 static struct clk exynos5_clk_armclk = {
343 .parent = &exynos5_clk_dout_arm2clk.clk,
346 /* Core list of CMU_CDREX side */
348 static struct clk *exynos5_clkset_cdrex_list[] = {
349 [0] = &exynos5_clk_mout_mpll.clk,
350 [1] = &exynos5_clk_mout_bpll.clk,
353 static struct clksrc_sources exynos5_clkset_cdrex = {
354 .sources = exynos5_clkset_cdrex_list,
355 .nr_sources = ARRAY_SIZE(exynos5_clkset_cdrex_list),
358 static struct clksrc_clk exynos5_clk_cdrex = {
362 .sources = &exynos5_clkset_cdrex,
363 .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 4, .size = 1 },
364 .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 16, .size = 3 },
367 static struct clksrc_clk exynos5_clk_aclk_acp = {
370 .parent = &exynos5_clk_mout_mpll.clk,
372 .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 },
375 static struct clksrc_clk exynos5_clk_pclk_acp = {
378 .parent = &exynos5_clk_aclk_acp.clk,
380 .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 },
383 /* Core list of CMU_TOP side */
385 struct clk *exynos5_clkset_aclk_top_list[] = {
386 [0] = &exynos5_clk_mout_mpll_user.clk,
387 [1] = &exynos5_clk_mout_bpll_user.clk,
390 struct clksrc_sources exynos5_clkset_aclk = {
391 .sources = exynos5_clkset_aclk_top_list,
392 .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_top_list),
395 static struct clksrc_clk exynos5_clk_aclk_400 = {
399 .sources = &exynos5_clkset_aclk,
400 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
401 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
404 struct clk *exynos5_clkset_aclk_333_166_list[] = {
405 [0] = &exynos5_clk_mout_cpll.clk,
406 [1] = &exynos5_clk_mout_mpll_user.clk,
409 struct clksrc_sources exynos5_clkset_aclk_333_166 = {
410 .sources = exynos5_clkset_aclk_333_166_list,
411 .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_333_166_list),
414 static struct clksrc_clk exynos5_clk_aclk_333 = {
418 .sources = &exynos5_clkset_aclk_333_166,
419 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 },
420 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 },
423 static struct clksrc_clk exynos5_clk_aclk_166 = {
427 .sources = &exynos5_clkset_aclk_333_166,
428 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 },
429 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 },
432 static struct clksrc_clk exynos5_clk_aclk_266 = {
435 .parent = &exynos5_clk_mout_mpll_user.clk,
437 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 },
440 static struct clksrc_clk exynos5_clk_aclk_200 = {
444 .sources = &exynos5_clkset_aclk,
445 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 },
446 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 },
449 static struct clksrc_clk exynos5_clk_aclk_66_pre = {
451 .name = "aclk_66_pre",
452 .parent = &exynos5_clk_mout_mpll_user.clk,
454 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 },
457 static struct clksrc_clk exynos5_clk_aclk_66 = {
460 .parent = &exynos5_clk_aclk_66_pre.clk,
462 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 },
465 static struct clk exynos5_init_clocks_off[] = {
468 .parent = &exynos5_clk_aclk_66.clk,
469 .enable = exynos5_clk_ip_peric_ctrl,
470 .ctrlbit = (1 << 24),
473 .parent = &exynos5_clk_aclk_66.clk,
474 .enable = exynos5_clk_ip_peris_ctrl,
475 .ctrlbit = (1 << 20),
478 .devname = "exynos4-sdhci.0",
479 .parent = &exynos5_clk_aclk_200.clk,
480 .enable = exynos5_clk_ip_fsys_ctrl,
481 .ctrlbit = (1 << 12),
484 .devname = "exynos4-sdhci.1",
485 .parent = &exynos5_clk_aclk_200.clk,
486 .enable = exynos5_clk_ip_fsys_ctrl,
487 .ctrlbit = (1 << 13),
490 .devname = "exynos4-sdhci.2",
491 .parent = &exynos5_clk_aclk_200.clk,
492 .enable = exynos5_clk_ip_fsys_ctrl,
493 .ctrlbit = (1 << 14),
496 .devname = "exynos4-sdhci.3",
497 .parent = &exynos5_clk_aclk_200.clk,
498 .enable = exynos5_clk_ip_fsys_ctrl,
499 .ctrlbit = (1 << 15),
502 .parent = &exynos5_clk_aclk_200.clk,
503 .enable = exynos5_clk_ip_fsys_ctrl,
504 .ctrlbit = (1 << 16),
508 .enable = exynos5_clk_ip_fsys_ctrl,
512 .enable = exynos5_clk_ip_fsys_ctrl,
513 .ctrlbit = (1 << 24),
515 .name = "sata_phy_i2c",
516 .enable = exynos5_clk_ip_fsys_ctrl,
517 .ctrlbit = (1 << 25),
520 .devname = "s5p-mfc",
521 .enable = exynos5_clk_ip_mfc_ctrl,
525 .devname = "exynos4-hdmi",
526 .enable = exynos5_clk_ip_disp1_ctrl,
530 .devname = "s5p-mixer",
531 .enable = exynos5_clk_ip_disp1_ctrl,
535 .enable = exynos5_clk_ip_gen_ctrl,
539 .enable = exynos5_clk_ip_disp1_ctrl,
543 .devname = "samsung-i2s.1",
544 .enable = exynos5_clk_ip_peric_ctrl,
545 .ctrlbit = (1 << 20),
548 .devname = "samsung-i2s.2",
549 .enable = exynos5_clk_ip_peric_ctrl,
550 .ctrlbit = (1 << 21),
553 .devname = "samsung-pcm.1",
554 .enable = exynos5_clk_ip_peric_ctrl,
555 .ctrlbit = (1 << 22),
558 .devname = "samsung-pcm.2",
559 .enable = exynos5_clk_ip_peric_ctrl,
560 .ctrlbit = (1 << 23),
563 .devname = "samsung-spdif",
564 .enable = exynos5_clk_ip_peric_ctrl,
565 .ctrlbit = (1 << 26),
568 .devname = "samsung-ac97",
569 .enable = exynos5_clk_ip_peric_ctrl,
570 .ctrlbit = (1 << 27),
573 .enable = exynos5_clk_ip_fsys_ctrl ,
574 .ctrlbit = (1 << 18),
577 .enable = exynos5_clk_ip_fsys_ctrl,
581 .enable = exynos5_clk_ip_gps_ctrl,
582 .ctrlbit = ((1 << 3) | (1 << 2) | (1 << 0)),
585 .enable = exynos5_clk_ip_fsys_ctrl,
586 .ctrlbit = (1 << 22),
589 .enable = exynos5_clk_ip_fsys_ctrl,
590 .ctrlbit = ((1 << 30) | (1 << 26) | (1 << 23)),
593 .enable = exynos5_clk_ip_core_ctrl,
594 .ctrlbit = ((1 << 21) | (1 << 3)),
597 .enable = exynos5_clk_ip_fsys_ctrl,
601 .devname = "s3c2440-i2c.0",
602 .parent = &exynos5_clk_aclk_66.clk,
603 .enable = exynos5_clk_ip_peric_ctrl,
607 .devname = "s3c2440-i2c.1",
608 .parent = &exynos5_clk_aclk_66.clk,
609 .enable = exynos5_clk_ip_peric_ctrl,
613 .devname = "s3c2440-i2c.2",
614 .parent = &exynos5_clk_aclk_66.clk,
615 .enable = exynos5_clk_ip_peric_ctrl,
619 .devname = "s3c2440-i2c.3",
620 .parent = &exynos5_clk_aclk_66.clk,
621 .enable = exynos5_clk_ip_peric_ctrl,
625 .devname = "s3c2440-i2c.4",
626 .parent = &exynos5_clk_aclk_66.clk,
627 .enable = exynos5_clk_ip_peric_ctrl,
628 .ctrlbit = (1 << 10),
631 .devname = "s3c2440-i2c.5",
632 .parent = &exynos5_clk_aclk_66.clk,
633 .enable = exynos5_clk_ip_peric_ctrl,
634 .ctrlbit = (1 << 11),
637 .devname = "s3c2440-i2c.6",
638 .parent = &exynos5_clk_aclk_66.clk,
639 .enable = exynos5_clk_ip_peric_ctrl,
640 .ctrlbit = (1 << 12),
643 .devname = "s3c2440-i2c.7",
644 .parent = &exynos5_clk_aclk_66.clk,
645 .enable = exynos5_clk_ip_peric_ctrl,
646 .ctrlbit = (1 << 13),
649 .devname = "s3c2440-hdmiphy-i2c",
650 .parent = &exynos5_clk_aclk_66.clk,
651 .enable = exynos5_clk_ip_peric_ctrl,
652 .ctrlbit = (1 << 14),
654 .name = SYSMMU_CLOCK_NAME,
655 .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
656 .enable = &exynos5_clk_ip_mfc_ctrl,
659 .name = SYSMMU_CLOCK_NAME,
660 .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
661 .enable = &exynos5_clk_ip_mfc_ctrl,
664 .name = SYSMMU_CLOCK_NAME,
665 .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
666 .enable = &exynos5_clk_ip_disp1_ctrl,
669 .name = SYSMMU_CLOCK_NAME,
670 .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
671 .enable = &exynos5_clk_ip_gen_ctrl,
674 .name = SYSMMU_CLOCK_NAME,
675 .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
676 .enable = &exynos5_clk_ip_gen_ctrl,
679 .name = SYSMMU_CLOCK_NAME,
680 .devname = SYSMMU_CLOCK_DEVNAME(gsc0, 5),
681 .enable = &exynos5_clk_ip_gscl_ctrl,
684 .name = SYSMMU_CLOCK_NAME,
685 .devname = SYSMMU_CLOCK_DEVNAME(gsc1, 6),
686 .enable = &exynos5_clk_ip_gscl_ctrl,
689 .name = SYSMMU_CLOCK_NAME,
690 .devname = SYSMMU_CLOCK_DEVNAME(gsc2, 7),
691 .enable = &exynos5_clk_ip_gscl_ctrl,
694 .name = SYSMMU_CLOCK_NAME,
695 .devname = SYSMMU_CLOCK_DEVNAME(gsc3, 8),
696 .enable = &exynos5_clk_ip_gscl_ctrl,
697 .ctrlbit = (1 << 10),
699 .name = SYSMMU_CLOCK_NAME,
700 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
701 .enable = &exynos5_clk_ip_isp0_ctrl,
702 .ctrlbit = (0x3F << 8),
704 .name = SYSMMU_CLOCK_NAME2,
705 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
706 .enable = &exynos5_clk_ip_isp1_ctrl,
707 .ctrlbit = (0xF << 4),
709 .name = SYSMMU_CLOCK_NAME,
710 .devname = SYSMMU_CLOCK_DEVNAME(camif0, 12),
711 .enable = &exynos5_clk_ip_gscl_ctrl,
712 .ctrlbit = (1 << 11),
714 .name = SYSMMU_CLOCK_NAME,
715 .devname = SYSMMU_CLOCK_DEVNAME(camif1, 13),
716 .enable = &exynos5_clk_ip_gscl_ctrl,
717 .ctrlbit = (1 << 12),
719 .name = SYSMMU_CLOCK_NAME,
720 .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
721 .enable = &exynos5_clk_ip_acp_ctrl,
726 static struct clk exynos5_init_clocks_on[] = {
729 .devname = "s5pv210-uart.0",
730 .enable = exynos5_clk_ip_peric_ctrl,
734 .devname = "s5pv210-uart.1",
735 .enable = exynos5_clk_ip_peric_ctrl,
739 .devname = "s5pv210-uart.2",
740 .enable = exynos5_clk_ip_peric_ctrl,
744 .devname = "s5pv210-uart.3",
745 .enable = exynos5_clk_ip_peric_ctrl,
749 .devname = "s5pv210-uart.4",
750 .enable = exynos5_clk_ip_peric_ctrl,
754 .devname = "s5pv210-uart.5",
755 .enable = exynos5_clk_ip_peric_ctrl,
760 static struct clk exynos5_clk_pdma0 = {
762 .devname = "dma-pl330.0",
763 .enable = exynos5_clk_ip_fsys_ctrl,
767 static struct clk exynos5_clk_pdma1 = {
769 .devname = "dma-pl330.1",
770 .enable = exynos5_clk_ip_fsys_ctrl,
774 static struct clk exynos5_clk_mdma1 = {
776 .devname = "dma-pl330.2",
777 .enable = exynos5_clk_ip_gen_ctrl,
781 struct clk *exynos5_clkset_group_list[] = {
782 [0] = &clk_ext_xtal_mux,
784 [2] = &exynos5_clk_sclk_hdmi24m,
785 [3] = &exynos5_clk_sclk_dptxphy,
786 [4] = &exynos5_clk_sclk_usbphy,
787 [5] = &exynos5_clk_sclk_hdmiphy,
788 [6] = &exynos5_clk_mout_mpll_user.clk,
789 [7] = &exynos5_clk_mout_epll.clk,
790 [8] = &exynos5_clk_sclk_vpll.clk,
791 [9] = &exynos5_clk_mout_cpll.clk,
794 struct clksrc_sources exynos5_clkset_group = {
795 .sources = exynos5_clkset_group_list,
796 .nr_sources = ARRAY_SIZE(exynos5_clkset_group_list),
799 /* Possible clock sources for aclk_266_gscl_sub Mux */
800 static struct clk *clk_src_gscl_266_list[] = {
801 [0] = &clk_ext_xtal_mux,
802 [1] = &exynos5_clk_aclk_266.clk,
805 static struct clksrc_sources clk_src_gscl_266 = {
806 .sources = clk_src_gscl_266_list,
807 .nr_sources = ARRAY_SIZE(clk_src_gscl_266_list),
810 static struct clksrc_clk exynos5_clk_dout_mmc0 = {
814 .sources = &exynos5_clkset_group,
815 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 },
816 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 },
819 static struct clksrc_clk exynos5_clk_dout_mmc1 = {
823 .sources = &exynos5_clkset_group,
824 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 },
825 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 },
828 static struct clksrc_clk exynos5_clk_dout_mmc2 = {
832 .sources = &exynos5_clkset_group,
833 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 },
834 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 },
837 static struct clksrc_clk exynos5_clk_dout_mmc3 = {
841 .sources = &exynos5_clkset_group,
842 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 },
843 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 },
846 static struct clksrc_clk exynos5_clk_dout_mmc4 = {
850 .sources = &exynos5_clkset_group,
851 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 },
852 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 },
855 static struct clksrc_clk exynos5_clk_sclk_uart0 = {
858 .devname = "exynos4210-uart.0",
859 .enable = exynos5_clksrc_mask_peric0_ctrl,
862 .sources = &exynos5_clkset_group,
863 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 },
864 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 },
867 static struct clksrc_clk exynos5_clk_sclk_uart1 = {
870 .devname = "exynos4210-uart.1",
871 .enable = exynos5_clksrc_mask_peric0_ctrl,
874 .sources = &exynos5_clkset_group,
875 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 },
876 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 },
879 static struct clksrc_clk exynos5_clk_sclk_uart2 = {
882 .devname = "exynos4210-uart.2",
883 .enable = exynos5_clksrc_mask_peric0_ctrl,
886 .sources = &exynos5_clkset_group,
887 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 },
888 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 },
891 static struct clksrc_clk exynos5_clk_sclk_uart3 = {
894 .devname = "exynos4210-uart.3",
895 .enable = exynos5_clksrc_mask_peric0_ctrl,
896 .ctrlbit = (1 << 12),
898 .sources = &exynos5_clkset_group,
899 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 },
900 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 },
903 static struct clksrc_clk exynos5_clk_sclk_mmc0 = {
906 .devname = "exynos4-sdhci.0",
907 .parent = &exynos5_clk_dout_mmc0.clk,
908 .enable = exynos5_clksrc_mask_fsys_ctrl,
911 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 },
914 static struct clksrc_clk exynos5_clk_sclk_mmc1 = {
917 .devname = "exynos4-sdhci.1",
918 .parent = &exynos5_clk_dout_mmc1.clk,
919 .enable = exynos5_clksrc_mask_fsys_ctrl,
922 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 },
925 static struct clksrc_clk exynos5_clk_sclk_mmc2 = {
928 .devname = "exynos4-sdhci.2",
929 .parent = &exynos5_clk_dout_mmc2.clk,
930 .enable = exynos5_clksrc_mask_fsys_ctrl,
933 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 },
936 static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
939 .devname = "exynos4-sdhci.3",
940 .parent = &exynos5_clk_dout_mmc3.clk,
941 .enable = exynos5_clksrc_mask_fsys_ctrl,
942 .ctrlbit = (1 << 12),
944 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
947 static struct clksrc_clk exynos5_clksrcs[] = {
950 .name = "sclk_dwmci",
951 .parent = &exynos5_clk_dout_mmc4.clk,
952 .enable = exynos5_clksrc_mask_fsys_ctrl,
953 .ctrlbit = (1 << 16),
955 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 8, .size = 8 },
959 .devname = "s3cfb.1",
960 .enable = exynos5_clksrc_mask_disp1_0_ctrl,
963 .sources = &exynos5_clkset_group,
964 .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 },
965 .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 },
968 .name = "aclk_266_gscl",
970 .sources = &clk_src_gscl_266,
971 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 },
975 .devname = "mali-t604.0",
976 .enable = exynos5_clk_block_ctrl,
979 .sources = &exynos5_clkset_aclk,
980 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
981 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
984 .name = "sclk_gscl_wrap",
985 .devname = "s5p-mipi-csis.0",
986 .enable = exynos5_clksrc_mask_gscl_ctrl,
987 .ctrlbit = (1 << 24),
989 .sources = &exynos5_clkset_group,
990 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 },
991 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 },
994 .name = "sclk_gscl_wrap",
995 .devname = "s5p-mipi-csis.1",
996 .enable = exynos5_clksrc_mask_gscl_ctrl,
997 .ctrlbit = (1 << 28),
999 .sources = &exynos5_clkset_group,
1000 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 },
1001 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 },
1004 .name = "sclk_cam0",
1005 .enable = exynos5_clksrc_mask_gscl_ctrl,
1006 .ctrlbit = (1 << 16),
1008 .sources = &exynos5_clkset_group,
1009 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 },
1010 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 },
1013 .name = "sclk_cam1",
1014 .enable = exynos5_clksrc_mask_gscl_ctrl,
1015 .ctrlbit = (1 << 20),
1017 .sources = &exynos5_clkset_group,
1018 .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 },
1019 .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 },
1022 .name = "sclk_jpeg",
1023 .parent = &exynos5_clk_mout_cpll.clk,
1025 .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 },
1029 /* Clock initialization code */
1030 static struct clksrc_clk *exynos5_sysclks[] = {
1031 &exynos5_clk_mout_apll,
1032 &exynos5_clk_sclk_apll,
1033 &exynos5_clk_mout_bpll,
1034 &exynos5_clk_mout_bpll_user,
1035 &exynos5_clk_mout_cpll,
1036 &exynos5_clk_mout_epll,
1037 &exynos5_clk_mout_mpll,
1038 &exynos5_clk_mout_mpll_user,
1039 &exynos5_clk_vpllsrc,
1040 &exynos5_clk_sclk_vpll,
1041 &exynos5_clk_mout_cpu,
1042 &exynos5_clk_dout_armclk,
1043 &exynos5_clk_dout_arm2clk,
1045 &exynos5_clk_aclk_400,
1046 &exynos5_clk_aclk_333,
1047 &exynos5_clk_aclk_266,
1048 &exynos5_clk_aclk_200,
1049 &exynos5_clk_aclk_166,
1050 &exynos5_clk_aclk_66_pre,
1051 &exynos5_clk_aclk_66,
1052 &exynos5_clk_dout_mmc0,
1053 &exynos5_clk_dout_mmc1,
1054 &exynos5_clk_dout_mmc2,
1055 &exynos5_clk_dout_mmc3,
1056 &exynos5_clk_dout_mmc4,
1057 &exynos5_clk_aclk_acp,
1058 &exynos5_clk_pclk_acp,
1061 static struct clk *exynos5_clk_cdev[] = {
1067 static struct clksrc_clk *exynos5_clksrc_cdev[] = {
1068 &exynos5_clk_sclk_uart0,
1069 &exynos5_clk_sclk_uart1,
1070 &exynos5_clk_sclk_uart2,
1071 &exynos5_clk_sclk_uart3,
1072 &exynos5_clk_sclk_mmc0,
1073 &exynos5_clk_sclk_mmc1,
1074 &exynos5_clk_sclk_mmc2,
1075 &exynos5_clk_sclk_mmc3,
1078 static struct clk_lookup exynos5_clk_lookup[] = {
1079 CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk),
1080 CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk),
1081 CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk),
1082 CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk),
1083 CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk),
1084 CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk),
1085 CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk),
1086 CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),
1087 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),
1088 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),
1089 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1),
1092 static unsigned long exynos5_epll_get_rate(struct clk *clk)
1097 static struct clk *exynos5_clks[] __initdata = {
1098 &exynos5_clk_sclk_hdmi27m,
1099 &exynos5_clk_sclk_hdmiphy,
1102 &exynos5_clk_armclk,
1105 static u32 epll_div[][6] = {
1106 { 192000000, 0, 48, 3, 1, 0 },
1107 { 180000000, 0, 45, 3, 1, 0 },
1108 { 73728000, 1, 73, 3, 3, 47710 },
1109 { 67737600, 1, 90, 4, 3, 20762 },
1110 { 49152000, 0, 49, 3, 3, 9961 },
1111 { 45158400, 0, 45, 3, 3, 10381 },
1112 { 180633600, 0, 45, 3, 1, 10381 },
1115 static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate)
1117 unsigned int epll_con, epll_con_k;
1120 unsigned int epll_rate;
1121 unsigned int locktime;
1122 unsigned int lockcnt;
1124 /* Return if nothing changed */
1125 if (clk->rate == rate)
1129 epll_rate = clk_get_rate(clk->parent);
1131 epll_rate = clk_ext_xtal_mux.rate;
1133 if (epll_rate != 24000000) {
1134 pr_err("Invalid Clock : recommended clock is 24MHz.\n");
1138 epll_con = __raw_readl(EXYNOS5_EPLL_CON0);
1139 epll_con &= ~(0x1 << 27 | \
1140 PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
1141 PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
1142 PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1144 for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1145 if (epll_div[i][0] == rate) {
1146 epll_con_k = epll_div[i][5] << 0;
1147 epll_con |= epll_div[i][1] << 27;
1148 epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
1149 epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
1150 epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
1155 if (i == ARRAY_SIZE(epll_div)) {
1156 printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1161 epll_rate /= 1000000;
1163 /* 3000 max_cycls : specification data */
1164 locktime = 3000 / epll_rate * epll_div[i][3];
1165 lockcnt = locktime * 10000 / (10000 / epll_rate);
1167 __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK);
1169 __raw_writel(epll_con, EXYNOS5_EPLL_CON0);
1170 __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1);
1173 tmp = __raw_readl(EXYNOS5_EPLL_CON0);
1174 } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
1181 static struct clk_ops exynos5_epll_ops = {
1182 .get_rate = exynos5_epll_get_rate,
1183 .set_rate = exynos5_epll_set_rate,
1186 static int xtal_rate;
1188 static unsigned long exynos5_fout_apll_get_rate(struct clk *clk)
1190 return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0));
1193 static struct clk_ops exynos5_fout_apll_ops = {
1194 .get_rate = exynos5_fout_apll_get_rate,
1198 static int exynos5_clock_suspend(void)
1200 s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1205 static void exynos5_clock_resume(void)
1207 s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1210 #define exynos5_clock_suspend NULL
1211 #define exynos5_clock_resume NULL
1214 struct syscore_ops exynos5_clock_syscore_ops = {
1215 .suspend = exynos5_clock_suspend,
1216 .resume = exynos5_clock_resume,
1219 void __init_or_cpufreq exynos5_setup_clocks(void)
1221 struct clk *xtal_clk;
1228 unsigned long vpllsrc;
1230 unsigned long armclk;
1231 unsigned long mout_cdrex;
1232 unsigned long aclk_400;
1233 unsigned long aclk_333;
1234 unsigned long aclk_266;
1235 unsigned long aclk_200;
1236 unsigned long aclk_166;
1237 unsigned long aclk_66;
1240 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1242 xtal_clk = clk_get(NULL, "xtal");
1243 BUG_ON(IS_ERR(xtal_clk));
1245 xtal = clk_get_rate(xtal_clk);
1251 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1253 apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0));
1254 bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0));
1255 cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0));
1256 mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0));
1257 epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0),
1258 __raw_readl(EXYNOS5_EPLL_CON1));
1260 vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk);
1261 vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0),
1262 __raw_readl(EXYNOS5_VPLL_CON1));
1264 clk_fout_apll.ops = &exynos5_fout_apll_ops;
1265 clk_fout_bpll.rate = bpll;
1266 clk_fout_cpll.rate = cpll;
1267 clk_fout_mpll.rate = mpll;
1268 clk_fout_epll.rate = epll;
1269 clk_fout_vpll.rate = vpll;
1271 printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
1272 "M=%ld, E=%ld V=%ld",
1273 apll, bpll, cpll, mpll, epll, vpll);
1275 armclk = clk_get_rate(&exynos5_clk_armclk);
1276 mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk);
1278 aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk);
1279 aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk);
1280 aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk);
1281 aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk);
1282 aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk);
1283 aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk);
1285 printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
1286 "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
1287 "ACLK166=%ld, ACLK66=%ld\n",
1288 armclk, mout_cdrex, aclk_400,
1289 aclk_333, aclk_266, aclk_200,
1293 clk_fout_epll.ops = &exynos5_epll_ops;
1295 if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
1296 printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
1297 clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
1299 clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000);
1300 clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000);
1302 clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000);
1303 clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000);
1305 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++)
1306 s3c_set_clksrc(&exynos5_clksrcs[ptr], true);
1309 void __init exynos5_register_clocks(void)
1313 s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks));
1315 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++)
1316 s3c_register_clksrc(exynos5_sysclks[ptr], 1);
1318 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++)
1319 s3c_register_clksrc(exynos5_sclk_tv[ptr], 1);
1321 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++)
1322 s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1);
1324 s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs));
1325 s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on));
1327 s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev));
1328 for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++)
1329 s3c_disable_clocks(exynos5_clk_cdev[ptr], 1);
1331 s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1332 s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1333 clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup));
1335 register_syscore_ops(&exynos5_clock_syscore_ops);