aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Turquette <mturquette@linaro.org>2013-08-05 14:59:06 -0400
committerMike Turquette <mturquette@linaro.org>2013-08-08 18:57:26 -0400
commit5cfe9614f365915d9e75d110d4008b06a5c0b99e (patch)
tree5fb6c7c7541363e286a97557fd845051feb48feb
parent6f9a4894c435bc9919dab31d90f69167d4638997 (diff)
parent06dda9d770063c5fefc0b41c7bfcc1321e2649dd (diff)
Merge branch 'clk-next-s3c64xx' into clk-next
-rw-r--r--Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt77
-rw-r--r--drivers/clk/clk-mux.c10
-rw-r--r--drivers/clk/samsung/Makefile3
-rw-r--r--drivers/clk/samsung/clk-pll.c160
-rw-r--r--drivers/clk/samsung/clk-pll.h4
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c473
-rw-r--r--include/dt-bindings/clock/samsung,s3c64xx-clock.h178
-rw-r--r--include/linux/clk-provider.h2
8 files changed, 906 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
new file mode 100644
index 000000000000..fa171dc4bd3c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
@@ -0,0 +1,77 @@
1* Samsung S3C64xx Clock Controller
2
3The S3C64xx clock controller generates and supplies clock to various controllers
4within the SoC. The clock binding described here is applicable to all SoCs in
5the S3C64xx family.
6
7Required Properties:
8
9- compatible: should be one of the following.
10 - "samsung,s3c6400-clock" - controller compatible with S3C6400 SoC.
11 - "samsung,s3c6410-clock" - controller compatible with S3C6410 SoC.
12
13- reg: physical base address of the controller and length of memory mapped
14 region.
15
16- #clock-cells: should be 1.
17
18Each clock is assigned an identifier and client nodes can use this identifier
19to specify the clock which they consume. Some of the clocks are available only
20on a particular S3C64xx SoC and this is specified where applicable.
21
22All available clocks are defined as preprocessor macros in
23dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used in device
24tree sources.
25
26External clocks:
27
28There are several clocks that are generated outside the SoC. It is expected
29that they are defined using standard clock bindings with following
30clock-output-names:
31 - "fin_pll" - PLL input clock (xtal/extclk) - required,
32 - "xusbxti" - USB xtal - required,
33 - "iiscdclk0" - I2S0 codec clock - optional,
34 - "iiscdclk1" - I2S1 codec clock - optional,
35 - "iiscdclk2" - I2S2 codec clock - optional,
36 - "pcmcdclk0" - PCM0 codec clock - optional,
37 - "pcmcdclk1" - PCM1 codec clock - optional, only S3C6410.
38
39Example: Clock controller node:
40
41 clock: clock-controller@7e00f000 {
42 compatible = "samsung,s3c6410-clock";
43 reg = <0x7e00f000 0x1000>;
44 #clock-cells = <1>;
45 };
46
47Example: Required external clocks:
48
49 fin_pll: clock-fin-pll {
50 compatible = "fixed-clock";
51 clock-output-names = "fin_pll";
52 clock-frequency = <12000000>;
53 #clock-cells = <0>;
54 };
55
56 xusbxti: clock-xusbxti {
57 compatible = "fixed-clock";
58 clock-output-names = "xusbxti";
59 clock-frequency = <48000000>;
60 #clock-cells = <0>;
61 };
62
63Example: UART controller node that consumes the clock generated by the clock
64 controller (refer to the standard clock bindings for information about
65 "clocks" and "clock-names" properties):
66
67 uart0: serial@7f005000 {
68 compatible = "samsung,s3c6400-uart";
69 reg = <0x7f005000 0x100>;
70 interrupt-parent = <&vic1>;
71 interrupts = <5>;
72 clock-names = "uart", "clk_uart_baud2",
73 "clk_uart_baud3";
74 clocks = <&clock PCLK_UART0>, <&clocks PCLK_UART0>,
75 <&clock SCLK_UART>;
76 status = "disabled";
77 };
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 614444ca40cd..92f1a1be5319 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -107,6 +107,11 @@ const struct clk_ops clk_mux_ops = {
107}; 107};
108EXPORT_SYMBOL_GPL(clk_mux_ops); 108EXPORT_SYMBOL_GPL(clk_mux_ops);
109 109
110const struct clk_ops clk_mux_ro_ops = {
111 .get_parent = clk_mux_get_parent,
112};
113EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
114
110struct clk *clk_register_mux_table(struct device *dev, const char *name, 115struct clk *clk_register_mux_table(struct device *dev, const char *name,
111 const char **parent_names, u8 num_parents, unsigned long flags, 116 const char **parent_names, u8 num_parents, unsigned long flags,
112 void __iomem *reg, u8 shift, u32 mask, 117 void __iomem *reg, u8 shift, u32 mask,
@@ -133,7 +138,10 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
133 } 138 }
134 139
135 init.name = name; 140 init.name = name;
136 init.ops = &clk_mux_ops; 141 if (clk_mux_flags & CLK_MUX_READ_ONLY)
142 init.ops = &clk_mux_ro_ops;
143 else
144 init.ops = &clk_mux_ops;
137 init.flags = flags | CLK_IS_BASIC; 145 init.flags = flags | CLK_IS_BASIC;
138 init.parent_names = parent_names; 146 init.parent_names = parent_names;
139 init.num_parents = num_parents; 147 init.num_parents = num_parents;
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 5d4d432cc4ac..3413380086d5 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,3 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
8obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o 8obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
9obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o 9obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
10obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o 10obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
11ifdef CONFIG_COMMON_CLK
12obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
13endif
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index f80efb6bc0b3..077555416ce1 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -438,6 +438,166 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
438} 438}
439 439
440/* 440/*
441 * PLL6552 Clock Type
442 */
443
444#define PLL6552_LOCK_REG 0x00
445#define PLL6552_CON_REG 0x0c
446
447#define PLL6552_MDIV_MASK 0x3ff
448#define PLL6552_PDIV_MASK 0x3f
449#define PLL6552_SDIV_MASK 0x7
450#define PLL6552_MDIV_SHIFT 16
451#define PLL6552_PDIV_SHIFT 8
452#define PLL6552_SDIV_SHIFT 0
453
454struct samsung_clk_pll6552 {
455 struct clk_hw hw;
456 void __iomem *reg_base;
457};
458
459#define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw)
460
461static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
462 unsigned long parent_rate)
463{
464 struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw);
465 u32 mdiv, pdiv, sdiv, pll_con;
466 u64 fvco = parent_rate;
467
468 pll_con = __raw_readl(pll->reg_base + PLL6552_CON_REG);
469 mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
470 pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
471 sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
472
473 fvco *= mdiv;
474 do_div(fvco, (pdiv << sdiv));
475
476 return (unsigned long)fvco;
477}
478
479static const struct clk_ops samsung_pll6552_clk_ops = {
480 .recalc_rate = samsung_pll6552_recalc_rate,
481};
482
483struct clk * __init samsung_clk_register_pll6552(const char *name,
484 const char *pname, void __iomem *base)
485{
486 struct samsung_clk_pll6552 *pll;
487 struct clk *clk;
488 struct clk_init_data init;
489
490 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
491 if (!pll) {
492 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
493 return NULL;
494 }
495
496 init.name = name;
497 init.ops = &samsung_pll6552_clk_ops;
498 init.parent_names = &pname;
499 init.num_parents = 1;
500
501 pll->hw.init = &init;
502 pll->reg_base = base;
503
504 clk = clk_register(NULL, &pll->hw);
505 if (IS_ERR(clk)) {
506 pr_err("%s: failed to register pll clock %s\n", __func__,
507 name);
508 kfree(pll);
509 }
510
511 if (clk_register_clkdev(clk, name, NULL))
512 pr_err("%s: failed to register lookup for %s", __func__, name);
513
514 return clk;
515}
516
517/*
518 * PLL6553 Clock Type
519 */
520
521#define PLL6553_LOCK_REG 0x00
522#define PLL6553_CON0_REG 0x0c
523#define PLL6553_CON1_REG 0x10
524
525#define PLL6553_MDIV_MASK 0xff
526#define PLL6553_PDIV_MASK 0x3f
527#define PLL6553_SDIV_MASK 0x7
528#define PLL6553_KDIV_MASK 0xffff
529#define PLL6553_MDIV_SHIFT 16
530#define PLL6553_PDIV_SHIFT 8
531#define PLL6553_SDIV_SHIFT 0
532#define PLL6553_KDIV_SHIFT 0
533
534struct samsung_clk_pll6553 {
535 struct clk_hw hw;
536 void __iomem *reg_base;
537};
538
539#define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw)
540
541static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
542 unsigned long parent_rate)
543{
544 struct samsung_clk_pll6553 *pll = to_clk_pll6553(hw);
545 u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
546 u64 fvco = parent_rate;
547
548 pll_con0 = __raw_readl(pll->reg_base + PLL6553_CON0_REG);
549 pll_con1 = __raw_readl(pll->reg_base + PLL6553_CON1_REG);
550 mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
551 pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
552 sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
553 kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
554
555 fvco *= (mdiv << 16) + kdiv;
556 do_div(fvco, (pdiv << sdiv));
557 fvco >>= 16;
558
559 return (unsigned long)fvco;
560}
561
562static const struct clk_ops samsung_pll6553_clk_ops = {
563 .recalc_rate = samsung_pll6553_recalc_rate,
564};
565
566struct clk * __init samsung_clk_register_pll6553(const char *name,
567 const char *pname, void __iomem *base)
568{
569 struct samsung_clk_pll6553 *pll;
570 struct clk *clk;
571 struct clk_init_data init;
572
573 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
574 if (!pll) {
575 pr_err("%s: could not allocate pll clk %s\n", __func__, name);
576 return NULL;
577 }
578
579 init.name = name;
580 init.ops = &samsung_pll6553_clk_ops;
581 init.parent_names = &pname;
582 init.num_parents = 1;
583
584 pll->hw.init = &init;
585 pll->reg_base = base;
586
587 clk = clk_register(NULL, &pll->hw);
588 if (IS_ERR(clk)) {
589 pr_err("%s: failed to register pll clock %s\n", __func__,
590 name);
591 kfree(pll);
592 }
593
594 if (clk_register_clkdev(clk, name, NULL))
595 pr_err("%s: failed to register lookup for %s", __func__, name);
596
597 return clk;
598}
599
600/*
441 * PLL2550x Clock Type 601 * PLL2550x Clock Type
442 */ 602 */
443 603
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 95ae23d75b3c..2f70e88d6104 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -64,6 +64,10 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
64extern struct clk * __init samsung_clk_register_pll46xx(const char *name, 64extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
65 const char *pname, const void __iomem *con_reg, 65 const char *pname, const void __iomem *con_reg,
66 enum pll46xx_type type); 66 enum pll46xx_type type);
67extern struct clk *samsung_clk_register_pll6552(const char *name,
68 const char *pname, void __iomem *base);
69extern struct clk *samsung_clk_register_pll6553(const char *name,
70 const char *pname, void __iomem *base);
67extern struct clk * __init samsung_clk_register_pll2550x(const char *name, 71extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
68 const char *pname, const void __iomem *reg_base, 72 const char *pname, const void __iomem *reg_base,
69 const unsigned long offset); 73 const unsigned long offset);
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
new file mode 100644
index 000000000000..eeda5675bd17
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -0,0 +1,473 @@
1/*
2 * Copyright (c) 2013 Tomasz Figa <tomasz.figa at gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Common Clock Framework support for all S3C64xx SoCs.
9*/
10
11#include <linux/clk.h>
12#include <linux/clkdev.h>
13#include <linux/clk-provider.h>
14#include <linux/of.h>
15#include <linux/of_address.h>
16
17#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
18
19#include "clk.h"
20#include "clk-pll.h"
21
22/* S3C64xx clock controller register offsets. */
23#define APLL_LOCK 0x000
24#define MPLL_LOCK 0x004
25#define EPLL_LOCK 0x008
26#define APLL_CON 0x00c
27#define MPLL_CON 0x010
28#define EPLL_CON0 0x014
29#define EPLL_CON1 0x018
30#define CLK_SRC 0x01c
31#define CLK_DIV0 0x020
32#define CLK_DIV1 0x024
33#define CLK_DIV2 0x028
34#define HCLK_GATE 0x030
35#define PCLK_GATE 0x034
36#define SCLK_GATE 0x038
37#define MEM0_GATE 0x03c
38#define CLK_SRC2 0x10c
39#define OTHERS 0x900
40
41/* Helper macros to define clock arrays. */
42#define FIXED_RATE_CLOCKS(name) \
43 static struct samsung_fixed_rate_clock name[]
44#define MUX_CLOCKS(name) \
45 static struct samsung_mux_clock name[]
46#define DIV_CLOCKS(name) \
47 static struct samsung_div_clock name[]
48#define GATE_CLOCKS(name) \
49 static struct samsung_gate_clock name[]
50
51/* Helper macros for gate types present on S3C64xx. */
52#define GATE_BUS(_id, cname, pname, o, b) \
53 GATE(_id, cname, pname, o, b, 0, 0)
54#define GATE_SCLK(_id, cname, pname, o, b) \
55 GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT, 0)
56#define GATE_ON(_id, cname, pname, o, b) \
57 GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
58
59/* list of PLLs to be registered */
60enum s3c64xx_plls {
61 apll, mpll, epll,
62};
63
64/*
65 * List of controller registers to be saved and restored during
66 * a suspend/resume cycle.
67 */
68static __initdata unsigned long s3c64xx_clk_regs[] = {
69 APLL_LOCK,
70 MPLL_LOCK,
71 EPLL_LOCK,
72 APLL_CON,
73 MPLL_CON,
74 EPLL_CON0,
75 EPLL_CON1,
76 CLK_SRC,
77 CLK_DIV0,
78 CLK_DIV1,
79 CLK_DIV2,
80 HCLK_GATE,
81 PCLK_GATE,
82 SCLK_GATE,
83};
84
85static __initdata unsigned long s3c6410_clk_regs[] = {
86 CLK_SRC2,
87 MEM0_GATE,
88};
89
90/* List of parent clocks common for all S3C64xx SoCs. */
91PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" };
92PNAME(uart_p) = { "mout_epll", "dout_mpll" };
93PNAME(audio0_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk0",
94 "pcmcdclk0", "none", "none", "none" };
95PNAME(audio1_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1",
96 "pcmcdclk0", "none", "none", "none" };
97PNAME(mfc_p) = { "hclkx2", "mout_epll" };
98PNAME(apll_p) = { "fin_pll", "fout_apll" };
99PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
100PNAME(epll_p) = { "fin_pll", "fout_epll" };
101PNAME(hclkx2_p) = { "mout_mpll", "mout_apll" };
102
103/* S3C6400-specific parent clocks. */
104PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none", "none" };
105PNAME(irda_p6400) = { "mout_epll", "dout_mpll", "none", "clk48m" };
106PNAME(uhost_p6400) = { "clk48m", "mout_epll", "dout_mpll", "none" };
107
108/* S3C6410-specific parent clocks. */
109PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
110PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "none" };
111PNAME(irda_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "clk48m" };
112PNAME(uhost_p6410) = { "clk48m", "mout_epll", "dout_mpll", "fin_pll" };
113PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2",
114 "pcmcdclk1", "none", "none", "none" };
115
116/* Fixed rate clocks generated outside the SoC. */
117FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
118 FRATE(0, "fin_pll", NULL, CLK_IS_ROOT, 0),
119 FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
120};
121
122/* Fixed rate clocks generated inside the SoC. */
123FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
124 FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
125 FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
126};
127
128/* List of clock muxes present on all S3C64xx SoCs. */
129MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
130 MUX_F(0, "mout_syncmux", hclkx2_p, OTHERS, 6, 1, 0, CLK_MUX_READ_ONLY),
131 MUX(MOUT_APLL, "mout_apll", apll_p, CLK_SRC, 0, 1),
132 MUX(MOUT_MPLL, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
133 MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
134 MUX(MOUT_MFC, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
135 MUX(MOUT_AUDIO0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
136 MUX(MOUT_AUDIO1, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
137 MUX(MOUT_UART, "mout_uart", uart_p, CLK_SRC, 13, 1),
138 MUX(MOUT_SPI0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
139 MUX(MOUT_SPI1, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
140 MUX(MOUT_MMC0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
141 MUX(MOUT_MMC1, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
142 MUX(MOUT_MMC2, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
143};
144
145/* List of clock muxes present on S3C6400. */
146MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
147 MUX(MOUT_UHOST, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
148 MUX(MOUT_IRDA, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
149 MUX(MOUT_LCD, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
150 MUX(MOUT_SCALER, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
151};
152
153/* List of clock muxes present on S3C6410. */
154MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
155 MUX(MOUT_UHOST, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
156 MUX(MOUT_IRDA, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
157 MUX(MOUT_LCD, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
158 MUX(MOUT_SCALER, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
159 MUX(MOUT_DAC27, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
160 MUX(MOUT_TV27, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
161 MUX(MOUT_AUDIO2, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
162};
163
164/* List of clock dividers present on all S3C64xx SoCs. */
165DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
166 DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
167 DIV(HCLKX2, "hclkx2", "mout_syncmux", CLK_DIV0, 9, 3),
168 DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
169 DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
170 DIV(DOUT_SECUR, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
171 DIV(DOUT_CAM, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
172 DIV(DOUT_JPEG, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
173 DIV(DOUT_MFC, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
174 DIV(DOUT_MMC0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
175 DIV(DOUT_MMC1, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
176 DIV(DOUT_MMC2, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
177 DIV(DOUT_LCD, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
178 DIV(DOUT_SCALER, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
179 DIV(DOUT_UHOST, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
180 DIV(DOUT_SPI0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
181 DIV(DOUT_SPI1, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
182 DIV(DOUT_AUDIO0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
183 DIV(DOUT_AUDIO1, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
184 DIV(DOUT_UART, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
185 DIV(DOUT_IRDA, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
186};
187
188/* List of clock dividers present on S3C6400. */
189DIV_CLOCKS(s3c6400_div_clks) __initdata = {
190 DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
191};
192
193/* List of clock dividers present on S3C6410. */
194DIV_CLOCKS(s3c6410_div_clks) __initdata = {
195 DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
196 DIV(DOUT_FIMC, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
197 DIV(DOUT_AUDIO2, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
198};
199
200/* List of clock gates present on all S3C64xx SoCs. */
201GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
202 GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
203 GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
204 GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
205 GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
206 GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
207 GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
208 GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE, 19),
209 GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE, 18),
210 GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE, 17),
211 GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
212 GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
213 GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
214 GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
215 GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
216 GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
217 GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
218 GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE, 9),
219 GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
220 GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
221 GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
222 GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
223 GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
224 GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
225 GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
226 GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
227 GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE, 23),
228 GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
229 GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
230 GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
231 GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
232 GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
233 GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
234 GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
235 GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
236 GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
237 GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
238 GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
239 GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE, 11),
240 GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
241 GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
242 GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
243 GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
244 GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
245 GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
246 GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
247 GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
248 GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
249 GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
250 GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
251 GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost", SCLK_GATE, 30),
252 GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m", SCLK_GATE, 29),
253 GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48", "clk48m", SCLK_GATE, 28),
254 GATE_SCLK(SCLK_MMC0_48, "sclk_mmc0_48", "clk48m", SCLK_GATE, 27),
255 GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26),
256 GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25),
257 GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24),
258 GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE, 23),
259 GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m", SCLK_GATE, 22),
260 GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1", SCLK_GATE, 21),
261 GATE_SCLK(SCLK_SPI0, "sclk_spi0", "dout_spi0", SCLK_GATE, 20),
262 GATE_SCLK(SCLK_DAC27, "sclk_dac27", "mout_dac27", SCLK_GATE, 19),
263 GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18),
264 GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE, 17),
265 GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler", SCLK_GATE, 16),
266 GATE_SCLK(SCLK_LCD27, "sclk_lcd27", "clk27m", SCLK_GATE, 15),
267 GATE_SCLK(SCLK_LCD, "sclk_lcd", "dout_lcd", SCLK_GATE, 14),
268 GATE_SCLK(SCLK_POST0_27, "sclk_post0_27", "clk27m", SCLK_GATE, 12),
269 GATE_SCLK(SCLK_POST0, "sclk_post0", "dout_lcd", SCLK_GATE, 10),
270 GATE_SCLK(SCLK_AUDIO1, "sclk_audio1", "dout_audio1", SCLK_GATE, 9),
271 GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE, 8),
272 GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE, 7),
273 GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda", SCLK_GATE, 6),
274 GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart", SCLK_GATE, 5),
275 GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE, 3),
276 GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE, 2),
277 GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg", SCLK_GATE, 1),
278};
279
280/* List of clock gates present on S3C6400. */
281GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
282 GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
283 GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent", SCLK_GATE, 4),
284};
285
286/* List of clock gates present on S3C6410. */
287GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
288 GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
289 GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
290 GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
291 GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
292 GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
293 GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
294 GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
295 GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE, 13),
296 GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2", SCLK_GATE, 11),
297 GATE_BUS(MEM0_CFCON, "mem0_cfcon", "hclk_mem0", MEM0_GATE, 5),
298 GATE_BUS(MEM0_ONENAND1, "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4),
299 GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE, 3),
300 GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE, 2),
301 GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0", MEM0_GATE, 1),
302};
303
304/* List of PLL clocks. */
305static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = {
306 [apll] = PLL(pll_6552, FOUT_APLL, "fout_apll", "fin_pll",
307 APLL_LOCK, APLL_CON, NULL),
308 [mpll] = PLL(pll_6552, FOUT_MPLL, "fout_mpll", "fin_pll",
309 MPLL_LOCK, MPLL_CON, NULL),
310 [epll] = PLL(pll_6553, FOUT_EPLL, "fout_epll", "fin_pll",
311 EPLL_LOCK, EPLL_CON0, NULL),
312};
313
314/* Aliases for common s3c64xx clocks. */
315static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
316 ALIAS(FOUT_APLL, NULL, "fout_apll"),
317 ALIAS(FOUT_MPLL, NULL, "fout_mpll"),
318 ALIAS(FOUT_EPLL, NULL, "fout_epll"),
319 ALIAS(MOUT_EPLL, NULL, "mout_epll"),
320 ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
321 ALIAS(HCLKX2, NULL, "hclk2"),
322 ALIAS(HCLK, NULL, "hclk"),
323 ALIAS(PCLK, NULL, "pclk"),
324 ALIAS(PCLK, NULL, "clk_uart_baud2"),
325 ALIAS(ARMCLK, NULL, "armclk"),
326 ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
327 ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
328 ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
329 ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
330 ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
331 ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
332 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
333 ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
334 ALIAS(HCLK_DMA1, NULL, "dma1"),
335 ALIAS(HCLK_DMA0, NULL, "dma0"),
336 ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
337 ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
338 ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
339 ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
340 ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
341 ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
342 ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
343 ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
344 ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
345 ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
346 ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
347 ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
348 ALIAS(PCLK_PWM, NULL, "timers"),
349 ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
350 ALIAS(PCLK_WDT, NULL, "watchdog"),
351 ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
352 ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
353 ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
354 ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
355 ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
356 ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
357 ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
358 ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
359 ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
360 ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
361 ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
362 ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
363 ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
364 ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
365 ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
366 ALIAS(SCLK_CAM, "s3c-camif", "camera"),
367};
368
369/* Aliases for s3c6400-specific clocks. */
370static struct samsung_clock_alias s3c6400_clock_aliases[] = {
371 /* Nothing to place here yet. */
372};
373
374/* Aliases for s3c6410-specific clocks. */
375static struct samsung_clock_alias s3c6410_clock_aliases[] = {
376 ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
377 ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
378 ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
379 ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
380 ALIAS(MEM0_SROM, NULL, "srom"),
381};
382
383static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f,
384 unsigned long xusbxti_f)
385{
386 s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
387 s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
388 samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
389 ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks));
390}
391
392/* Register s3c64xx clocks. */
393void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
394 unsigned long xusbxti_f, bool is_s3c6400,
395 void __iomem *reg_base)
396{
397 unsigned long *soc_regs = NULL;
398 unsigned long nr_soc_regs = 0;
399
400 if (np) {
401 reg_base = of_iomap(np, 0);
402 if (!reg_base)
403 panic("%s: failed to map registers\n", __func__);
404 }
405
406 if (!is_s3c6400) {
407 soc_regs = s3c6410_clk_regs;
408 nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
409 }
410
411 samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
412 ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs);
413
414 /* Register external clocks. */
415 if (!np)
416 s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
417
418 /* Register PLLs. */
419 samsung_clk_register_pll(s3c64xx_pll_clks,
420 ARRAY_SIZE(s3c64xx_pll_clks), reg_base);
421
422 /* Register common internal clocks. */
423 samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
424 ARRAY_SIZE(s3c64xx_fixed_rate_clks));
425 samsung_clk_register_mux(s3c64xx_mux_clks,
426 ARRAY_SIZE(s3c64xx_mux_clks));
427 samsung_clk_register_div(s3c64xx_div_clks,
428 ARRAY_SIZE(s3c64xx_div_clks));
429 samsung_clk_register_gate(s3c64xx_gate_clks,
430 ARRAY_SIZE(s3c64xx_gate_clks));
431
432 /* Register SoC-specific clocks. */
433 if (is_s3c6400) {
434 samsung_clk_register_mux(s3c6400_mux_clks,
435 ARRAY_SIZE(s3c6400_mux_clks));
436 samsung_clk_register_div(s3c6400_div_clks,
437 ARRAY_SIZE(s3c6400_div_clks));
438 samsung_clk_register_gate(s3c6400_gate_clks,
439 ARRAY_SIZE(s3c6400_gate_clks));
440 samsung_clk_register_alias(s3c6400_clock_aliases,
441 ARRAY_SIZE(s3c6400_clock_aliases));
442 } else {
443 samsung_clk_register_mux(s3c6410_mux_clks,
444 ARRAY_SIZE(s3c6410_mux_clks));
445 samsung_clk_register_div(s3c6410_div_clks,
446 ARRAY_SIZE(s3c6410_div_clks));
447 samsung_clk_register_gate(s3c6410_gate_clks,
448 ARRAY_SIZE(s3c6410_gate_clks));
449 samsung_clk_register_alias(s3c6410_clock_aliases,
450 ARRAY_SIZE(s3c6410_clock_aliases));
451 }
452
453 samsung_clk_register_alias(s3c64xx_clock_aliases,
454 ARRAY_SIZE(s3c64xx_clock_aliases));
455
456 pr_info("%s clocks: apll = %lu, mpll = %lu\n"
457 "\tepll = %lu, arm_clk = %lu\n",
458 is_s3c6400 ? "S3C6400" : "S3C6410",
459 _get_rate("fout_apll"), _get_rate("fout_mpll"),
460 _get_rate("fout_epll"), _get_rate("armclk"));
461}
462
463static void __init s3c6400_clk_init(struct device_node *np)
464{
465 s3c64xx_clk_init(np, 0, 0, true, NULL);
466}
467CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock", s3c6400_clk_init);
468
469static void __init s3c6410_clk_init(struct device_node *np)
470{
471 s3c64xx_clk_init(np, 0, 0, false, NULL);
472}
473CLK_OF_DECLARE(s3c6410_clk, "samsung,s3c6410-clock", s3c6410_clk_init);
diff --git a/include/dt-bindings/clock/samsung,s3c64xx-clock.h b/include/dt-bindings/clock/samsung,s3c64xx-clock.h
new file mode 100644
index 000000000000..ad95c7f50090
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,s3c64xx-clock.h
@@ -0,0 +1,178 @@
1/*
2 * Copyright (c) 2013 Tomasz Figa <tomasz.figa at gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Device Tree binding constants for Samsung S3C64xx clock controller.
9*/
10
11#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
12#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
13
14/*
15 * Let each exported clock get a unique index, which is used on DT-enabled
16 * platforms to lookup the clock from a clock specifier. These indices are
17 * therefore considered an ABI and so must not be changed. This implies
18 * that new clocks should be added either in free spaces between clock groups
19 * or at the end.
20 */
21
22/* Core clocks. */
23#define CLK27M 1
24#define CLK48M 2
25#define FOUT_APLL 3
26#define FOUT_MPLL 4
27#define FOUT_EPLL 5
28#define ARMCLK 6
29#define HCLKX2 7
30#define HCLK 8
31#define PCLK 9
32
33/* HCLK bus clocks. */
34#define HCLK_3DSE 16
35#define HCLK_UHOST 17
36#define HCLK_SECUR 18
37#define HCLK_SDMA1 19
38#define HCLK_SDMA0 20
39#define HCLK_IROM 21
40#define HCLK_DDR1 22
41#define HCLK_MEM1 23
42#define HCLK_MEM0 24
43#define HCLK_USB 25
44#define HCLK_HSMMC2 26
45#define HCLK_HSMMC1 27
46#define HCLK_HSMMC0 28
47#define HCLK_MDP 29
48#define HCLK_DHOST 30
49#define HCLK_IHOST 31
50#define HCLK_DMA1 32
51#define HCLK_DMA0 33
52#define HCLK_JPEG 34
53#define HCLK_CAMIF 35
54#define HCLK_SCALER 36
55#define HCLK_2D 37
56#define HCLK_TV 38
57#define HCLK_POST0 39
58#define HCLK_ROT 40
59#define HCLK_LCD 41
60#define HCLK_TZIC 42
61#define HCLK_INTC 43
62#define HCLK_MFC 44
63#define HCLK_DDR0 45
64
65/* PCLK bus clocks. */
66#define PCLK_IIC1 48
67#define PCLK_IIS2 49
68#define PCLK_SKEY 50
69#define PCLK_CHIPID 51
70#define PCLK_SPI1 52
71#define PCLK_SPI0 53
72#define PCLK_HSIRX 54
73#define PCLK_HSITX 55
74#define PCLK_GPIO 56
75#define PCLK_IIC0 57
76#define PCLK_IIS1 58
77#define PCLK_IIS0 59
78#define PCLK_AC97 60
79#define PCLK_TZPC 61
80#define PCLK_TSADC 62
81#define PCLK_KEYPAD 63
82#define PCLK_IRDA 64
83#define PCLK_PCM1 65
84#define PCLK_PCM0 66
85#define PCLK_PWM 67
86#define PCLK_RTC 68
87#define PCLK_WDT 69
88#define PCLK_UART3 70
89#define PCLK_UART2 71
90#define PCLK_UART1 72
91#define PCLK_UART0 73
92#define PCLK_MFC 74
93
94/* Special clocks. */
95#define SCLK_UHOST 80
96#define SCLK_MMC2_48 81
97#define SCLK_MMC1_48 82
98#define SCLK_MMC0_48 83
99#define SCLK_MMC2 84
100#define SCLK_MMC1 85
101#define SCLK_MMC0 86
102#define SCLK_SPI1_48 87
103#define SCLK_SPI0_48 88
104#define SCLK_SPI1 89
105#define SCLK_SPI0 90
106#define SCLK_DAC27 91
107#define SCLK_TV27 92
108#define SCLK_SCALER27 93
109#define SCLK_SCALER 94
110#define SCLK_LCD27 95
111#define SCLK_LCD 96
112#define SCLK_FIMC 97
113#define SCLK_POST0_27 98
114#define SCLK_AUDIO2 99
115#define SCLK_POST0 100
116#define SCLK_AUDIO1 101
117#define SCLK_AUDIO0 102
118#define SCLK_SECUR 103
119#define SCLK_IRDA 104
120#define SCLK_UART 105
121#define SCLK_MFC 106
122#define SCLK_CAM 107
123#define SCLK_JPEG 108
124#define SCLK_ONENAND 109
125
126/* MEM0 bus clocks - S3C6410-specific. */
127#define MEM0_CFCON 112
128#define MEM0_ONENAND1 113
129#define MEM0_ONENAND0 114
130#define MEM0_NFCON 115
131#define MEM0_SROM 116
132
133/* Muxes. */
134#define MOUT_APLL 128
135#define MOUT_MPLL 129
136#define MOUT_EPLL 130
137#define MOUT_MFC 131
138#define MOUT_AUDIO0 132
139#define MOUT_AUDIO1 133
140#define MOUT_UART 134
141#define MOUT_SPI0 135
142#define MOUT_SPI1 136
143#define MOUT_MMC0 137
144#define MOUT_MMC1 138
145#define MOUT_MMC2 139
146#define MOUT_UHOST 140
147#define MOUT_IRDA 141
148#define MOUT_LCD 142
149#define MOUT_SCALER 143
150#define MOUT_DAC27 144
151#define MOUT_TV27 145
152#define MOUT_AUDIO2 146
153
154/* Dividers. */
155#define DOUT_MPLL 160
156#define DOUT_SECUR 161
157#define DOUT_CAM 162
158#define DOUT_JPEG 163
159#define DOUT_MFC 164
160#define DOUT_MMC0 165
161#define DOUT_MMC1 166
162#define DOUT_MMC2 167
163#define DOUT_LCD 168
164#define DOUT_SCALER 169
165#define DOUT_UHOST 170
166#define DOUT_SPI0 171
167#define DOUT_SPI1 172
168#define DOUT_AUDIO0 173
169#define DOUT_AUDIO1 174
170#define DOUT_UART 175
171#define DOUT_IRDA 176
172#define DOUT_FIMC 177
173#define DOUT_AUDIO2 178
174
175/* Total number of clocks. */
176#define NR_CLKS (DOUT_AUDIO2 + 1)
177
178#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H */
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 1ec14a732176..9487b96939e8 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -327,8 +327,10 @@ struct clk_mux {
327#define CLK_MUX_INDEX_ONE BIT(0) 327#define CLK_MUX_INDEX_ONE BIT(0)
328#define CLK_MUX_INDEX_BIT BIT(1) 328#define CLK_MUX_INDEX_BIT BIT(1)
329#define CLK_MUX_HIWORD_MASK BIT(2) 329#define CLK_MUX_HIWORD_MASK BIT(2)
330#define CLK_MUX_READ_ONLY BIT(3) /* mux setting cannot be changed */
330 331
331extern const struct clk_ops clk_mux_ops; 332extern const struct clk_ops clk_mux_ops;
333extern const struct clk_ops clk_mux_ro_ops;
332 334
333struct clk *clk_register_mux(struct device *dev, const char *name, 335struct clk *clk_register_mux(struct device *dev, const char *name,
334 const char **parent_names, u8 num_parents, unsigned long flags, 336 const char **parent_names, u8 num_parents, unsigned long flags,