Skip to contentSkip to conversation

clk: meson: Add clock controller

PATCH New Carlo Caione 2 participants 9 messages Mar 2, 2015 – May 1, 2015

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover clk: meson: Add clock controller

From: Carlo Caione <[email protected]>

This patchset introduces preliminary support for the clock controller found on Amlogic MesonX SoCs and enables it for the Meson8b.

DTS patches with support for Meson8b SoCs will follow.

Carlo Caione (3):
clk: meson: Add support for Meson clock controller
clk: meson: Document bindings for Meson8b clock controller
clk: meson8b: Add support for Meson8b clocks

 .../bindings/clock/amlogic,meson8b-clkc.txt        |  40 +++
 drivers/clk/Makefile                               |   1 +
 drivers/clk/meson/Makefile                         |   6 +
 drivers/clk/meson/clk-cpu.c                        | 291 +++++++++++++++++++++
 drivers/clk/meson/clk-pll.c                        | 231 ++++++++++++++++
 drivers/clk/meson/clkc.c                           | 234 +++++++++++++++++
 drivers/clk/meson/clkc.h                           | 187 +++++++++++++
 drivers/clk/meson/meson8b-clkc.c                   | 182 +++++++++++++
 include/dt-bindings/clock/meson8b-clkc.h           |  20 ++
 9 files changed, 1192 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
 create mode 100644 drivers/clk/meson/Makefile
 create mode 100644 drivers/clk/meson/clk-cpu.c
 create mode 100644 drivers/clk/meson/clk-pll.c
 create mode 100644 drivers/clk/meson/clkc.c
 create mode 100644 drivers/clk/meson/clkc.h
 create mode 100644 drivers/clk/meson/meson8b-clkc.c
 create mode 100644 include/dt-bindings/clock/meson8b-clkc.h
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/3 clk: meson: Add support for Meson clock controller

From: Carlo Caione <[email protected]>

This patchset adds the infrastructure for registering and managing the core clocks found on Amlogic MesonX SoCs. In particular:

- PLLs
- CPU clock
- Fixed rate clocks, fixed factor clocks, ...

---
 drivers/clk/Makefile                     |   1 +
 drivers/clk/meson/Makefile               |   5 +
 drivers/clk/meson/clk-cpu.c              | 291 +++++++++++++++++++++++++++++++
 drivers/clk/meson/clk-pll.c              | 231 ++++++++++++++++++++++++
 drivers/clk/meson/clkc.c                 | 234 +++++++++++++++++++++++++
 drivers/clk/meson/clkc.h                 | 187 ++++++++++++++++++++
 include/dt-bindings/clock/meson8b-clkc.h |  20 +++
 7 files changed, 969 insertions(+)
 create mode 100644 drivers/clk/meson/Makefile
 create mode 100644 drivers/clk/meson/clk-cpu.c
 create mode 100644 drivers/clk/meson/clk-pll.c
 create mode 100644 drivers/clk/meson/clkc.c
 create mode 100644 drivers/clk/meson/clkc.h
 create mode 100644 include/dt-bindings/clock/meson8b-clkc.h
drivers/clk/Makefile +1 -0
index d5fba5b..e93d134 100644
@@ -51,6 +51,7 @@ ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
 endif
 obj-$(CONFIG_PLAT_ORION)		+= mvebu/
+obj-$(CONFIG_ARCH_MESON)		+= meson/
 obj-$(CONFIG_ARCH_MXS)			+= mxs/
 obj-$(CONFIG_COMMON_CLK_PXA)		+= pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)		+= qcom/
drivers/clk/meson/Makefile new file +5 -0
new file mode 100644
index 0000000..66c6d8d
@@ -0,0 +1,5 @@
+#
+# Makefile for Meson specific clk
+#
+
+obj-y += clkc.o clk-pll.o clk-cpu.o
drivers/clk/meson/clk-cpu.c new file +291 -0

291 lines not on this page · raw message

drivers/clk/meson/clk-pll.c new file +231 -0

231 lines not on this page · raw message

drivers/clk/meson/clkc.c new file +234 -0

234 lines not on this page · raw message

drivers/clk/meson/clkc.h new file +187 -0

187 lines not on this page · raw message

include/dt-bindings/clock/meson8b-clkc.h new file +20 -0
new file mode 100644
index 0000000..9e9203c
@@ -0,0 +1,20 @@
+/*
+ * Meson6 clock tree IDs
+ */
+
+#define CLKID_UNUSED		0
+#define CLKID_XTAL		1
+#define CLKID_PLL_FIXED		2
+#define CLKID_PLL_VID		3
+#define CLKID_PLL_SYS		4
+#define CLKID_FCLK_DIV2		5
+#define CLKID_FCLK_DIV3		6
+#define CLKID_FCLK_DIV4		7
+#define CLKID_FCLK_DIV5		8
+#define CLKID_FCLK_DIV7		9
+#define CLKID_CLK81		10
+#define CLKID_MALI		11
+#define CLKID_CPUCLK		12
+#define CLKID_ZERO		13
+
+#define CLK_NR_CLKS		(CLKID_ZERO + 1)
Signature · 1 line
1.9.1
#2 lore raw

PATCH 1/3 clk: meson: Add support for Meson clock controller

Quoting Carlo Caione (2015-03-02 08:22:00)

Quoted 26 lines
drivers/clk/meson/clk-cpu.c new file +26 -0
+static int meson_clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long parent_rate)
+{
+       struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
+       unsigned int div, sel, N = 0;
+       u32 reg;
+
+       div = DIV_ROUND_UP(parent_rate, rate);
+
+       if (div <= 3) {
+               sel = div - 1;
+       } else {
+               sel = 3;
+               N = div / 2;
+       }
+
+       reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
+       reg = PARM_SET(MESON_N_WIDTH, MESON_N_SHIFT, reg, N);
+       writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
+
+       reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
+       reg = PARM_SET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg, sel);
+       writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
+
+       return 0;
+}

<snip>

Quoted 54 lines
drivers/clk/meson/clk-cpu.c new file +54 -0
+static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
+                                        struct clk_notifier_data *ndata)
+{
+       u32 cpu_clk_cntl;
+
+       spin_lock(clk_cpu->lock);
+
+       /* switch MUX1 to xtal */
+       cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       cpu_clk_cntl &= ~MESON_CPU_CLK_MUX1;
+       writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       udelay(100);
+
+       /* switch MUX2 to sys-pll */
+       cpu_clk_cntl |= MESON_CPU_CLK_MUX2;
+       writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+
+       spin_unlock(clk_cpu->lock);
+
+       return 0;
+}
+
+static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
+                                         struct clk_notifier_data *ndata)
+{
+       u32 cpu_clk_cntl;
+
+       spin_lock(clk_cpu->lock);
+
+       /* switch MUX1 to divisors' output */
+       cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       cpu_clk_cntl |= MESON_CPU_CLK_MUX1;
+       writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       udelay(100);
+
+       spin_unlock(clk_cpu->lock);
+
+       return 0;
+}
+
+/*
+ * This clock notifier is called when the frequency of the of the parent
+ * PLL clock is to be changed. We use the xtal input as temporary parent
+ * while the PLL frequency is stabilized.
+ */
+static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
+                                    unsigned long event, void *data)
+{
+       struct clk_notifier_data *ndata = data;

drivers/clk/meson/clk-cpu.c line 233

Quoted 10 lines
drivers/clk/meson/clk-cpu.c new file +10 -0
+       struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_nb(nb);
+       int ret = 0;
+
+       if (event == PRE_RATE_CHANGE)
+               ret = meson_clk_cpu_pre_rate_change(clk_cpu, ndata);
+       else if (event == POST_RATE_CHANGE)
+               ret = meson_clk_cpu_post_rate_change(clk_cpu, ndata);
+
+       return notifier_from_errno(ret);
+}

Why use a notifier for this? Could you simply call meson_clk_cpu_{pre,post}_rate_change directly from meson_clk_cpu_set_rate?

Regards,
Mike

#3 lore raw

PATCH 1/3 clk: meson: Add support for Meson clock controller

Quoted 61 lines · Michael Turquette

Quoting Carlo Caione (2015-03-02 08:22:00)

Quoted 60 lines
drivers/clk/meson/clk-cpu.c new file +60 -0
+static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
+                                        struct clk_notifier_data *ndata)
+{
+       u32 cpu_clk_cntl;
+
+       spin_lock(clk_cpu->lock);
+
+       /* switch MUX1 to xtal */
+       cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       cpu_clk_cntl &= ~MESON_CPU_CLK_MUX1;
+       writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       udelay(100);
+
+       /* switch MUX2 to sys-pll */
+       cpu_clk_cntl |= MESON_CPU_CLK_MUX2;
+       writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+
+       spin_unlock(clk_cpu->lock);
+
+       return 0;
+}
+
+static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
+                                         struct clk_notifier_data *ndata)
+{
+       u32 cpu_clk_cntl;
+
+       spin_lock(clk_cpu->lock);
+
+       /* switch MUX1 to divisors' output */
+       cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       cpu_clk_cntl |= MESON_CPU_CLK_MUX1;
+       writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+                               + MESON_CPU_CLK_CNTL);
+       udelay(100);
+
+       spin_unlock(clk_cpu->lock);
+
+       return 0;
+}
+
+/*
+ * This clock notifier is called when the frequency of the of the parent
+ * PLL clock is to be changed. We use the xtal input as temporary parent
+ * while the PLL frequency is stabilized.
+ */
+static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
+                                    unsigned long event, void *data)
+{
+       struct clk_notifier_data *ndata = data;
+       struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_nb(nb);
+       int ret = 0;
+
+       if (event == PRE_RATE_CHANGE)
+               ret = meson_clk_cpu_pre_rate_change(clk_cpu, ndata);
+       else if (event == POST_RATE_CHANGE)
Quoted 8 lines

drivers/clk/meson/clk-cpu.c line 233

Quoted 4 lines
drivers/clk/meson/clk-cpu.c new file +4 -0
+               ret = meson_clk_cpu_post_rate_change(clk_cpu, ndata);
+
+       return notifier_from_errno(ret);
+}

Why use a notifier for this? Could you simply call meson_clk_cpu_{pre,post}_rate_change directly from meson_clk_cpu_set_rate?

Hi Mike,

the notifier is used to reparent the CPU clock when the frequency of the parent PLL is changed and before the PLL frequency is actually changed.
IIUC using the {pre,post} hooks from meson_clk_cpu_set_rate doesn't achieve the same. The idea is adapted from the CPU clock driver of the rockchip SoCs (rockchip/clk-cpu.c).

Thanks for the review,

Signature · 1 line
Carlo Caione
#4 lore raw

PATCH 1/3 clk: meson: Add support for Meson clock controller

Quoted 6 lines · Carlo Caione
Quoted 3 lines · Michael Turquette

Why use a notifier for this? Could you simply call meson_clk_cpu_{pre,post}_rate_change directly from meson_clk_cpu_set_rate?

Quoted 8 lines

Hi Mike,

the notifier is used to reparent the CPU clock when the frequency of the parent PLL is changed and before the PLL frequency is actually changed.
IIUC using the {pre,post} hooks from meson_clk_cpu_set_rate doesn't achieve the same. The idea is adapted from the CPU clock driver of the rockchip SoCs (rockchip/clk-cpu.c).

Hey Mike,
what do you think about this point?

Signature · 1 line
Carlo Caione
#5 lore raw

PATCH 2/3 clk: meson: Document bindings for Meson8b clock controller

In reply to Carlo Caione

From: Carlo Caione <[email protected]>

Add documentation for the clock controller.

---
 .../bindings/clock/amlogic,meson8b-clkc.txt        | 40 ++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt new file +40 -0
new file mode 100644
index 0000000..2b7b3fa
@@ -0,0 +1,40 @@
+* Amlogic Meson8b Clock and Reset Unit
+
+The Amlogic Meson8b clock controller generates and supplies clock to various
+controllers within the SoC.
+
+Required Properties:
+
+- compatible: should be "amlogic,meson8b-clkc"
+- reg: it must be composed by two tuples:
+	0) physical base address of the xtal register and length of memory
+	   mapped region.
+	1) physical base address of the clock 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. All available clocks are defined as
+preprocessor macros in the dt-bindings/clock/meson8b-clkc.h header and can be
+used in device tree sources.
+
+Example: Clock controller node:
+
+	clkc: clock-controller at c1104000 {
+		#clock-cells = <1>;
+		compatible = "amlogic,meson8b-clkc";
+		reg = <0xc1108000 0x4>, <0xc1104000 0x460>;
+	};
+
+
+Example: UART controller node that consumes the clock generated by the clock
+  controller:
+
+	uart_AO: serial at c81004c0 {
+		compatible = "amlogic,meson-uart";
+		reg = <0xc81004c0 0x14>;
+		interrupts = <0 90 1>;
+		clocks = <&clkc CLKID_CLK81>;
+		status = "disabled";
+	};
Signature · 1 line
1.9.1
#6 lore raw

PATCH 3/3 clk: meson8b: Add support for Meson8b clocks

In reply to Carlo Caione

From: Carlo Caione <[email protected]>

This patch adds support for the basic clocks found on the Amlogic Meson8b SoCs.

---
 drivers/clk/meson/Makefile       |   1 +
 drivers/clk/meson/meson8b-clkc.c | 182 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 183 insertions(+)
 create mode 100644 drivers/clk/meson/meson8b-clkc.c
drivers/clk/meson/Makefile +1 -0
index 66c6d8d..6d45531 100644
@@ -3,3 +3,4 @@
 #
 
 obj-y += clkc.o clk-pll.o clk-cpu.o
+obj-y += meson8b-clkc.o
drivers/clk/meson/meson8b-clkc.c new file +182 -0

182 lines not on this page · raw message

Signature · 1 line
1.9.1
#7 lore raw

cover clk: meson: Add clock controller

In reply to Carlo Caione
Quoted 11 lines · Carlo Caione

From: Carlo Caione <[email protected]>

This patchset introduces preliminary support for the clock controller found on Amlogic MesonX SoCs and enables it for the Meson8b.

DTS patches with support for Meson8b SoCs will follow.

Carlo Caione (3):
clk: meson: Add support for Meson clock controller
clk: meson: Document bindings for Meson8b clock controller
clk: meson8b: Add support for Meson8b clocks

Hi Mike,
any feedback on this patchset?

Signature · 1 line
Carlo Caione
#8 lore raw

cover clk: meson: Add clock controller

Quoting Carlo Caione (2015-03-15 14:03:07)

Quoted 8 lines · Carlo Caione
Quoted 7 lines

From: Carlo Caione <[email protected]>

This patchset introduces preliminary support for the clock controller found on Amlogic MesonX SoCs and enables it for the Meson8b.

DTS patches with support for Meson8b SoCs will follow.

Quoted 7 lines
Quoted 4 lines

Carlo Caione (3):
clk: meson: Add support for Meson clock controller
clk: meson: Document bindings for Meson8b clock controller
clk: meson8b: Add support for Meson8b clocks

Hi Mike,
any feedback on this patchset?

Hi Carlo,

This series looks good. The ascii art describing the hardware is especially appreciated. I had one small question regarding your use of the clock rate change notifier for the meson 8b cpu clocks. Once we've worked that out then I can merge these into clk-next.

Regards,
Mike

Quoted 3 lines
Signature · 2 lines
-- 
Carlo Caione