diff options
author | Mike Turquette <mturquette@linaro.org> | 2013-08-05 14:59:06 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2013-08-08 18:57:26 -0400 |
commit | 5cfe9614f365915d9e75d110d4008b06a5c0b99e (patch) | |
tree | 5fb6c7c7541363e286a97557fd845051feb48feb | |
parent | 6f9a4894c435bc9919dab31d90f69167d4638997 (diff) | |
parent | 06dda9d770063c5fefc0b41c7bfcc1321e2649dd (diff) |
Merge branch 'clk-next-s3c64xx' into clk-next
-rw-r--r-- | Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt | 77 | ||||
-rw-r--r-- | drivers/clk/clk-mux.c | 10 | ||||
-rw-r--r-- | drivers/clk/samsung/Makefile | 3 | ||||
-rw-r--r-- | drivers/clk/samsung/clk-pll.c | 160 | ||||
-rw-r--r-- | drivers/clk/samsung/clk-pll.h | 4 | ||||
-rw-r--r-- | drivers/clk/samsung/clk-s3c64xx.c | 473 | ||||
-rw-r--r-- | include/dt-bindings/clock/samsung,s3c64xx-clock.h | 178 | ||||
-rw-r--r-- | include/linux/clk-provider.h | 2 |
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 | |||
3 | The S3C64xx clock controller generates and supplies clock to various controllers | ||
4 | within the SoC. The clock binding described here is applicable to all SoCs in | ||
5 | the S3C64xx family. | ||
6 | |||
7 | Required 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 | |||
18 | Each clock is assigned an identifier and client nodes can use this identifier | ||
19 | to specify the clock which they consume. Some of the clocks are available only | ||
20 | on a particular S3C64xx SoC and this is specified where applicable. | ||
21 | |||
22 | All available clocks are defined as preprocessor macros in | ||
23 | dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used in device | ||
24 | tree sources. | ||
25 | |||
26 | External clocks: | ||
27 | |||
28 | There are several clocks that are generated outside the SoC. It is expected | ||
29 | that they are defined using standard clock bindings with following | ||
30 | clock-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 | |||
39 | Example: Clock controller node: | ||
40 | |||
41 | clock: clock-controller@7e00f000 { | ||
42 | compatible = "samsung,s3c6410-clock"; | ||
43 | reg = <0x7e00f000 0x1000>; | ||
44 | #clock-cells = <1>; | ||
45 | }; | ||
46 | |||
47 | Example: 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 | |||
63 | Example: 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 | }; |
108 | EXPORT_SYMBOL_GPL(clk_mux_ops); | 108 | EXPORT_SYMBOL_GPL(clk_mux_ops); |
109 | 109 | ||
110 | const struct clk_ops clk_mux_ro_ops = { | ||
111 | .get_parent = clk_mux_get_parent, | ||
112 | }; | ||
113 | EXPORT_SYMBOL_GPL(clk_mux_ro_ops); | ||
114 | |||
110 | struct clk *clk_register_mux_table(struct device *dev, const char *name, | 115 | struct 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 | |||
8 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o | 8 | obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o |
9 | obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o | 9 | obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o |
10 | obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o | 10 | obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o |
11 | ifdef CONFIG_COMMON_CLK | ||
12 | obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o | ||
13 | endif | ||
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 | |||
454 | struct 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 | |||
461 | static 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 | |||
479 | static const struct clk_ops samsung_pll6552_clk_ops = { | ||
480 | .recalc_rate = samsung_pll6552_recalc_rate, | ||
481 | }; | ||
482 | |||
483 | struct 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 | |||
534 | struct 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 | |||
541 | static 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 | |||
562 | static const struct clk_ops samsung_pll6553_clk_ops = { | ||
563 | .recalc_rate = samsung_pll6553_recalc_rate, | ||
564 | }; | ||
565 | |||
566 | struct 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, | |||
64 | extern struct clk * __init samsung_clk_register_pll46xx(const char *name, | 64 | extern 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); |
67 | extern struct clk *samsung_clk_register_pll6552(const char *name, | ||
68 | const char *pname, void __iomem *base); | ||
69 | extern struct clk *samsung_clk_register_pll6553(const char *name, | ||
70 | const char *pname, void __iomem *base); | ||
67 | extern struct clk * __init samsung_clk_register_pll2550x(const char *name, | 71 | extern 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 */ | ||
60 | enum 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 | */ | ||
68 | static __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 | |||
85 | static __initdata unsigned long s3c6410_clk_regs[] = { | ||
86 | CLK_SRC2, | ||
87 | MEM0_GATE, | ||
88 | }; | ||
89 | |||
90 | /* List of parent clocks common for all S3C64xx SoCs. */ | ||
91 | PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" }; | ||
92 | PNAME(uart_p) = { "mout_epll", "dout_mpll" }; | ||
93 | PNAME(audio0_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk0", | ||
94 | "pcmcdclk0", "none", "none", "none" }; | ||
95 | PNAME(audio1_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1", | ||
96 | "pcmcdclk0", "none", "none", "none" }; | ||
97 | PNAME(mfc_p) = { "hclkx2", "mout_epll" }; | ||
98 | PNAME(apll_p) = { "fin_pll", "fout_apll" }; | ||
99 | PNAME(mpll_p) = { "fin_pll", "fout_mpll" }; | ||
100 | PNAME(epll_p) = { "fin_pll", "fout_epll" }; | ||
101 | PNAME(hclkx2_p) = { "mout_mpll", "mout_apll" }; | ||
102 | |||
103 | /* S3C6400-specific parent clocks. */ | ||
104 | PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none", "none" }; | ||
105 | PNAME(irda_p6400) = { "mout_epll", "dout_mpll", "none", "clk48m" }; | ||
106 | PNAME(uhost_p6400) = { "clk48m", "mout_epll", "dout_mpll", "none" }; | ||
107 | |||
108 | /* S3C6410-specific parent clocks. */ | ||
109 | PNAME(clk27_p6410) = { "clk27m", "fin_pll" }; | ||
110 | PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "none" }; | ||
111 | PNAME(irda_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "clk48m" }; | ||
112 | PNAME(uhost_p6410) = { "clk48m", "mout_epll", "dout_mpll", "fin_pll" }; | ||
113 | PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2", | ||
114 | "pcmcdclk1", "none", "none", "none" }; | ||
115 | |||
116 | /* Fixed rate clocks generated outside the SoC. */ | ||
117 | FIXED_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. */ | ||
123 | FIXED_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. */ | ||
129 | MUX_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. */ | ||
146 | MUX_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. */ | ||
154 | MUX_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. */ | ||
165 | DIV_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. */ | ||
189 | DIV_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. */ | ||
194 | DIV_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. */ | ||
201 | GATE_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. */ | ||
281 | GATE_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. */ | ||
287 | GATE_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. */ | ||
305 | static 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. */ | ||
315 | static 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. */ | ||
370 | static struct samsung_clock_alias s3c6400_clock_aliases[] = { | ||
371 | /* Nothing to place here yet. */ | ||
372 | }; | ||
373 | |||
374 | /* Aliases for s3c6410-specific clocks. */ | ||
375 | static 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 | |||
383 | static 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. */ | ||
393 | void __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 | |||
463 | static void __init s3c6400_clk_init(struct device_node *np) | ||
464 | { | ||
465 | s3c64xx_clk_init(np, 0, 0, true, NULL); | ||
466 | } | ||
467 | CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock", s3c6400_clk_init); | ||
468 | |||
469 | static void __init s3c6410_clk_init(struct device_node *np) | ||
470 | { | ||
471 | s3c64xx_clk_init(np, 0, 0, false, NULL); | ||
472 | } | ||
473 | CLK_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 | ||
331 | extern const struct clk_ops clk_mux_ops; | 332 | extern const struct clk_ops clk_mux_ops; |
333 | extern const struct clk_ops clk_mux_ro_ops; | ||
332 | 334 | ||
333 | struct clk *clk_register_mux(struct device *dev, const char *name, | 335 | struct 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, |