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
;