1 /* linux/arch/arm/plat-s5pc1xx/s5pc100-clock.c
3 * Copyright 2009 Samsung Electronics, Co.
4 * Byungho Min <bhmin@samsung.com>
6 * S5PC100 based common clock support
8 * Based on plat-s3c64xx/s3c6400-clock.c
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/init.h>
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/list.h>
19 #include <linux/errno.h>
20 #include <linux/err.h>
21 #include <linux/clk.h>
22 #include <linux/sysdev.h>
25 #include <mach/hardware.h>
28 #include <plat/cpu-freq.h>
30 #include <plat/regs-clock.h>
31 #include <plat/clock.h>
34 #include <plat/devs.h>
35 #include <plat/s5pc100.h>
37 /* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
38 * ext_xtal_mux for want of an actual name from the manual.
41 static struct clk clk_ext_xtal_mux = {
46 #define clk_fin_apll clk_ext_xtal_mux
47 #define clk_fin_mpll clk_ext_xtal_mux
48 #define clk_fin_epll clk_ext_xtal_mux
49 #define clk_fin_hpll clk_ext_xtal_mux
51 #define clk_fout_mpll clk_mpll
54 unsigned int nr_sources;
63 struct clk_sources *sources;
65 unsigned int divider_shift;
66 void __iomem *reg_divider;
67 void __iomem *reg_source;
70 static int clk_default_setrate(struct clk *clk, unsigned long rate)
76 struct clk clk_27m = {
82 static int clk_48m_ctrl(struct clk *clk, int enable)
87 /* can't rely on clock lock, this register has other usages */
88 local_irq_save(flags);
90 val = __raw_readl(S5PC1XX_CLK_SRC1);
92 val |= S5PC100_CLKSRC1_CLK48M_MASK;
94 val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
96 __raw_writel(val, S5PC1XX_CLK_SRC1);
97 local_irq_restore(flags);
102 struct clk clk_48m = {
106 .enable = clk_48m_ctrl,
109 struct clk clk_54m = {
115 struct clk clk_hpll = {
120 struct clk clk_hd0 = {
126 .set_rate = clk_default_setrate,
129 struct clk clk_pd0 = {
135 .set_rate = clk_default_setrate,
138 static int s5pc1xx_clk_gate(void __iomem *reg,
142 unsigned int ctrlbit = clk->ctrlbit;
145 con = __raw_readl(reg);
152 __raw_writel(con, reg);
156 static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable)
158 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
161 static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable)
163 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
166 static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable)
168 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
171 static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable)
173 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
176 static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable)
178 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
181 static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable)
183 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
186 static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable)
188 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
191 static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable)
193 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
196 static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable)
198 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
201 static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable)
203 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
206 int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable)
208 return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
211 int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable)
213 return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
216 static struct clk init_clocks_disable[] = {
221 .enable = s5pc1xx_clk_d11_ctrl,
222 .ctrlbit = S5PC100_CLKGATE_D11_DSI,
227 .enable = s5pc1xx_clk_d11_ctrl,
228 .ctrlbit = S5PC100_CLKGATE_D11_CSI,
233 .enable = s5pc1xx_clk_d14_ctrl,
234 .ctrlbit = S5PC100_CLKGATE_D14_CCAN0,
239 .enable = s5pc1xx_clk_d14_ctrl,
240 .ctrlbit = S5PC100_CLKGATE_D14_CCAN1,
245 .enable = s5pc1xx_clk_d15_ctrl,
246 .ctrlbit = S5PC100_CLKGATE_D15_KEYIF,
251 .enable = s5pc1xx_clk_d20_ctrl,
252 .ctrlbit = S5PC100_CLKGATE_D20_HCLKD2,
257 .enable = s5pc1xx_clk_d20_ctrl,
258 .ctrlbit = S5PC100_CLKGATE_D20_I2SD2,
263 .enable = s5pc1xx_clk_d10_ctrl,
264 .ctrlbit = S5PC100_CLKGATE_D10_USBOTG,
268 static struct clk init_clocks[] = {
269 /* System1 (D0_0) devices */
274 .enable = s5pc1xx_clk_d00_ctrl,
275 .ctrlbit = S5PC100_CLKGATE_D00_INTC,
280 .enable = s5pc1xx_clk_d00_ctrl,
281 .ctrlbit = S5PC100_CLKGATE_D00_TZIC,
286 .enable = s5pc1xx_clk_d00_ctrl,
287 .ctrlbit = S5PC100_CLKGATE_D00_CFCON,
292 .enable = s5pc1xx_clk_d00_ctrl,
293 .ctrlbit = S5PC100_CLKGATE_D00_MDMA,
298 .enable = s5pc1xx_clk_d00_ctrl,
299 .ctrlbit = S5PC100_CLKGATE_D00_G2D,
304 .enable = s5pc1xx_clk_d00_ctrl,
305 .ctrlbit = S5PC100_CLKGATE_D00_SECSS,
310 .enable = s5pc1xx_clk_d00_ctrl,
311 .ctrlbit = S5PC100_CLKGATE_D00_CSSYS,
314 /* Memory (D0_1) devices */
319 .enable = s5pc1xx_clk_d01_ctrl,
320 .ctrlbit = S5PC100_CLKGATE_D01_DMC,
325 .enable = s5pc1xx_clk_d01_ctrl,
326 .ctrlbit = S5PC100_CLKGATE_D01_SROMC,
331 .enable = s5pc1xx_clk_d01_ctrl,
332 .ctrlbit = S5PC100_CLKGATE_D01_ONENAND,
337 .enable = s5pc1xx_clk_d01_ctrl,
338 .ctrlbit = S5PC100_CLKGATE_D01_NFCON,
343 .enable = s5pc1xx_clk_d01_ctrl,
344 .ctrlbit = S5PC100_CLKGATE_D01_INTMEM,
349 .enable = s5pc1xx_clk_d01_ctrl,
350 .ctrlbit = S5PC100_CLKGATE_D01_EBI,
353 /* System2 (D0_2) devices */
358 .enable = s5pc1xx_clk_d02_ctrl,
359 .ctrlbit = S5PC100_CLKGATE_D02_SECKEY,
364 .enable = s5pc1xx_clk_d02_ctrl,
365 .ctrlbit = S5PC100_CLKGATE_D02_SDM,
368 /* File (D1_0) devices */
373 .enable = s5pc1xx_clk_d10_ctrl,
374 .ctrlbit = S5PC100_CLKGATE_D10_PDMA0,
379 .enable = s5pc1xx_clk_d10_ctrl,
380 .ctrlbit = S5PC100_CLKGATE_D10_PDMA1,
385 .enable = s5pc1xx_clk_d10_ctrl,
386 .ctrlbit = S5PC100_CLKGATE_D10_USBHOST,
391 .enable = s5pc1xx_clk_d10_ctrl,
392 .ctrlbit = S5PC100_CLKGATE_D10_MODEMIF,
397 .enable = s5pc1xx_clk_d10_ctrl,
398 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC0,
403 .enable = s5pc1xx_clk_d10_ctrl,
404 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC1,
409 .enable = s5pc1xx_clk_d10_ctrl,
410 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC2,
413 /* Multimedia1 (D1_1) devices */
418 .enable = s5pc1xx_clk_d11_ctrl,
419 .ctrlbit = S5PC100_CLKGATE_D11_LCD,
424 .enable = s5pc1xx_clk_d11_ctrl,
425 .ctrlbit = S5PC100_CLKGATE_D11_ROTATOR,
430 .enable = s5pc1xx_clk_d11_ctrl,
431 .ctrlbit = S5PC100_CLKGATE_D11_FIMC0,
436 .enable = s5pc1xx_clk_d11_ctrl,
437 .ctrlbit = S5PC100_CLKGATE_D11_FIMC1,
442 .enable = s5pc1xx_clk_d11_ctrl,
443 .ctrlbit = S5PC100_CLKGATE_D11_FIMC2,
448 .enable = s5pc1xx_clk_d11_ctrl,
449 .ctrlbit = S5PC100_CLKGATE_D11_JPEG,
454 .enable = s5pc1xx_clk_d11_ctrl,
455 .ctrlbit = S5PC100_CLKGATE_D11_G3D,
458 /* Multimedia2 (D1_2) devices */
463 .enable = s5pc1xx_clk_d12_ctrl,
464 .ctrlbit = S5PC100_CLKGATE_D12_TV,
469 .enable = s5pc1xx_clk_d12_ctrl,
470 .ctrlbit = S5PC100_CLKGATE_D12_VP,
475 .enable = s5pc1xx_clk_d12_ctrl,
476 .ctrlbit = S5PC100_CLKGATE_D12_MIXER,
481 .enable = s5pc1xx_clk_d12_ctrl,
482 .ctrlbit = S5PC100_CLKGATE_D12_HDMI,
487 .enable = s5pc1xx_clk_d12_ctrl,
488 .ctrlbit = S5PC100_CLKGATE_D12_MFC,
491 /* System (D1_3) devices */
496 .enable = s5pc1xx_clk_d13_ctrl,
497 .ctrlbit = S5PC100_CLKGATE_D13_CHIPID,
502 .enable = s5pc1xx_clk_d13_ctrl,
503 .ctrlbit = S5PC100_CLKGATE_D13_GPIO,
508 .enable = s5pc1xx_clk_d13_ctrl,
509 .ctrlbit = S5PC100_CLKGATE_D13_APC,
514 .enable = s5pc1xx_clk_d13_ctrl,
515 .ctrlbit = S5PC100_CLKGATE_D13_IEC,
520 .enable = s5pc1xx_clk_d13_ctrl,
521 .ctrlbit = S5PC100_CLKGATE_D13_PWM,
526 .enable = s5pc1xx_clk_d13_ctrl,
527 .ctrlbit = S5PC100_CLKGATE_D13_SYSTIMER,
532 .enable = s5pc1xx_clk_d13_ctrl,
533 .ctrlbit = S5PC100_CLKGATE_D13_WDT,
538 .enable = s5pc1xx_clk_d13_ctrl,
539 .ctrlbit = S5PC100_CLKGATE_D13_RTC,
542 /* Connectivity (D1_4) devices */
547 .enable = s5pc1xx_clk_d14_ctrl,
548 .ctrlbit = S5PC100_CLKGATE_D14_UART0,
553 .enable = s5pc1xx_clk_d14_ctrl,
554 .ctrlbit = S5PC100_CLKGATE_D14_UART1,
559 .enable = s5pc1xx_clk_d14_ctrl,
560 .ctrlbit = S5PC100_CLKGATE_D14_UART2,
565 .enable = s5pc1xx_clk_d14_ctrl,
566 .ctrlbit = S5PC100_CLKGATE_D14_UART3,
571 .enable = s5pc1xx_clk_d14_ctrl,
572 .ctrlbit = S5PC100_CLKGATE_D14_IIC,
577 .enable = s5pc1xx_clk_d14_ctrl,
578 .ctrlbit = S5PC100_CLKGATE_D14_HDMI_IIC,
583 .enable = s5pc1xx_clk_d14_ctrl,
584 .ctrlbit = S5PC100_CLKGATE_D14_SPI0,
589 .enable = s5pc1xx_clk_d14_ctrl,
590 .ctrlbit = S5PC100_CLKGATE_D14_SPI1,
595 .enable = s5pc1xx_clk_d14_ctrl,
596 .ctrlbit = S5PC100_CLKGATE_D14_SPI2,
601 .enable = s5pc1xx_clk_d14_ctrl,
602 .ctrlbit = S5PC100_CLKGATE_D14_IRDA,
607 .enable = s5pc1xx_clk_d14_ctrl,
608 .ctrlbit = S5PC100_CLKGATE_D14_HSITX,
613 .enable = s5pc1xx_clk_d14_ctrl,
614 .ctrlbit = S5PC100_CLKGATE_D14_HSIRX,
617 /* Audio (D1_5) devices */
622 .enable = s5pc1xx_clk_d15_ctrl,
623 .ctrlbit = S5PC100_CLKGATE_D15_IIS0,
628 .enable = s5pc1xx_clk_d15_ctrl,
629 .ctrlbit = S5PC100_CLKGATE_D15_IIS1,
634 .enable = s5pc1xx_clk_d15_ctrl,
635 .ctrlbit = S5PC100_CLKGATE_D15_IIS2,
640 .enable = s5pc1xx_clk_d15_ctrl,
641 .ctrlbit = S5PC100_CLKGATE_D15_AC97,
646 .enable = s5pc1xx_clk_d15_ctrl,
647 .ctrlbit = S5PC100_CLKGATE_D15_PCM0,
652 .enable = s5pc1xx_clk_d15_ctrl,
653 .ctrlbit = S5PC100_CLKGATE_D15_PCM1,
658 .enable = s5pc1xx_clk_d15_ctrl,
659 .ctrlbit = S5PC100_CLKGATE_D15_SPDIF,
664 .enable = s5pc1xx_clk_d15_ctrl,
665 .ctrlbit = S5PC100_CLKGATE_D15_TSADC,
670 .enable = s5pc1xx_clk_d15_ctrl,
671 .ctrlbit = S5PC100_CLKGATE_D15_KEYIF,
676 .enable = s5pc1xx_clk_d15_ctrl,
677 .ctrlbit = S5PC100_CLKGATE_D15_CG,
680 /* Audio (D2_0) devices: all disabled */
682 /* Special Clocks 1 */
687 .enable = s5pc1xx_sclk0_ctrl,
688 .ctrlbit = S5PC1XX_CLKGATE_SCLK0_HPM,
690 .name = "sclk_onenand",
693 .enable = s5pc1xx_sclk0_ctrl,
694 .ctrlbit = S5PC100_CLKGATE_SCLK0_ONENAND,
696 .name = "sclk_spi_48",
699 .enable = s5pc1xx_sclk0_ctrl,
700 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0_48,
702 .name = "sclk_spi_48",
705 .enable = s5pc1xx_sclk0_ctrl,
706 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1_48,
708 .name = "sclk_spi_48",
711 .enable = s5pc1xx_sclk0_ctrl,
712 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2_48,
714 .name = "sclk_mmc_48",
717 .enable = s5pc1xx_sclk0_ctrl,
718 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0_48,
720 .name = "sclk_mmc_48",
723 .enable = s5pc1xx_sclk0_ctrl,
724 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1_48,
726 .name = "sclk_mmc_48",
729 .enable = s5pc1xx_sclk0_ctrl,
730 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2_48,
733 /* Special Clocks 2 */
735 .name = "sclk_tv_54",
738 .enable = s5pc1xx_sclk1_ctrl,
739 .ctrlbit = S5PC100_CLKGATE_SCLK1_TV54,
741 .name = "sclk_vdac_54",
744 .enable = s5pc1xx_sclk1_ctrl,
745 .ctrlbit = S5PC100_CLKGATE_SCLK1_VDAC54,
747 .name = "sclk_spdif",
750 .enable = s5pc1xx_sclk1_ctrl,
751 .ctrlbit = S5PC100_CLKGATE_SCLK1_SPDIF,
755 void __init s5pc1xx_register_clocks(void)
762 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
763 ret = s3c24xx_register_clock(clkp);
765 printk(KERN_ERR "Failed to register clock %s (%d)\n",
770 clkp = init_clocks_disable;
771 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
773 ret = s3c24xx_register_clock(clkp);
775 printk(KERN_ERR "Failed to register clock %s (%d)\n",
779 (clkp->enable)(clkp, 0);
784 static struct clk clk_fout_apll = {
789 static struct clk *clk_src_apll_list[] = {
791 [1] = &clk_fout_apll,
794 static struct clk_sources clk_src_apll = {
795 .sources = clk_src_apll_list,
796 .nr_sources = ARRAY_SIZE(clk_src_apll_list),
799 static struct clksrc_clk clk_mout_apll = {
804 .shift = S5PC1XX_CLKSRC0_APLL_SHIFT,
805 .mask = S5PC1XX_CLKSRC0_APLL_MASK,
806 .sources = &clk_src_apll,
807 .reg_source = S5PC1XX_CLK_SRC0,
810 static struct clk clk_fout_epll = {
815 static struct clk *clk_src_epll_list[] = {
817 [1] = &clk_fout_epll,
820 static struct clk_sources clk_src_epll = {
821 .sources = clk_src_epll_list,
822 .nr_sources = ARRAY_SIZE(clk_src_epll_list),
825 static struct clksrc_clk clk_mout_epll = {
830 .shift = S5PC1XX_CLKSRC0_EPLL_SHIFT,
831 .mask = S5PC1XX_CLKSRC0_EPLL_MASK,
832 .sources = &clk_src_epll,
833 .reg_source = S5PC1XX_CLK_SRC0,
836 static struct clk *clk_src_mpll_list[] = {
838 [1] = &clk_fout_mpll,
841 static struct clk_sources clk_src_mpll = {
842 .sources = clk_src_mpll_list,
843 .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
846 static struct clksrc_clk clk_mout_mpll = {
851 .shift = S5PC1XX_CLKSRC0_MPLL_SHIFT,
852 .mask = S5PC1XX_CLKSRC0_MPLL_MASK,
853 .sources = &clk_src_mpll,
854 .reg_source = S5PC1XX_CLK_SRC0,
857 static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
859 unsigned long rate = clk_get_rate(clk->parent);
860 unsigned long clkdiv;
862 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
864 clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK;
865 rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
870 static struct clk clk_dout_mpll = {
873 .parent = &clk_mout_mpll.clk,
874 .get_rate = s5pc1xx_clk_doutmpll_get_rate,
877 static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
879 unsigned long rate = clk_get_rate(clk->parent);
880 unsigned long clkdiv;
882 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
884 clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
885 rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
890 struct clk clk_dout_mpll2 = {
891 .name = "dout_mpll2",
893 .parent = &clk_mout_mpll.clk,
894 .get_rate = s5pc1xx_clk_doutmpll2_get_rate,
897 static struct clk *clkset_uart_list[] = {
904 static struct clk_sources clkset_uart = {
905 .sources = clkset_uart_list,
906 .nr_sources = ARRAY_SIZE(clkset_uart_list),
909 static inline struct clksrc_clk *to_clksrc(struct clk *clk)
911 return container_of(clk, struct clksrc_clk, clk);
914 static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
916 struct clksrc_clk *sclk = to_clksrc(clk);
917 unsigned long rate = clk_get_rate(clk->parent);
918 u32 clkdiv = __raw_readl(sclk->reg_divider);
920 clkdiv >>= sclk->divider_shift;
928 static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
930 struct clksrc_clk *sclk = to_clksrc(clk);
931 void __iomem *reg = sclk->reg_divider;
935 rate = clk_round_rate(clk, rate);
936 div = clk_get_rate(clk->parent) / rate;
940 val = __raw_readl(reg);
941 val &= ~(0xf << sclk->shift);
942 val |= (div - 1) << sclk->shift;
943 __raw_writel(val, reg);
948 static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
950 struct clksrc_clk *sclk = to_clksrc(clk);
951 struct clk_sources *srcs = sclk->sources;
952 u32 clksrc = __raw_readl(sclk->reg_source);
956 for (ptr = 0; ptr < srcs->nr_sources; ptr++)
957 if (srcs->sources[ptr] == parent) {
963 clksrc &= ~sclk->mask;
964 clksrc |= src_nr << sclk->shift;
966 __raw_writel(clksrc, sclk->reg_source);
973 static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
976 unsigned long parent_rate = clk_get_rate(clk->parent);
979 if (rate > parent_rate)
982 div = rate / parent_rate;
989 rate = parent_rate / div;
995 static struct clksrc_clk clk_uart_uclk1 = {
999 .ctrlbit = S5PC100_CLKGATE_SCLK0_UART,
1000 .enable = s5pc1xx_sclk0_ctrl,
1001 .set_parent = s5pc1xx_setparent_clksrc,
1002 .get_rate = s5pc1xx_getrate_clksrc,
1003 .set_rate = s5pc1xx_setrate_clksrc,
1004 .round_rate = s5pc1xx_roundrate_clksrc,
1006 .shift = S5PC100_CLKSRC1_UART_SHIFT,
1007 .mask = S5PC100_CLKSRC1_UART_MASK,
1008 .sources = &clkset_uart,
1009 .divider_shift = S5PC100_CLKDIV2_UART_SHIFT,
1010 .reg_divider = S5PC1XX_CLK_DIV2,
1011 .reg_source = S5PC1XX_CLK_SRC1,
1014 /* Clock initialisation code */
1016 static struct clksrc_clk *init_parents[] = {
1023 static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
1025 struct clk_sources *srcs = clk->sources;
1026 u32 clksrc = __raw_readl(clk->reg_source);
1028 clksrc &= clk->mask;
1029 clksrc >>= clk->shift;
1031 if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
1032 printk(KERN_ERR "%s: bad source %d\n",
1033 clk->clk.name, clksrc);
1037 clk->clk.parent = srcs->sources[clksrc];
1039 printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
1040 clk->clk.name, clk->clk.parent->name, clksrc,
1041 clk_get_rate(&clk->clk));
1044 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
1046 void __init_or_cpufreq s5pc100_setup_clocks(void)
1048 struct clk *xtal_clk;
1050 unsigned long armclk;
1051 unsigned long hclkd0;
1053 unsigned long pclkd0;
1060 u32 clkdiv0, clkdiv1;
1062 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1064 clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0);
1065 clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1);
1067 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1068 __func__, clkdiv0, clkdiv1);
1070 xtal_clk = clk_get(NULL, "xtal");
1071 BUG_ON(IS_ERR(xtal_clk));
1073 xtal = clk_get_rate(xtal_clk);
1076 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1078 apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON));
1079 mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON));
1080 epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON));
1081 hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
1083 printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
1084 apll, mpll, epll, hpll);
1086 armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL);
1087 armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
1088 hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
1089 pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
1090 hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
1091 pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
1093 printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n",
1094 armclk, hclkd0, pclkd0, hclk, pclk);
1096 clk_fout_apll.rate = apll;
1097 clk_fout_mpll.rate = mpll;
1098 clk_fout_epll.rate = epll;
1099 clk_fout_apll.rate = apll;
1104 for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
1105 s5pc1xx_set_clksrc(init_parents[ptr]);
1108 static struct clk *clks[] __initdata = {
1114 &clk_uart_uclk1.clk,
1122 void __init s5pc100_register_clocks(void)
1128 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
1130 ret = s3c24xx_register_clock(clkp);
1132 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1137 clk_mpll.parent = &clk_mout_mpll.clk;
1138 clk_epll.parent = &clk_mout_epll.clk;