* [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx
@ 2013-06-05 23:57 Tomasz Figa
2013-06-05 23:57 ` [PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553 Tomasz Figa
` (7 more replies)
0 siblings, 8 replies; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This series is an attempt to move clock support on Samsung S3C64xx SoCs
to Common Clock Framework.
First, support for PLL types present on S3C64xx SoCs is added to Samsung
Common Clock Framework driver. Then the main clock driver for mentioned
SoCs is introduced. Further patches contain fixes for drivers to make them
compliant with CCF semantics, migration of platform code to use the new
clock driver and removal of old clock management code.
Depends on:
- [PATCH 0/6] Samsung watchdog support clean-up
http://thread.gmane.org/gmane.linux.kernel.samsung-soc/18736/focus=18989
- [PATCH 00/15] Final Samsung PWM support cleanup
http://www.spinics.net/lists/arm-kernel/msg248725.html
On S3C6410-based Tiny6410 board (Mini6410-compatible):
Tested-by: Tomasz Figa <tomasz.figa@gmail.com>
Tomasz Figa (7):
clk: samsung: pll: Add support for PLL6552 and PLL6553
clk: samsung: Add clock driver for S3C64xx SoCs
ARM: SAMSUNG: Add soc_is_s3c6400/s3c6410 macros
ARM: s3c64xx: dma: Use clk_prepare_enable/clk_disable_unprepare
usb: host: ohci-s3c2410 Use clk_prepare_enable/clk_disable_unprepare
ARM: s3c64xx: Migrate clock handling to Common Clock Framework
ARM: s3c64xx: Remove old clock management code
.../bindings/clock/samsung,s3c64xx-clock.txt | 48 +
arch/arm/Kconfig | 2 +-
arch/arm/mach-s3c64xx/Makefile | 2 +-
arch/arm/mach-s3c64xx/clock.c | 1007 --------------------
arch/arm/mach-s3c64xx/common.c | 21 +-
arch/arm/mach-s3c64xx/common.h | 12 +-
arch/arm/mach-s3c64xx/dma.c | 4 +-
arch/arm/mach-s3c64xx/include/mach/regs-clock.h | 132 +--
arch/arm/mach-s3c64xx/mach-anw6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-crag6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-hmt.c | 2 +-
arch/arm/mach-s3c64xx/mach-mini6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-ncp.c | 2 +-
arch/arm/mach-s3c64xx/mach-smartq.c | 11 +-
arch/arm/mach-s3c64xx/mach-smdk6400.c | 2 +-
arch/arm/mach-s3c64xx/mach-smdk6410.c | 2 +-
arch/arm/mach-s3c64xx/pm.c | 21 -
arch/arm/mach-s3c64xx/s3c6400.c | 6 -
arch/arm/mach-s3c64xx/s3c6410.c | 7 -
arch/arm/plat-samsung/include/plat/cpu.h | 4 +
drivers/clk/samsung/Makefile | 1 +
drivers/clk/samsung/clk-pll.c | 160 ++++
drivers/clk/samsung/clk-pll.h | 4 +
drivers/clk/samsung/clk-s3c64xx.c | 503 ++++++++++
drivers/usb/host/ohci-s3c2410.c | 8 +-
include/dt-bindings/clock/samsung,s3c64xx-clock.h | 144 +++
26 files changed, 907 insertions(+), 1204 deletions(-)
create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
delete mode 100644 arch/arm/mach-s3c64xx/clock.c
create mode 100644 drivers/clk/samsung/clk-s3c64xx.c
create mode 100644 include/dt-bindings/clock/samsung,s3c64xx-clock.h
--
1.8.2.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
@ 2013-06-05 23:57 ` Tomasz Figa
2013-06-12 2:53 ` Mike Turquette
2013-06-05 23:57 ` [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs Tomasz Figa
` (6 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds support for PLL6552 and PLL6553 PLLs present on Samsung
S3C64xx SoCs.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
drivers/clk/samsung/clk-pll.c | 160 ++++++++++++++++++++++++++++++++++++++++++
drivers/clk/samsung/clk-pll.h | 4 ++
2 files changed, 164 insertions(+)
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 89135f6..cef0bb9 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -336,6 +336,166 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
}
/*
+ * PLL6552 Clock Type
+ */
+
+#define PLL6552_LOCK_REG 0x00
+#define PLL6552_CON_REG 0x0c
+
+#define PLL6552_MDIV_MASK 0x3ff
+#define PLL6552_PDIV_MASK 0x3f
+#define PLL6552_SDIV_MASK 0x7
+#define PLL6552_MDIV_SHIFT 16
+#define PLL6552_PDIV_SHIFT 8
+#define PLL6552_SDIV_SHIFT 0
+
+struct samsung_clk_pll6552 {
+ struct clk_hw hw;
+ void __iomem *reg_base;
+};
+
+#define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw)
+
+static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw);
+ u32 mdiv, pdiv, sdiv, pll_con;
+ u64 fvco = parent_rate;
+
+ pll_con = __raw_readl(pll->reg_base + PLL6552_CON_REG);
+ mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
+ pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
+ sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll6552_clk_ops = {
+ .recalc_rate = samsung_pll6552_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll6552(const char *name,
+ const char *pname, void __iomem *base)
+{
+ struct samsung_clk_pll6552 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll6552_clk_ops;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->reg_base = base;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
+ * PLL6553 Clock Type
+ */
+
+#define PLL6553_LOCK_REG 0x00
+#define PLL6553_CON0_REG 0x0c
+#define PLL6553_CON1_REG 0x10
+
+#define PLL6553_MDIV_MASK 0xff
+#define PLL6553_PDIV_MASK 0x3f
+#define PLL6553_SDIV_MASK 0x7
+#define PLL6553_KDIV_MASK 0xffff
+#define PLL6553_MDIV_SHIFT 16
+#define PLL6553_PDIV_SHIFT 8
+#define PLL6553_SDIV_SHIFT 0
+#define PLL6553_KDIV_SHIFT 0
+
+struct samsung_clk_pll6553 {
+ struct clk_hw hw;
+ void __iomem *reg_base;
+};
+
+#define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw)
+
+static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct samsung_clk_pll6553 *pll = to_clk_pll6553(hw);
+ u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
+ u64 fvco = parent_rate;
+
+ pll_con0 = __raw_readl(pll->reg_base + PLL6553_CON0_REG);
+ pll_con1 = __raw_readl(pll->reg_base + PLL6553_CON1_REG);
+ mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
+ pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
+ sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
+ kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
+
+ fvco *= (mdiv << 16) + kdiv;
+ do_div(fvco, (pdiv << sdiv));
+ fvco >>= 16;
+
+ return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll6553_clk_ops = {
+ .recalc_rate = samsung_pll6553_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll6553(const char *name,
+ const char *pname, void __iomem *base)
+{
+ struct samsung_clk_pll6553 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll) {
+ pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+ return NULL;
+ }
+
+ init.name = name;
+ init.ops = &samsung_pll6553_clk_ops;
+ init.parent_names = &pname;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+ pll->reg_base = base;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register pll clock %s\n", __func__,
+ name);
+ kfree(pll);
+ }
+
+ if (clk_register_clkdev(clk, name, NULL))
+ pr_err("%s: failed to register lookup for %s", __func__, name);
+
+ return clk;
+}
+
+/*
* PLL2550x Clock Type
*/
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index f33786e..1d68a68 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -34,6 +34,10 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
const char *pname, const void __iomem *con_reg,
enum pll46xx_type type);
+extern struct clk *samsung_clk_register_pll6552(const char *name,
+ const char *pname, void __iomem *base);
+extern struct clk *samsung_clk_register_pll6553(const char *name,
+ const char *pname, void __iomem *base);
extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
const char *pname, const void __iomem *reg_base,
const unsigned long offset);
--
1.8.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
2013-06-05 23:57 ` [PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553 Tomasz Figa
@ 2013-06-05 23:57 ` Tomasz Figa
2013-06-12 2:54 ` Mike Turquette
2013-06-05 23:57 ` [PATCH 3/7] ARM: SAMSUNG: Add soc_is_s3c6400/s3c6410 macros Tomasz Figa
` (5 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds new, Common Clock Framework-based clock driver for Samsung
S3C64xx SoCs. The driver is just added, without actually letting the
platforms use it yet, since this requires more intermediate steps.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
.../bindings/clock/samsung,s3c64xx-clock.txt | 48 ++
drivers/clk/samsung/Makefile | 3 +
drivers/clk/samsung/clk-s3c64xx.c | 503 +++++++++++++++++++++
include/dt-bindings/clock/samsung,s3c64xx-clock.h | 144 ++++++
4 files changed, 698 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
create mode 100644 drivers/clk/samsung/clk-s3c64xx.c
create mode 100644 include/dt-bindings/clock/samsung,s3c64xx-clock.h
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 0000000..278ab6e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
@@ -0,0 +1,48 @@
+* Samsung S3C64xx Clock Controller
+
+The S3C64xx clock controller generates and supplies clock to various controllers
+within the SoC. The clock binding described here is applicable to all SoCs in
+the S3C64xx family.
+
+Required Properties:
+
+- comptible: should be one of the following.
+ - "samsung,s3c6400-clock" - controller compatible with S3C6400 SoC.
+ - "samsung,s3c6410-clock" - controller compatible with S3C6410 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+ region.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. Some of the clocks are available only
+on a particular S3C64xx SoC and this is specified where applicable.
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used in device
+tree sources.
+
+Example: Clock controller node:
+
+ clocks: clock-controller at 7e00f000 {
+ compatible = "samsung,s3c6410-clock";
+ reg = <0x7e00f000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+Example: UART controller node that consumes the clock generated by the clock
+ controller (refer to the standard clock bindings for information about
+ "clocks" and "clock-names" properties):
+
+ uart0: serial at 7f005000 {
+ compatible = "samsung,s3c6400-uart";
+ reg = <0x7f005000 0x100>;
+ interrupt-parent = <&vic1>;
+ interrupts = <5>;
+ clock-names = "uart", "clk_uart_baud2",
+ "clk_uart_baud3";
+ clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
+ <&clocks SCLK_UART>;
+ status = "disabled";
+ };
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index b7c232e..c023474 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -6,3 +6,6 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
+ifdef CONFIG_COMMON_CLK
+obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
+endif
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
new file mode 100644
index 0000000..253a972
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for all S3C64xx SoCs.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
+
+#include "clk.h"
+#include "clk-pll.h"
+
+/* S3C64xx clock controller register offsets. */
+#define APLL_LOCK 0x000
+#define MPLL_LOCK 0x004
+#define EPLL_LOCK 0x008
+#define APLL_CON 0x00c
+#define MPLL_CON 0x010
+#define EPLL_CON0 0x014
+#define EPLL_CON1 0x018
+#define CLK_SRC 0x01c
+#define CLK_DIV0 0x020
+#define CLK_DIV1 0x024
+#define CLK_DIV2 0x028
+#define HCLK_GATE 0x030
+#define PCLK_GATE 0x034
+#define SCLK_GATE 0x038
+#define MEM0_GATE 0x03c
+#define CLK_SRC2 0x10c
+#define OTHERS 0x900
+
+/* Special bitfields used in the driver. */
+#define OTHERS_SYNCMUXSEL (1 << 6)
+
+/* Helper macros to define clock arrays. */
+#define FIXED_RATE_CLOCKS(name) \
+ static struct samsung_fixed_rate_clock name[]
+#define MUX_CLOCKS(name) \
+ static struct samsung_mux_clock name[]
+#define DIV_CLOCKS(name) \
+ static struct samsung_div_clock name[]
+#define GATE_CLOCKS(name) \
+ static struct samsung_gate_clock name[]
+
+/* Helper macros for gate types present on S3C64xx. */
+#define GATE_BUS(_id, cname, pname, o, b) \
+ GATE(_id, cname, pname, o, b, 0, 0)
+#define GATE_SCLK(_id, cname, pname, o, b) \
+ GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT, 0)
+#define GATE_ON(_id, cname, pname, o, b) \
+ GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
+
+/*
+ * List of controller registers to be saved and restored during
+ * a suspend/resume cycle.
+ */
+static __initdata unsigned long s3c64xx_clk_regs[] = {
+ APLL_LOCK,
+ MPLL_LOCK,
+ EPLL_LOCK,
+ APLL_CON,
+ MPLL_CON,
+ EPLL_CON0,
+ EPLL_CON1,
+ CLK_SRC,
+ CLK_DIV0,
+ CLK_DIV1,
+ CLK_DIV2,
+ HCLK_GATE,
+ PCLK_GATE,
+ SCLK_GATE,
+};
+
+static __initdata unsigned long s3c6410_clk_regs[] = {
+ CLK_SRC2,
+ MEM0_GATE,
+};
+
+/* List of parent clocks common for all S3C64xx SoCs. */
+PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" };
+PNAME(uart_p) = { "mout_epll", "dout_mpll" };
+PNAME(audio0_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk0",
+ "pcmcdclk0", "none", "none", "none" };
+PNAME(audio1_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1",
+ "pcmcdclk0", "none", "none", "none" };
+PNAME(mfc_p) = { "hclkx2", "mout_epll" };
+PNAME(apll_p) = { "fin_pll", "fout_apll" };
+PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
+PNAME(epll_p) = { "fin_pll", "fout_epll" };
+
+/* S3C6400-specific parent clocks. */
+PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none", "none" };
+PNAME(irda_p6400) = { "mout_epll", "dout_mpll", "none", "clk48m" };
+PNAME(uhost_p6400) = { "clk48m", "mout_epll", "dout_mpll", "none" };
+
+/* S3C6410-specific parent clocks. */
+PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
+PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "none" };
+PNAME(irda_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "clk48m" };
+PNAME(uhost_p6410) = { "clk48m", "mout_epll", "dout_mpll", "fin_pll" };
+PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2",
+ "pcmcdclk1", "none", "none", "none" };
+
+/* Fixed rate clocks generated outside the SoC. */
+FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
+ FRATE(FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0),
+ FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
+};
+
+/* Fixed rate clocks generated inside the SoC. */
+FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
+ FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
+ FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* List of clock muxes present on all S3C64xx SoCs. */
+MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
+ MUX(0, "mout_apll", apll_p, CLK_SRC, 0, 1),
+ MUX(0, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
+ MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
+ MUX(0, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
+ MUX(0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
+ MUX(0, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
+ MUX(0, "mout_uart", uart_p, CLK_SRC, 13, 1),
+ MUX(0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
+ MUX(0, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
+ MUX(0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
+ MUX(0, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
+ MUX(0, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
+};
+
+/* List of clock muxes present on S3C6400. */
+MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
+ MUX(0, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
+ MUX(0, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
+ MUX(0, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
+ MUX(0, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
+};
+
+/* List of clock muxes present on S3C6410. */
+MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
+ MUX(0, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
+ MUX(0, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
+ MUX(0, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
+ MUX(0, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
+ MUX(0, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
+ MUX(0, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
+ MUX(0, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
+};
+
+/* List of clock dividers present on all S3C64xx SoCs. */
+DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
+ DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
+ DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
+ DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
+ DIV(0, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
+ DIV(0, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
+ DIV(0, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
+ DIV(0, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
+ DIV(0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
+ DIV(0, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
+ DIV(0, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
+ DIV(0, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
+ DIV(0, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
+ DIV(0, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
+ DIV(0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
+ DIV(0, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
+ DIV(0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
+ DIV(0, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
+ DIV(0, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
+ DIV(0, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
+};
+
+/* List of clock dividers present on S3C6400. */
+DIV_CLOCKS(s3c6400_div_clks) __initdata = {
+ DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
+};
+
+/* List of clock dividers present on S3C6410. */
+DIV_CLOCKS(s3c6410_div_clks) __initdata = {
+ DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
+ DIV(0, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
+ DIV(0, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
+};
+
+/* List of clock gates present on all S3C64xx SoCs. */
+GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
+ GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
+ GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
+ GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
+ GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
+ GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
+ GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
+ GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE, 19),
+ GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE, 18),
+ GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE, 17),
+ GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
+ GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
+ GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
+ GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
+ GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
+ GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
+ GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
+ GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE, 9),
+ GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
+ GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
+ GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
+ GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
+ GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
+ GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
+ GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
+ GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
+ GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE, 23),
+ GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
+ GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
+ GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
+ GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
+ GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
+ GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
+ GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
+ GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
+ GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
+ GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
+ GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
+ GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE, 11),
+ GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
+ GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
+ GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
+ GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
+ GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
+ GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
+ GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
+ GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
+ GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
+ GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
+ GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
+ GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost", SCLK_GATE, 30),
+ GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m", SCLK_GATE, 29),
+ GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48", "clk48m", SCLK_GATE, 28),
+ GATE_SCLK(SCLK_MMC0_48, "sclk_mmc0_48", "clk48m", SCLK_GATE, 27),
+ GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26),
+ GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25),
+ GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24),
+ GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE, 23),
+ GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m", SCLK_GATE, 22),
+ GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1", SCLK_GATE, 21),
+ GATE_SCLK(SCLK_SPI0, "sclk_spi0", "dout_spi0", SCLK_GATE, 20),
+ GATE_SCLK(SCLK_DAC27, "sclk_dac27", "mout_dac27", SCLK_GATE, 19),
+ GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18),
+ GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE, 17),
+ GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler", SCLK_GATE, 16),
+ GATE_SCLK(SCLK_LCD27, "sclk_lcd27", "clk27m", SCLK_GATE, 15),
+ GATE_SCLK(SCLK_LCD, "sclk_lcd", "dout_lcd", SCLK_GATE, 14),
+ GATE_SCLK(SCLK_POST0_27, "sclk_post0_27", "clk27m", SCLK_GATE, 12),
+ GATE_SCLK(SCLK_POST0, "sclk_post0", "dout_lcd", SCLK_GATE, 10),
+ GATE_SCLK(SCLK_AUDIO1, "sclk_audio1", "dout_audio1", SCLK_GATE, 9),
+ GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE, 8),
+ GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE, 7),
+ GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda", SCLK_GATE, 6),
+ GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart", SCLK_GATE, 5),
+ GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE, 3),
+ GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE, 2),
+ GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg", SCLK_GATE, 1),
+};
+
+/* List of clock gates present on S3C6400. */
+GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
+ GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
+ GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent", SCLK_GATE, 4),
+};
+
+/* List of clock gates present on S3C6410. */
+GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
+ GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
+ GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
+ GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
+ GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
+ GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
+ GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
+ GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
+ GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE, 13),
+ GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2", SCLK_GATE, 11),
+ GATE_BUS(MEM0_CFCON, "mem0_cfcon", "hclk_mem0", MEM0_GATE, 5),
+ GATE_BUS(MEM0_ONENAND1, "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4),
+ GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE, 3),
+ GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE, 2),
+ GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0", MEM0_GATE, 1),
+};
+
+/* Aliases for common s3c64xx clocks. */
+static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
+ ALIAS(MOUT_EPLL, NULL, "mout_epll"),
+ ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
+ ALIAS(HCLKX2, NULL, "hclk2"),
+ ALIAS(HCLK, NULL, "hclk"),
+ ALIAS(PCLK, NULL, "pclk"),
+ ALIAS(PCLK, NULL, "clk_uart_baud2"),
+ ALIAS(ARMCLK, NULL, "armclk"),
+ ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
+ ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
+ ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
+ ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
+ ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
+ ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
+ ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
+ ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
+ ALIAS(HCLK_DMA1, NULL, "dma1"),
+ ALIAS(HCLK_DMA0, NULL, "dma0"),
+ ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
+ ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
+ ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
+ ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
+ ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
+ ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
+ ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
+ ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
+ ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
+ ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
+ ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
+ ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
+ ALIAS(PCLK_PWM, NULL, "timers"),
+ ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
+ ALIAS(PCLK_WDT, NULL, "watchdog"),
+ ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
+ ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
+ ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
+ ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
+ ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
+ ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
+ ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
+ ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
+ ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
+ ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
+ ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
+ ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
+ ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
+ ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
+ ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
+ ALIAS(SCLK_CAM, "s3c-camif", "camera"),
+};
+
+/* Aliases for s3c6400-specific clocks. */
+static struct samsung_clock_alias s3c6400_clock_aliases[] = {
+ /* Nothing to place here yet. */
+};
+
+/* Aliases for s3c6410-specific clocks. */
+static struct samsung_clock_alias s3c6410_clock_aliases[] = {
+ ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
+ ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
+ ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
+ ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
+ ALIAS(MEM0_SROM, NULL, "srom"),
+};
+
+/*
+ * Parent of the hclkx2 clock depends on whether the SoC is operating in
+ * synchronous or asynchronous mode. Depending on value of OTHERS[6]
+ * (SYNCMUXSEL) bit, it can be either mout_mpll or mout_apll.
+ */
+static void __init s3c64xx_clk_register_hclkx2(void __iomem *reg_base)
+{
+ struct samsung_div_clock hclkx2;
+ u32 others;
+
+ memset(&hclkx2, 0, sizeof(hclkx2));
+
+ hclkx2.id = HCLKX2;
+ hclkx2.name = "hclkx2";
+ hclkx2.offset = CLK_DIV0;
+ hclkx2.shift = 9;
+ hclkx2.width = 3;
+
+ others = readl(reg_base + OTHERS);
+ if (others & OTHERS_SYNCMUXSEL)
+ hclkx2.parent_name = "mout_apll";
+ else
+ hclkx2.parent_name = "mout_mpll";
+
+ samsung_clk_register_div(&hclkx2, 1);
+}
+
+static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f,
+ unsigned long xusbxti_f)
+{
+ s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
+ s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
+ samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
+ ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks));
+}
+
+static __initdata struct of_device_id ext_clk_match[] = {
+ { .compatible = "samsung,clock-fin-pll", .data = (void *)0, },
+ { .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
+ {},
+};
+
+/* Register s3c64xx clocks. */
+void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
+ unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base)
+{
+ struct clk *clk;
+ unsigned long *soc_regs = NULL;
+ unsigned long nr_soc_regs = 0;
+
+ if (np) {
+ reg_base = of_iomap(np, 0);
+ if (!reg_base)
+ panic("%s: failed to map registers\n", __func__);
+ }
+
+ if (!is_s3c6400) {
+ soc_regs = s3c6410_clk_regs;
+ nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
+ }
+
+ samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
+ ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs);
+
+ /* Register external clocks. */
+ if (np)
+ samsung_clk_of_register_fixed_ext(s3c64xx_fixed_rate_ext_clks,
+ ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks),
+ ext_clk_match);
+ else
+ s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
+
+ /* Register PLLs. */
+ clk = samsung_clk_register_pll6552("fout_apll",
+ "fin_pll", reg_base + APLL_LOCK);
+ samsung_clk_add_lookup(clk, FOUT_APLL);
+
+ clk = samsung_clk_register_pll6552("fout_mpll",
+ "fin_pll", reg_base + MPLL_LOCK);
+ samsung_clk_add_lookup(clk, FOUT_MPLL);
+
+ clk = samsung_clk_register_pll6553("fout_epll",
+ "fin_pll", reg_base + EPLL_LOCK);
+ samsung_clk_add_lookup(clk, FOUT_EPLL);
+
+ /* Register common internal clocks. */
+ s3c64xx_clk_register_hclkx2(reg_base);
+
+ samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
+ ARRAY_SIZE(s3c64xx_fixed_rate_clks));
+ samsung_clk_register_mux(s3c64xx_mux_clks,
+ ARRAY_SIZE(s3c64xx_mux_clks));
+ samsung_clk_register_div(s3c64xx_div_clks,
+ ARRAY_SIZE(s3c64xx_div_clks));
+ samsung_clk_register_gate(s3c64xx_gate_clks,
+ ARRAY_SIZE(s3c64xx_gate_clks));
+
+ /* Register SoC-specific clocks. */
+ if (is_s3c6400) {
+ samsung_clk_register_mux(s3c6400_mux_clks,
+ ARRAY_SIZE(s3c6400_mux_clks));
+ samsung_clk_register_div(s3c6400_div_clks,
+ ARRAY_SIZE(s3c6400_div_clks));
+ samsung_clk_register_gate(s3c6400_gate_clks,
+ ARRAY_SIZE(s3c6400_gate_clks));
+ samsung_clk_register_alias(s3c6400_clock_aliases,
+ ARRAY_SIZE(s3c6400_clock_aliases));
+ } else {
+ samsung_clk_register_mux(s3c6410_mux_clks,
+ ARRAY_SIZE(s3c6410_mux_clks));
+ samsung_clk_register_div(s3c6410_div_clks,
+ ARRAY_SIZE(s3c6410_div_clks));
+ samsung_clk_register_gate(s3c6410_gate_clks,
+ ARRAY_SIZE(s3c6410_gate_clks));
+ samsung_clk_register_alias(s3c6410_clock_aliases,
+ ARRAY_SIZE(s3c6410_clock_aliases));
+ }
+
+ samsung_clk_register_alias(s3c64xx_clock_aliases,
+ ARRAY_SIZE(s3c64xx_clock_aliases));
+
+ pr_info("%s clocks: apll = %lu, mpll = %lu\n"
+ "\tepll = %lu, arm_clk = %lu\n",
+ is_s3c6400 ? "S3C6400" : "S3C6410",
+ _get_rate("fout_apll"), _get_rate("fout_mpll"),
+ _get_rate("fout_epll"), _get_rate("armclk"));
+}
+
+static void __init s3c6400_clk_init(struct device_node *np)
+{
+ s3c64xx_clk_init(np, 0, 0, true, NULL);
+}
+CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock", s3c6400_clk_init);
+
+static void __init s3c6410_clk_init(struct device_node *np)
+{
+ s3c64xx_clk_init(np, 0, 0, false, NULL);
+}
+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 0000000..3e9a1f9
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,s3c64xx-clock.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Device Tree binding constants for Samsung S3C64xx clock controller.
+*/
+
+#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
+#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
+
+/*
+ * Let each exported clock get a unique index, which is used on DT-enabled
+ * platforms to lookup the clock from a clock specifier. These indices are
+ * therefore considered an ABI and so must not be changed. This implies
+ * that new clocks should be added either in free spaces between clock groups
+ * or at the end.
+ */
+
+/* Core clocks. */
+#define IISCDCLK0 3
+#define PCMCDCLK0 4
+#define IISCDCLK1 5
+#define PCMCDCLK1 6
+#define IISCDCLK2 7
+#define CLK27M 8
+#define CLK48M 9
+#define FIN_PLL 10
+#define FOUT_APLL 11
+#define FOUT_MPLL 12
+#define FOUT_EPLL 13
+#define ARMCLK 14
+#define HCLKX2 15
+#define HCLK 16
+#define PCLK 17
+#define MOUT_EPLL 18
+#define DOUT_MPLL 19
+
+/* HCLK bus clocks. */
+#define HCLK_3DSE 32
+#define HCLK_UHOST 33
+#define HCLK_SECUR 34
+#define HCLK_SDMA1 35
+#define HCLK_SDMA0 36
+#define HCLK_IROM 37
+#define HCLK_DDR1 38
+#define HCLK_MEM1 39
+#define HCLK_MEM0 40
+#define HCLK_USB 41
+#define HCLK_HSMMC2 42
+#define HCLK_HSMMC1 43
+#define HCLK_HSMMC0 44
+#define HCLK_MDP 45
+#define HCLK_DHOST 46
+#define HCLK_IHOST 47
+#define HCLK_DMA1 48
+#define HCLK_DMA0 49
+#define HCLK_JPEG 50
+#define HCLK_CAMIF 51
+#define HCLK_SCALER 52
+#define HCLK_2D 53
+#define HCLK_TV 54
+#define HCLK_POST0 55
+#define HCLK_ROT 56
+#define HCLK_LCD 57
+#define HCLK_TZIC 58
+#define HCLK_INTC 59
+#define HCLK_MFC 60
+#define HCLK_DDR0 61
+
+/* PCLK bus clocks. */
+#define PCLK_IIC1 64
+#define PCLK_IIS2 65
+#define PCLK_SKEY 66
+#define PCLK_CHIPID 67
+#define PCLK_SPI1 68
+#define PCLK_SPI0 69
+#define PCLK_HSIRX 70
+#define PCLK_HSITX 71
+#define PCLK_GPIO 72
+#define PCLK_IIC0 73
+#define PCLK_IIS1 74
+#define PCLK_IIS0 75
+#define PCLK_AC97 76
+#define PCLK_TZPC 77
+#define PCLK_TSADC 78
+#define PCLK_KEYPAD 79
+#define PCLK_IRDA 80
+#define PCLK_PCM1 81
+#define PCLK_PCM0 82
+#define PCLK_PWM 83
+#define PCLK_RTC 84
+#define PCLK_WDT 85
+#define PCLK_UART3 86
+#define PCLK_UART2 87
+#define PCLK_UART1 88
+#define PCLK_UART0 89
+#define PCLK_MFC 90
+
+/* Special clocks. */
+#define SCLK_UHOST 96
+#define SCLK_MMC2_48 97
+#define SCLK_MMC1_48 98
+#define SCLK_MMC0_48 99
+#define SCLK_MMC2 100
+#define SCLK_MMC1 101
+#define SCLK_MMC0 102
+#define SCLK_SPI1_48 103
+#define SCLK_SPI0_48 104
+#define SCLK_SPI1 105
+#define SCLK_SPI0 106
+#define SCLK_DAC27 107
+#define SCLK_TV27 108
+#define SCLK_SCALER27 109
+#define SCLK_SCALER 110
+#define SCLK_LCD27 111
+#define SCLK_LCD 112
+#define SCLK_FIMC 113
+#define SCLK_POST0_27 114
+#define SCLK_AUDIO2 115
+#define SCLK_POST0 116
+#define SCLK_AUDIO1 117
+#define SCLK_AUDIO0 118
+#define SCLK_SECUR 119
+#define SCLK_IRDA 120
+#define SCLK_UART 121
+#define SCLK_MFC 122
+#define SCLK_CAM 123
+#define SCLK_JPEG 124
+#define SCLK_ONENAND 125
+
+/* MEM0 bus clocks - S3C6410-specific. */
+#define MEM0_CFCON 128
+#define MEM0_ONENAND1 129
+#define MEM0_ONENAND0 130
+#define MEM0_NFCON 131
+#define MEM0_SROM 132
+
+/* Total number of clocks. */
+#define NR_CLKS (MEM0_SROM + 1)
+
+#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H */
--
1.8.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/7] ARM: SAMSUNG: Add soc_is_s3c6400/s3c6410 macros
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
2013-06-05 23:57 ` [PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553 Tomasz Figa
2013-06-05 23:57 ` [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs Tomasz Figa
@ 2013-06-05 23:57 ` Tomasz Figa
2013-06-05 23:57 ` [PATCH 4/7] ARM: s3c64xx: dma: Use clk_prepare_enable/clk_disable_unprepare Tomasz Figa
` (4 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds soc_is_s3c6400() and soc_is_s3c6410() macros that allow
to distinguish between specific SoCs from s3c64xx series that is needed
to handle differences between them.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
arch/arm/plat-samsung/include/plat/cpu.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 989fefe..8e55196 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -85,8 +85,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
#endif
#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
+# define soc_is_s3c6400() is_samsung_s3c6400()
+# define soc_is_s3c6410() is_samsung_s3c6410()
# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410())
#else
+# define soc_is_s3c6400() 0
+# define soc_is_s3c6410() 0
# define soc_is_s3c64xx() 0
#endif
--
1.8.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/7] ARM: s3c64xx: dma: Use clk_prepare_enable/clk_disable_unprepare
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
` (2 preceding siblings ...)
2013-06-05 23:57 ` [PATCH 3/7] ARM: SAMSUNG: Add soc_is_s3c6400/s3c6410 macros Tomasz Figa
@ 2013-06-05 23:57 ` Tomasz Figa
2013-06-05 23:57 ` [PATCH 5/7] usb: host: ohci-s3c2410 " Tomasz Figa
` (3 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This patch modifies s3c64xx DMA driver to prepare and unprepare clocks
in addition to enableind and disabling, since it is required by common
clock framework.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
arch/arm/mach-s3c64xx/dma.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c
index 759846c..c511dfa 100644
--- a/arch/arm/mach-s3c64xx/dma.c
+++ b/arch/arm/mach-s3c64xx/dma.c
@@ -677,7 +677,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
goto err_map;
}
- clk_enable(dmac->clk);
+ clk_prepare_enable(dmac->clk);
dmac->regs = regs;
dmac->chanbase = chbase;
@@ -711,7 +711,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
return 0;
err_clk:
- clk_disable(dmac->clk);
+ clk_disable_unprepare(dmac->clk);
clk_put(dmac->clk);
err_map:
iounmap(regs);
--
1.8.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/7] usb: host: ohci-s3c2410 Use clk_prepare_enable/clk_disable_unprepare
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
` (3 preceding siblings ...)
2013-06-05 23:57 ` [PATCH 4/7] ARM: s3c64xx: dma: Use clk_prepare_enable/clk_disable_unprepare Tomasz Figa
@ 2013-06-05 23:57 ` Tomasz Figa
2013-06-05 23:57 ` [PATCH 6/7] ARM: s3c64xx: Migrate clock handling to Common Clock Framework Tomasz Figa
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This patch modifies the ohci-s3c2410 driver to prepare and unprepare
clocks in addition to enabling and disabling, since it is required
by common clock framework.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
drivers/usb/host/ohci-s3c2410.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index e125770..db096bf 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -47,10 +47,10 @@ static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)
dev_dbg(&dev->dev, "s3c2410_start_hc:\n");
- clk_enable(usb_clk);
+ clk_prepare_enable(usb_clk);
mdelay(2); /* let the bus clock stabilise */
- clk_enable(clk);
+ clk_prepare_enable(clk);
if (info != NULL) {
info->hcd = hcd;
@@ -75,8 +75,8 @@ static void s3c2410_stop_hc(struct platform_device *dev)
(info->enable_oc)(info, 0);
}
- clk_disable(clk);
- clk_disable(usb_clk);
+ clk_disable_unprepare(clk);
+ clk_disable_unprepare(usb_clk);
}
/* ohci_s3c2410_hub_status_data
--
1.8.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 6/7] ARM: s3c64xx: Migrate clock handling to Common Clock Framework
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
` (4 preceding siblings ...)
2013-06-05 23:57 ` [PATCH 5/7] usb: host: ohci-s3c2410 " Tomasz Figa
@ 2013-06-05 23:57 ` Tomasz Figa
2013-06-05 23:57 ` [PATCH 7/7] ARM: s3c64xx: Remove old clock management code Tomasz Figa
2013-06-19 14:17 ` [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Kukjin Kim
7 siblings, 0 replies; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This patch migrates the s3c64xx platform to use the new clock driver
using Common Clock Framework.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
arch/arm/Kconfig | 2 +-
arch/arm/mach-s3c64xx/Makefile | 2 +-
arch/arm/mach-s3c64xx/common.c | 21 +++++++++++++++++----
arch/arm/mach-s3c64xx/common.h | 10 +++++-----
arch/arm/mach-s3c64xx/mach-anw6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-crag6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-hmt.c | 2 +-
arch/arm/mach-s3c64xx/mach-mini6410.c | 2 +-
arch/arm/mach-s3c64xx/mach-ncp.c | 2 +-
arch/arm/mach-s3c64xx/mach-smartq.c | 11 ++---------
arch/arm/mach-s3c64xx/mach-smdk6400.c | 2 +-
arch/arm/mach-s3c64xx/mach-smdk6410.c | 2 +-
arch/arm/mach-s3c64xx/s3c6400.c | 6 ------
arch/arm/mach-s3c64xx/s3c6410.c | 7 -------
drivers/clk/samsung/Makefile | 2 --
15 files changed, 33 insertions(+), 42 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 64d3ff9..5d29ae9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -717,6 +717,7 @@ config ARCH_S3C64XX
select ARM_VIC
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select COMMON_CLK
select CPU_V6
select GENERIC_CLOCKEVENTS
select HAVE_CLK
@@ -728,7 +729,6 @@ config ARCH_S3C64XX
select PLAT_SAMSUNG
select S3C_DEV_NAND
select S3C_GPIO_TRACK
- select SAMSUNG_CLKSRC
select SAMSUNG_GPIOLIB_4BIT
select SAMSUNG_WDT_RESET
select USB_ARCH_HAS_OHCI
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 31d0c91..645a8fe 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -12,7 +12,7 @@ obj- :=
# Core
-obj-y += common.o clock.o
+obj-y += common.o
# Core support
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index 0b33683..bf00e60 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/clk-provider.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/serial_core.h>
@@ -37,7 +38,6 @@
#include <mach/regs-gpio.h>
#include <plat/cpu.h>
-#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/pm.h>
#include <plat/gpio-cfg.h>
@@ -49,6 +49,19 @@
#include "common.h"
+/* External clock frequency */
+static unsigned long xtal_f = 12000000, xusbxti_f = 48000000;
+
+void __init s3c64xx_set_xtal_freq(unsigned long freq)
+{
+ xtal_f = freq;
+}
+
+void __init s3c64xx_set_xusbxti_freq(unsigned long freq)
+{
+ xusbxti_f = freq;
+}
+
/* uart registration process */
static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
@@ -66,7 +79,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = S3C6400_CPU_ID,
.idmask = S3C64XX_CPU_MASK,
.map_io = s3c6400_map_io,
- .init_clocks = s3c6400_init_clocks,
.init_uarts = s3c64xx_init_uarts,
.init = s3c6400_init,
.name = name_s3c6400,
@@ -74,7 +86,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.idcode = S3C6410_CPU_ID,
.idmask = S3C64XX_CPU_MASK,
.map_io = s3c6410_map_io,
- .init_clocks = s3c6410_init_clocks,
.init_uarts = s3c64xx_init_uarts,
.init = s3c6410_init,
.name = name_s3c6410,
@@ -212,8 +223,10 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
{
/*
* FIXME: there is no better place to put this at the moment
- * (samsung_wdt_reset_init needs clocks)
+ * (s3c64xx_clk_init needs ioremap and must happen before init_time
+ * samsung_wdt_reset_init needs clocks)
*/
+ s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS);
samsung_wdt_reset_init(S3C_VA_WATCHDOG);
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h
index 6cfc99b..76ce4fe 100644
--- a/arch/arm/mach-s3c64xx/common.h
+++ b/arch/arm/mach-s3c64xx/common.h
@@ -20,18 +20,19 @@
void s3c64xx_init_irq(u32 vic0, u32 vic1);
void s3c64xx_init_io(struct map_desc *mach_desc, int size);
-void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
-void s3c64xx_setup_clocks(void);
-
void s3c64xx_restart(char mode, const char *cmd);
void s3c64xx_init_late(void);
+void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
+ unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base);
+void s3c64xx_set_xtal_freq(unsigned long freq);
+void s3c64xx_set_xusbxti_freq(unsigned long freq);
+
#ifdef CONFIG_CPU_S3C6400
extern int s3c6400_init(void);
extern void s3c6400_init_irq(void);
extern void s3c6400_map_io(void);
-extern void s3c6400_init_clocks(int xtal);
#else
#define s3c6400_init_clocks NULL
@@ -44,7 +45,6 @@ extern void s3c6400_init_clocks(int xtal);
extern int s3c6410_init(void);
extern void s3c6410_init_irq(void);
extern void s3c6410_map_io(void);
-extern void s3c6410_init_clocks(int xtal);
#else
#define s3c6410_init_clocks NULL
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index 35e3f54..d266dd5 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -207,7 +207,7 @@ static struct platform_device *anw6410_devices[] __initdata = {
static void __init anw6410_map_io(void)
{
s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 28889cc..4d92e4d 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -743,7 +743,7 @@ static struct s3c2410_platform_i2c i2c1_pdata = {
static void __init crag6410_map_io(void)
{
s3c64xx_init_io(NULL, 0);
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index f39569e..e806404 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -247,7 +247,7 @@ static struct platform_device *hmt_devices[] __initdata = {
static void __init hmt_map_io(void)
{
s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
}
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index 87f406e..3cceda2 100644
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -231,7 +231,7 @@ static void __init mini6410_map_io(void)
u32 tmp;
s3c64xx_init_io(NULL, 0);
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index 7e2c390..2067b0b 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -86,7 +86,7 @@ static struct map_desc ncp_iodesc[] __initdata = {};
static void __init ncp_map_io(void)
{
s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
}
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
index 86d980b..0f47237 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -337,13 +337,6 @@ err:
return ret;
}
-static int __init smartq_usb_otg_init(void)
-{
- clk_xusbxti.rate = 12000000;
-
- return 0;
-}
-
static int __init smartq_wifi_init(void)
{
int ret;
@@ -377,7 +370,8 @@ static struct map_desc smartq_iodesc[] __initdata = {};
void __init smartq_map_io(void)
{
s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc));
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
+ s3c64xx_set_xusbxti_freq(12000000);
s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
@@ -399,7 +393,6 @@ void __init smartq_machine_init(void)
WARN_ON(smartq_lcd_setup_gpio());
WARN_ON(smartq_power_off_init());
WARN_ON(smartq_usb_host_init());
- WARN_ON(smartq_usb_otg_init());
WARN_ON(smartq_wifi_init());
platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
index d70c084..27381cf 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6400.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -65,7 +65,7 @@ static struct map_desc smdk6400_iodesc[] = {};
static void __init smdk6400_map_io(void)
{
s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
}
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 2b54ba0..590a624 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -634,7 +634,7 @@ static void __init smdk6410_map_io(void)
u32 tmp;
s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
- s3c24xx_init_clocks(12000000);
+ s3c64xx_set_xtal_freq(12000000);
s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c
index 4869714..331fe8e 100644
--- a/arch/arm/mach-s3c64xx/s3c6400.c
+++ b/arch/arm/mach-s3c64xx/s3c6400.c
@@ -58,12 +58,6 @@ void __init s3c6400_map_io(void)
s3c64xx_onenand1_setname("s3c6400-onenand");
}
-void __init s3c6400_init_clocks(int xtal)
-{
- s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK);
- s3c64xx_setup_clocks();
-}
-
void __init s3c6400_init_irq(void)
{
/* VIC0 does not have IRQS 5..7,
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
index 31c29fd..7e6fa12 100644
--- a/arch/arm/mach-s3c64xx/s3c6410.c
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -62,13 +62,6 @@ void __init s3c6410_map_io(void)
s3c_cfcon_setname("s3c64xx-pata");
}
-void __init s3c6410_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
- s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK);
- s3c64xx_setup_clocks();
-}
-
void __init s3c6410_init_irq(void)
{
/* VIC0 is missing IRQ7, VIC1 is fully populated. */
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index c023474..d2cc91e 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -6,6 +6,4 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
-ifdef CONFIG_COMMON_CLK
obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
-endif
--
1.8.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 7/7] ARM: s3c64xx: Remove old clock management code
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
` (5 preceding siblings ...)
2013-06-05 23:57 ` [PATCH 6/7] ARM: s3c64xx: Migrate clock handling to Common Clock Framework Tomasz Figa
@ 2013-06-05 23:57 ` Tomasz Figa
2013-06-19 14:17 ` [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Kukjin Kim
7 siblings, 0 replies; 16+ messages in thread
From: Tomasz Figa @ 2013-06-05 23:57 UTC (permalink / raw)
To: linux-arm-kernel
This patch removes old clock management code of S3C64xx, since the
platform has been already moved to the new clock driver using Common
Clock Framework.
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
---
arch/arm/mach-s3c64xx/clock.c | 1007 -----------------------
arch/arm/mach-s3c64xx/common.h | 2 -
arch/arm/mach-s3c64xx/include/mach/regs-clock.h | 132 +--
arch/arm/mach-s3c64xx/pm.c | 21 -
4 files changed, 4 insertions(+), 1158 deletions(-)
delete mode 100644 arch/arm/mach-s3c64xx/clock.c
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
deleted file mode 100644
index c1bcc4a..0000000
diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h
index 76ce4fe..0184abf 100644
--- a/arch/arm/mach-s3c64xx/common.h
+++ b/arch/arm/mach-s3c64xx/common.h
@@ -35,7 +35,6 @@ extern void s3c6400_init_irq(void);
extern void s3c6400_map_io(void);
#else
-#define s3c6400_init_clocks NULL
#define s3c6400_map_io NULL
#define s3c6400_init NULL
#endif
@@ -47,7 +46,6 @@ extern void s3c6410_init_irq(void);
extern void s3c6410_map_io(void);
#else
-#define s3c6410_init_clocks NULL
#define s3c6410_map_io NULL
#define s3c6410_init NULL
#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
index 05332b9..4f44aac 100644
--- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -15,145 +15,21 @@
#ifndef __PLAT_REGS_CLOCK_H
#define __PLAT_REGS_CLOCK_H __FILE__
+/*
+ * FIXME: Remove remaining definitions
+ */
+
#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
-#define S3C_APLL_LOCK S3C_CLKREG(0x00)
-#define S3C_MPLL_LOCK S3C_CLKREG(0x04)
-#define S3C_EPLL_LOCK S3C_CLKREG(0x08)
-#define S3C_APLL_CON S3C_CLKREG(0x0C)
-#define S3C_MPLL_CON S3C_CLKREG(0x10)
-#define S3C_EPLL_CON0 S3C_CLKREG(0x14)
-#define S3C_EPLL_CON1 S3C_CLKREG(0x18)
-#define S3C_CLK_SRC S3C_CLKREG(0x1C)
-#define S3C_CLK_DIV0 S3C_CLKREG(0x20)
-#define S3C_CLK_DIV1 S3C_CLKREG(0x24)
-#define S3C_CLK_DIV2 S3C_CLKREG(0x28)
-#define S3C_CLK_OUT S3C_CLKREG(0x2C)
-#define S3C_HCLK_GATE S3C_CLKREG(0x30)
#define S3C_PCLK_GATE S3C_CLKREG(0x34)
-#define S3C_SCLK_GATE S3C_CLKREG(0x38)
-#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C)
#define S3C_MEM_SYS_CFG S3C_CLKREG(0x120)
-/* CLKDIV0 */
-#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
-#define S3C6400_CLKDIV0_PCLK_SHIFT (12)
-#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9)
-#define S3C6400_CLKDIV0_HCLK2_SHIFT (9)
-#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8)
-#define S3C6400_CLKDIV0_HCLK_SHIFT (8)
-#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
-#define S3C6400_CLKDIV0_MPLL_SHIFT (4)
-
-#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0)
-#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0)
-#define S3C6400_CLKDIV0_ARM_SHIFT (0)
-
-/* HCLK GATE Registers */
-#define S3C_CLKCON_HCLK_3DSE (1<<31)
-#define S3C_CLKCON_HCLK_UHOST (1<<29)
-#define S3C_CLKCON_HCLK_SECUR (1<<28)
-#define S3C_CLKCON_HCLK_SDMA1 (1<<27)
-#define S3C_CLKCON_HCLK_SDMA0 (1<<26)
-#define S3C_CLKCON_HCLK_IROM (1<<25)
-#define S3C_CLKCON_HCLK_DDR1 (1<<24)
-#define S3C_CLKCON_HCLK_DDR0 (1<<23)
-#define S3C_CLKCON_HCLK_MEM1 (1<<22)
-#define S3C_CLKCON_HCLK_MEM0 (1<<21)
-#define S3C_CLKCON_HCLK_USB (1<<20)
-#define S3C_CLKCON_HCLK_HSMMC2 (1<<19)
-#define S3C_CLKCON_HCLK_HSMMC1 (1<<18)
-#define S3C_CLKCON_HCLK_HSMMC0 (1<<17)
-#define S3C_CLKCON_HCLK_MDP (1<<16)
-#define S3C_CLKCON_HCLK_DHOST (1<<15)
-#define S3C_CLKCON_HCLK_IHOST (1<<14)
-#define S3C_CLKCON_HCLK_DMA1 (1<<13)
-#define S3C_CLKCON_HCLK_DMA0 (1<<12)
-#define S3C_CLKCON_HCLK_JPEG (1<<11)
-#define S3C_CLKCON_HCLK_CAMIF (1<<10)
-#define S3C_CLKCON_HCLK_SCALER (1<<9)
-#define S3C_CLKCON_HCLK_2D (1<<8)
-#define S3C_CLKCON_HCLK_TV (1<<7)
-#define S3C_CLKCON_HCLK_POST0 (1<<5)
-#define S3C_CLKCON_HCLK_ROT (1<<4)
-#define S3C_CLKCON_HCLK_LCD (1<<3)
-#define S3C_CLKCON_HCLK_TZIC (1<<2)
-#define S3C_CLKCON_HCLK_INTC (1<<1)
-#define S3C_CLKCON_HCLK_MFC (1<<0)
-
/* PCLK GATE Registers */
-#define S3C6410_CLKCON_PCLK_I2C1 (1<<27)
-#define S3C6410_CLKCON_PCLK_IIS2 (1<<26)
-#define S3C_CLKCON_PCLK_SKEY (1<<24)
-#define S3C_CLKCON_PCLK_CHIPID (1<<23)
-#define S3C_CLKCON_PCLK_SPI1 (1<<22)
-#define S3C_CLKCON_PCLK_SPI0 (1<<21)
-#define S3C_CLKCON_PCLK_HSIRX (1<<20)
-#define S3C_CLKCON_PCLK_HSITX (1<<19)
-#define S3C_CLKCON_PCLK_GPIO (1<<18)
-#define S3C_CLKCON_PCLK_IIC (1<<17)
-#define S3C_CLKCON_PCLK_IIS1 (1<<16)
-#define S3C_CLKCON_PCLK_IIS0 (1<<15)
-#define S3C_CLKCON_PCLK_AC97 (1<<14)
-#define S3C_CLKCON_PCLK_TZPC (1<<13)
-#define S3C_CLKCON_PCLK_TSADC (1<<12)
-#define S3C_CLKCON_PCLK_KEYPAD (1<<11)
-#define S3C_CLKCON_PCLK_IRDA (1<<10)
-#define S3C_CLKCON_PCLK_PCM1 (1<<9)
-#define S3C_CLKCON_PCLK_PCM0 (1<<8)
-#define S3C_CLKCON_PCLK_PWM (1<<7)
-#define S3C_CLKCON_PCLK_RTC (1<<6)
-#define S3C_CLKCON_PCLK_WDT (1<<5)
#define S3C_CLKCON_PCLK_UART3 (1<<4)
#define S3C_CLKCON_PCLK_UART2 (1<<3)
#define S3C_CLKCON_PCLK_UART1 (1<<2)
#define S3C_CLKCON_PCLK_UART0 (1<<1)
-#define S3C_CLKCON_PCLK_MFC (1<<0)
-
-/* SCLK GATE Registers */
-#define S3C_CLKCON_SCLK_UHOST (1<<30)
-#define S3C_CLKCON_SCLK_MMC2_48 (1<<29)
-#define S3C_CLKCON_SCLK_MMC1_48 (1<<28)
-#define S3C_CLKCON_SCLK_MMC0_48 (1<<27)
-#define S3C_CLKCON_SCLK_MMC2 (1<<26)
-#define S3C_CLKCON_SCLK_MMC1 (1<<25)
-#define S3C_CLKCON_SCLK_MMC0 (1<<24)
-#define S3C_CLKCON_SCLK_SPI1_48 (1<<23)
-#define S3C_CLKCON_SCLK_SPI0_48 (1<<22)
-#define S3C_CLKCON_SCLK_SPI1 (1<<21)
-#define S3C_CLKCON_SCLK_SPI0 (1<<20)
-#define S3C_CLKCON_SCLK_DAC27 (1<<19)
-#define S3C_CLKCON_SCLK_TV27 (1<<18)
-#define S3C_CLKCON_SCLK_SCALER27 (1<<17)
-#define S3C_CLKCON_SCLK_SCALER (1<<16)
-#define S3C_CLKCON_SCLK_LCD27 (1<<15)
-#define S3C_CLKCON_SCLK_LCD (1<<14)
-#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13)
-#define S3C6410_CLKCON_FIMC (1<<13)
-#define S3C_CLKCON_SCLK_POST0_27 (1<<12)
-#define S3C6400_CLKCON_SCLK_POST1 (1<<11)
-#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11)
-#define S3C_CLKCON_SCLK_POST0 (1<<10)
-#define S3C_CLKCON_SCLK_AUDIO1 (1<<9)
-#define S3C_CLKCON_SCLK_AUDIO0 (1<<8)
-#define S3C_CLKCON_SCLK_SECUR (1<<7)
-#define S3C_CLKCON_SCLK_IRDA (1<<6)
-#define S3C_CLKCON_SCLK_UART (1<<5)
-#define S3C_CLKCON_SCLK_ONENAND (1<<4)
-#define S3C_CLKCON_SCLK_MFC (1<<3)
-#define S3C_CLKCON_SCLK_CAM (1<<2)
-#define S3C_CLKCON_SCLK_JPEG (1<<1)
-
-/* CLKSRC */
-
-#define S3C6400_CLKSRC_APLL_MOUT (1 << 0)
-#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1)
-#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2)
-#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0)
-#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1)
-#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
-#define S3C6400_CLKSRC_MFC (1 << 4)
/* MEM_SYS_CFG */
#define MEM_SYS_CFG_INDEP_CF 0x4000
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index 6a1f91f..8cdb824 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -194,29 +194,8 @@ void s3c_pm_debug_smdkled(u32 set, u32 clear)
#endif
static struct sleep_save core_save[] = {
- SAVE_ITEM(S3C_APLL_LOCK),
- SAVE_ITEM(S3C_MPLL_LOCK),
- SAVE_ITEM(S3C_EPLL_LOCK),
- SAVE_ITEM(S3C_CLK_SRC),
- SAVE_ITEM(S3C_CLK_DIV0),
- SAVE_ITEM(S3C_CLK_DIV1),
- SAVE_ITEM(S3C_CLK_DIV2),
- SAVE_ITEM(S3C_CLK_OUT),
- SAVE_ITEM(S3C_HCLK_GATE),
- SAVE_ITEM(S3C_PCLK_GATE),
- SAVE_ITEM(S3C_SCLK_GATE),
- SAVE_ITEM(S3C_MEM0_GATE),
-
- SAVE_ITEM(S3C_EPLL_CON1),
- SAVE_ITEM(S3C_EPLL_CON0),
-
SAVE_ITEM(S3C64XX_MEM0DRVCON),
SAVE_ITEM(S3C64XX_MEM1DRVCON),
-
-#ifndef CONFIG_CPU_FREQ
- SAVE_ITEM(S3C_APLL_CON),
- SAVE_ITEM(S3C_MPLL_CON),
-#endif
};
static struct sleep_save misc_save[] = {
--
1.8.2.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553
2013-06-05 23:57 ` [PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553 Tomasz Figa
@ 2013-06-12 2:53 ` Mike Turquette
0 siblings, 0 replies; 16+ messages in thread
From: Mike Turquette @ 2013-06-12 2:53 UTC (permalink / raw)
To: linux-arm-kernel
Quoting Tomasz Figa (2013-06-05 16:57:25)
> This patch adds support for PLL6552 and PLL6553 PLLs present on Samsung
> S3C64xx SoCs.
>
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
Acked-by: Mike Turquette <mturquette@linaro.org>
or I can take it into clk-next.
> ---
> drivers/clk/samsung/clk-pll.c | 160 ++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/samsung/clk-pll.h | 4 ++
> 2 files changed, 164 insertions(+)
>
> diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
> index 89135f6..cef0bb9 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -336,6 +336,166 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
> }
>
> /*
> + * PLL6552 Clock Type
> + */
> +
> +#define PLL6552_LOCK_REG 0x00
> +#define PLL6552_CON_REG 0x0c
> +
> +#define PLL6552_MDIV_MASK 0x3ff
> +#define PLL6552_PDIV_MASK 0x3f
> +#define PLL6552_SDIV_MASK 0x7
> +#define PLL6552_MDIV_SHIFT 16
> +#define PLL6552_PDIV_SHIFT 8
> +#define PLL6552_SDIV_SHIFT 0
> +
> +struct samsung_clk_pll6552 {
> + struct clk_hw hw;
> + void __iomem *reg_base;
> +};
> +
> +#define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw)
> +
> +static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw);
> + u32 mdiv, pdiv, sdiv, pll_con;
> + u64 fvco = parent_rate;
> +
> + pll_con = __raw_readl(pll->reg_base + PLL6552_CON_REG);
> + mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
> + pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
> + sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
> +
> + fvco *= mdiv;
> + do_div(fvco, (pdiv << sdiv));
> +
> + return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll6552_clk_ops = {
> + .recalc_rate = samsung_pll6552_recalc_rate,
> +};
> +
> +struct clk * __init samsung_clk_register_pll6552(const char *name,
> + const char *pname, void __iomem *base)
> +{
> + struct samsung_clk_pll6552 *pll;
> + struct clk *clk;
> + struct clk_init_data init;
> +
> + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> + if (!pll) {
> + pr_err("%s: could not allocate pll clk %s\n", __func__, name);
> + return NULL;
> + }
> +
> + init.name = name;
> + init.ops = &samsung_pll6552_clk_ops;
> + init.parent_names = &pname;
> + init.num_parents = 1;
> +
> + pll->hw.init = &init;
> + pll->reg_base = base;
> +
> + clk = clk_register(NULL, &pll->hw);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register pll clock %s\n", __func__,
> + name);
> + kfree(pll);
> + }
> +
> + if (clk_register_clkdev(clk, name, NULL))
> + pr_err("%s: failed to register lookup for %s", __func__, name);
> +
> + return clk;
> +}
> +
> +/*
> + * PLL6553 Clock Type
> + */
> +
> +#define PLL6553_LOCK_REG 0x00
> +#define PLL6553_CON0_REG 0x0c
> +#define PLL6553_CON1_REG 0x10
> +
> +#define PLL6553_MDIV_MASK 0xff
> +#define PLL6553_PDIV_MASK 0x3f
> +#define PLL6553_SDIV_MASK 0x7
> +#define PLL6553_KDIV_MASK 0xffff
> +#define PLL6553_MDIV_SHIFT 16
> +#define PLL6553_PDIV_SHIFT 8
> +#define PLL6553_SDIV_SHIFT 0
> +#define PLL6553_KDIV_SHIFT 0
> +
> +struct samsung_clk_pll6553 {
> + struct clk_hw hw;
> + void __iomem *reg_base;
> +};
> +
> +#define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw)
> +
> +static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct samsung_clk_pll6553 *pll = to_clk_pll6553(hw);
> + u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
> + u64 fvco = parent_rate;
> +
> + pll_con0 = __raw_readl(pll->reg_base + PLL6553_CON0_REG);
> + pll_con1 = __raw_readl(pll->reg_base + PLL6553_CON1_REG);
> + mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
> + pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
> + sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
> + kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
> +
> + fvco *= (mdiv << 16) + kdiv;
> + do_div(fvco, (pdiv << sdiv));
> + fvco >>= 16;
> +
> + return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll6553_clk_ops = {
> + .recalc_rate = samsung_pll6553_recalc_rate,
> +};
> +
> +struct clk * __init samsung_clk_register_pll6553(const char *name,
> + const char *pname, void __iomem *base)
> +{
> + struct samsung_clk_pll6553 *pll;
> + struct clk *clk;
> + struct clk_init_data init;
> +
> + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> + if (!pll) {
> + pr_err("%s: could not allocate pll clk %s\n", __func__, name);
> + return NULL;
> + }
> +
> + init.name = name;
> + init.ops = &samsung_pll6553_clk_ops;
> + init.parent_names = &pname;
> + init.num_parents = 1;
> +
> + pll->hw.init = &init;
> + pll->reg_base = base;
> +
> + clk = clk_register(NULL, &pll->hw);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register pll clock %s\n", __func__,
> + name);
> + kfree(pll);
> + }
> +
> + if (clk_register_clkdev(clk, name, NULL))
> + pr_err("%s: failed to register lookup for %s", __func__, name);
> +
> + return clk;
> +}
> +
> +/*
> * PLL2550x Clock Type
> */
>
> diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
> index f33786e..1d68a68 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -34,6 +34,10 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
> extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
> const char *pname, const void __iomem *con_reg,
> enum pll46xx_type type);
> +extern struct clk *samsung_clk_register_pll6552(const char *name,
> + const char *pname, void __iomem *base);
> +extern struct clk *samsung_clk_register_pll6553(const char *name,
> + const char *pname, void __iomem *base);
> extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
> const char *pname, const void __iomem *reg_base,
> const unsigned long offset);
> --
> 1.8.2.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs
2013-06-05 23:57 ` [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs Tomasz Figa
@ 2013-06-12 2:54 ` Mike Turquette
2013-06-12 6:26 ` Tomasz Figa
0 siblings, 1 reply; 16+ messages in thread
From: Mike Turquette @ 2013-06-12 2:54 UTC (permalink / raw)
To: linux-arm-kernel
Quoting Tomasz Figa (2013-06-05 16:57:26)
> This patch adds new, Common Clock Framework-based clock driver for Samsung
> S3C64xx SoCs. The driver is just added, without actually letting the
> platforms use it yet, since this requires more intermediate steps.
>
It seems like there is an awful lot of clock data here that exists
alongside the stuff in DT. Is this how you plan to keep things going
forward or is this conversion just an intermediate step?
Regards,
Mike
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> ---
> .../bindings/clock/samsung,s3c64xx-clock.txt | 48 ++
> drivers/clk/samsung/Makefile | 3 +
> drivers/clk/samsung/clk-s3c64xx.c | 503 +++++++++++++++++++++
> include/dt-bindings/clock/samsung,s3c64xx-clock.h | 144 ++++++
> 4 files changed, 698 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
> create mode 100644 drivers/clk/samsung/clk-s3c64xx.c
> create mode 100644 include/dt-bindings/clock/samsung,s3c64xx-clock.h
>
> 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 0000000..278ab6e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
> @@ -0,0 +1,48 @@
> +* Samsung S3C64xx Clock Controller
> +
> +The S3C64xx clock controller generates and supplies clock to various controllers
> +within the SoC. The clock binding described here is applicable to all SoCs in
> +the S3C64xx family.
> +
> +Required Properties:
> +
> +- comptible: should be one of the following.
> + - "samsung,s3c6400-clock" - controller compatible with S3C6400 SoC.
> + - "samsung,s3c6410-clock" - controller compatible with S3C6410 SoC.
> +
> +- reg: physical base address of the controller and length of memory mapped
> + region.
> +
> +- #clock-cells: should be 1.
> +
> +Each clock is assigned an identifier and client nodes can use this identifier
> +to specify the clock which they consume. Some of the clocks are available only
> +on a particular S3C64xx SoC and this is specified where applicable.
> +
> +All available clocks are defined as preprocessor macros in
> +dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used in device
> +tree sources.
> +
> +Example: Clock controller node:
> +
> + clocks: clock-controller at 7e00f000 {
> + compatible = "samsung,s3c6410-clock";
> + reg = <0x7e00f000 0x1000>;
> + #clock-cells = <1>;
> + };
> +
> +Example: UART controller node that consumes the clock generated by the clock
> + controller (refer to the standard clock bindings for information about
> + "clocks" and "clock-names" properties):
> +
> + uart0: serial at 7f005000 {
> + compatible = "samsung,s3c6400-uart";
> + reg = <0x7f005000 0x100>;
> + interrupt-parent = <&vic1>;
> + interrupts = <5>;
> + clock-names = "uart", "clk_uart_baud2",
> + "clk_uart_baud3";
> + clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
> + <&clocks SCLK_UART>;
> + status = "disabled";
> + };
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index b7c232e..c023474 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -6,3 +6,6 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
> obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
> obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
> obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
> +ifdef CONFIG_COMMON_CLK
> +obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
> +endif
> diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
> new file mode 100644
> index 0000000..253a972
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c64xx.c
> @@ -0,0 +1,503 @@
> +/*
> + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Common Clock Framework support for all S3C64xx SoCs.
> +*/
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
> +
> +#include "clk.h"
> +#include "clk-pll.h"
> +
> +/* S3C64xx clock controller register offsets. */
> +#define APLL_LOCK 0x000
> +#define MPLL_LOCK 0x004
> +#define EPLL_LOCK 0x008
> +#define APLL_CON 0x00c
> +#define MPLL_CON 0x010
> +#define EPLL_CON0 0x014
> +#define EPLL_CON1 0x018
> +#define CLK_SRC 0x01c
> +#define CLK_DIV0 0x020
> +#define CLK_DIV1 0x024
> +#define CLK_DIV2 0x028
> +#define HCLK_GATE 0x030
> +#define PCLK_GATE 0x034
> +#define SCLK_GATE 0x038
> +#define MEM0_GATE 0x03c
> +#define CLK_SRC2 0x10c
> +#define OTHERS 0x900
> +
> +/* Special bitfields used in the driver. */
> +#define OTHERS_SYNCMUXSEL (1 << 6)
> +
> +/* Helper macros to define clock arrays. */
> +#define FIXED_RATE_CLOCKS(name) \
> + static struct samsung_fixed_rate_clock name[]
> +#define MUX_CLOCKS(name) \
> + static struct samsung_mux_clock name[]
> +#define DIV_CLOCKS(name) \
> + static struct samsung_div_clock name[]
> +#define GATE_CLOCKS(name) \
> + static struct samsung_gate_clock name[]
> +
> +/* Helper macros for gate types present on S3C64xx. */
> +#define GATE_BUS(_id, cname, pname, o, b) \
> + GATE(_id, cname, pname, o, b, 0, 0)
> +#define GATE_SCLK(_id, cname, pname, o, b) \
> + GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT, 0)
> +#define GATE_ON(_id, cname, pname, o, b) \
> + GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
> +
> +/*
> + * List of controller registers to be saved and restored during
> + * a suspend/resume cycle.
> + */
> +static __initdata unsigned long s3c64xx_clk_regs[] = {
> + APLL_LOCK,
> + MPLL_LOCK,
> + EPLL_LOCK,
> + APLL_CON,
> + MPLL_CON,
> + EPLL_CON0,
> + EPLL_CON1,
> + CLK_SRC,
> + CLK_DIV0,
> + CLK_DIV1,
> + CLK_DIV2,
> + HCLK_GATE,
> + PCLK_GATE,
> + SCLK_GATE,
> +};
> +
> +static __initdata unsigned long s3c6410_clk_regs[] = {
> + CLK_SRC2,
> + MEM0_GATE,
> +};
> +
> +/* List of parent clocks common for all S3C64xx SoCs. */
> +PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" };
> +PNAME(uart_p) = { "mout_epll", "dout_mpll" };
> +PNAME(audio0_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk0",
> + "pcmcdclk0", "none", "none", "none" };
> +PNAME(audio1_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1",
> + "pcmcdclk0", "none", "none", "none" };
> +PNAME(mfc_p) = { "hclkx2", "mout_epll" };
> +PNAME(apll_p) = { "fin_pll", "fout_apll" };
> +PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
> +PNAME(epll_p) = { "fin_pll", "fout_epll" };
> +
> +/* S3C6400-specific parent clocks. */
> +PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none", "none" };
> +PNAME(irda_p6400) = { "mout_epll", "dout_mpll", "none", "clk48m" };
> +PNAME(uhost_p6400) = { "clk48m", "mout_epll", "dout_mpll", "none" };
> +
> +/* S3C6410-specific parent clocks. */
> +PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
> +PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "none" };
> +PNAME(irda_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "clk48m" };
> +PNAME(uhost_p6410) = { "clk48m", "mout_epll", "dout_mpll", "fin_pll" };
> +PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2",
> + "pcmcdclk1", "none", "none", "none" };
> +
> +/* Fixed rate clocks generated outside the SoC. */
> +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
> + FRATE(FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0),
> + FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
> +};
> +
> +/* Fixed rate clocks generated inside the SoC. */
> +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
> + FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
> + FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +/* List of clock muxes present on all S3C64xx SoCs. */
> +MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
> + MUX(0, "mout_apll", apll_p, CLK_SRC, 0, 1),
> + MUX(0, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
> + MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
> + MUX(0, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
> + MUX(0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
> + MUX(0, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
> + MUX(0, "mout_uart", uart_p, CLK_SRC, 13, 1),
> + MUX(0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
> + MUX(0, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
> + MUX(0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
> + MUX(0, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
> + MUX(0, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
> +};
> +
> +/* List of clock muxes present on S3C6400. */
> +MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
> + MUX(0, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
> + MUX(0, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
> + MUX(0, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
> + MUX(0, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
> +};
> +
> +/* List of clock muxes present on S3C6410. */
> +MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
> + MUX(0, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
> + MUX(0, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
> + MUX(0, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
> + MUX(0, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
> + MUX(0, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
> + MUX(0, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
> + MUX(0, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
> +};
> +
> +/* List of clock dividers present on all S3C64xx SoCs. */
> +DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
> + DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
> + DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
> + DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
> + DIV(0, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
> + DIV(0, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
> + DIV(0, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
> + DIV(0, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
> + DIV(0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
> + DIV(0, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
> + DIV(0, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
> + DIV(0, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
> + DIV(0, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
> + DIV(0, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
> + DIV(0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
> + DIV(0, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
> + DIV(0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
> + DIV(0, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
> + DIV(0, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
> + DIV(0, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
> +};
> +
> +/* List of clock dividers present on S3C6400. */
> +DIV_CLOCKS(s3c6400_div_clks) __initdata = {
> + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
> +};
> +
> +/* List of clock dividers present on S3C6410. */
> +DIV_CLOCKS(s3c6410_div_clks) __initdata = {
> + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
> + DIV(0, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
> + DIV(0, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
> +};
> +
> +/* List of clock gates present on all S3C64xx SoCs. */
> +GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
> + GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
> + GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
> + GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
> + GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
> + GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
> + GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
> + GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE, 19),
> + GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE, 18),
> + GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE, 17),
> + GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
> + GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
> + GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
> + GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
> + GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
> + GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
> + GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
> + GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE, 9),
> + GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
> + GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
> + GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
> + GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
> + GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
> + GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
> + GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
> + GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
> + GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE, 23),
> + GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
> + GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
> + GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
> + GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
> + GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
> + GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
> + GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
> + GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
> + GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
> + GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
> + GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
> + GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE, 11),
> + GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
> + GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
> + GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
> + GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
> + GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
> + GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
> + GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
> + GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
> + GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
> + GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
> + GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
> + GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost", SCLK_GATE, 30),
> + GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m", SCLK_GATE, 29),
> + GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48", "clk48m", SCLK_GATE, 28),
> + GATE_SCLK(SCLK_MMC0_48, "sclk_mmc0_48", "clk48m", SCLK_GATE, 27),
> + GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26),
> + GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25),
> + GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24),
> + GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE, 23),
> + GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m", SCLK_GATE, 22),
> + GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1", SCLK_GATE, 21),
> + GATE_SCLK(SCLK_SPI0, "sclk_spi0", "dout_spi0", SCLK_GATE, 20),
> + GATE_SCLK(SCLK_DAC27, "sclk_dac27", "mout_dac27", SCLK_GATE, 19),
> + GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18),
> + GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE, 17),
> + GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler", SCLK_GATE, 16),
> + GATE_SCLK(SCLK_LCD27, "sclk_lcd27", "clk27m", SCLK_GATE, 15),
> + GATE_SCLK(SCLK_LCD, "sclk_lcd", "dout_lcd", SCLK_GATE, 14),
> + GATE_SCLK(SCLK_POST0_27, "sclk_post0_27", "clk27m", SCLK_GATE, 12),
> + GATE_SCLK(SCLK_POST0, "sclk_post0", "dout_lcd", SCLK_GATE, 10),
> + GATE_SCLK(SCLK_AUDIO1, "sclk_audio1", "dout_audio1", SCLK_GATE, 9),
> + GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE, 8),
> + GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE, 7),
> + GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda", SCLK_GATE, 6),
> + GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart", SCLK_GATE, 5),
> + GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE, 3),
> + GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE, 2),
> + GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg", SCLK_GATE, 1),
> +};
> +
> +/* List of clock gates present on S3C6400. */
> +GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
> + GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
> + GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent", SCLK_GATE, 4),
> +};
> +
> +/* List of clock gates present on S3C6410. */
> +GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
> + GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
> + GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
> + GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
> + GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
> + GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
> + GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
> + GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
> + GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE, 13),
> + GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2", SCLK_GATE, 11),
> + GATE_BUS(MEM0_CFCON, "mem0_cfcon", "hclk_mem0", MEM0_GATE, 5),
> + GATE_BUS(MEM0_ONENAND1, "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4),
> + GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE, 3),
> + GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE, 2),
> + GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0", MEM0_GATE, 1),
> +};
> +
> +/* Aliases for common s3c64xx clocks. */
> +static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
> + ALIAS(MOUT_EPLL, NULL, "mout_epll"),
> + ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
> + ALIAS(HCLKX2, NULL, "hclk2"),
> + ALIAS(HCLK, NULL, "hclk"),
> + ALIAS(PCLK, NULL, "pclk"),
> + ALIAS(PCLK, NULL, "clk_uart_baud2"),
> + ALIAS(ARMCLK, NULL, "armclk"),
> + ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
> + ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
> + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
> + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
> + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
> + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
> + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
> + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
> + ALIAS(HCLK_DMA1, NULL, "dma1"),
> + ALIAS(HCLK_DMA0, NULL, "dma0"),
> + ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
> + ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
> + ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
> + ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
> + ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
> + ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
> + ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
> + ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
> + ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
> + ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
> + ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
> + ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
> + ALIAS(PCLK_PWM, NULL, "timers"),
> + ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
> + ALIAS(PCLK_WDT, NULL, "watchdog"),
> + ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
> + ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
> + ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
> + ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
> + ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
> + ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
> + ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
> + ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
> + ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
> + ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
> + ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
> + ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
> + ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
> + ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
> + ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
> + ALIAS(SCLK_CAM, "s3c-camif", "camera"),
> +};
> +
> +/* Aliases for s3c6400-specific clocks. */
> +static struct samsung_clock_alias s3c6400_clock_aliases[] = {
> + /* Nothing to place here yet. */
> +};
> +
> +/* Aliases for s3c6410-specific clocks. */
> +static struct samsung_clock_alias s3c6410_clock_aliases[] = {
> + ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
> + ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
> + ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
> + ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
> + ALIAS(MEM0_SROM, NULL, "srom"),
> +};
> +
> +/*
> + * Parent of the hclkx2 clock depends on whether the SoC is operating in
> + * synchronous or asynchronous mode. Depending on value of OTHERS[6]
> + * (SYNCMUXSEL) bit, it can be either mout_mpll or mout_apll.
> + */
> +static void __init s3c64xx_clk_register_hclkx2(void __iomem *reg_base)
> +{
> + struct samsung_div_clock hclkx2;
> + u32 others;
> +
> + memset(&hclkx2, 0, sizeof(hclkx2));
> +
> + hclkx2.id = HCLKX2;
> + hclkx2.name = "hclkx2";
> + hclkx2.offset = CLK_DIV0;
> + hclkx2.shift = 9;
> + hclkx2.width = 3;
> +
> + others = readl(reg_base + OTHERS);
> + if (others & OTHERS_SYNCMUXSEL)
> + hclkx2.parent_name = "mout_apll";
> + else
> + hclkx2.parent_name = "mout_mpll";
> +
> + samsung_clk_register_div(&hclkx2, 1);
> +}
> +
> +static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f,
> + unsigned long xusbxti_f)
> +{
> + s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
> + s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
> + samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
> + ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks));
> +}
> +
> +static __initdata struct of_device_id ext_clk_match[] = {
> + { .compatible = "samsung,clock-fin-pll", .data = (void *)0, },
> + { .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
> + {},
> +};
> +
> +/* Register s3c64xx clocks. */
> +void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
> + unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base)
> +{
> + struct clk *clk;
> + unsigned long *soc_regs = NULL;
> + unsigned long nr_soc_regs = 0;
> +
> + if (np) {
> + reg_base = of_iomap(np, 0);
> + if (!reg_base)
> + panic("%s: failed to map registers\n", __func__);
> + }
> +
> + if (!is_s3c6400) {
> + soc_regs = s3c6410_clk_regs;
> + nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
> + }
> +
> + samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
> + ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs);
> +
> + /* Register external clocks. */
> + if (np)
> + samsung_clk_of_register_fixed_ext(s3c64xx_fixed_rate_ext_clks,
> + ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks),
> + ext_clk_match);
> + else
> + s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
> +
> + /* Register PLLs. */
> + clk = samsung_clk_register_pll6552("fout_apll",
> + "fin_pll", reg_base + APLL_LOCK);
> + samsung_clk_add_lookup(clk, FOUT_APLL);
> +
> + clk = samsung_clk_register_pll6552("fout_mpll",
> + "fin_pll", reg_base + MPLL_LOCK);
> + samsung_clk_add_lookup(clk, FOUT_MPLL);
> +
> + clk = samsung_clk_register_pll6553("fout_epll",
> + "fin_pll", reg_base + EPLL_LOCK);
> + samsung_clk_add_lookup(clk, FOUT_EPLL);
> +
> + /* Register common internal clocks. */
> + s3c64xx_clk_register_hclkx2(reg_base);
> +
> + samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
> + ARRAY_SIZE(s3c64xx_fixed_rate_clks));
> + samsung_clk_register_mux(s3c64xx_mux_clks,
> + ARRAY_SIZE(s3c64xx_mux_clks));
> + samsung_clk_register_div(s3c64xx_div_clks,
> + ARRAY_SIZE(s3c64xx_div_clks));
> + samsung_clk_register_gate(s3c64xx_gate_clks,
> + ARRAY_SIZE(s3c64xx_gate_clks));
> +
> + /* Register SoC-specific clocks. */
> + if (is_s3c6400) {
> + samsung_clk_register_mux(s3c6400_mux_clks,
> + ARRAY_SIZE(s3c6400_mux_clks));
> + samsung_clk_register_div(s3c6400_div_clks,
> + ARRAY_SIZE(s3c6400_div_clks));
> + samsung_clk_register_gate(s3c6400_gate_clks,
> + ARRAY_SIZE(s3c6400_gate_clks));
> + samsung_clk_register_alias(s3c6400_clock_aliases,
> + ARRAY_SIZE(s3c6400_clock_aliases));
> + } else {
> + samsung_clk_register_mux(s3c6410_mux_clks,
> + ARRAY_SIZE(s3c6410_mux_clks));
> + samsung_clk_register_div(s3c6410_div_clks,
> + ARRAY_SIZE(s3c6410_div_clks));
> + samsung_clk_register_gate(s3c6410_gate_clks,
> + ARRAY_SIZE(s3c6410_gate_clks));
> + samsung_clk_register_alias(s3c6410_clock_aliases,
> + ARRAY_SIZE(s3c6410_clock_aliases));
> + }
> +
> + samsung_clk_register_alias(s3c64xx_clock_aliases,
> + ARRAY_SIZE(s3c64xx_clock_aliases));
> +
> + pr_info("%s clocks: apll = %lu, mpll = %lu\n"
> + " epll = %lu, arm_clk = %lu\n",
> + is_s3c6400 ? "S3C6400" : "S3C6410",
> + _get_rate("fout_apll"), _get_rate("fout_mpll"),
> + _get_rate("fout_epll"), _get_rate("armclk"));
> +}
> +
> +static void __init s3c6400_clk_init(struct device_node *np)
> +{
> + s3c64xx_clk_init(np, 0, 0, true, NULL);
> +}
> +CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock", s3c6400_clk_init);
> +
> +static void __init s3c6410_clk_init(struct device_node *np)
> +{
> + s3c64xx_clk_init(np, 0, 0, false, NULL);
> +}
> +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 0000000..3e9a1f9
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,s3c64xx-clock.h
> @@ -0,0 +1,144 @@
> +/*
> + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Device Tree binding constants for Samsung S3C64xx clock controller.
> +*/
> +
> +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> +
> +/*
> + * Let each exported clock get a unique index, which is used on DT-enabled
> + * platforms to lookup the clock from a clock specifier. These indices are
> + * therefore considered an ABI and so must not be changed. This implies
> + * that new clocks should be added either in free spaces between clock groups
> + * or at the end.
> + */
> +
> +/* Core clocks. */
> +#define IISCDCLK0 3
> +#define PCMCDCLK0 4
> +#define IISCDCLK1 5
> +#define PCMCDCLK1 6
> +#define IISCDCLK2 7
> +#define CLK27M 8
> +#define CLK48M 9
> +#define FIN_PLL 10
> +#define FOUT_APLL 11
> +#define FOUT_MPLL 12
> +#define FOUT_EPLL 13
> +#define ARMCLK 14
> +#define HCLKX2 15
> +#define HCLK 16
> +#define PCLK 17
> +#define MOUT_EPLL 18
> +#define DOUT_MPLL 19
> +
> +/* HCLK bus clocks. */
> +#define HCLK_3DSE 32
> +#define HCLK_UHOST 33
> +#define HCLK_SECUR 34
> +#define HCLK_SDMA1 35
> +#define HCLK_SDMA0 36
> +#define HCLK_IROM 37
> +#define HCLK_DDR1 38
> +#define HCLK_MEM1 39
> +#define HCLK_MEM0 40
> +#define HCLK_USB 41
> +#define HCLK_HSMMC2 42
> +#define HCLK_HSMMC1 43
> +#define HCLK_HSMMC0 44
> +#define HCLK_MDP 45
> +#define HCLK_DHOST 46
> +#define HCLK_IHOST 47
> +#define HCLK_DMA1 48
> +#define HCLK_DMA0 49
> +#define HCLK_JPEG 50
> +#define HCLK_CAMIF 51
> +#define HCLK_SCALER 52
> +#define HCLK_2D 53
> +#define HCLK_TV 54
> +#define HCLK_POST0 55
> +#define HCLK_ROT 56
> +#define HCLK_LCD 57
> +#define HCLK_TZIC 58
> +#define HCLK_INTC 59
> +#define HCLK_MFC 60
> +#define HCLK_DDR0 61
> +
> +/* PCLK bus clocks. */
> +#define PCLK_IIC1 64
> +#define PCLK_IIS2 65
> +#define PCLK_SKEY 66
> +#define PCLK_CHIPID 67
> +#define PCLK_SPI1 68
> +#define PCLK_SPI0 69
> +#define PCLK_HSIRX 70
> +#define PCLK_HSITX 71
> +#define PCLK_GPIO 72
> +#define PCLK_IIC0 73
> +#define PCLK_IIS1 74
> +#define PCLK_IIS0 75
> +#define PCLK_AC97 76
> +#define PCLK_TZPC 77
> +#define PCLK_TSADC 78
> +#define PCLK_KEYPAD 79
> +#define PCLK_IRDA 80
> +#define PCLK_PCM1 81
> +#define PCLK_PCM0 82
> +#define PCLK_PWM 83
> +#define PCLK_RTC 84
> +#define PCLK_WDT 85
> +#define PCLK_UART3 86
> +#define PCLK_UART2 87
> +#define PCLK_UART1 88
> +#define PCLK_UART0 89
> +#define PCLK_MFC 90
> +
> +/* Special clocks. */
> +#define SCLK_UHOST 96
> +#define SCLK_MMC2_48 97
> +#define SCLK_MMC1_48 98
> +#define SCLK_MMC0_48 99
> +#define SCLK_MMC2 100
> +#define SCLK_MMC1 101
> +#define SCLK_MMC0 102
> +#define SCLK_SPI1_48 103
> +#define SCLK_SPI0_48 104
> +#define SCLK_SPI1 105
> +#define SCLK_SPI0 106
> +#define SCLK_DAC27 107
> +#define SCLK_TV27 108
> +#define SCLK_SCALER27 109
> +#define SCLK_SCALER 110
> +#define SCLK_LCD27 111
> +#define SCLK_LCD 112
> +#define SCLK_FIMC 113
> +#define SCLK_POST0_27 114
> +#define SCLK_AUDIO2 115
> +#define SCLK_POST0 116
> +#define SCLK_AUDIO1 117
> +#define SCLK_AUDIO0 118
> +#define SCLK_SECUR 119
> +#define SCLK_IRDA 120
> +#define SCLK_UART 121
> +#define SCLK_MFC 122
> +#define SCLK_CAM 123
> +#define SCLK_JPEG 124
> +#define SCLK_ONENAND 125
> +
> +/* MEM0 bus clocks - S3C6410-specific. */
> +#define MEM0_CFCON 128
> +#define MEM0_ONENAND1 129
> +#define MEM0_ONENAND0 130
> +#define MEM0_NFCON 131
> +#define MEM0_SROM 132
> +
> +/* Total number of clocks. */
> +#define NR_CLKS (MEM0_SROM + 1)
> +
> +#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H */
> --
> 1.8.2.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs
2013-06-12 2:54 ` Mike Turquette
@ 2013-06-12 6:26 ` Tomasz Figa
2013-06-12 16:51 ` Mike Turquette
0 siblings, 1 reply; 16+ messages in thread
From: Tomasz Figa @ 2013-06-12 6:26 UTC (permalink / raw)
To: linux-arm-kernel
Hi Mike,
On Tuesday 11 of June 2013 19:54:51 Mike Turquette wrote:
> Quoting Tomasz Figa (2013-06-05 16:57:26)
>
> > This patch adds new, Common Clock Framework-based clock driver for
> > Samsung S3C64xx SoCs. The driver is just added, without actually
> > letting the platforms use it yet, since this requires more
> > intermediate steps.
> It seems like there is an awful lot of clock data here that exists
> alongside the stuff in DT. Is this how you plan to keep things going
> forward or is this conversion just an intermediate step?
Current S3C64xx support contains a lot of boards, for which I don't see
any chance for DT conversion in any time soon, so the driver must cover
both DT and non-DT cases. (Not even saying that DT support for S3C64xx is
not yet submitted, as I want to get all the dependencies merged, or at
least acked, first.)
Also, personally, I don't see anything wrong with having those clocks
defined in the driver. The binding specifies the exact mapping between
clock IDs inside the clock provider and hardware clocks and not all clocks
need to be exported (most of muxes and divs don't need to), so I find it
more reasonable to define them in the driver instead.
Another thing is that it's unlikely for any new SoC from S3C64xx series to
show up, so basically the clock list is fixed.
Best regards,
Tomasz
> Regards,
> Mike
>
> > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > ---
> >
> > .../bindings/clock/samsung,s3c64xx-clock.txt | 48 ++
> > drivers/clk/samsung/Makefile | 3 +
> > drivers/clk/samsung/clk-s3c64xx.c | 503
> > +++++++++++++++++++++
> > include/dt-bindings/clock/samsung,s3c64xx-clock.h | 144 ++++++ 4
> > files changed, 698 insertions(+)
> > create mode 100644
> > Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
> > create mode 100644 drivers/clk/samsung/clk-s3c64xx.c
> > create mode 100644 include/dt-bindings/clock/samsung,s3c64xx-clock.h
> >
> > 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 0000000..278ab6e
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
> > @@ -0,0 +1,48 @@
> > +* Samsung S3C64xx Clock Controller
> > +
> > +The S3C64xx clock controller generates and supplies clock to various
> > controllers +within the SoC. The clock binding described here is
> > applicable to all SoCs in +the S3C64xx family.
> > +
> > +Required Properties:
> > +
> > +- comptible: should be one of the following.
> > + - "samsung,s3c6400-clock" - controller compatible with S3C6400 SoC.
> > + - "samsung,s3c6410-clock" - controller compatible with S3C6410 SoC.
> > +
> > +- reg: physical base address of the controller and length of memory
> > mapped + region.
> > +
> > +- #clock-cells: should be 1.
> > +
> > +Each clock is assigned an identifier and client nodes can use this
> > identifier +to specify the clock which they consume. Some of the
> > clocks are available only +on a particular S3C64xx SoC and this is
> > specified where applicable. +
> > +All available clocks are defined as preprocessor macros in
> > +dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used in
> > device +tree sources.
> > +
> > +Example: Clock controller node:
> > +
> > + clocks: clock-controller at 7e00f000 {
> > + compatible = "samsung,s3c6410-clock";
> > + reg = <0x7e00f000 0x1000>;
> > + #clock-cells = <1>;
> > + };
> > +
> > +Example: UART controller node that consumes the clock generated by
> > the clock + controller (refer to the standard clock bindings for
> > information about + "clocks" and "clock-names" properties):
> > +
> > + uart0: serial at 7f005000 {
> > + compatible = "samsung,s3c6400-uart";
> > + reg = <0x7f005000 0x100>;
> > + interrupt-parent = <&vic1>;
> > + interrupts = <5>;
> > + clock-names = "uart", "clk_uart_baud2",
> > + "clk_uart_baud3";
> > + clocks = <&clocks PCLK_UART0>, <&clocks
> > PCLK_UART0>, + <&clocks
> > SCLK_UART>;
> > + status = "disabled";
> > + };
> > diff --git a/drivers/clk/samsung/Makefile
> > b/drivers/clk/samsung/Makefile index b7c232e..c023474 100644
> > --- a/drivers/clk/samsung/Makefile
> > +++ b/drivers/clk/samsung/Makefile
> > @@ -6,3 +6,6 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
> >
> > obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
> > obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
> > obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
> >
> > +ifdef CONFIG_COMMON_CLK
> > +obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
> > +endif
> > diff --git a/drivers/clk/samsung/clk-s3c64xx.c
> > b/drivers/clk/samsung/clk-s3c64xx.c new file mode 100644
> > index 0000000..253a972
> > --- /dev/null
> > +++ b/drivers/clk/samsung/clk-s3c64xx.c
> > @@ -0,0 +1,503 @@
> > +/*
> > + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify + * it under the terms of the GNU General Public License
> > version 2 as + * published by the Free Software Foundation.
> > + *
> > + * Common Clock Framework support for all S3C64xx SoCs.
> > +*/
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clkdev.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +
> > +#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
> > +
> > +#include "clk.h"
> > +#include "clk-pll.h"
> > +
> > +/* S3C64xx clock controller register offsets. */
> > +#define APLL_LOCK 0x000
> > +#define MPLL_LOCK 0x004
> > +#define EPLL_LOCK 0x008
> > +#define APLL_CON 0x00c
> > +#define MPLL_CON 0x010
> > +#define EPLL_CON0 0x014
> > +#define EPLL_CON1 0x018
> > +#define CLK_SRC 0x01c
> > +#define CLK_DIV0 0x020
> > +#define CLK_DIV1 0x024
> > +#define CLK_DIV2 0x028
> > +#define HCLK_GATE 0x030
> > +#define PCLK_GATE 0x034
> > +#define SCLK_GATE 0x038
> > +#define MEM0_GATE 0x03c
> > +#define CLK_SRC2 0x10c
> > +#define OTHERS 0x900
> > +
> > +/* Special bitfields used in the driver. */
> > +#define OTHERS_SYNCMUXSEL (1 << 6)
> > +
> > +/* Helper macros to define clock arrays. */
> > +#define FIXED_RATE_CLOCKS(name) \
> > + static struct samsung_fixed_rate_clock name[]
> > +#define MUX_CLOCKS(name) \
> > + static struct samsung_mux_clock name[]
> > +#define DIV_CLOCKS(name) \
> > + static struct samsung_div_clock name[]
> > +#define GATE_CLOCKS(name) \
> > + static struct samsung_gate_clock name[]
> > +
> > +/* Helper macros for gate types present on S3C64xx. */
> > +#define GATE_BUS(_id, cname, pname, o, b) \
> > + GATE(_id, cname, pname, o, b, 0, 0)
> > +#define GATE_SCLK(_id, cname, pname, o, b) \
> > + GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT, 0)
> > +#define GATE_ON(_id, cname, pname, o, b) \
> > + GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
> > +
> > +/*
> > + * List of controller registers to be saved and restored during
> > + * a suspend/resume cycle.
> > + */
> > +static __initdata unsigned long s3c64xx_clk_regs[] = {
> > + APLL_LOCK,
> > + MPLL_LOCK,
> > + EPLL_LOCK,
> > + APLL_CON,
> > + MPLL_CON,
> > + EPLL_CON0,
> > + EPLL_CON1,
> > + CLK_SRC,
> > + CLK_DIV0,
> > + CLK_DIV1,
> > + CLK_DIV2,
> > + HCLK_GATE,
> > + PCLK_GATE,
> > + SCLK_GATE,
> > +};
> > +
> > +static __initdata unsigned long s3c6410_clk_regs[] = {
> > + CLK_SRC2,
> > + MEM0_GATE,
> > +};
> > +
> > +/* List of parent clocks common for all S3C64xx SoCs. */
> > +PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll",
> > "clk27m" }; +PNAME(uart_p) = { "mout_epll", "dout_mpll" };
> > +PNAME(audio0_p) = { "mout_epll", "dout_mpll",
> > "fin_pll", "iiscdclk0", + "pcmcdclk0",
> > "none", "none", "none" }; +PNAME(audio1_p) = {
> > "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1", +
> > "pcmcdclk0", "none", "none", "none" }; +PNAME(mfc_p)
> > = { "hclkx2", "mout_epll" };
> > +PNAME(apll_p) = { "fin_pll", "fout_apll" };
> > +PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
> > +PNAME(epll_p) = { "fin_pll", "fout_epll" };
> > +
> > +/* S3C6400-specific parent clocks. */
> > +PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none",
> > "none" }; +PNAME(irda_p6400) = { "mout_epll", "dout_mpll",
> > "none", "clk48m" }; +PNAME(uhost_p6400) = { "clk48m",
> > "mout_epll", "dout_mpll", "none" }; +
> > +/* S3C6410-specific parent clocks. */
> > +PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
> > +PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll",
> > "fin_pll", "none" }; +PNAME(irda_p6410) = { "mout_epll",
> > "dout_mpll", "fin_pll", "clk48m" }; +PNAME(uhost_p6410) = {
> > "clk48m", "mout_epll", "dout_mpll", "fin_pll" }; +PNAME(audio2_p6410)
> > = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2", +
> > "pcmcdclk1", "none", "none", "none" }; +
> > +/* Fixed rate clocks generated outside the SoC. */
> > +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
> > + FRATE(FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0),
> > + FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
> > +};
> > +
> > +/* Fixed rate clocks generated inside the SoC. */
> > +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
> > + FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
> > + FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
> > +};
> > +
> > +/* List of clock muxes present on all S3C64xx SoCs. */
> > +MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
> > + MUX(0, "mout_apll", apll_p, CLK_SRC, 0, 1),
> > + MUX(0, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
> > + MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
> > + MUX(0, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
> > + MUX(0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
> > + MUX(0, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
> > + MUX(0, "mout_uart", uart_p, CLK_SRC, 13, 1),
> > + MUX(0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
> > + MUX(0, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
> > + MUX(0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
> > + MUX(0, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
> > + MUX(0, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
> > +};
> > +
> > +/* List of clock muxes present on S3C6400. */
> > +MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
> > + MUX(0, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
> > + MUX(0, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
> > + MUX(0, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
> > + MUX(0, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
> > +};
> > +
> > +/* List of clock muxes present on S3C6410. */
> > +MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
> > + MUX(0, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
> > + MUX(0, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
> > + MUX(0, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
> > + MUX(0, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
> > + MUX(0, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
> > + MUX(0, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
> > + MUX(0, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
> > +};
> > +
> > +/* List of clock dividers present on all S3C64xx SoCs. */
> > +DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
> > + DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
> > + DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
> > + DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
> > + DIV(0, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
> > + DIV(0, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
> > + DIV(0, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
> > + DIV(0, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
> > + DIV(0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
> > + DIV(0, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
> > + DIV(0, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
> > + DIV(0, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
> > + DIV(0, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
> > + DIV(0, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
> > + DIV(0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
> > + DIV(0, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
> > + DIV(0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
> > + DIV(0, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
> > + DIV(0, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
> > + DIV(0, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
> > +};
> > +
> > +/* List of clock dividers present on S3C6400. */
> > +DIV_CLOCKS(s3c6400_div_clks) __initdata = {
> > + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
> > +};
> > +
> > +/* List of clock dividers present on S3C6410. */
> > +DIV_CLOCKS(s3c6410_div_clks) __initdata = {
> > + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
> > + DIV(0, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
> > + DIV(0, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
> > +};
> > +
> > +/* List of clock gates present on all S3C64xx SoCs. */
> > +GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
> > + GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
> > + GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
> > + GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
> > + GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
> > + GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
> > + GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
> > + GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE, 19),
> > + GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE, 18),
> > + GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE, 17),
> > + GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
> > + GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
> > + GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
> > + GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
> > + GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
> > + GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
> > + GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
> > + GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE, 9),
> > + GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
> > + GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
> > + GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
> > + GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
> > + GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
> > + GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
> > + GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
> > + GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
> > + GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE, 23),
> > + GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
> > + GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
> > + GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
> > + GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
> > + GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
> > + GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
> > + GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
> > + GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
> > + GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
> > + GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
> > + GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
> > + GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE, 11),
> > + GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
> > + GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
> > + GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
> > + GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
> > + GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
> > + GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
> > + GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
> > + GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
> > + GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
> > + GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
> > + GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
> > + GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost", SCLK_GATE,
> > 30), + GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m",
> > SCLK_GATE, 29), + GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48",
> > "clk48m", SCLK_GATE, 28), + GATE_SCLK(SCLK_MMC0_48,
> > "sclk_mmc0_48", "clk48m", SCLK_GATE, 27), +
> > GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26), +
> > GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25), +
> > GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24), +
> > GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE, 23),
> > + GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m", SCLK_GATE,
> > 22), + GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1",
> > SCLK_GATE, 21), + GATE_SCLK(SCLK_SPI0, "sclk_spi0",
> > "dout_spi0", SCLK_GATE, 20), + GATE_SCLK(SCLK_DAC27,
> > "sclk_dac27", "mout_dac27", SCLK_GATE, 19), +
> > GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18), +
> > GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE, 17),
> > + GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler",
> > SCLK_GATE, 16), + GATE_SCLK(SCLK_LCD27, "sclk_lcd27", "clk27m",
> > SCLK_GATE, 15), + GATE_SCLK(SCLK_LCD, "sclk_lcd", "dout_lcd",
> > SCLK_GATE, 14), + GATE_SCLK(SCLK_POST0_27, "sclk_post0_27",
> > "clk27m", SCLK_GATE, 12), + GATE_SCLK(SCLK_POST0, "sclk_post0",
> > "dout_lcd", SCLK_GATE, 10), + GATE_SCLK(SCLK_AUDIO1,
> > "sclk_audio1", "dout_audio1", SCLK_GATE, 9), +
> > GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE, 8), +
> > GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE,
> > 7), + GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda", SCLK_GATE,
> > 6), + GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart", SCLK_GATE,
> > 5), + GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE,
> > 3), + GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE,
> > 2), + GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg", SCLK_GATE,
> > 1), +};
> > +
> > +/* List of clock gates present on S3C6400. */
> > +GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
> > + GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
> > + GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent", SCLK_GATE,
> > 4), +};
> > +
> > +/* List of clock gates present on S3C6410. */
> > +GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
> > + GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
> > + GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
> > + GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
> > + GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
> > + GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
> > + GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
> > + GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
> > + GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE, 13),
> > + GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2",
> > SCLK_GATE, 11), + GATE_BUS(MEM0_CFCON, "mem0_cfcon",
> > "hclk_mem0", MEM0_GATE, 5), + GATE_BUS(MEM0_ONENAND1,
> > "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4), +
> > GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE, 3),
> > + GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE,
> > 2), + GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0", MEM0_GATE,
> > 1), +};
> > +
> > +/* Aliases for common s3c64xx clocks. */
> > +static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
> > + ALIAS(MOUT_EPLL, NULL, "mout_epll"),
> > + ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
> > + ALIAS(HCLKX2, NULL, "hclk2"),
> > + ALIAS(HCLK, NULL, "hclk"),
> > + ALIAS(PCLK, NULL, "pclk"),
> > + ALIAS(PCLK, NULL, "clk_uart_baud2"),
> > + ALIAS(ARMCLK, NULL, "armclk"),
> > + ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
> > + ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
> > + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
> > + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
> > + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
> > + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
> > + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
> > + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
> > + ALIAS(HCLK_DMA1, NULL, "dma1"),
> > + ALIAS(HCLK_DMA0, NULL, "dma0"),
> > + ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
> > + ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
> > + ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
> > + ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
> > + ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
> > + ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
> > + ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
> > + ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
> > + ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
> > + ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
> > + ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
> > + ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
> > + ALIAS(PCLK_PWM, NULL, "timers"),
> > + ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
> > + ALIAS(PCLK_WDT, NULL, "watchdog"),
> > + ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
> > + ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
> > + ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
> > + ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
> > + ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
> > + ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
> > + ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
> > + ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
> > + ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
> > + ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
> > + ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
> > + ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
> > + ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
> > + ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
> > + ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
> > + ALIAS(SCLK_CAM, "s3c-camif", "camera"),
> > +};
> > +
> > +/* Aliases for s3c6400-specific clocks. */
> > +static struct samsung_clock_alias s3c6400_clock_aliases[] = {
> > + /* Nothing to place here yet. */
> > +};
> > +
> > +/* Aliases for s3c6410-specific clocks. */
> > +static struct samsung_clock_alias s3c6410_clock_aliases[] = {
> > + ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
> > + ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
> > + ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
> > + ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
> > + ALIAS(MEM0_SROM, NULL, "srom"),
> > +};
> > +
> > +/*
> > + * Parent of the hclkx2 clock depends on whether the SoC is operating
> > in + * synchronous or asynchronous mode. Depending on value of
> > OTHERS[6] + * (SYNCMUXSEL) bit, it can be either mout_mpll or
> > mout_apll. + */
> > +static void __init s3c64xx_clk_register_hclkx2(void __iomem
> > *reg_base)
> > +{
> > + struct samsung_div_clock hclkx2;
> > + u32 others;
> > +
> > + memset(&hclkx2, 0, sizeof(hclkx2));
> > +
> > + hclkx2.id = HCLKX2;
> > + hclkx2.name = "hclkx2";
> > + hclkx2.offset = CLK_DIV0;
> > + hclkx2.shift = 9;
> > + hclkx2.width = 3;
> > +
> > + others = readl(reg_base + OTHERS);
> > + if (others & OTHERS_SYNCMUXSEL)
> > + hclkx2.parent_name = "mout_apll";
> > + else
> > + hclkx2.parent_name = "mout_mpll";
> > +
> > + samsung_clk_register_div(&hclkx2, 1);
> > +}
> > +
> > +static void __init s3c64xx_clk_register_fixed_ext(unsigned long
> > fin_pll_f, +
> > unsigned long xusbxti_f) +{
> > + s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
> > + s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
> > + samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
> > +
> > ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks)); +}
> > +
> > +static __initdata struct of_device_id ext_clk_match[] = {
> > + { .compatible = "samsung,clock-fin-pll", .data = (void *)0, },
> > + { .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
> > + {},
> > +};
> > +
> > +/* Register s3c64xx clocks. */
> > +void __init s3c64xx_clk_init(struct device_node *np, unsigned long
> > xtal_f, + unsigned long xusbxti_f, bool is_s3c6400,
> > void __iomem *reg_base) +{
> > + struct clk *clk;
> > + unsigned long *soc_regs = NULL;
> > + unsigned long nr_soc_regs = 0;
> > +
> > + if (np) {
> > + reg_base = of_iomap(np, 0);
> > + if (!reg_base)
> > + panic("%s: failed to map registers\n",
> > __func__); + }
> > +
> > + if (!is_s3c6400) {
> > + soc_regs = s3c6410_clk_regs;
> > + nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
> > + }
> > +
> > + samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
> > + ARRAY_SIZE(s3c64xx_clk_regs), soc_regs,
> > nr_soc_regs); +
> > + /* Register external clocks. */
> > + if (np)
> > +
> > samsung_clk_of_register_fixed_ext(s3c64xx_fixed_rate_ext_clks, +
> > ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks), +
> > ext_clk_match);
> > + else
> > + s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
> > +
> > + /* Register PLLs. */
> > + clk = samsung_clk_register_pll6552("fout_apll",
> > + "fin_pll", reg_base +
> > APLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_APLL);
> > +
> > + clk = samsung_clk_register_pll6552("fout_mpll",
> > + "fin_pll", reg_base +
> > MPLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_MPLL);
> > +
> > + clk = samsung_clk_register_pll6553("fout_epll",
> > + "fin_pll", reg_base +
> > EPLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_EPLL);
> > +
> > + /* Register common internal clocks. */
> > + s3c64xx_clk_register_hclkx2(reg_base);
> > +
> > + samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
> > +
> > ARRAY_SIZE(s3c64xx_fixed_rate_clks)); +
> > samsung_clk_register_mux(s3c64xx_mux_clks,
> > + ARRAY_SIZE(s3c64xx_mux_clks));
> > + samsung_clk_register_div(s3c64xx_div_clks,
> > + ARRAY_SIZE(s3c64xx_div_clks));
> > + samsung_clk_register_gate(s3c64xx_gate_clks,
> > +
> > ARRAY_SIZE(s3c64xx_gate_clks));
> > +
> > + /* Register SoC-specific clocks. */
> > + if (is_s3c6400) {
> > + samsung_clk_register_mux(s3c6400_mux_clks,
> > + ARRAY_SIZE(s3c6400_mux_clks));
> > + samsung_clk_register_div(s3c6400_div_clks,
> > + ARRAY_SIZE(s3c6400_div_clks));
> > + samsung_clk_register_gate(s3c6400_gate_clks,
> > +
> > ARRAY_SIZE(s3c6400_gate_clks));
> > + samsung_clk_register_alias(s3c6400_clock_aliases,
> > +
> > ARRAY_SIZE(s3c6400_clock_aliases)); + } else {
> > + samsung_clk_register_mux(s3c6410_mux_clks,
> > + ARRAY_SIZE(s3c6410_mux_clks));
> > + samsung_clk_register_div(s3c6410_div_clks,
> > + ARRAY_SIZE(s3c6410_div_clks));
> > + samsung_clk_register_gate(s3c6410_gate_clks,
> > +
> > ARRAY_SIZE(s3c6410_gate_clks));
> > + samsung_clk_register_alias(s3c6410_clock_aliases,
> > +
> > ARRAY_SIZE(s3c6410_clock_aliases)); + }
> > +
> > + samsung_clk_register_alias(s3c64xx_clock_aliases,
> > +
> > ARRAY_SIZE(s3c64xx_clock_aliases)); +
> > + pr_info("%s clocks: apll = %lu, mpll = %lu\n"
> > + " epll = %lu, arm_clk = %lu\n",
> > + is_s3c6400 ? "S3C6400" : "S3C6410",
> > + _get_rate("fout_apll"), _get_rate("fout_mpll"),
> > + _get_rate("fout_epll"), _get_rate("armclk"));
> > +}
> > +
> > +static void __init s3c6400_clk_init(struct device_node *np)
> > +{
> > + s3c64xx_clk_init(np, 0, 0, true, NULL);
> > +}
> > +CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock",
> > s3c6400_clk_init); +
> > +static void __init s3c6410_clk_init(struct device_node *np)
> > +{
> > + s3c64xx_clk_init(np, 0, 0, false, NULL);
> > +}
> > +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 0000000..3e9a1f9
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/samsung,s3c64xx-clock.h
> > @@ -0,0 +1,144 @@
> > +/*
> > + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify + * it under the terms of the GNU General Public License
> > version 2 as + * published by the Free Software Foundation.
> > + *
> > + * Device Tree binding constants for Samsung S3C64xx clock
> > controller.
> > +*/
> > +
> > +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> > +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> > +
> > +/*
> > + * Let each exported clock get a unique index, which is used on
> > DT-enabled + * platforms to lookup the clock from a clock specifier.
> > These indices are + * therefore considered an ABI and so must not be
> > changed. This implies + * that new clocks should be added either in
> > free spaces between clock groups + * or at the end.
> > + */
> > +
> > +/* Core clocks. */
> > +#define IISCDCLK0 3
> > +#define PCMCDCLK0 4
> > +#define IISCDCLK1 5
> > +#define PCMCDCLK1 6
> > +#define IISCDCLK2 7
> > +#define CLK27M 8
> > +#define CLK48M 9
> > +#define FIN_PLL 10
> > +#define FOUT_APLL 11
> > +#define FOUT_MPLL 12
> > +#define FOUT_EPLL 13
> > +#define ARMCLK 14
> > +#define HCLKX2 15
> > +#define HCLK 16
> > +#define PCLK 17
> > +#define MOUT_EPLL 18
> > +#define DOUT_MPLL 19
> > +
> > +/* HCLK bus clocks. */
> > +#define HCLK_3DSE 32
> > +#define HCLK_UHOST 33
> > +#define HCLK_SECUR 34
> > +#define HCLK_SDMA1 35
> > +#define HCLK_SDMA0 36
> > +#define HCLK_IROM 37
> > +#define HCLK_DDR1 38
> > +#define HCLK_MEM1 39
> > +#define HCLK_MEM0 40
> > +#define HCLK_USB 41
> > +#define HCLK_HSMMC2 42
> > +#define HCLK_HSMMC1 43
> > +#define HCLK_HSMMC0 44
> > +#define HCLK_MDP 45
> > +#define HCLK_DHOST 46
> > +#define HCLK_IHOST 47
> > +#define HCLK_DMA1 48
> > +#define HCLK_DMA0 49
> > +#define HCLK_JPEG 50
> > +#define HCLK_CAMIF 51
> > +#define HCLK_SCALER 52
> > +#define HCLK_2D 53
> > +#define HCLK_TV 54
> > +#define HCLK_POST0 55
> > +#define HCLK_ROT 56
> > +#define HCLK_LCD 57
> > +#define HCLK_TZIC 58
> > +#define HCLK_INTC 59
> > +#define HCLK_MFC 60
> > +#define HCLK_DDR0 61
> > +
> > +/* PCLK bus clocks. */
> > +#define PCLK_IIC1 64
> > +#define PCLK_IIS2 65
> > +#define PCLK_SKEY 66
> > +#define PCLK_CHIPID 67
> > +#define PCLK_SPI1 68
> > +#define PCLK_SPI0 69
> > +#define PCLK_HSIRX 70
> > +#define PCLK_HSITX 71
> > +#define PCLK_GPIO 72
> > +#define PCLK_IIC0 73
> > +#define PCLK_IIS1 74
> > +#define PCLK_IIS0 75
> > +#define PCLK_AC97 76
> > +#define PCLK_TZPC 77
> > +#define PCLK_TSADC 78
> > +#define PCLK_KEYPAD 79
> > +#define PCLK_IRDA 80
> > +#define PCLK_PCM1 81
> > +#define PCLK_PCM0 82
> > +#define PCLK_PWM 83
> > +#define PCLK_RTC 84
> > +#define PCLK_WDT 85
> > +#define PCLK_UART3 86
> > +#define PCLK_UART2 87
> > +#define PCLK_UART1 88
> > +#define PCLK_UART0 89
> > +#define PCLK_MFC 90
> > +
> > +/* Special clocks. */
> > +#define SCLK_UHOST 96
> > +#define SCLK_MMC2_48 97
> > +#define SCLK_MMC1_48 98
> > +#define SCLK_MMC0_48 99
> > +#define SCLK_MMC2 100
> > +#define SCLK_MMC1 101
> > +#define SCLK_MMC0 102
> > +#define SCLK_SPI1_48 103
> > +#define SCLK_SPI0_48 104
> > +#define SCLK_SPI1 105
> > +#define SCLK_SPI0 106
> > +#define SCLK_DAC27 107
> > +#define SCLK_TV27 108
> > +#define SCLK_SCALER27 109
> > +#define SCLK_SCALER 110
> > +#define SCLK_LCD27 111
> > +#define SCLK_LCD 112
> > +#define SCLK_FIMC 113
> > +#define SCLK_POST0_27 114
> > +#define SCLK_AUDIO2 115
> > +#define SCLK_POST0 116
> > +#define SCLK_AUDIO1 117
> > +#define SCLK_AUDIO0 118
> > +#define SCLK_SECUR 119
> > +#define SCLK_IRDA 120
> > +#define SCLK_UART 121
> > +#define SCLK_MFC 122
> > +#define SCLK_CAM 123
> > +#define SCLK_JPEG 124
> > +#define SCLK_ONENAND 125
> > +
> > +/* MEM0 bus clocks - S3C6410-specific. */
> > +#define MEM0_CFCON 128
> > +#define MEM0_ONENAND1 129
> > +#define MEM0_ONENAND0 130
> > +#define MEM0_NFCON 131
> > +#define MEM0_SROM 132
> > +
> > +/* Total number of clocks. */
> > +#define NR_CLKS (MEM0_SROM + 1)
> > +
> > +#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H */
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs
2013-06-12 6:26 ` Tomasz Figa
@ 2013-06-12 16:51 ` Mike Turquette
2013-06-12 21:38 ` Tomasz Figa
0 siblings, 1 reply; 16+ messages in thread
From: Mike Turquette @ 2013-06-12 16:51 UTC (permalink / raw)
To: linux-arm-kernel
Quoting Tomasz Figa (2013-06-11 23:26:54)
> Hi Mike,
>
> On Tuesday 11 of June 2013 19:54:51 Mike Turquette wrote:
> > Quoting Tomasz Figa (2013-06-05 16:57:26)
> >
> > > This patch adds new, Common Clock Framework-based clock driver for
> > > Samsung S3C64xx SoCs. The driver is just added, without actually
> > > letting the platforms use it yet, since this requires more
> > > intermediate steps.
> > It seems like there is an awful lot of clock data here that exists
> > alongside the stuff in DT. Is this how you plan to keep things going
> > forward or is this conversion just an intermediate step?
>
> Current S3C64xx support contains a lot of boards, for which I don't see
> any chance for DT conversion in any time soon, so the driver must cover
> both DT and non-DT cases. (Not even saying that DT support for S3C64xx is
> not yet submitted, as I want to get all the dependencies merged, or at
> least acked, first.)
>
Ah right, you're concerned about both DT and non-DT.
> Also, personally, I don't see anything wrong with having those clocks
> defined in the driver. The binding specifies the exact mapping between
> clock IDs inside the clock provider and hardware clocks and not all clocks
> need to be exported (most of muxes and divs don't need to), so I find it
> more reasonable to define them in the driver instead.
I'm not saying there is anything wrong with it. Other platforms are
doing similar things.
>
> Another thing is that it's unlikely for any new SoC from S3C64xx series to
> show up, so basically the clock list is fixed.
>
Sure. I can take this into clk-next along with patch #1, or if you
prefer:
Acked-by: Mike Turquette <mturquette@linaro.org>
> Best regards,
> Tomasz
>
> > Regards,
> > Mike
> >
> > > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > > ---
> > >
> > > .../bindings/clock/samsung,s3c64xx-clock.txt | 48 ++
> > > drivers/clk/samsung/Makefile | 3 +
> > > drivers/clk/samsung/clk-s3c64xx.c | 503
> > > +++++++++++++++++++++
> > > include/dt-bindings/clock/samsung,s3c64xx-clock.h | 144 ++++++ 4
> > > files changed, 698 insertions(+)
> > > create mode 100644
> > > Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
> > > create mode 100644 drivers/clk/samsung/clk-s3c64xx.c
> > > create mode 100644 include/dt-bindings/clock/samsung,s3c64xx-clock.h
> > >
> > > 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 0000000..278ab6e
> > > --- /dev/null
> > > +++
> > > b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
> > > @@ -0,0 +1,48 @@
> > > +* Samsung S3C64xx Clock Controller
> > > +
> > > +The S3C64xx clock controller generates and supplies clock to various
> > > controllers +within the SoC. The clock binding described here is
> > > applicable to all SoCs in +the S3C64xx family.
> > > +
> > > +Required Properties:
> > > +
> > > +- comptible: should be one of the following.
> > > + - "samsung,s3c6400-clock" - controller compatible with S3C6400 SoC.
> > > + - "samsung,s3c6410-clock" - controller compatible with S3C6410 SoC.
> > > +
> > > +- reg: physical base address of the controller and length of memory
> > > mapped + region.
> > > +
> > > +- #clock-cells: should be 1.
> > > +
> > > +Each clock is assigned an identifier and client nodes can use this
> > > identifier +to specify the clock which they consume. Some of the
> > > clocks are available only +on a particular S3C64xx SoC and this is
> > > specified where applicable. +
> > > +All available clocks are defined as preprocessor macros in
> > > +dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used in
> > > device +tree sources.
> > > +
> > > +Example: Clock controller node:
> > > +
> > > + clocks: clock-controller at 7e00f000 {
> > > + compatible = "samsung,s3c6410-clock";
> > > + reg = <0x7e00f000 0x1000>;
> > > + #clock-cells = <1>;
> > > + };
> > > +
> > > +Example: UART controller node that consumes the clock generated by
> > > the clock + controller (refer to the standard clock bindings for
> > > information about + "clocks" and "clock-names" properties):
> > > +
> > > + uart0: serial at 7f005000 {
> > > + compatible = "samsung,s3c6400-uart";
> > > + reg = <0x7f005000 0x100>;
> > > + interrupt-parent = <&vic1>;
> > > + interrupts = <5>;
> > > + clock-names = "uart", "clk_uart_baud2",
> > > + "clk_uart_baud3";
> > > + clocks = <&clocks PCLK_UART0>, <&clocks
> > > PCLK_UART0>, + <&clocks
> > > SCLK_UART>;
> > > + status = "disabled";
> > > + };
> > > diff --git a/drivers/clk/samsung/Makefile
> > > b/drivers/clk/samsung/Makefile index b7c232e..c023474 100644
> > > --- a/drivers/clk/samsung/Makefile
> > > +++ b/drivers/clk/samsung/Makefile
> > > @@ -6,3 +6,6 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
> > >
> > > obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
> > > obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
> > > obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
> > >
> > > +ifdef CONFIG_COMMON_CLK
> > > +obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
> > > +endif
> > > diff --git a/drivers/clk/samsung/clk-s3c64xx.c
> > > b/drivers/clk/samsung/clk-s3c64xx.c new file mode 100644
> > > index 0000000..253a972
> > > --- /dev/null
> > > +++ b/drivers/clk/samsung/clk-s3c64xx.c
> > > @@ -0,0 +1,503 @@
> > > +/*
> > > + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > modify + * it under the terms of the GNU General Public License
> > > version 2 as + * published by the Free Software Foundation.
> > > + *
> > > + * Common Clock Framework support for all S3C64xx SoCs.
> > > +*/
> > > +
> > > +#include <linux/clk.h>
> > > +#include <linux/clkdev.h>
> > > +#include <linux/clk-provider.h>
> > > +#include <linux/of.h>
> > > +#include <linux/of_address.h>
> > > +
> > > +#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
> > > +
> > > +#include "clk.h"
> > > +#include "clk-pll.h"
> > > +
> > > +/* S3C64xx clock controller register offsets. */
> > > +#define APLL_LOCK 0x000
> > > +#define MPLL_LOCK 0x004
> > > +#define EPLL_LOCK 0x008
> > > +#define APLL_CON 0x00c
> > > +#define MPLL_CON 0x010
> > > +#define EPLL_CON0 0x014
> > > +#define EPLL_CON1 0x018
> > > +#define CLK_SRC 0x01c
> > > +#define CLK_DIV0 0x020
> > > +#define CLK_DIV1 0x024
> > > +#define CLK_DIV2 0x028
> > > +#define HCLK_GATE 0x030
> > > +#define PCLK_GATE 0x034
> > > +#define SCLK_GATE 0x038
> > > +#define MEM0_GATE 0x03c
> > > +#define CLK_SRC2 0x10c
> > > +#define OTHERS 0x900
> > > +
> > > +/* Special bitfields used in the driver. */
> > > +#define OTHERS_SYNCMUXSEL (1 << 6)
> > > +
> > > +/* Helper macros to define clock arrays. */
> > > +#define FIXED_RATE_CLOCKS(name) \
> > > + static struct samsung_fixed_rate_clock name[]
> > > +#define MUX_CLOCKS(name) \
> > > + static struct samsung_mux_clock name[]
> > > +#define DIV_CLOCKS(name) \
> > > + static struct samsung_div_clock name[]
> > > +#define GATE_CLOCKS(name) \
> > > + static struct samsung_gate_clock name[]
> > > +
> > > +/* Helper macros for gate types present on S3C64xx. */
> > > +#define GATE_BUS(_id, cname, pname, o, b) \
> > > + GATE(_id, cname, pname, o, b, 0, 0)
> > > +#define GATE_SCLK(_id, cname, pname, o, b) \
> > > + GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT, 0)
> > > +#define GATE_ON(_id, cname, pname, o, b) \
> > > + GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
> > > +
> > > +/*
> > > + * List of controller registers to be saved and restored during
> > > + * a suspend/resume cycle.
> > > + */
> > > +static __initdata unsigned long s3c64xx_clk_regs[] = {
> > > + APLL_LOCK,
> > > + MPLL_LOCK,
> > > + EPLL_LOCK,
> > > + APLL_CON,
> > > + MPLL_CON,
> > > + EPLL_CON0,
> > > + EPLL_CON1,
> > > + CLK_SRC,
> > > + CLK_DIV0,
> > > + CLK_DIV1,
> > > + CLK_DIV2,
> > > + HCLK_GATE,
> > > + PCLK_GATE,
> > > + SCLK_GATE,
> > > +};
> > > +
> > > +static __initdata unsigned long s3c6410_clk_regs[] = {
> > > + CLK_SRC2,
> > > + MEM0_GATE,
> > > +};
> > > +
> > > +/* List of parent clocks common for all S3C64xx SoCs. */
> > > +PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll",
> > > "clk27m" }; +PNAME(uart_p) = { "mout_epll", "dout_mpll" };
> > > +PNAME(audio0_p) = { "mout_epll", "dout_mpll",
> > > "fin_pll", "iiscdclk0", + "pcmcdclk0",
> > > "none", "none", "none" }; +PNAME(audio1_p) = {
> > > "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1", +
> > > "pcmcdclk0", "none", "none", "none" }; +PNAME(mfc_p)
> > > = { "hclkx2", "mout_epll" };
> > > +PNAME(apll_p) = { "fin_pll", "fout_apll" };
> > > +PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
> > > +PNAME(epll_p) = { "fin_pll", "fout_epll" };
> > > +
> > > +/* S3C6400-specific parent clocks. */
> > > +PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none",
> > > "none" }; +PNAME(irda_p6400) = { "mout_epll", "dout_mpll",
> > > "none", "clk48m" }; +PNAME(uhost_p6400) = { "clk48m",
> > > "mout_epll", "dout_mpll", "none" }; +
> > > +/* S3C6410-specific parent clocks. */
> > > +PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
> > > +PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll",
> > > "fin_pll", "none" }; +PNAME(irda_p6410) = { "mout_epll",
> > > "dout_mpll", "fin_pll", "clk48m" }; +PNAME(uhost_p6410) = {
> > > "clk48m", "mout_epll", "dout_mpll", "fin_pll" }; +PNAME(audio2_p6410)
> > > = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2", +
> > > "pcmcdclk1", "none", "none", "none" }; +
> > > +/* Fixed rate clocks generated outside the SoC. */
> > > +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
> > > + FRATE(FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0),
> > > + FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
> > > +};
> > > +
> > > +/* Fixed rate clocks generated inside the SoC. */
> > > +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
> > > + FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
> > > + FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
> > > +};
> > > +
> > > +/* List of clock muxes present on all S3C64xx SoCs. */
> > > +MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
> > > + MUX(0, "mout_apll", apll_p, CLK_SRC, 0, 1),
> > > + MUX(0, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
> > > + MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
> > > + MUX(0, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
> > > + MUX(0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
> > > + MUX(0, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
> > > + MUX(0, "mout_uart", uart_p, CLK_SRC, 13, 1),
> > > + MUX(0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
> > > + MUX(0, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
> > > + MUX(0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
> > > + MUX(0, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
> > > + MUX(0, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
> > > +};
> > > +
> > > +/* List of clock muxes present on S3C6400. */
> > > +MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
> > > + MUX(0, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
> > > + MUX(0, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
> > > + MUX(0, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
> > > + MUX(0, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
> > > +};
> > > +
> > > +/* List of clock muxes present on S3C6410. */
> > > +MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
> > > + MUX(0, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
> > > + MUX(0, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
> > > + MUX(0, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
> > > + MUX(0, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
> > > + MUX(0, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
> > > + MUX(0, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
> > > + MUX(0, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
> > > +};
> > > +
> > > +/* List of clock dividers present on all S3C64xx SoCs. */
> > > +DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
> > > + DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
> > > + DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
> > > + DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
> > > + DIV(0, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
> > > + DIV(0, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
> > > + DIV(0, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
> > > + DIV(0, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
> > > + DIV(0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
> > > + DIV(0, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
> > > + DIV(0, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
> > > + DIV(0, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
> > > + DIV(0, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
> > > + DIV(0, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
> > > + DIV(0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
> > > + DIV(0, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
> > > + DIV(0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
> > > + DIV(0, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
> > > + DIV(0, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
> > > + DIV(0, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
> > > +};
> > > +
> > > +/* List of clock dividers present on S3C6400. */
> > > +DIV_CLOCKS(s3c6400_div_clks) __initdata = {
> > > + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
> > > +};
> > > +
> > > +/* List of clock dividers present on S3C6410. */
> > > +DIV_CLOCKS(s3c6410_div_clks) __initdata = {
> > > + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
> > > + DIV(0, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
> > > + DIV(0, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
> > > +};
> > > +
> > > +/* List of clock gates present on all S3C64xx SoCs. */
> > > +GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
> > > + GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
> > > + GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
> > > + GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
> > > + GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
> > > + GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
> > > + GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
> > > + GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE, 19),
> > > + GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE, 18),
> > > + GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE, 17),
> > > + GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
> > > + GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
> > > + GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
> > > + GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
> > > + GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
> > > + GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
> > > + GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
> > > + GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE, 9),
> > > + GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
> > > + GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
> > > + GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
> > > + GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
> > > + GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
> > > + GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
> > > + GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
> > > + GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
> > > + GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE, 23),
> > > + GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
> > > + GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
> > > + GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
> > > + GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
> > > + GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
> > > + GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
> > > + GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
> > > + GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
> > > + GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
> > > + GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
> > > + GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
> > > + GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE, 11),
> > > + GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
> > > + GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
> > > + GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
> > > + GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
> > > + GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
> > > + GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
> > > + GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
> > > + GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
> > > + GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
> > > + GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
> > > + GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
> > > + GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost", SCLK_GATE,
> > > 30), + GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m",
> > > SCLK_GATE, 29), + GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48",
> > > "clk48m", SCLK_GATE, 28), + GATE_SCLK(SCLK_MMC0_48,
> > > "sclk_mmc0_48", "clk48m", SCLK_GATE, 27), +
> > > GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26), +
> > > GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25), +
> > > GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24), +
> > > GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE, 23),
> > > + GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m", SCLK_GATE,
> > > 22), + GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1",
> > > SCLK_GATE, 21), + GATE_SCLK(SCLK_SPI0, "sclk_spi0",
> > > "dout_spi0", SCLK_GATE, 20), + GATE_SCLK(SCLK_DAC27,
> > > "sclk_dac27", "mout_dac27", SCLK_GATE, 19), +
> > > GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18), +
> > > GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE, 17),
> > > + GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler",
> > > SCLK_GATE, 16), + GATE_SCLK(SCLK_LCD27, "sclk_lcd27", "clk27m",
> > > SCLK_GATE, 15), + GATE_SCLK(SCLK_LCD, "sclk_lcd", "dout_lcd",
> > > SCLK_GATE, 14), + GATE_SCLK(SCLK_POST0_27, "sclk_post0_27",
> > > "clk27m", SCLK_GATE, 12), + GATE_SCLK(SCLK_POST0, "sclk_post0",
> > > "dout_lcd", SCLK_GATE, 10), + GATE_SCLK(SCLK_AUDIO1,
> > > "sclk_audio1", "dout_audio1", SCLK_GATE, 9), +
> > > GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE, 8), +
> > > GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE,
> > > 7), + GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda", SCLK_GATE,
> > > 6), + GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart", SCLK_GATE,
> > > 5), + GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE,
> > > 3), + GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE,
> > > 2), + GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg", SCLK_GATE,
> > > 1), +};
> > > +
> > > +/* List of clock gates present on S3C6400. */
> > > +GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
> > > + GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
> > > + GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent", SCLK_GATE,
> > > 4), +};
> > > +
> > > +/* List of clock gates present on S3C6410. */
> > > +GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
> > > + GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
> > > + GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
> > > + GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
> > > + GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
> > > + GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
> > > + GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
> > > + GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
> > > + GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE, 13),
> > > + GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2",
> > > SCLK_GATE, 11), + GATE_BUS(MEM0_CFCON, "mem0_cfcon",
> > > "hclk_mem0", MEM0_GATE, 5), + GATE_BUS(MEM0_ONENAND1,
> > > "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4), +
> > > GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE, 3),
> > > + GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE,
> > > 2), + GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0", MEM0_GATE,
> > > 1), +};
> > > +
> > > +/* Aliases for common s3c64xx clocks. */
> > > +static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
> > > + ALIAS(MOUT_EPLL, NULL, "mout_epll"),
> > > + ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
> > > + ALIAS(HCLKX2, NULL, "hclk2"),
> > > + ALIAS(HCLK, NULL, "hclk"),
> > > + ALIAS(PCLK, NULL, "pclk"),
> > > + ALIAS(PCLK, NULL, "clk_uart_baud2"),
> > > + ALIAS(ARMCLK, NULL, "armclk"),
> > > + ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
> > > + ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
> > > + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
> > > + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
> > > + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
> > > + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
> > > + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
> > > + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
> > > + ALIAS(HCLK_DMA1, NULL, "dma1"),
> > > + ALIAS(HCLK_DMA0, NULL, "dma0"),
> > > + ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
> > > + ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
> > > + ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
> > > + ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
> > > + ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
> > > + ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
> > > + ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
> > > + ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
> > > + ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
> > > + ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
> > > + ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
> > > + ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
> > > + ALIAS(PCLK_PWM, NULL, "timers"),
> > > + ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
> > > + ALIAS(PCLK_WDT, NULL, "watchdog"),
> > > + ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
> > > + ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
> > > + ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
> > > + ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
> > > + ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
> > > + ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
> > > + ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
> > > + ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
> > > + ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
> > > + ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
> > > + ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
> > > + ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
> > > + ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
> > > + ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
> > > + ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
> > > + ALIAS(SCLK_CAM, "s3c-camif", "camera"),
> > > +};
> > > +
> > > +/* Aliases for s3c6400-specific clocks. */
> > > +static struct samsung_clock_alias s3c6400_clock_aliases[] = {
> > > + /* Nothing to place here yet. */
> > > +};
> > > +
> > > +/* Aliases for s3c6410-specific clocks. */
> > > +static struct samsung_clock_alias s3c6410_clock_aliases[] = {
> > > + ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
> > > + ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
> > > + ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
> > > + ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
> > > + ALIAS(MEM0_SROM, NULL, "srom"),
> > > +};
> > > +
> > > +/*
> > > + * Parent of the hclkx2 clock depends on whether the SoC is operating
> > > in + * synchronous or asynchronous mode. Depending on value of
> > > OTHERS[6] + * (SYNCMUXSEL) bit, it can be either mout_mpll or
> > > mout_apll. + */
> > > +static void __init s3c64xx_clk_register_hclkx2(void __iomem
> > > *reg_base)
> > > +{
> > > + struct samsung_div_clock hclkx2;
> > > + u32 others;
> > > +
> > > + memset(&hclkx2, 0, sizeof(hclkx2));
> > > +
> > > + hclkx2.id = HCLKX2;
> > > + hclkx2.name = "hclkx2";
> > > + hclkx2.offset = CLK_DIV0;
> > > + hclkx2.shift = 9;
> > > + hclkx2.width = 3;
> > > +
> > > + others = readl(reg_base + OTHERS);
> > > + if (others & OTHERS_SYNCMUXSEL)
> > > + hclkx2.parent_name = "mout_apll";
> > > + else
> > > + hclkx2.parent_name = "mout_mpll";
> > > +
> > > + samsung_clk_register_div(&hclkx2, 1);
> > > +}
> > > +
> > > +static void __init s3c64xx_clk_register_fixed_ext(unsigned long
> > > fin_pll_f, +
> > > unsigned long xusbxti_f) +{
> > > + s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
> > > + s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
> > > + samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
> > > +
> > > ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks)); +}
> > > +
> > > +static __initdata struct of_device_id ext_clk_match[] = {
> > > + { .compatible = "samsung,clock-fin-pll", .data = (void *)0, },
> > > + { .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
> > > + {},
> > > +};
> > > +
> > > +/* Register s3c64xx clocks. */
> > > +void __init s3c64xx_clk_init(struct device_node *np, unsigned long
> > > xtal_f, + unsigned long xusbxti_f, bool is_s3c6400,
> > > void __iomem *reg_base) +{
> > > + struct clk *clk;
> > > + unsigned long *soc_regs = NULL;
> > > + unsigned long nr_soc_regs = 0;
> > > +
> > > + if (np) {
> > > + reg_base = of_iomap(np, 0);
> > > + if (!reg_base)
> > > + panic("%s: failed to map registers\n",
> > > __func__); + }
> > > +
> > > + if (!is_s3c6400) {
> > > + soc_regs = s3c6410_clk_regs;
> > > + nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
> > > + }
> > > +
> > > + samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
> > > + ARRAY_SIZE(s3c64xx_clk_regs), soc_regs,
> > > nr_soc_regs); +
> > > + /* Register external clocks. */
> > > + if (np)
> > > +
> > > samsung_clk_of_register_fixed_ext(s3c64xx_fixed_rate_ext_clks, +
> > > ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks), +
> > > ext_clk_match);
> > > + else
> > > + s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
> > > +
> > > + /* Register PLLs. */
> > > + clk = samsung_clk_register_pll6552("fout_apll",
> > > + "fin_pll", reg_base +
> > > APLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_APLL);
> > > +
> > > + clk = samsung_clk_register_pll6552("fout_mpll",
> > > + "fin_pll", reg_base +
> > > MPLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_MPLL);
> > > +
> > > + clk = samsung_clk_register_pll6553("fout_epll",
> > > + "fin_pll", reg_base +
> > > EPLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_EPLL);
> > > +
> > > + /* Register common internal clocks. */
> > > + s3c64xx_clk_register_hclkx2(reg_base);
> > > +
> > > + samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
> > > +
> > > ARRAY_SIZE(s3c64xx_fixed_rate_clks)); +
> > > samsung_clk_register_mux(s3c64xx_mux_clks,
> > > + ARRAY_SIZE(s3c64xx_mux_clks));
> > > + samsung_clk_register_div(s3c64xx_div_clks,
> > > + ARRAY_SIZE(s3c64xx_div_clks));
> > > + samsung_clk_register_gate(s3c64xx_gate_clks,
> > > +
> > > ARRAY_SIZE(s3c64xx_gate_clks));
> > > +
> > > + /* Register SoC-specific clocks. */
> > > + if (is_s3c6400) {
> > > + samsung_clk_register_mux(s3c6400_mux_clks,
> > > + ARRAY_SIZE(s3c6400_mux_clks));
> > > + samsung_clk_register_div(s3c6400_div_clks,
> > > + ARRAY_SIZE(s3c6400_div_clks));
> > > + samsung_clk_register_gate(s3c6400_gate_clks,
> > > +
> > > ARRAY_SIZE(s3c6400_gate_clks));
> > > + samsung_clk_register_alias(s3c6400_clock_aliases,
> > > +
> > > ARRAY_SIZE(s3c6400_clock_aliases)); + } else {
> > > + samsung_clk_register_mux(s3c6410_mux_clks,
> > > + ARRAY_SIZE(s3c6410_mux_clks));
> > > + samsung_clk_register_div(s3c6410_div_clks,
> > > + ARRAY_SIZE(s3c6410_div_clks));
> > > + samsung_clk_register_gate(s3c6410_gate_clks,
> > > +
> > > ARRAY_SIZE(s3c6410_gate_clks));
> > > + samsung_clk_register_alias(s3c6410_clock_aliases,
> > > +
> > > ARRAY_SIZE(s3c6410_clock_aliases)); + }
> > > +
> > > + samsung_clk_register_alias(s3c64xx_clock_aliases,
> > > +
> > > ARRAY_SIZE(s3c64xx_clock_aliases)); +
> > > + pr_info("%s clocks: apll = %lu, mpll = %lu\n"
> > > + " epll = %lu, arm_clk = %lu\n",
> > > + is_s3c6400 ? "S3C6400" : "S3C6410",
> > > + _get_rate("fout_apll"), _get_rate("fout_mpll"),
> > > + _get_rate("fout_epll"), _get_rate("armclk"));
> > > +}
> > > +
> > > +static void __init s3c6400_clk_init(struct device_node *np)
> > > +{
> > > + s3c64xx_clk_init(np, 0, 0, true, NULL);
> > > +}
> > > +CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock",
> > > s3c6400_clk_init); +
> > > +static void __init s3c6410_clk_init(struct device_node *np)
> > > +{
> > > + s3c64xx_clk_init(np, 0, 0, false, NULL);
> > > +}
> > > +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 0000000..3e9a1f9
> > > --- /dev/null
> > > +++ b/include/dt-bindings/clock/samsung,s3c64xx-clock.h
> > > @@ -0,0 +1,144 @@
> > > +/*
> > > + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > modify + * it under the terms of the GNU General Public License
> > > version 2 as + * published by the Free Software Foundation.
> > > + *
> > > + * Device Tree binding constants for Samsung S3C64xx clock
> > > controller.
> > > +*/
> > > +
> > > +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> > > +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> > > +
> > > +/*
> > > + * Let each exported clock get a unique index, which is used on
> > > DT-enabled + * platforms to lookup the clock from a clock specifier.
> > > These indices are + * therefore considered an ABI and so must not be
> > > changed. This implies + * that new clocks should be added either in
> > > free spaces between clock groups + * or at the end.
> > > + */
> > > +
> > > +/* Core clocks. */
> > > +#define IISCDCLK0 3
> > > +#define PCMCDCLK0 4
> > > +#define IISCDCLK1 5
> > > +#define PCMCDCLK1 6
> > > +#define IISCDCLK2 7
> > > +#define CLK27M 8
> > > +#define CLK48M 9
> > > +#define FIN_PLL 10
> > > +#define FOUT_APLL 11
> > > +#define FOUT_MPLL 12
> > > +#define FOUT_EPLL 13
> > > +#define ARMCLK 14
> > > +#define HCLKX2 15
> > > +#define HCLK 16
> > > +#define PCLK 17
> > > +#define MOUT_EPLL 18
> > > +#define DOUT_MPLL 19
> > > +
> > > +/* HCLK bus clocks. */
> > > +#define HCLK_3DSE 32
> > > +#define HCLK_UHOST 33
> > > +#define HCLK_SECUR 34
> > > +#define HCLK_SDMA1 35
> > > +#define HCLK_SDMA0 36
> > > +#define HCLK_IROM 37
> > > +#define HCLK_DDR1 38
> > > +#define HCLK_MEM1 39
> > > +#define HCLK_MEM0 40
> > > +#define HCLK_USB 41
> > > +#define HCLK_HSMMC2 42
> > > +#define HCLK_HSMMC1 43
> > > +#define HCLK_HSMMC0 44
> > > +#define HCLK_MDP 45
> > > +#define HCLK_DHOST 46
> > > +#define HCLK_IHOST 47
> > > +#define HCLK_DMA1 48
> > > +#define HCLK_DMA0 49
> > > +#define HCLK_JPEG 50
> > > +#define HCLK_CAMIF 51
> > > +#define HCLK_SCALER 52
> > > +#define HCLK_2D 53
> > > +#define HCLK_TV 54
> > > +#define HCLK_POST0 55
> > > +#define HCLK_ROT 56
> > > +#define HCLK_LCD 57
> > > +#define HCLK_TZIC 58
> > > +#define HCLK_INTC 59
> > > +#define HCLK_MFC 60
> > > +#define HCLK_DDR0 61
> > > +
> > > +/* PCLK bus clocks. */
> > > +#define PCLK_IIC1 64
> > > +#define PCLK_IIS2 65
> > > +#define PCLK_SKEY 66
> > > +#define PCLK_CHIPID 67
> > > +#define PCLK_SPI1 68
> > > +#define PCLK_SPI0 69
> > > +#define PCLK_HSIRX 70
> > > +#define PCLK_HSITX 71
> > > +#define PCLK_GPIO 72
> > > +#define PCLK_IIC0 73
> > > +#define PCLK_IIS1 74
> > > +#define PCLK_IIS0 75
> > > +#define PCLK_AC97 76
> > > +#define PCLK_TZPC 77
> > > +#define PCLK_TSADC 78
> > > +#define PCLK_KEYPAD 79
> > > +#define PCLK_IRDA 80
> > > +#define PCLK_PCM1 81
> > > +#define PCLK_PCM0 82
> > > +#define PCLK_PWM 83
> > > +#define PCLK_RTC 84
> > > +#define PCLK_WDT 85
> > > +#define PCLK_UART3 86
> > > +#define PCLK_UART2 87
> > > +#define PCLK_UART1 88
> > > +#define PCLK_UART0 89
> > > +#define PCLK_MFC 90
> > > +
> > > +/* Special clocks. */
> > > +#define SCLK_UHOST 96
> > > +#define SCLK_MMC2_48 97
> > > +#define SCLK_MMC1_48 98
> > > +#define SCLK_MMC0_48 99
> > > +#define SCLK_MMC2 100
> > > +#define SCLK_MMC1 101
> > > +#define SCLK_MMC0 102
> > > +#define SCLK_SPI1_48 103
> > > +#define SCLK_SPI0_48 104
> > > +#define SCLK_SPI1 105
> > > +#define SCLK_SPI0 106
> > > +#define SCLK_DAC27 107
> > > +#define SCLK_TV27 108
> > > +#define SCLK_SCALER27 109
> > > +#define SCLK_SCALER 110
> > > +#define SCLK_LCD27 111
> > > +#define SCLK_LCD 112
> > > +#define SCLK_FIMC 113
> > > +#define SCLK_POST0_27 114
> > > +#define SCLK_AUDIO2 115
> > > +#define SCLK_POST0 116
> > > +#define SCLK_AUDIO1 117
> > > +#define SCLK_AUDIO0 118
> > > +#define SCLK_SECUR 119
> > > +#define SCLK_IRDA 120
> > > +#define SCLK_UART 121
> > > +#define SCLK_MFC 122
> > > +#define SCLK_CAM 123
> > > +#define SCLK_JPEG 124
> > > +#define SCLK_ONENAND 125
> > > +
> > > +/* MEM0 bus clocks - S3C6410-specific. */
> > > +#define MEM0_CFCON 128
> > > +#define MEM0_ONENAND1 129
> > > +#define MEM0_ONENAND0 130
> > > +#define MEM0_NFCON 131
> > > +#define MEM0_SROM 132
> > > +
> > > +/* Total number of clocks. */
> > > +#define NR_CLKS (MEM0_SROM + 1)
> > > +
> > > +#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H */
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs
2013-06-12 16:51 ` Mike Turquette
@ 2013-06-12 21:38 ` Tomasz Figa
2013-06-19 14:18 ` Kukjin Kim
0 siblings, 1 reply; 16+ messages in thread
From: Tomasz Figa @ 2013-06-12 21:38 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 12 of June 2013 09:51:08 Mike Turquette wrote:
> Quoting Tomasz Figa (2013-06-11 23:26:54)
>
> > Hi Mike,
> >
> > On Tuesday 11 of June 2013 19:54:51 Mike Turquette wrote:
> > > Quoting Tomasz Figa (2013-06-05 16:57:26)
> > >
> > > > This patch adds new, Common Clock Framework-based clock driver for
> > > > Samsung S3C64xx SoCs. The driver is just added, without actually
> > > > letting the platforms use it yet, since this requires more
> > > > intermediate steps.
> > >
> > > It seems like there is an awful lot of clock data here that exists
> > > alongside the stuff in DT. Is this how you plan to keep things
> > > going
> > > forward or is this conversion just an intermediate step?
> >
> > Current S3C64xx support contains a lot of boards, for which I don't
> > see
> > any chance for DT conversion in any time soon, so the driver must
> > cover
> > both DT and non-DT cases. (Not even saying that DT support for S3C64xx
> > is not yet submitted, as I want to get all the dependencies merged,
> > or at least acked, first.)
>
> Ah right, you're concerned about both DT and non-DT.
>
> > Also, personally, I don't see anything wrong with having those clocks
> > defined in the driver. The binding specifies the exact mapping between
> > clock IDs inside the clock provider and hardware clocks and not all
> > clocks need to be exported (most of muxes and divs don't need to), so
> > I find it more reasonable to define them in the driver instead.
>
> I'm not saying there is anything wrong with it. Other platforms are
> doing similar things.
OK. I have observed some signs of moving all clock definitions to DT in
case of some platforms, which ends up with a lot of nodes, phandles and
data to parse in general without any specific need or advantage.
Good to hear that you are fine with the solution I used for this driver as
well.
> > Another thing is that it's unlikely for any new SoC from S3C64xx
> > series to show up, so basically the clock list is fixed.
>
> Sure. I can take this into clk-next along with patch #1, or if you
> prefer:
>
> Acked-by: Mike Turquette <mturquette@linaro.org>
Thanks.
IMHO with all the remaining platform patches in this series, it should go
through Samsung tree.
Best regards,
Tomasz
> > Best regards,
> > Tomasz
> >
> > > Regards,
> > > Mike
> > >
> > > > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> > > > ---
> > > >
> > > > .../bindings/clock/samsung,s3c64xx-clock.txt | 48 ++
> > > > drivers/clk/samsung/Makefile | 3 +
> > > > drivers/clk/samsung/clk-s3c64xx.c | 503
> > > > +++++++++++++++++++++
> > > > include/dt-bindings/clock/samsung,s3c64xx-clock.h | 144 ++++++ 4
> > > > files changed, 698 insertions(+)
> > > > create mode 100644
> > > > Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt
> > > > create mode 100644 drivers/clk/samsung/clk-s3c64xx.c
> > > > create mode 100644
> > > > include/dt-bindings/clock/samsung,s3c64xx-clock.h
> > > >
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.tx
> > > > t
> > > > b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.tx
> > > > t
> > > > new file mode 100644
> > > > index 0000000..278ab6e
> > > > --- /dev/null
> > > > +++
> > > > b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.tx
> > > > t
> > > > @@ -0,0 +1,48 @@
> > > > +* Samsung S3C64xx Clock Controller
> > > > +
> > > > +The S3C64xx clock controller generates and supplies clock to
> > > > various
> > > > controllers +within the SoC. The clock binding described here is
> > > > applicable to all SoCs in +the S3C64xx family.
> > > > +
> > > > +Required Properties:
> > > > +
> > > > +- comptible: should be one of the following.
> > > > + - "samsung,s3c6400-clock" - controller compatible with S3C6400
> > > > SoC.
> > > > + - "samsung,s3c6410-clock" - controller compatible with S3C6410
> > > > SoC.
> > > > +
> > > > +- reg: physical base address of the controller and length of
> > > > memory
> > > > mapped + region.
> > > > +
> > > > +- #clock-cells: should be 1.
> > > > +
> > > > +Each clock is assigned an identifier and client nodes can use
> > > > this
> > > > identifier +to specify the clock which they consume. Some of the
> > > > clocks are available only +on a particular S3C64xx SoC and this is
> > > > specified where applicable. +
> > > > +All available clocks are defined as preprocessor macros in
> > > > +dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used
> > > > in
> > > > device +tree sources.
> > > > +
> > > > +Example: Clock controller node:
> > > > +
> > > > + clocks: clock-controller at 7e00f000 {
> > > > + compatible = "samsung,s3c6410-clock";
> > > > + reg = <0x7e00f000 0x1000>;
> > > > + #clock-cells = <1>;
> > > > + };
> > > > +
> > > > +Example: UART controller node that consumes the clock generated
> > > > by
> > > > the clock + controller (refer to the standard clock bindings for
> > > > information about + "clocks" and "clock-names" properties):
> > > > +
> > > > + uart0: serial at 7f005000 {
> > > > + compatible = "samsung,s3c6400-uart";
> > > > + reg = <0x7f005000 0x100>;
> > > > + interrupt-parent = <&vic1>;
> > > > + interrupts = <5>;
> > > > + clock-names = "uart", "clk_uart_baud2",
> > > > + "clk_uart_baud3";
> > > > + clocks = <&clocks PCLK_UART0>, <&clocks
> > > > PCLK_UART0>, + <&clocks
> > > > SCLK_UART>;
> > > > + status = "disabled";
> > > > + };
> > > > diff --git a/drivers/clk/samsung/Makefile
> > > > b/drivers/clk/samsung/Makefile index b7c232e..c023474 100644
> > > > --- a/drivers/clk/samsung/Makefile
> > > > +++ b/drivers/clk/samsung/Makefile
> > > > @@ -6,3 +6,6 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
> > > >
> > > > obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
> > > > obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
> > > > obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
> > > >
> > > > +ifdef CONFIG_COMMON_CLK
> > > > +obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
> > > > +endif
> > > > diff --git a/drivers/clk/samsung/clk-s3c64xx.c
> > > > b/drivers/clk/samsung/clk-s3c64xx.c new file mode 100644
> > > > index 0000000..253a972
> > > > --- /dev/null
> > > > +++ b/drivers/clk/samsung/clk-s3c64xx.c
> > > > @@ -0,0 +1,503 @@
> > > > +/*
> > > > + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> > > > + *
> > > > + * This program is free software; you can redistribute it and/or
> > > > modify + * it under the terms of the GNU General Public License
> > > > version 2 as + * published by the Free Software Foundation.
> > > > + *
> > > > + * Common Clock Framework support for all S3C64xx SoCs.
> > > > +*/
> > > > +
> > > > +#include <linux/clk.h>
> > > > +#include <linux/clkdev.h>
> > > > +#include <linux/clk-provider.h>
> > > > +#include <linux/of.h>
> > > > +#include <linux/of_address.h>
> > > > +
> > > > +#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
> > > > +
> > > > +#include "clk.h"
> > > > +#include "clk-pll.h"
> > > > +
> > > > +/* S3C64xx clock controller register offsets. */
> > > > +#define APLL_LOCK 0x000
> > > > +#define MPLL_LOCK 0x004
> > > > +#define EPLL_LOCK 0x008
> > > > +#define APLL_CON 0x00c
> > > > +#define MPLL_CON 0x010
> > > > +#define EPLL_CON0 0x014
> > > > +#define EPLL_CON1 0x018
> > > > +#define CLK_SRC 0x01c
> > > > +#define CLK_DIV0 0x020
> > > > +#define CLK_DIV1 0x024
> > > > +#define CLK_DIV2 0x028
> > > > +#define HCLK_GATE 0x030
> > > > +#define PCLK_GATE 0x034
> > > > +#define SCLK_GATE 0x038
> > > > +#define MEM0_GATE 0x03c
> > > > +#define CLK_SRC2 0x10c
> > > > +#define OTHERS 0x900
> > > > +
> > > > +/* Special bitfields used in the driver. */
> > > > +#define OTHERS_SYNCMUXSEL (1 << 6)
> > > > +
> > > > +/* Helper macros to define clock arrays. */
> > > > +#define FIXED_RATE_CLOCKS(name) \
> > > > + static struct samsung_fixed_rate_clock name[]
> > > > +#define MUX_CLOCKS(name) \
> > > > + static struct samsung_mux_clock name[]
> > > > +#define DIV_CLOCKS(name) \
> > > > + static struct samsung_div_clock name[]
> > > > +#define GATE_CLOCKS(name) \
> > > > + static struct samsung_gate_clock name[]
> > > > +
> > > > +/* Helper macros for gate types present on S3C64xx. */
> > > > +#define GATE_BUS(_id, cname, pname, o, b) \
> > > > + GATE(_id, cname, pname, o, b, 0, 0)
> > > > +#define GATE_SCLK(_id, cname, pname, o, b) \
> > > > + GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT,
> > > > 0)
> > > > +#define GATE_ON(_id, cname, pname, o, b) \
> > > > + GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED,
> > > > 0)
> > > > +
> > > > +/*
> > > > + * List of controller registers to be saved and restored during
> > > > + * a suspend/resume cycle.
> > > > + */
> > > > +static __initdata unsigned long s3c64xx_clk_regs[] = {
> > > > + APLL_LOCK,
> > > > + MPLL_LOCK,
> > > > + EPLL_LOCK,
> > > > + APLL_CON,
> > > > + MPLL_CON,
> > > > + EPLL_CON0,
> > > > + EPLL_CON1,
> > > > + CLK_SRC,
> > > > + CLK_DIV0,
> > > > + CLK_DIV1,
> > > > + CLK_DIV2,
> > > > + HCLK_GATE,
> > > > + PCLK_GATE,
> > > > + SCLK_GATE,
> > > > +};
> > > > +
> > > > +static __initdata unsigned long s3c6410_clk_regs[] = {
> > > > + CLK_SRC2,
> > > > + MEM0_GATE,
> > > > +};
> > > > +
> > > > +/* List of parent clocks common for all S3C64xx SoCs. */
> > > > +PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll",
> > > > "clk27m" }; +PNAME(uart_p) = { "mout_epll", "dout_mpll"
> > > > };
> > > > +PNAME(audio0_p) = { "mout_epll", "dout_mpll",
> > > > "fin_pll", "iiscdclk0", +
> > > > "pcmcdclk0",
> > > > "none", "none", "none" }; +PNAME(audio1_p) = {
> > > > "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1", +
> > > >
> > > > "pcmcdclk0", "none", "none", "none" }; +PNAME(mfc_p)
> > > >
> > > > = { "hclkx2", "mout_epll" };
> > > >
> > > > +PNAME(apll_p) = { "fin_pll", "fout_apll" };
> > > > +PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
> > > > +PNAME(epll_p) = { "fin_pll", "fout_epll" };
> > > > +
> > > > +/* S3C6400-specific parent clocks. */
> > > > +PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll",
> > > > "none",
> > > > "none" }; +PNAME(irda_p6400) = { "mout_epll", "dout_mpll",
> > > > "none", "clk48m" }; +PNAME(uhost_p6400) = { "clk48m",
> > > > "mout_epll", "dout_mpll", "none" }; +
> > > > +/* S3C6410-specific parent clocks. */
> > > > +PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
> > > > +PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll",
> > > > "fin_pll", "none" }; +PNAME(irda_p6410) = { "mout_epll",
> > > > "dout_mpll", "fin_pll", "clk48m" }; +PNAME(uhost_p6410) = {
> > > > "clk48m", "mout_epll", "dout_mpll", "fin_pll" };
> > > > +PNAME(audio2_p6410)
> > > >
> > > > = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2", +
> > > >
> > > > "pcmcdclk1", "none", "none", "none" }; +
> > > >
> > > > +/* Fixed rate clocks generated outside the SoC. */
> > > > +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
> > > > + FRATE(FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0),
> > > > + FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
> > > > +};
> > > > +
> > > > +/* Fixed rate clocks generated inside the SoC. */
> > > > +FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
> > > > + FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
> > > > + FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
> > > > +};
> > > > +
> > > > +/* List of clock muxes present on all S3C64xx SoCs. */
> > > > +MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
> > > > + MUX(0, "mout_apll", apll_p, CLK_SRC, 0, 1),
> > > > + MUX(0, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
> > > > + MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
> > > > + MUX(0, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
> > > > + MUX(0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
> > > > + MUX(0, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
> > > > + MUX(0, "mout_uart", uart_p, CLK_SRC, 13, 1),
> > > > + MUX(0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
> > > > + MUX(0, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
> > > > + MUX(0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
> > > > + MUX(0, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
> > > > + MUX(0, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
> > > > +};
> > > > +
> > > > +/* List of clock muxes present on S3C6400. */
> > > > +MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
> > > > + MUX(0, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
> > > > + MUX(0, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
> > > > + MUX(0, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
> > > > + MUX(0, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
> > > > +};
> > > > +
> > > > +/* List of clock muxes present on S3C6410. */
> > > > +MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
> > > > + MUX(0, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
> > > > + MUX(0, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
> > > > + MUX(0, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
> > > > + MUX(0, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
> > > > + MUX(0, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
> > > > + MUX(0, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
> > > > + MUX(0, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
> > > > +};
> > > > +
> > > > +/* List of clock dividers present on all S3C64xx SoCs. */
> > > > +DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
> > > > + DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
> > > > + DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
> > > > + DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
> > > > + DIV(0, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
> > > > + DIV(0, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
> > > > + DIV(0, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
> > > > + DIV(0, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
> > > > + DIV(0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
> > > > + DIV(0, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
> > > > + DIV(0, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
> > > > + DIV(0, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
> > > > + DIV(0, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
> > > > + DIV(0, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
> > > > + DIV(0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
> > > > + DIV(0, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
> > > > + DIV(0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
> > > > + DIV(0, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
> > > > + DIV(0, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
> > > > + DIV(0, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
> > > > +};
> > > > +
> > > > +/* List of clock dividers present on S3C6400. */
> > > > +DIV_CLOCKS(s3c6400_div_clks) __initdata = {
> > > > + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
> > > > +};
> > > > +
> > > > +/* List of clock dividers present on S3C6410. */
> > > > +DIV_CLOCKS(s3c6410_div_clks) __initdata = {
> > > > + DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
> > > > + DIV(0, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
> > > > + DIV(0, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
> > > > +};
> > > > +
> > > > +/* List of clock gates present on all S3C64xx SoCs. */
> > > > +GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
> > > > + GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
> > > > + GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
> > > > + GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
> > > > + GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
> > > > + GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
> > > > + GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
> > > > + GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE,
> > > > 19),
> > > > + GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE,
> > > > 18),
> > > > + GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE,
> > > > 17),
> > > > + GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
> > > > + GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
> > > > + GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
> > > > + GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
> > > > + GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
> > > > + GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
> > > > + GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
> > > > + GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE,
> > > > 9),
> > > > + GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
> > > > + GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
> > > > + GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
> > > > + GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
> > > > + GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
> > > > + GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
> > > > + GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
> > > > + GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
> > > > + GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE,
> > > > 23),
> > > > + GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
> > > > + GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
> > > > + GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
> > > > + GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
> > > > + GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
> > > > + GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
> > > > + GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
> > > > + GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
> > > > + GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
> > > > + GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
> > > > + GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
> > > > + GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE,
> > > > 11),
> > > > + GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
> > > > + GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
> > > > + GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
> > > > + GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
> > > > + GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
> > > > + GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
> > > > + GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
> > > > + GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
> > > > + GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
> > > > + GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
> > > > + GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
> > > > + GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost",
> > > > SCLK_GATE,
> > > > 30), + GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m",
> > > > SCLK_GATE, 29), + GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48",
> > > > "clk48m", SCLK_GATE, 28), + GATE_SCLK(SCLK_MMC0_48,
> > > > "sclk_mmc0_48", "clk48m", SCLK_GATE, 27), +
> > > > GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26), +
> > > >
> > > > GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25), +
> > > >
> > > > GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24), +
> > > >
> > > > GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE,
> > > > 23),
> > > >
> > > > + GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m",
> > > > SCLK_GATE,
> > > > 22), + GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1",
> > > > SCLK_GATE, 21), + GATE_SCLK(SCLK_SPI0, "sclk_spi0",
> > > > "dout_spi0", SCLK_GATE, 20), + GATE_SCLK(SCLK_DAC27,
> > > > "sclk_dac27", "mout_dac27", SCLK_GATE, 19), +
> > > > GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18), +
> > > >
> > > > GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE,
> > > > 17),
> > > >
> > > > + GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler",
> > > > SCLK_GATE, 16), + GATE_SCLK(SCLK_LCD27, "sclk_lcd27",
> > > > "clk27m",
> > > > SCLK_GATE, 15), + GATE_SCLK(SCLK_LCD, "sclk_lcd",
> > > > "dout_lcd",
> > > > SCLK_GATE, 14), + GATE_SCLK(SCLK_POST0_27, "sclk_post0_27",
> > > > "clk27m", SCLK_GATE, 12), + GATE_SCLK(SCLK_POST0,
> > > > "sclk_post0",
> > > > "dout_lcd", SCLK_GATE, 10), + GATE_SCLK(SCLK_AUDIO1,
> > > > "sclk_audio1", "dout_audio1", SCLK_GATE, 9), +
> > > > GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE,
> > > > 8), +
> > > >
> > > > GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE,
> > > >
> > > > 7), + GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda",
> > > > SCLK_GATE,
> > > > 6), + GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart",
> > > > SCLK_GATE,
> > > > 5), + GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE,
> > > > 3), + GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE,
> > > > 2), + GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg",
> > > > SCLK_GATE,
> > > > 1), +};
> > > > +
> > > > +/* List of clock gates present on S3C6400. */
> > > > +GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
> > > > + GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
> > > > + GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent",
> > > > SCLK_GATE,
> > > > 4), +};
> > > > +
> > > > +/* List of clock gates present on S3C6410. */
> > > > +GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
> > > > + GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
> > > > + GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
> > > > + GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
> > > > + GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
> > > > + GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
> > > > + GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
> > > > + GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
> > > > + GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE,
> > > > 13),
> > > > + GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2",
> > > > SCLK_GATE, 11), + GATE_BUS(MEM0_CFCON, "mem0_cfcon",
> > > > "hclk_mem0", MEM0_GATE, 5), + GATE_BUS(MEM0_ONENAND1,
> > > > "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4), +
> > > > GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE,
> > > > 3),
> > > > + GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE,
> > > > 2), + GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0",
> > > > MEM0_GATE,
> > > > 1), +};
> > > > +
> > > > +/* Aliases for common s3c64xx clocks. */
> > > > +static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
> > > > + ALIAS(MOUT_EPLL, NULL, "mout_epll"),
> > > > + ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
> > > > + ALIAS(HCLKX2, NULL, "hclk2"),
> > > > + ALIAS(HCLK, NULL, "hclk"),
> > > > + ALIAS(PCLK, NULL, "pclk"),
> > > > + ALIAS(PCLK, NULL, "clk_uart_baud2"),
> > > > + ALIAS(ARMCLK, NULL, "armclk"),
> > > > + ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
> > > > + ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
> > > > + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
> > > > + ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
> > > > + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
> > > > + ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
> > > > + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
> > > > + ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
> > > > + ALIAS(HCLK_DMA1, NULL, "dma1"),
> > > > + ALIAS(HCLK_DMA0, NULL, "dma0"),
> > > > + ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
> > > > + ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
> > > > + ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
> > > > + ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
> > > > + ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
> > > > + ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
> > > > + ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
> > > > + ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
> > > > + ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
> > > > + ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
> > > > + ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
> > > > + ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
> > > > + ALIAS(PCLK_PWM, NULL, "timers"),
> > > > + ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
> > > > + ALIAS(PCLK_WDT, NULL, "watchdog"),
> > > > + ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
> > > > + ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
> > > > + ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
> > > > + ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
> > > > + ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
> > > > + ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
> > > > + ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
> > > > + ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
> > > > + ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
> > > > + ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
> > > > + ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
> > > > + ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
> > > > + ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
> > > > + ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
> > > > + ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
> > > > + ALIAS(SCLK_CAM, "s3c-camif", "camera"),
> > > > +};
> > > > +
> > > > +/* Aliases for s3c6400-specific clocks. */
> > > > +static struct samsung_clock_alias s3c6400_clock_aliases[] = {
> > > > + /* Nothing to place here yet. */
> > > > +};
> > > > +
> > > > +/* Aliases for s3c6410-specific clocks. */
> > > > +static struct samsung_clock_alias s3c6410_clock_aliases[] = {
> > > > + ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
> > > > + ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
> > > > + ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
> > > > + ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
> > > > + ALIAS(MEM0_SROM, NULL, "srom"),
> > > > +};
> > > > +
> > > > +/*
> > > > + * Parent of the hclkx2 clock depends on whether the SoC is
> > > > operating
> > > > in + * synchronous or asynchronous mode. Depending on value of
> > > > OTHERS[6] + * (SYNCMUXSEL) bit, it can be either mout_mpll or
> > > > mout_apll. + */
> > > > +static void __init s3c64xx_clk_register_hclkx2(void __iomem
> > > > *reg_base)
> > > > +{
> > > > + struct samsung_div_clock hclkx2;
> > > > + u32 others;
> > > > +
> > > > + memset(&hclkx2, 0, sizeof(hclkx2));
> > > > +
> > > > + hclkx2.id = HCLKX2;
> > > > + hclkx2.name = "hclkx2";
> > > > + hclkx2.offset = CLK_DIV0;
> > > > + hclkx2.shift = 9;
> > > > + hclkx2.width = 3;
> > > > +
> > > > + others = readl(reg_base + OTHERS);
> > > > + if (others & OTHERS_SYNCMUXSEL)
> > > > + hclkx2.parent_name = "mout_apll";
> > > > + else
> > > > + hclkx2.parent_name = "mout_mpll";
> > > > +
> > > > + samsung_clk_register_div(&hclkx2, 1);
> > > > +}
> > > > +
> > > > +static void __init s3c64xx_clk_register_fixed_ext(unsigned long
> > > > fin_pll_f, +
> > > > unsigned long xusbxti_f) +{
> > > > + s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
> > > > + s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
> > > > +
> > > > samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
> > > > +
> > > > ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks)); +}
> > > > +
> > > > +static __initdata struct of_device_id ext_clk_match[] = {
> > > > + { .compatible = "samsung,clock-fin-pll", .data = (void
> > > > *)0, },
> > > > + { .compatible = "samsung,clock-xusbxti", .data = (void
> > > > *)1, },
> > > > + {},
> > > > +};
> > > > +
> > > > +/* Register s3c64xx clocks. */
> > > > +void __init s3c64xx_clk_init(struct device_node *np, unsigned
> > > > long
> > > > xtal_f, + unsigned long xusbxti_f, bool is_s3c6400,
> > > > void __iomem *reg_base) +{
> > > > + struct clk *clk;
> > > > + unsigned long *soc_regs = NULL;
> > > > + unsigned long nr_soc_regs = 0;
> > > > +
> > > > + if (np) {
> > > > + reg_base = of_iomap(np, 0);
> > > > + if (!reg_base)
> > > > + panic("%s: failed to map registers\n",
> > > > __func__); + }
> > > > +
> > > > + if (!is_s3c6400) {
> > > > + soc_regs = s3c6410_clk_regs;
> > > > + nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
> > > > + }
> > > > +
> > > > + samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
> > > > + ARRAY_SIZE(s3c64xx_clk_regs), soc_regs,
> > > > nr_soc_regs); +
> > > > + /* Register external clocks. */
> > > > + if (np)
> > > > +
> > > > samsung_clk_of_register_fixed_ext(s3c64xx_fixed_rate_ext_clks, +
> > > >
> > > > ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks), +
> > > >
> > > > ext_clk_match);
> > > >
> > > > + else
> > > > + s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
> > > > +
> > > > + /* Register PLLs. */
> > > > + clk = samsung_clk_register_pll6552("fout_apll",
> > > > + "fin_pll", reg_base +
> > > > APLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_APLL);
> > > > +
> > > > + clk = samsung_clk_register_pll6552("fout_mpll",
> > > > + "fin_pll", reg_base +
> > > > MPLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_MPLL);
> > > > +
> > > > + clk = samsung_clk_register_pll6553("fout_epll",
> > > > + "fin_pll", reg_base +
> > > > EPLL_LOCK); + samsung_clk_add_lookup(clk, FOUT_EPLL);
> > > > +
> > > > + /* Register common internal clocks. */
> > > > + s3c64xx_clk_register_hclkx2(reg_base);
> > > > +
> > > > + samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
> > > > +
> > > > ARRAY_SIZE(s3c64xx_fixed_rate_clks)); +
> > > > samsung_clk_register_mux(s3c64xx_mux_clks,
> > > > +
> > > > ARRAY_SIZE(s3c64xx_mux_clks));
> > > > + samsung_clk_register_div(s3c64xx_div_clks,
> > > > +
> > > > ARRAY_SIZE(s3c64xx_div_clks));
> > > > + samsung_clk_register_gate(s3c64xx_gate_clks,
> > > > +
> > > > ARRAY_SIZE(s3c64xx_gate_clks));
> > > > +
> > > > + /* Register SoC-specific clocks. */
> > > > + if (is_s3c6400) {
> > > > + samsung_clk_register_mux(s3c6400_mux_clks,
> > > > +
> > > > ARRAY_SIZE(s3c6400_mux_clks));
> > > > + samsung_clk_register_div(s3c6400_div_clks,
> > > > +
> > > > ARRAY_SIZE(s3c6400_div_clks));
> > > > + samsung_clk_register_gate(s3c6400_gate_clks,
> > > > +
> > > > ARRAY_SIZE(s3c6400_gate_clks));
> > > > + samsung_clk_register_alias(s3c6400_clock_aliases,
> > > > +
> > > > ARRAY_SIZE(s3c6400_clock_aliases)); + } else {
> > > > + samsung_clk_register_mux(s3c6410_mux_clks,
> > > > +
> > > > ARRAY_SIZE(s3c6410_mux_clks));
> > > > + samsung_clk_register_div(s3c6410_div_clks,
> > > > +
> > > > ARRAY_SIZE(s3c6410_div_clks));
> > > > + samsung_clk_register_gate(s3c6410_gate_clks,
> > > > +
> > > > ARRAY_SIZE(s3c6410_gate_clks));
> > > > + samsung_clk_register_alias(s3c6410_clock_aliases,
> > > > +
> > > > ARRAY_SIZE(s3c6410_clock_aliases)); + }
> > > > +
> > > > + samsung_clk_register_alias(s3c64xx_clock_aliases,
> > > > +
> > > > ARRAY_SIZE(s3c64xx_clock_aliases)); +
> > > > + pr_info("%s clocks: apll = %lu, mpll = %lu\n"
> > > > + " epll = %lu, arm_clk = %lu\n",
> > > > + is_s3c6400 ? "S3C6400" : "S3C6410",
> > > > + _get_rate("fout_apll"), _get_rate("fout_mpll"),
> > > > + _get_rate("fout_epll"), _get_rate("armclk"));
> > > > +}
> > > > +
> > > > +static void __init s3c6400_clk_init(struct device_node *np)
> > > > +{
> > > > + s3c64xx_clk_init(np, 0, 0, true, NULL);
> > > > +}
> > > > +CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock",
> > > > s3c6400_clk_init); +
> > > > +static void __init s3c6410_clk_init(struct device_node *np)
> > > > +{
> > > > + s3c64xx_clk_init(np, 0, 0, false, NULL);
> > > > +}
> > > > +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 0000000..3e9a1f9
> > > > --- /dev/null
> > > > +++ b/include/dt-bindings/clock/samsung,s3c64xx-clock.h
> > > > @@ -0,0 +1,144 @@
> > > > +/*
> > > > + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> > > > + *
> > > > + * This program is free software; you can redistribute it and/or
> > > > modify + * it under the terms of the GNU General Public License
> > > > version 2 as + * published by the Free Software Foundation.
> > > > + *
> > > > + * Device Tree binding constants for Samsung S3C64xx clock
> > > > controller.
> > > > +*/
> > > > +
> > > > +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> > > > +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
> > > > +
> > > > +/*
> > > > + * Let each exported clock get a unique index, which is used on
> > > > DT-enabled + * platforms to lookup the clock from a clock
> > > > specifier.
> > > > These indices are + * therefore considered an ABI and so must not
> > > > be
> > > > changed. This implies + * that new clocks should be added either
> > > > in
> > > > free spaces between clock groups + * or at the end.
> > > > + */
> > > > +
> > > > +/* Core clocks. */
> > > > +#define IISCDCLK0 3
> > > > +#define PCMCDCLK0 4
> > > > +#define IISCDCLK1 5
> > > > +#define PCMCDCLK1 6
> > > > +#define IISCDCLK2 7
> > > > +#define CLK27M 8
> > > > +#define CLK48M 9
> > > > +#define FIN_PLL 10
> > > > +#define FOUT_APLL 11
> > > > +#define FOUT_MPLL 12
> > > > +#define FOUT_EPLL 13
> > > > +#define ARMCLK 14
> > > > +#define HCLKX2 15
> > > > +#define HCLK 16
> > > > +#define PCLK 17
> > > > +#define MOUT_EPLL 18
> > > > +#define DOUT_MPLL 19
> > > > +
> > > > +/* HCLK bus clocks. */
> > > > +#define HCLK_3DSE 32
> > > > +#define HCLK_UHOST 33
> > > > +#define HCLK_SECUR 34
> > > > +#define HCLK_SDMA1 35
> > > > +#define HCLK_SDMA0 36
> > > > +#define HCLK_IROM 37
> > > > +#define HCLK_DDR1 38
> > > > +#define HCLK_MEM1 39
> > > > +#define HCLK_MEM0 40
> > > > +#define HCLK_USB 41
> > > > +#define HCLK_HSMMC2 42
> > > > +#define HCLK_HSMMC1 43
> > > > +#define HCLK_HSMMC0 44
> > > > +#define HCLK_MDP 45
> > > > +#define HCLK_DHOST 46
> > > > +#define HCLK_IHOST 47
> > > > +#define HCLK_DMA1 48
> > > > +#define HCLK_DMA0 49
> > > > +#define HCLK_JPEG 50
> > > > +#define HCLK_CAMIF 51
> > > > +#define HCLK_SCALER 52
> > > > +#define HCLK_2D 53
> > > > +#define HCLK_TV 54
> > > > +#define HCLK_POST0 55
> > > > +#define HCLK_ROT 56
> > > > +#define HCLK_LCD 57
> > > > +#define HCLK_TZIC 58
> > > > +#define HCLK_INTC 59
> > > > +#define HCLK_MFC 60
> > > > +#define HCLK_DDR0 61
> > > > +
> > > > +/* PCLK bus clocks. */
> > > > +#define PCLK_IIC1 64
> > > > +#define PCLK_IIS2 65
> > > > +#define PCLK_SKEY 66
> > > > +#define PCLK_CHIPID 67
> > > > +#define PCLK_SPI1 68
> > > > +#define PCLK_SPI0 69
> > > > +#define PCLK_HSIRX 70
> > > > +#define PCLK_HSITX 71
> > > > +#define PCLK_GPIO 72
> > > > +#define PCLK_IIC0 73
> > > > +#define PCLK_IIS1 74
> > > > +#define PCLK_IIS0 75
> > > > +#define PCLK_AC97 76
> > > > +#define PCLK_TZPC 77
> > > > +#define PCLK_TSADC 78
> > > > +#define PCLK_KEYPAD 79
> > > > +#define PCLK_IRDA 80
> > > > +#define PCLK_PCM1 81
> > > > +#define PCLK_PCM0 82
> > > > +#define PCLK_PWM 83
> > > > +#define PCLK_RTC 84
> > > > +#define PCLK_WDT 85
> > > > +#define PCLK_UART3 86
> > > > +#define PCLK_UART2 87
> > > > +#define PCLK_UART1 88
> > > > +#define PCLK_UART0 89
> > > > +#define PCLK_MFC 90
> > > > +
> > > > +/* Special clocks. */
> > > > +#define SCLK_UHOST 96
> > > > +#define SCLK_MMC2_48 97
> > > > +#define SCLK_MMC1_48 98
> > > > +#define SCLK_MMC0_48 99
> > > > +#define SCLK_MMC2 100
> > > > +#define SCLK_MMC1 101
> > > > +#define SCLK_MMC0 102
> > > > +#define SCLK_SPI1_48 103
> > > > +#define SCLK_SPI0_48 104
> > > > +#define SCLK_SPI1 105
> > > > +#define SCLK_SPI0 106
> > > > +#define SCLK_DAC27 107
> > > > +#define SCLK_TV27 108
> > > > +#define SCLK_SCALER27 109
> > > > +#define SCLK_SCALER 110
> > > > +#define SCLK_LCD27 111
> > > > +#define SCLK_LCD 112
> > > > +#define SCLK_FIMC 113
> > > > +#define SCLK_POST0_27 114
> > > > +#define SCLK_AUDIO2 115
> > > > +#define SCLK_POST0 116
> > > > +#define SCLK_AUDIO1 117
> > > > +#define SCLK_AUDIO0 118
> > > > +#define SCLK_SECUR 119
> > > > +#define SCLK_IRDA 120
> > > > +#define SCLK_UART 121
> > > > +#define SCLK_MFC 122
> > > > +#define SCLK_CAM 123
> > > > +#define SCLK_JPEG 124
> > > > +#define SCLK_ONENAND 125
> > > > +
> > > > +/* MEM0 bus clocks - S3C6410-specific. */
> > > > +#define MEM0_CFCON 128
> > > > +#define MEM0_ONENAND1 129
> > > > +#define MEM0_ONENAND0 130
> > > > +#define MEM0_NFCON 131
> > > > +#define MEM0_SROM 132
> > > > +
> > > > +/* Total number of clocks. */
> > > > +#define NR_CLKS (MEM0_SROM + 1)
> > > > +
> > > > +#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H */
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
` (6 preceding siblings ...)
2013-06-05 23:57 ` [PATCH 7/7] ARM: s3c64xx: Remove old clock management code Tomasz Figa
@ 2013-06-19 14:17 ` Kukjin Kim
2013-06-19 14:23 ` Tomasz Figa
7 siblings, 1 reply; 16+ messages in thread
From: Kukjin Kim @ 2013-06-19 14:17 UTC (permalink / raw)
To: linux-arm-kernel
On 06/06/13 08:57, Tomasz Figa wrote:
> This series is an attempt to move clock support on Samsung S3C64xx SoCs
> to Common Clock Framework.
>
Looks good :)
> First, support for PLL types present on S3C64xx SoCs is added to Samsung
> Common Clock Framework driver. Then the main clock driver for mentioned
> SoCs is introduced. Further patches contain fixes for drivers to make them
> compliant with CCF semantics, migration of platform code to use the new
> clock driver and removal of old clock management code.
>
> Depends on:
> - [PATCH 0/6] Samsung watchdog support clean-up
> http://thread.gmane.org/gmane.linux.kernel.samsung-soc/18736/focus=18989
> - [PATCH 00/15] Final Samsung PWM support cleanup
> http://www.spinics.net/lists/arm-kernel/msg248725.html
BTW, Tomasz, so how was going on above PWM patches?
>
> On S3C6410-based Tiny6410 board (Mini6410-compatible):
>
> Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
>
> Tomasz Figa (7):
> clk: samsung: pll: Add support for PLL6552 and PLL6553
> clk: samsung: Add clock driver for S3C64xx SoCs
> ARM: SAMSUNG: Add soc_is_s3c6400/s3c6410 macros
> ARM: s3c64xx: dma: Use clk_prepare_enable/clk_disable_unprepare
> usb: host: ohci-s3c2410 Use clk_prepare_enable/clk_disable_unprepare
> ARM: s3c64xx: Migrate clock handling to Common Clock Framework
> ARM: s3c64xx: Remove old clock management code
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs
2013-06-12 21:38 ` Tomasz Figa
@ 2013-06-19 14:18 ` Kukjin Kim
0 siblings, 0 replies; 16+ messages in thread
From: Kukjin Kim @ 2013-06-19 14:18 UTC (permalink / raw)
To: linux-arm-kernel
On 06/13/13 06:38, Tomasz Figa wrote:
[...]
>>> Another thing is that it's unlikely for any new SoC from S3C64xx
>>> series to show up, so basically the clock list is fixed.
>>
>> Sure. I can take this into clk-next along with patch #1, or if you
>> prefer:
>>
>> Acked-by: Mike Turquette<mturquette@linaro.org>
>
> Thanks.
>
> IMHO with all the remaining platform patches in this series, it should go
> through Samsung tree.
>
Mike, thanks for your ack. Let me take this whole series into samsung
tree when ready for other dependencies like PWM...
- Kukjin
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx
2013-06-19 14:17 ` [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Kukjin Kim
@ 2013-06-19 14:23 ` Tomasz Figa
0 siblings, 0 replies; 16+ messages in thread
From: Tomasz Figa @ 2013-06-19 14:23 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 19 of June 2013 23:17:06 Kukjin Kim wrote:
> On 06/06/13 08:57, Tomasz Figa wrote:
> > This series is an attempt to move clock support on Samsung S3C64xx SoCs
> > to Common Clock Framework.
>
> Looks good :)
Thanks.
> > First, support for PLL types present on S3C64xx SoCs is added to
> > Samsung
> > Common Clock Framework driver. Then the main clock driver for mentioned
> > SoCs is introduced. Further patches contain fixes for drivers to make
> > them compliant with CCF semantics, migration of platform code to use
> > the new clock driver and removal of old clock management code.
> >
> > Depends on:
> > - [PATCH 0/6] Samsung watchdog support clean-up
> >
> > http://thread.gmane.org/gmane.linux.kernel.samsung-soc/18736/focus=
> > 18989
> >
> > - [PATCH 00/15] Final Samsung PWM support cleanup
> >
> > http://www.spinics.net/lists/arm-kernel/msg248725.html
>
> BTW, Tomasz, so how was going on above PWM patches?
>
I have them ready now, but the PWM maintainer has some objections, which
will hopefully be resolved soon.
Best regards,
Tomasz
> > On S3C6410-based Tiny6410 board (Mini6410-compatible):
> >
> > Tested-by: Tomasz Figa<tomasz.figa@gmail.com>
> >
> > Tomasz Figa (7):
> > clk: samsung: pll: Add support for PLL6552 and PLL6553
> > clk: samsung: Add clock driver for S3C64xx SoCs
> > ARM: SAMSUNG: Add soc_is_s3c6400/s3c6410 macros
> > ARM: s3c64xx: dma: Use clk_prepare_enable/clk_disable_unprepare
> > usb: host: ohci-s3c2410 Use clk_prepare_enable/clk_disable_unprepare
> > ARM: s3c64xx: Migrate clock handling to Common Clock Framework
> > ARM: s3c64xx: Remove old clock management code
>
> --
> To unsubscribe from this list: send the line "unsubscribe
> linux-samsung-soc" in the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2013-06-19 14:23 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-05 23:57 [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Tomasz Figa
2013-06-05 23:57 ` [PATCH 1/7] clk: samsung: pll: Add support for PLL6552 and PLL6553 Tomasz Figa
2013-06-12 2:53 ` Mike Turquette
2013-06-05 23:57 ` [PATCH 2/7] clk: samsung: Add clock driver for S3C64xx SoCs Tomasz Figa
2013-06-12 2:54 ` Mike Turquette
2013-06-12 6:26 ` Tomasz Figa
2013-06-12 16:51 ` Mike Turquette
2013-06-12 21:38 ` Tomasz Figa
2013-06-19 14:18 ` Kukjin Kim
2013-06-05 23:57 ` [PATCH 3/7] ARM: SAMSUNG: Add soc_is_s3c6400/s3c6410 macros Tomasz Figa
2013-06-05 23:57 ` [PATCH 4/7] ARM: s3c64xx: dma: Use clk_prepare_enable/clk_disable_unprepare Tomasz Figa
2013-06-05 23:57 ` [PATCH 5/7] usb: host: ohci-s3c2410 " Tomasz Figa
2013-06-05 23:57 ` [PATCH 6/7] ARM: s3c64xx: Migrate clock handling to Common Clock Framework Tomasz Figa
2013-06-05 23:57 ` [PATCH 7/7] ARM: s3c64xx: Remove old clock management code Tomasz Figa
2013-06-19 14:17 ` [PATCH 0/7] Common Clock Framework support for Samsung S3C64xx Kukjin Kim
2013-06-19 14:23 ` Tomasz Figa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).