16 #include <linux/module.h>
23 #include <mach/hardware.h>
26 #include <mach/regs-sys.h>
27 #include <mach/regs-clock.h>
32 #include <plat/clock.h>
40 static struct clk clk_ext_xtal_mux = {
44 #define clk_fin_apll clk_ext_xtal_mux
45 #define clk_fin_mpll clk_ext_xtal_mux
46 #define clk_fin_epll clk_ext_xtal_mux
48 #define clk_fout_mpll clk_mpll
49 #define clk_fout_epll clk_epll
84 .enable = clk_48m_ctrl,
92 static int inline s3c64xx_gate(
void __iomem *
reg,
110 static int s3c64xx_pclk_ctrl(
struct clk *clk,
int enable)
115 static int s3c64xx_hclk_ctrl(
struct clk *clk,
int enable)
125 static struct clk init_clocks_off[] = {
132 .enable = s3c64xx_pclk_ctrl,
137 .enable = s3c64xx_pclk_ctrl,
141 #ifdef CONFIG_S3C_DEV_I2C1
142 .devname =
"s3c2440-i2c.0",
144 .devname =
"s3c2440-i2c",
147 .enable = s3c64xx_pclk_ctrl,
151 .devname =
"s3c2440-i2c.1",
153 .enable = s3c64xx_pclk_ctrl,
157 .devname =
"samsung-i2s.0",
159 .enable = s3c64xx_pclk_ctrl,
163 .devname =
"samsung-i2s.1",
165 .enable = s3c64xx_pclk_ctrl,
168 #ifdef CONFIG_CPU_S3C6410
171 .enable = s3c64xx_pclk_ctrl,
177 .enable = s3c64xx_pclk_ctrl,
181 .devname =
"s3c6410-spi.0",
183 .enable = s3c64xx_pclk_ctrl,
187 .devname =
"s3c6410-spi.1",
189 .enable = s3c64xx_pclk_ctrl,
193 .devname =
"s3c-sdhci.0",
199 .devname =
"s3c-sdhci.1",
205 .devname =
"s3c-sdhci.2",
216 .enable = s3c64xx_hclk_ctrl,
221 .enable = s3c64xx_hclk_ctrl,
226 .enable = s3c64xx_hclk_ctrl,
231 .enable = s3c64xx_hclk_ctrl,
234 .name =
"hclk_secur",
236 .enable = s3c64xx_hclk_ctrl,
241 .enable = s3c64xx_hclk_ctrl,
246 .enable = s3c64xx_hclk_ctrl,
251 .enable = s3c64xx_hclk_ctrl,
256 .enable = s3c64xx_hclk_ctrl,
259 .name =
"hclk_scaler",
261 .enable = s3c64xx_hclk_ctrl,
266 .enable = s3c64xx_hclk_ctrl,
271 .enable = s3c64xx_hclk_ctrl,
276 .enable = s3c64xx_hclk_ctrl,
281 .enable = s3c64xx_hclk_ctrl,
286 .enable = s3c64xx_hclk_ctrl,
291 .enable = s3c64xx_pclk_ctrl,
306 .name =
"sclk_scaler",
332 static struct clk clk_48m_spi0 = {
334 .devname =
"s3c6410-spi.0",
340 static struct clk clk_48m_spi1 = {
342 .devname =
"s3c6410-spi.1",
348 static struct clk init_clocks[] = {
352 .enable = s3c64xx_hclk_ctrl,
357 .enable = s3c64xx_pclk_ctrl,
362 .enable = s3c64xx_hclk_ctrl,
367 .enable = s3c64xx_hclk_ctrl,
372 .enable = s3c64xx_pclk_ctrl,
376 .devname =
"s3c6400-uart.0",
378 .enable = s3c64xx_pclk_ctrl,
382 .devname =
"s3c6400-uart.1",
384 .enable = s3c64xx_pclk_ctrl,
388 .devname =
"s3c6400-uart.2",
390 .enable = s3c64xx_pclk_ctrl,
394 .devname =
"s3c6400-uart.3",
396 .enable = s3c64xx_pclk_ctrl,
405 static struct clk clk_hsmmc0 = {
407 .devname =
"s3c-sdhci.0",
409 .enable = s3c64xx_hclk_ctrl,
413 static struct clk clk_hsmmc1 = {
415 .devname =
"s3c-sdhci.1",
417 .enable = s3c64xx_hclk_ctrl,
421 static struct clk clk_hsmmc2 = {
423 .devname =
"s3c-sdhci.2",
425 .enable = s3c64xx_hclk_ctrl,
429 static struct clk clk_fout_apll = {
433 static struct clk *clk_src_apll_list[] = {
435 [1] = &clk_fout_apll,
439 .sources = clk_src_apll_list,
447 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 0, .size = 1 },
448 .sources = &clk_src_apll,
451 static struct clk *clk_src_epll_list[] = {
457 .sources = clk_src_epll_list,
465 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 2, .size = 1 },
466 .sources = &clk_src_epll,
469 static struct clk *clk_src_mpll_list[] = {
475 .sources = clk_src_mpll_list,
483 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 1, .size = 1 },
484 .sources = &clk_src_mpll,
487 static unsigned int armclk_mask;
489 static unsigned long s3c64xx_clk_arm_get_rate(
struct clk *clk)
497 return rate / (clkdiv + 1);
500 static unsigned long s3c64xx_clk_arm_round_rate(
struct clk *clk,
509 div = (parent /
rate) - 1;
510 if (div > armclk_mask)
513 return parent / (div + 1);
516 static int s3c64xx_clk_arm_set_rate(
struct clk *clk,
unsigned long rate)
522 if (rate < parent / (armclk_mask + 1))
539 .parent = &clk_mout_apll.
clk,
541 .get_rate = s3c64xx_clk_arm_get_rate,
542 .set_rate = s3c64xx_clk_arm_set_rate,
543 .round_rate = s3c64xx_clk_arm_round_rate,
547 static unsigned long s3c64xx_clk_doutmpll_get_rate(
struct clk *clk)
559 static struct clk_ops clk_dout_ops = {
560 .get_rate = s3c64xx_clk_doutmpll_get_rate,
563 static struct clk clk_dout_mpll = {
565 .parent = &clk_mout_mpll.
clk,
566 .ops = &clk_dout_ops,
569 static struct clk *clkset_spi_mmc_list[] = {
577 .sources = clkset_spi_mmc_list,
578 .nr_sources =
ARRAY_SIZE(clkset_spi_mmc_list),
581 static struct clk *clkset_irda_list[] = {
589 .sources = clkset_irda_list,
593 static struct clk *clkset_uart_list[] = {
601 .sources = clkset_uart_list,
605 static struct clk *clkset_uhost_list[] = {
613 .sources = clkset_uhost_list,
629 static struct clk clk_iis_cd0 = {
630 .name =
"iis_cdclk0",
633 static struct clk clk_iis_cd1 = {
634 .name =
"iis_cdclk1",
637 static struct clk clk_iisv4_cd = {
638 .name =
"iis_cdclk_v4",
641 static struct clk clk_pcm_cd = {
645 static struct clk *clkset_audio0_list[] = {
646 [0] = &clk_mout_epll.
clk,
647 [1] = &clk_dout_mpll,
654 .sources = clkset_audio0_list,
658 static struct clk *clkset_audio1_list[] = {
659 [0] = &clk_mout_epll.
clk,
660 [1] = &clk_dout_mpll,
667 .sources = clkset_audio1_list,
671 static struct clk *clkset_audio2_list[] = {
672 [0] = &clk_mout_epll.
clk,
673 [1] = &clk_dout_mpll,
680 .sources = clkset_audio2_list,
684 static struct clk *clkset_camif_list[] = {
689 .sources = clkset_camif_list,
696 .name =
"usb-bus-host",
700 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 5, .size = 2 },
701 .reg_div = { .reg =
S3C_CLK_DIV1, .shift = 20, .size = 4 },
702 .sources = &clkset_uhost,
706 .devname =
"samsung-i2s.0",
710 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 7, .size = 3 },
711 .reg_div = { .reg =
S3C_CLK_DIV2, .shift = 8, .size = 4 },
712 .sources = &clkset_audio0,
716 .devname =
"samsung-i2s.1",
720 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 10, .size = 3 },
721 .reg_div = { .reg =
S3C_CLK_DIV2, .shift = 12, .size = 4 },
722 .sources = &clkset_audio1,
726 .devname =
"samsung-i2s.2",
731 .reg_div = { .reg =
S3C_CLK_DIV2, .shift = 24, .size = 4 },
732 .sources = &clkset_audio2,
739 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 24, .size = 2 },
740 .reg_div = { .reg =
S3C_CLK_DIV2, .shift = 20, .size = 4 },
741 .sources = &clkset_irda,
748 .reg_div = { .reg =
S3C_CLK_DIV0, .shift = 20, .size = 4 },
749 .reg_src = { .reg =
NULL, .shift = 0, .size = 0 },
750 .sources = &clkset_camif,
761 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 13, .size = 1 },
762 .reg_div = { .reg =
S3C_CLK_DIV2, .shift = 16, .size = 4 },
763 .sources = &clkset_uart,
769 .devname =
"s3c-sdhci.0",
773 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 18, .size = 2 },
774 .reg_div = { .reg =
S3C_CLK_DIV1, .shift = 0, .size = 4 },
775 .sources = &clkset_spi_mmc,
781 .devname =
"s3c-sdhci.1",
785 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 20, .size = 2 },
786 .reg_div = { .reg =
S3C_CLK_DIV1, .shift = 4, .size = 4 },
787 .sources = &clkset_spi_mmc,
793 .devname =
"s3c-sdhci.2",
797 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 22, .size = 2 },
798 .reg_div = { .reg =
S3C_CLK_DIV1, .shift = 8, .size = 4 },
799 .sources = &clkset_spi_mmc,
805 .devname =
"s3c6410-spi.0",
809 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 14, .size = 2 },
810 .reg_div = { .reg =
S3C_CLK_DIV2, .shift = 0, .size = 4 },
811 .sources = &clkset_spi_mmc,
817 .devname =
"s3c6410-spi.1",
821 .reg_src = { .reg =
S3C_CLK_SRC, .shift = 16, .size = 2 },
822 .reg_div = { .reg =
S3C_CLK_DIV2, .shift = 4, .size = 4 },
823 .sources = &clkset_spi_mmc,
843 static struct clk *clk_cdev[] = {
851 static struct clk_lookup s3c64xx_clk_lookup[] = {
854 CLKDEV_INIT(
"s3c-sdhci.0",
"mmc_busclk.0", &clk_hsmmc0),
855 CLKDEV_INIT(
"s3c-sdhci.1",
"mmc_busclk.0", &clk_hsmmc1),
856 CLKDEV_INIT(
"s3c-sdhci.2",
"mmc_busclk.0", &clk_hsmmc2),
862 CLKDEV_INIT(
"s3c6410-spi.0",
"spi_busclk2", &clk_48m_spi0),
864 CLKDEV_INIT(
"s3c6410-spi.1",
"spi_busclk2", &clk_48m_spi1),
867 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
871 struct clk *xtal_clk;
897 clk_ext_xtal_mux.
parent = xtal_clk;
911 hclk2 = apll /
GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
914 hclk2 = mpll /
GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
916 hclk = hclk2 /
GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
917 pclk = hclk2 /
GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
924 clk_fout_apll.
rate = apll;
931 for (ptr = 0; ptr <
ARRAY_SIZE(init_parents); ptr++)
934 for (ptr = 0; ptr <
ARRAY_SIZE(clksrcs); ptr++)
950 static struct clk *clks[] __initdata = {
973 unsigned armclk_divlimit)
977 armclk_mask = armclk_divlimit;
988 for (cnt = 0; cnt <
ARRAY_SIZE(clk_cdev); cnt++)
993 for (cnt = 0; cnt <
ARRAY_SIZE(clksrc_cdev); cnt++)