mirror of https://lore.kernel.org/linux-amlogic/
 help / color / mirror / Atom feed
* [PATCH 0/7] Add Amlogic S7 clock controllers
@ 2026-11-06  8:30 Carlo Caione
  2026-11-06  8:30 ` [PATCH 1/7] dt-bindings: clock: Add Amlogic S7 SCMI clock IDs Carlo Caione
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

This series adds the clock controllers of the Amlogic S7 SoC family
(S905Y5, S805X3): the IDs of the clocks the firmware exposes over SCMI,
the PLL clock controller and the peripherals clock controller.

The peripherals controller is close to the S4 one. Two changes to the
common code come with the PLL controller: clk-pll handles PLLs without
a pre-divider and PLLs with an active-low reset, like the HDMI PLL.

The new clock headers are covered by MAINTAINERS once [1] is applied.

[1] https://lore.kernel.org/all/20261022-upstream-maintainers-clk-headers-v1-1-d09dd4db01d6@baylibre.com/

---
Carlo Caione (7):
      dt-bindings: clock: Add Amlogic S7 SCMI clock IDs
      clk: meson: pll: Support PLLs without a pre-divider
      clk: meson: pll: Support active-low resets
      dt-bindings: clock: Add Amlogic S7 PLL clock controller
      clk: amlogic: Add S7 PLL clock controller driver
      dt-bindings: clock: Add Amlogic S7 peripherals clock controller
      clk: amlogic: Add S7 peripherals clock controller driver

 .../clock/amlogic,s7-peripherals-clkc.yaml         |  126 ++
 .../bindings/clock/amlogic,s7-pll-clkc.yaml        |   73 +
 drivers/clk/meson/Kconfig                          |   30 +
 drivers/clk/meson/Makefile                         |    2 +
 drivers/clk/meson/clk-pll.c                        |   52 +-
 drivers/clk/meson/clk-pll.h                        |    1 +
 drivers/clk/meson/s7-peripherals.c                 | 2149 ++++++++++++++++++++
 drivers/clk/meson/s7-pll.c                         |  648 ++++++
 .../clock/amlogic,s7-peripherals-clkc.h            |  245 +++
 include/dt-bindings/clock/amlogic,s7-pll-clkc.h    |   42 +
 include/dt-bindings/clock/amlogic,s7-scmi-clkc.h   |   27 +
 11 files changed, 3380 insertions(+), 15 deletions(-)
---
base-commit: 363f97a1ce635b86be7fd263d56a040fbd87bdbb
change-id: 20261026-upstream-s7-clk-3fbe6f33652d

Best regards,
--  
Carlo Caione <ccaione@baylibre.com>


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/7] dt-bindings: clock: Add Amlogic S7 SCMI clock IDs
  2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
@ 2026-11-06  8:30 ` Carlo Caione
  2026-11-06  8:30 ` [PATCH 2/7] clk: meson: pll: Support PLLs without a pre-divider Carlo Caione
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

The S7 firmware exposes clocks through SCMI, including sources needed
by the other clock controllers.

Define their identifiers so devicetree can reference these
firmware-provided clocks.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
 include/dt-bindings/clock/amlogic,s7-scmi-clkc.h | 27 ++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/include/dt-bindings/clock/amlogic,s7-scmi-clkc.h b/include/dt-bindings/clock/amlogic,s7-scmi-clkc.h
new file mode 100644
index 000000000000..10d7caa5d1e2
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,s7-scmi-clkc.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ */
+
+#ifndef __AMLOGIC_S7_SCMI_CLKC_H
+#define __AMLOGIC_S7_SCMI_CLKC_H
+
+#define CLKID_DDR_PHY_OSC			0
+#define CLKID_USB1_PLL_OSC			1
+#define CLKID_TOP_PLL_OSC			2
+#define CLKID_HDMI_PLL_OSC			3
+#define CLKID_USB0_PHY_PLL_OSC			4
+#define CLKID_USB1_PHY_PLL_OSC			5
+#define CLKID_USB0_PLL_OSC			6
+#define CLKID_ETH_PLL_OSC			7
+#define CLKID_ADC_PLL_OSC			8
+#define CLKID_CPU_CLK				9
+#define CLKID_DSU_CLK				10
+#define CLKID_GP1_PLL				11
+#define CLKID_ACLKM				12
+#define CLKID_PWM_G				13
+#define CLKID_PWM_H				14
+#define CLKID_PWM_I				15
+#define CLKID_PWM_J				16
+
+#endif /* __AMLOGIC_S7_SCMI_CLKC_H */

-- 
2.56.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/7] clk: meson: pll: Support PLLs without a pre-divider
  2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
  2026-11-06  8:30 ` [PATCH 1/7] dt-bindings: clock: Add Amlogic S7 SCMI clock IDs Carlo Caione
@ 2026-11-06  8:30 ` Carlo Caione
  2026-11-06  8:35   ` sashiko-bot
  2026-11-06  8:30 ` [PATCH 3/7] clk: meson: pll: Support active-low resets Carlo Caione
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

The common PLL code assumes that every PLL has a pre-divider. This
does not hold for the S7 HDMI PLL, and the S7 GP0 and HIFI PLLs are
meant to run with theirs set to 1.

Make the pre-divider optional so these PLLs can use the common
implementation.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
 drivers/clk/meson/clk-pll.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 1ea6579a760f..44b33051405f 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -76,7 +76,9 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 	unsigned int m, n, frac;
 
-	n = meson_parm_read(clk->map, &pll->n);
+	n = MESON_PARM_APPLICABLE(&pll->n) ?
+		meson_parm_read(clk->map, &pll->n) :
+		1;
 
 	/*
 	 * On some HW, N is set to zero on init. This value is invalid as
@@ -174,7 +176,7 @@ static int meson_clk_get_pll_range_index(unsigned long rate,
 	*n = index + 1;
 
 	/* Check the predivider range */
-	if (*n >= (1 << pll->n.width))
+	if (*n >= (MESON_PARM_APPLICABLE(&pll->n) ? 1 << pll->n.width : 2))
 		return -EINVAL;
 
 	if (*n == 1) {
@@ -437,7 +439,8 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	if (enabled)
 		meson_clk_pll_disable(hw);
 
-	meson_parm_write(clk->map, &pll->n, n);
+	if (MESON_PARM_APPLICABLE(&pll->n))
+		meson_parm_write(clk->map, &pll->n, n);
 	meson_parm_write(clk->map, &pll->m, m);
 
 	if (MESON_PARM_APPLICABLE(&pll->frac)) {

-- 
2.56.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 3/7] clk: meson: pll: Support active-low resets
  2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
  2026-11-06  8:30 ` [PATCH 1/7] dt-bindings: clock: Add Amlogic S7 SCMI clock IDs Carlo Caione
  2026-11-06  8:30 ` [PATCH 2/7] clk: meson: pll: Support PLLs without a pre-divider Carlo Caione
@ 2026-11-06  8:30 ` Carlo Caione
  2026-11-06  8:30 ` [PATCH 4/7] dt-bindings: clock: Add Amlogic S7 PLL clock controller Carlo Caione
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

The common PLL code assumes that the reset of a PLL is active high. The
S7 HDMI PLL has an active-low reset, and its lock flag only rises
reliably when the PLL goes through it.

Add a flag for PLLs with an active-low reset so this PLL can use the
common implementation.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
 drivers/clk/meson/clk-pll.c | 43 +++++++++++++++++++++++++++++++------------
 drivers/clk/meson/clk-pll.h |  1 +
 2 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
index 44b33051405f..4ac5e45c1e9b 100644
--- a/drivers/clk/meson/clk-pll.c
+++ b/drivers/clk/meson/clk-pll.c
@@ -293,13 +293,37 @@ static int meson_clk_pll_wait_lock(struct clk_hw *hw)
 	return -ETIMEDOUT;
 }
 
+static bool meson_clk_pll_in_reset(struct clk_regmap *clk,
+				   struct meson_clk_pll_data *pll)
+{
+	unsigned int rst;
+
+	if (!MESON_PARM_APPLICABLE(&pll->rst))
+		return false;
+
+	rst = meson_parm_read(clk->map, &pll->rst);
+
+	return pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW ? !rst : rst;
+}
+
+static void meson_clk_pll_reset(struct clk_regmap *clk,
+				struct meson_clk_pll_data *pll, bool reset)
+{
+	if (!MESON_PARM_APPLICABLE(&pll->rst))
+		return;
+
+	if (pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW)
+		reset = !reset;
+
+	meson_parm_write(clk->map, &pll->rst, reset);
+}
+
 static int meson_clk_pll_is_enabled(struct clk_hw *hw)
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
-	if (MESON_PARM_APPLICABLE(&pll->rst) &&
-	    meson_parm_read(clk->map, &pll->rst))
+	if (meson_clk_pll_in_reset(clk, pll))
 		return 0;
 
 	if (!meson_parm_read(clk->map, &pll->en) ||
@@ -328,14 +352,12 @@ static int meson_clk_pll_init(struct clk_hw *hw)
 		return 0;
 
 	if (pll->init_count) {
-		if (MESON_PARM_APPLICABLE(&pll->rst))
-			meson_parm_write(clk->map, &pll->rst, 1);
+		meson_clk_pll_reset(clk, pll, true);
 
 		regmap_multi_reg_write(clk->map, pll->init_regs,
 				       pll->init_count);
 
-		if (MESON_PARM_APPLICABLE(&pll->rst))
-			meson_parm_write(clk->map, &pll->rst, 0);
+		meson_clk_pll_reset(clk, pll, false);
 	}
 
 	return 0;
@@ -365,15 +387,13 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
 		return 0;
 
 	/* Make sure the pll is in reset */
-	if (MESON_PARM_APPLICABLE(&pll->rst))
-		meson_parm_write(clk->map, &pll->rst, 1);
+	meson_clk_pll_reset(clk, pll, true);
 
 	/* Enable the pll */
 	meson_parm_write(clk->map, &pll->en, 1);
 
 	/* Take the pll out reset */
-	if (MESON_PARM_APPLICABLE(&pll->rst))
-		meson_parm_write(clk->map, &pll->rst, 0);
+	meson_clk_pll_reset(clk, pll, false);
 
 	/*
 	 * Compared with the previous SoCs, self-adaption current module
@@ -406,8 +426,7 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
 	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
 
 	/* Put the pll is in reset */
-	if (MESON_PARM_APPLICABLE(&pll->rst))
-		meson_parm_write(clk->map, &pll->rst, 1);
+	meson_clk_pll_reset(clk, pll, true);
 
 	/* Disable the pll */
 	meson_parm_write(clk->map, &pll->en, 0);
diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
index 949157fb7bf5..8384b75ae38d 100644
--- a/drivers/clk/meson/clk-pll.h
+++ b/drivers/clk/meson/clk-pll.h
@@ -29,6 +29,7 @@ struct pll_mult_range {
 
 #define CLK_MESON_PLL_ROUND_CLOSEST	BIT(0)
 #define CLK_MESON_PLL_NOINIT_ENABLED	BIT(1)
+#define CLK_MESON_PLL_RST_ACTIVE_LOW	BIT(2)
 
 struct meson_clk_pll_data {
 	struct parm en;

-- 
2.56.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 4/7] dt-bindings: clock: Add Amlogic S7 PLL clock controller
  2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
                   ` (2 preceding siblings ...)
  2026-11-06  8:30 ` [PATCH 3/7] clk: meson: pll: Support active-low resets Carlo Caione
@ 2026-11-06  8:30 ` Carlo Caione
  2026-11-06 17:35   ` Conor Dooley
  2026-11-06  8:30 ` [PATCH 5/7] clk: amlogic: Add S7 PLL clock controller driver Carlo Caione
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

The S7 PLL controller supplies clock sources for the peripheral clock
tree and receives its reference clocks through firmware-controlled
oscillator gates.

Add the binding and clock identifiers needed to describe this
controller and its connections.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
 .../bindings/clock/amlogic,s7-pll-clkc.yaml        | 73 ++++++++++++++++++++++
 include/dt-bindings/clock/amlogic,s7-pll-clkc.h    | 42 +++++++++++++
 2 files changed, 115 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/amlogic,s7-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s7-pll-clkc.yaml
new file mode 100644
index 000000000000..e2b5ba5524a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,s7-pll-clkc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2026 BayLibre, SAS.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,s7-pll-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic S7 Series PLL Clock Controller
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Carlo Caione <ccaione@baylibre.com>
+
+properties:
+  compatible:
+    const: amlogic,s7-pll-clkc
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  clocks:
+    items:
+      - description: input fixed pll
+      - description: input gp0 pll
+      - description: input hifi pll
+      - description: input hifi1 pll
+      - description: input hdmi pll
+
+  clock-names:
+    items:
+      - const: fix
+      - const: gp0
+      - const: hifi
+      - const: hifi1
+      - const: hdmi
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@8000 {
+            compatible = "amlogic,s7-pll-clkc";
+            reg = <0x0 0x8000 0x0 0x1e8>;
+            #clock-cells = <1>;
+            clocks = <&scmi_clk CLKID_TOP_PLL_OSC>,
+                     <&scmi_clk CLKID_TOP_PLL_OSC>,
+                     <&scmi_clk CLKID_TOP_PLL_OSC>,
+                     <&scmi_clk CLKID_TOP_PLL_OSC>,
+                     <&scmi_clk CLKID_HDMI_PLL_OSC>;
+            clock-names = "fix",
+                          "gp0",
+                          "hifi",
+                          "hifi1",
+                          "hdmi";
+        };
+    };
diff --git a/include/dt-bindings/clock/amlogic,s7-pll-clkc.h b/include/dt-bindings/clock/amlogic,s7-pll-clkc.h
new file mode 100644
index 000000000000..4014314a3eb0
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,s7-pll-clkc.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S7_PLL_CLKC_H
+#define _DT_BINDINGS_CLOCK_AMLOGIC_S7_PLL_CLKC_H
+
+#define CLKID_FIXED_PLL_VCO			0
+#define CLKID_FIXED_PLL				1
+#define CLKID_FCLK_DIV2_DIV			2
+#define CLKID_FCLK_DIV2				3
+#define CLKID_FCLK_DIV3_DIV			4
+#define CLKID_FCLK_DIV3				5
+#define CLKID_FCLK_DIV4_DIV			6
+#define CLKID_FCLK_DIV4				7
+#define CLKID_FCLK_DIV5_DIV			8
+#define CLKID_FCLK_DIV5				9
+#define CLKID_FCLK_DIV7_DIV			10
+#define CLKID_FCLK_DIV7				11
+#define CLKID_FCLK_DIV2P5_DIV			12
+#define CLKID_FCLK_DIV2P5			13
+#define CLKID_GP0_PLL_DIV0P5			14
+#define CLKID_GP0_PLL_VCO			15
+#define CLKID_GP0_PLL				16
+#define CLKID_HIFI_PLL_DIV0P5			17
+#define CLKID_HIFI_PLL_VCO			18
+#define CLKID_HIFI_PLL				19
+#define CLKID_HIFI1_PLL_DIV0P5			20
+#define CLKID_HIFI1_PLL_VCO			21
+#define CLKID_HIFI1_PLL				22
+#define CLKID_HDMI_PLL_DIV0P5			23
+#define CLKID_HDMI_PLL_VCO			24
+#define CLKID_HDMI_PLL_OD0			25
+#define CLKID_HDMI_PLL_OD1			26
+#define CLKID_HDMI_PLL				27
+#define CLKID_HDMI_PLL_PIX_DIV5			28
+#define CLKID_HDMI_PLL_PIX_DIV6P25		29
+#define CLKID_HDMI_PLL_PIX_DIV7P5		30
+#define CLKID_HDMI_PLL_PIX			31
+
+#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S7_PLL_CLKC_H */

-- 
2.56.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 5/7] clk: amlogic: Add S7 PLL clock controller driver
  2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
                   ` (3 preceding siblings ...)
  2026-11-06  8:30 ` [PATCH 4/7] dt-bindings: clock: Add Amlogic S7 PLL clock controller Carlo Caione
@ 2026-11-06  8:30 ` Carlo Caione
  2026-11-06  8:51   ` sashiko-bot
  2026-11-06  8:30 ` [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller Carlo Caione
  2026-11-06  8:30 ` [PATCH 7/7] clk: amlogic: Add S7 peripherals clock controller driver Carlo Caione
  6 siblings, 1 reply; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

The S7 PLL controller provides the fixed PLL with its fclk dividers,
the GP0, HIFI0 and HIFI1 PLLs, and the HDMI PLL.

Add a driver for it. The GP0 and HIFI PLLs are expected to run with
their input divided by 2 (div0p5) and the HDMI PLL without it, as the
firmware and the init sequences set them up.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
 drivers/clk/meson/Kconfig  |  14 +
 drivers/clk/meson/Makefile |   1 +
 drivers/clk/meson/s7-pll.c | 648 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 663 insertions(+)

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index d460514bb8a1..35f2971448af 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -229,6 +229,20 @@ config COMMON_CLK_S4_PERIPHERALS
 	  Support for the peripherals clock controller on Amlogic S805X2 and S905Y4
 	  devices, AKA S4. Say Y if you want S4 peripherals clock controller to work.
 
+config COMMON_CLK_S7_PLL
+	tristate "Amlogic S7 SoC PLL controller support"
+	depends on ARM64 || COMPILE_TEST
+	default ARCH_MESON
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_CLKC_UTILS
+	select COMMON_CLK_MESON_PLL
+	imply COMMON_CLK_SCMI
+	help
+	  Support for the PLL clock controller on Amlogic S805X3 based
+	  devices, AKA S7. This controller provides the fixed PLL and its
+	  dividers, the GP0, HIFI0 and HIFI1 PLLs and the HDMI PLL. Say Y if
+	  you want the S7 PLL clock controller to work.
+
 config COMMON_CLK_T7_PLL
 	tristate "Amlogic T7 SoC PLL controller support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 56b04254eb1a..9d439106d11c 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -28,5 +28,6 @@ obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
 obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o
 obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o
+obj-$(CONFIG_COMMON_CLK_S7_PLL) += s7-pll.o
 obj-$(CONFIG_COMMON_CLK_T7_PLL) += t7-pll.o
 obj-$(CONFIG_COMMON_CLK_T7_PERIPHERALS) += t7-peripherals.o
diff --git a/drivers/clk/meson/s7-pll.c b/drivers/clk/meson/s7-pll.c
new file mode 100644
index 000000000000..2aa253a5f211
--- /dev/null
+++ b/drivers/clk/meson/s7-pll.c
@@ -0,0 +1,648 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Amlogic S7 PLL Clock Controller Driver
+ *
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Carlo Caione <ccaione@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "meson-clkc-utils.h"
+#include <dt-bindings/clock/amlogic,s7-pll-clkc.h>
+
+#define FIXPLL_CTRL0			0x040
+#define FIXPLL_CTRL1			0x044
+#define FIXPLL_STS			0x05c
+#define GP0PLL_CTRL0			0x080
+#define GP0PLL_CTRL1			0x084
+#define GP0PLL_CTRL2			0x088
+#define GP0PLL_CTRL3			0x08c
+#define GP0PLL_STS			0x09c
+#define HIFI0PLL_CTRL0			0x100
+#define HIFI0PLL_CTRL1			0x104
+#define HIFI0PLL_CTRL2			0x108
+#define HIFI0PLL_CTRL3			0x10c
+#define HIFI1PLL_CTRL0			0x110
+#define HIFI1PLL_CTRL1			0x114
+#define HIFI1PLL_CTRL2			0x118
+#define HIFI1PLL_CTRL3			0x11c
+#define HIFI0PLL_STS			0x120
+#define HIFI1PLL_STS			0x124
+#define HDMIPLL_CTRL0			0x1c0
+#define HDMIPLL_CTRL1			0x1c4
+#define HDMIPLL_CTRL2			0x1c8
+#define HDMIPLL_CTRL3			0x1cc
+#define HDMIPLL_STS			0x1dc
+
+static struct clk_regmap s7_fixed_pll_vco = {
+	.data = &(struct meson_clk_pll_data) {
+		.en = {
+			.reg_off = FIXPLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = FIXPLL_CTRL0,
+			.shift   = 0,
+			.width   = 9,
+		},
+		.n = {
+			.reg_off = FIXPLL_CTRL0,
+			.shift   = 11,
+			.width   = 5,
+		},
+		.l = {
+			.reg_off = FIXPLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = FIXPLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixed_pll_vco",
+		.ops = &meson_clk_pll_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "fix",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_fixed_pll = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = FIXPLL_CTRL0,
+		.shift = 9,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_READ_ONLY,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fixed_pll",
+		.ops = &clk_regmap_divider_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_fixed_pll_vco.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+#define S7_FCLK(_name, _mult, _divider, _reg, _bit)			\
+static struct clk_fixed_factor s7_##_name##_div = {			\
+	.mult = (_mult),						\
+	.div = (_divider),						\
+	.hw.init = &(struct clk_init_data) {				\
+		.name = #_name "_div",					\
+		.ops = &clk_fixed_factor_ops,				\
+		.parent_hws = (const struct clk_hw *[]) {		\
+			&s7_fixed_pll.hw				\
+		},							\
+		.num_parents = 1,					\
+	},								\
+};									\
+									\
+static struct clk_regmap s7_##_name = {					\
+	.data = &(struct clk_regmap_gate_data) {			\
+		.offset = (_reg),					\
+		.bit_idx = (_bit),					\
+	},								\
+	.hw.init = &(struct clk_init_data) {				\
+		.name = #_name,						\
+		.ops = &clk_regmap_gate_ro_ops,				\
+		.parent_hws = (const struct clk_hw *[]) {		\
+			&s7_##_name##_div.hw				\
+		},							\
+		.num_parents = 1,					\
+	},								\
+}
+
+/* The datasheet documents FIXPLL_CTRL1[30:26] as a single fclk_en field */
+S7_FCLK(fclk_div2, 1, 2, FIXPLL_CTRL1, 30);
+S7_FCLK(fclk_div3, 1, 3, FIXPLL_CTRL1, 26);
+S7_FCLK(fclk_div4, 1, 4, FIXPLL_CTRL1, 27);
+S7_FCLK(fclk_div5, 1, 5, FIXPLL_CTRL1, 28);
+S7_FCLK(fclk_div7, 1, 7, FIXPLL_CTRL1, 29);
+S7_FCLK(fclk_div2p5, 2, 5, FIXPLL_CTRL0, 25);
+
+static const struct pll_mult_range s7_pll_mult_range = {
+	.min = 134,
+	.max = 265,
+};
+
+static const struct reg_sequence s7_gp0_pll_init_regs[] = {
+	{ .reg = GP0PLL_CTRL0,	.def = 0x02520800 },
+	{ .reg = GP0PLL_CTRL1,	.def = 0x09900322 },
+	{ .reg = GP0PLL_CTRL2,	.def = 0x00000000 },
+	{ .reg = GP0PLL_CTRL3,	.def = 0x00000006 },
+};
+
+static struct clk_fixed_factor s7_gp0_pll_div0p5 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "gp0_pll_div0p5",
+		.ops = &clk_fixed_factor_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "gp0",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_gp0_pll_vco = {
+	.data = &(struct meson_clk_pll_data) {
+		.en = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 0,
+			.width   = 9,
+		},
+		.frac = {
+			.reg_off = GP0PLL_CTRL2,
+			.shift   = 0,
+			.width   = 17,
+		},
+		.l = {
+			.reg_off = GP0PLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.frac_max = 131072,
+		.range = &s7_pll_mult_range,
+		.init_regs = s7_gp0_pll_init_regs,
+		.init_count = ARRAY_SIZE(s7_gp0_pll_init_regs),
+		.flags = CLK_MESON_PLL_NOINIT_ENABLED,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gp0_pll_vco",
+		.ops = &meson_clk_pll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_gp0_pll_div0p5.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_gp0_pll = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = GP0PLL_CTRL0,
+		.shift = 9,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO |
+			 CLK_DIVIDER_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gp0_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_gp0_pll_vco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/* hifi is HIFI0 in the datasheet */
+static const struct reg_sequence s7_hifi_pll_init_regs[] = {
+	{ .reg = HIFI0PLL_CTRL0,	.def = 0x02520800 },
+	{ .reg = HIFI0PLL_CTRL1,	.def = 0x09900322 },
+	{ .reg = HIFI0PLL_CTRL2,	.def = 0x00000000 },
+	{ .reg = HIFI0PLL_CTRL3,	.def = 0x00000006 },
+};
+
+static struct clk_fixed_factor s7_hifi_pll_div0p5 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi_pll_div0p5",
+		.ops = &clk_fixed_factor_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "hifi",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_hifi_pll_vco = {
+	.data = &(struct meson_clk_pll_data) {
+		.en = {
+			.reg_off = HIFI0PLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = HIFI0PLL_CTRL0,
+			.shift   = 0,
+			.width   = 9,
+		},
+		.frac = {
+			.reg_off = HIFI0PLL_CTRL2,
+			.shift   = 0,
+			.width   = 17,
+		},
+		.l = {
+			.reg_off = HIFI0PLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = HIFI0PLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.frac_max = 100000,
+		.range = &s7_pll_mult_range,
+		.init_regs = s7_hifi_pll_init_regs,
+		.init_count = ARRAY_SIZE(s7_hifi_pll_init_regs),
+		.flags = CLK_MESON_PLL_ROUND_CLOSEST |
+			 CLK_MESON_PLL_NOINIT_ENABLED,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi_pll_vco",
+		.ops = &meson_clk_pll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hifi_pll_div0p5.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_hifi_pll = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = HIFI0PLL_CTRL0,
+		.shift = 9,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO |
+			 CLK_DIVIDER_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hifi_pll_vco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence s7_hifi1_pll_init_regs[] = {
+	{ .reg = HIFI1PLL_CTRL0,	.def = 0x02520800 },
+	{ .reg = HIFI1PLL_CTRL1,	.def = 0x09900322 },
+	{ .reg = HIFI1PLL_CTRL2,	.def = 0x00000000 },
+	{ .reg = HIFI1PLL_CTRL3,	.def = 0x00000006 },
+};
+
+static struct clk_fixed_factor s7_hifi1_pll_div0p5 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi1_pll_div0p5",
+		.ops = &clk_fixed_factor_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "hifi1",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_hifi1_pll_vco = {
+	.data = &(struct meson_clk_pll_data) {
+		.en = {
+			.reg_off = HIFI1PLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = HIFI1PLL_CTRL0,
+			.shift   = 0,
+			.width   = 9,
+		},
+		.frac = {
+			.reg_off = HIFI1PLL_CTRL2,
+			.shift   = 0,
+			.width   = 17,
+		},
+		.l = {
+			.reg_off = HIFI1PLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = HIFI1PLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.frac_max = 100000,
+		.range = &s7_pll_mult_range,
+		.init_regs = s7_hifi1_pll_init_regs,
+		.init_count = ARRAY_SIZE(s7_hifi1_pll_init_regs),
+		.flags = CLK_MESON_PLL_ROUND_CLOSEST |
+			 CLK_MESON_PLL_NOINIT_ENABLED,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi1_pll_vco",
+		.ops = &meson_clk_pll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hifi1_pll_div0p5.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_hifi1_pll = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = HIFI1PLL_CTRL0,
+		.shift = 9,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO |
+			 CLK_DIVIDER_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi1_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hifi1_pll_vco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct pll_mult_range s7_hdmi_pll_mult_range = {
+	.min = 125,
+	.max = 249,
+};
+
+static const struct reg_sequence s7_hdmi_pll_init_regs[] = {
+	{ .reg = HDMIPLL_CTRL0,	.def = 0x00881000 },
+	{ .reg = HDMIPLL_CTRL1,	.def = 0x2c6011cc },
+	{ .reg = HDMIPLL_CTRL2,	.def = 0x86801000 },
+	{ .reg = HDMIPLL_CTRL3,	.def = 0x00000000 },
+};
+
+static const struct clk_div_table s7_hdmi_pll_div0p5_table[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ /* sentinel */ }
+};
+
+static struct clk_regmap s7_hdmi_pll_div0p5 = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = HDMIPLL_CTRL1,
+		.shift = 19,
+		.width = 1,
+		.table = s7_hdmi_pll_div0p5_table,
+		.flags = CLK_DIVIDER_READ_ONLY,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_div0p5",
+		.ops = &clk_regmap_divider_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "hdmi",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_hdmi_pll_vco = {
+	.data = &(struct meson_clk_pll_data) {
+		.en = {
+			.reg_off = HDMIPLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = HDMIPLL_CTRL0,
+			.shift   = 0,
+			.width   = 9,
+		},
+		.frac = {
+			.reg_off = HDMIPLL_CTRL3,
+			.shift   = 0,
+			.width   = 17,
+		},
+		.l = {
+			.reg_off = HDMIPLL_STS,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = HDMIPLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.range = &s7_hdmi_pll_mult_range,
+		.init_regs = s7_hdmi_pll_init_regs,
+		.init_count = ARRAY_SIZE(s7_hdmi_pll_init_regs),
+		.flags = CLK_MESON_PLL_RST_ACTIVE_LOW |
+			 CLK_MESON_PLL_NOINIT_ENABLED,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_vco",
+		.ops = &meson_clk_pll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll_div0p5.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+/*
+ * The datasheet documents HDMIPLL_CTRL2[22:19] and [18:15] as single fields:
+ * each is two power-of-two dividers.
+ */
+static struct clk_regmap s7_hdmi_pll_od0 = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = HDMIPLL_CTRL2,
+		.shift = 19,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_od0",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll_vco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_hdmi_pll_od1 = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = HDMIPLL_CTRL2,
+		.shift = 21,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_od1",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll_od0.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_hdmi_pll = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = HDMIPLL_CTRL2,
+		.shift = 15,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll_od1.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_hdmi_pll_pix_div5 = {
+	.mult = 1,
+	.div = 5,
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_pix_div5",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_hdmi_pll_pix_div6p25 = {
+	.mult = 4,
+	.div = 25,
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_pix_div6p25",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_hdmi_pll_pix_div7p5 = {
+	.mult = 2,
+	.div = 15,
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_pix_div7p5",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_hdmi_pll_pix = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = HDMIPLL_CTRL0,
+		.mask = 0x3,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmi_pll_pix",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmi_pll_pix_div5.hw,
+			&s7_hdmi_pll_pix_div6p25.hw,
+			&s7_hdmi_pll_pix_div7p5.hw
+		},
+		.num_parents = 3,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_hw *s7_pll_hws[] = {
+	[CLKID_FIXED_PLL_VCO]		= &s7_fixed_pll_vco.hw,
+	[CLKID_FIXED_PLL]		= &s7_fixed_pll.hw,
+	[CLKID_FCLK_DIV2_DIV]		= &s7_fclk_div2_div.hw,
+	[CLKID_FCLK_DIV2]		= &s7_fclk_div2.hw,
+	[CLKID_FCLK_DIV3_DIV]		= &s7_fclk_div3_div.hw,
+	[CLKID_FCLK_DIV3]		= &s7_fclk_div3.hw,
+	[CLKID_FCLK_DIV4_DIV]		= &s7_fclk_div4_div.hw,
+	[CLKID_FCLK_DIV4]		= &s7_fclk_div4.hw,
+	[CLKID_FCLK_DIV5_DIV]		= &s7_fclk_div5_div.hw,
+	[CLKID_FCLK_DIV5]		= &s7_fclk_div5.hw,
+	[CLKID_FCLK_DIV7_DIV]		= &s7_fclk_div7_div.hw,
+	[CLKID_FCLK_DIV7]		= &s7_fclk_div7.hw,
+	[CLKID_FCLK_DIV2P5_DIV]		= &s7_fclk_div2p5_div.hw,
+	[CLKID_FCLK_DIV2P5]		= &s7_fclk_div2p5.hw,
+	[CLKID_GP0_PLL_DIV0P5]		= &s7_gp0_pll_div0p5.hw,
+	[CLKID_GP0_PLL_VCO]		= &s7_gp0_pll_vco.hw,
+	[CLKID_GP0_PLL]			= &s7_gp0_pll.hw,
+	[CLKID_HIFI_PLL_DIV0P5]		= &s7_hifi_pll_div0p5.hw,
+	[CLKID_HIFI_PLL_VCO]		= &s7_hifi_pll_vco.hw,
+	[CLKID_HIFI_PLL]		= &s7_hifi_pll.hw,
+	[CLKID_HIFI1_PLL_DIV0P5]	= &s7_hifi1_pll_div0p5.hw,
+	[CLKID_HIFI1_PLL_VCO]		= &s7_hifi1_pll_vco.hw,
+	[CLKID_HIFI1_PLL]		= &s7_hifi1_pll.hw,
+	[CLKID_HDMI_PLL_DIV0P5]		= &s7_hdmi_pll_div0p5.hw,
+	[CLKID_HDMI_PLL_VCO]		= &s7_hdmi_pll_vco.hw,
+	[CLKID_HDMI_PLL_OD0]		= &s7_hdmi_pll_od0.hw,
+	[CLKID_HDMI_PLL_OD1]		= &s7_hdmi_pll_od1.hw,
+	[CLKID_HDMI_PLL]		= &s7_hdmi_pll.hw,
+	[CLKID_HDMI_PLL_PIX_DIV5]	= &s7_hdmi_pll_pix_div5.hw,
+	[CLKID_HDMI_PLL_PIX_DIV6P25]	= &s7_hdmi_pll_pix_div6p25.hw,
+	[CLKID_HDMI_PLL_PIX_DIV7P5]	= &s7_hdmi_pll_pix_div7p5.hw,
+	[CLKID_HDMI_PLL_PIX]		= &s7_hdmi_pll_pix.hw,
+};
+
+static const struct meson_clkc_data s7_pll_clkc_data = {
+	.hw_clks = {
+		.hws = s7_pll_hws,
+		.num = ARRAY_SIZE(s7_pll_hws),
+	},
+};
+
+static const struct of_device_id s7_pll_clkc_match_table[] = {
+	{
+		.compatible = "amlogic,s7-pll-clkc",
+		.data = &s7_pll_clkc_data,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, s7_pll_clkc_match_table);
+
+static struct platform_driver s7_pll_clkc_driver = {
+	.probe		= meson_clkc_mmio_probe,
+	.driver		= {
+		.name	= "s7-pll-clkc",
+		.of_match_table = s7_pll_clkc_match_table,
+	},
+};
+module_platform_driver(s7_pll_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic S7 PLL Clock Controller driver");
+MODULE_AUTHOR("Carlo Caione <ccaione@baylibre.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");

-- 
2.56.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller
  2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
                   ` (4 preceding siblings ...)
  2026-11-06  8:30 ` [PATCH 5/7] clk: amlogic: Add S7 PLL clock controller driver Carlo Caione
@ 2026-11-06  8:30 ` Carlo Caione
  2026-11-06 17:34   ` Conor Dooley
  2026-11-06  8:30 ` [PATCH 7/7] clk: amlogic: Add S7 peripherals clock controller driver Carlo Caione
  6 siblings, 1 reply; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

The S7 peripherals clock controller supplies the SoC buses and
peripherals, using sources from both the PLL controller and firmware.

Add the binding and clock identifiers so peripheral devices can
reference their clocks in devicetree.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
 .../clock/amlogic,s7-peripherals-clkc.yaml         | 126 +++++++++++
 .../clock/amlogic,s7-peripherals-clkc.h            | 245 +++++++++++++++++++++
 2 files changed, 371 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/amlogic,s7-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s7-peripherals-clkc.yaml
new file mode 100644
index 000000000000..980a215ed4dd
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,s7-peripherals-clkc.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2026 BayLibre, SAS.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,s7-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic S7 Series Peripherals Clock Controller
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+  - Jerome Brunet <jbrunet@baylibre.com>
+  - Carlo Caione <ccaione@baylibre.com>
+
+description:
+  The peripherals clock controller provides the system (bus) clock, the bus
+  clock gates and the clocks of the peripherals. Its inputs are the board
+  oscillator, the fixed PLL dividers and the GP0, HIFI0 and HIFI1 PLLs of the
+  PLL block, the GP1 PLL and the CPU AXI clock provided by the firmware, the
+  HDMI PLL and its pixel clock, and a few optional sources from outside the
+  clock controllers (pads, audio codec).
+
+properties:
+  compatible:
+    const: amlogic,s7-peripherals-clkc
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  clocks:
+    minItems: 14
+    items:
+      - description: input fixed pll div2
+      - description: input fixed pll div2p5
+      - description: input fixed pll div3
+      - description: input fixed pll div4
+      - description: input fixed pll div5
+      - description: input fixed pll div7
+      - description: input hifi pll
+      - description: input gp0 pll
+      - description: input hifi1 pll
+      - description: input gp1 pll
+      - description: input hdmi pll
+      - description: input hdmi pll pixel clk
+      - description: input oscillator (usually at 24MHz)
+      - description: input axi clk from the cpu
+      - description: input external 32kHz reference (optional)
+      - description: input external rmii reference (optional)
+      - description: input audio codec dac clk (optional)
+
+  clock-names:
+    minItems: 14
+    items:
+      - const: fclk_div2
+      - const: fclk_div2p5
+      - const: fclk_div3
+      - const: fclk_div4
+      - const: fclk_div5
+      - const: fclk_div7
+      - const: hifi_pll
+      - const: gp0_pll
+      - const: hifi1_pll
+      - const: gp1_pll
+      - const: hdmi_pll
+      - const: vid_pix
+      - const: xtal
+      - const: axi_frcpu
+      - const: ext_32k
+      - const: ext_rmii
+      - const: acodec_dac
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,s7-pll-clkc.h>
+    #include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@0 {
+            compatible = "amlogic,s7-peripherals-clkc";
+            reg = <0x0 0x0 0x0 0x49c>;
+            #clock-cells = <1>;
+            clocks = <&clkc_pll CLKID_FCLK_DIV2>,
+                     <&clkc_pll CLKID_FCLK_DIV2P5>,
+                     <&clkc_pll CLKID_FCLK_DIV3>,
+                     <&clkc_pll CLKID_FCLK_DIV4>,
+                     <&clkc_pll CLKID_FCLK_DIV5>,
+                     <&clkc_pll CLKID_FCLK_DIV7>,
+                     <&clkc_pll CLKID_HIFI_PLL>,
+                     <&clkc_pll CLKID_GP0_PLL>,
+                     <&clkc_pll CLKID_HIFI1_PLL>,
+                     <&scmi_clk CLKID_GP1_PLL>,
+                     <&clkc_pll CLKID_HDMI_PLL>,
+                     <&clkc_pll CLKID_HDMI_PLL_PIX>,
+                     <&xtal>,
+                     <&scmi_clk CLKID_ACLKM>;
+            clock-names = "fclk_div2",
+                          "fclk_div2p5",
+                          "fclk_div3",
+                          "fclk_div4",
+                          "fclk_div5",
+                          "fclk_div7",
+                          "hifi_pll",
+                          "gp0_pll",
+                          "hifi1_pll",
+                          "gp1_pll",
+                          "hdmi_pll",
+                          "vid_pix",
+                          "xtal",
+                          "axi_frcpu";
+        };
+    };
diff --git a/include/dt-bindings/clock/amlogic,s7-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s7-peripherals-clkc.h
new file mode 100644
index 000000000000..44bf1521e25e
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,s7-peripherals-clkc.h
@@ -0,0 +1,245 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S7_PERIPHERALS_CLKC_H
+#define _DT_BINDINGS_CLOCK_AMLOGIC_S7_PERIPHERALS_CLKC_H
+
+#define CLKID_SYS_AM_AXI			0
+#define CLKID_SYS_DOS				1
+#define CLKID_SYS_ETH_PHY			2
+#define CLKID_SYS_MALI				3
+#define CLKID_SYS_AOCPU				4
+#define CLKID_SYS_AUCPU				5
+#define CLKID_SYS_CEC				6
+#define CLKID_SYS_SD_EMMC_A			7
+#define CLKID_SYS_SD_EMMC_B			8
+#define CLKID_SYS_SD_EMMC_C			9
+#define CLKID_SYS_SC				10
+#define CLKID_SYS_ACODEC			11
+#define CLKID_SYS_MSR				12
+#define CLKID_SYS_IR_CTRL			13
+#define CLKID_SYS_AUDIO				14
+#define CLKID_SYS_ETH				15
+#define CLKID_SYS_UART_A			16
+#define CLKID_SYS_UART_B			17
+#define CLKID_SYS_UART_C			18
+#define CLKID_SYS_UART_D			19
+#define CLKID_SYS_UART_E			20
+#define CLKID_SYS_TS_PLL			21
+#define CLKID_SYS_GE2D				22
+#define CLKID_SYS_SPICC				23
+#define CLKID_SYS_USB				24
+#define CLKID_SYS_I2C_M_A			25
+#define CLKID_SYS_I2C_M_B			26
+#define CLKID_SYS_I2C_M_C			27
+#define CLKID_SYS_I2C_M_D			28
+#define CLKID_SYS_I2C_M_E			29
+#define CLKID_SYS_HDMITX_APB			30
+#define CLKID_SYS_I2C_S_A			31
+#define CLKID_SYS_HDMI20_AES			32
+#define CLKID_SYS_MMC_APB			33
+#define CLKID_SYS_CPU_APB			34
+#define CLKID_SYS_VPU_INTR			35
+#define CLKID_SYS_SAR_ADC			36
+#define CLKID_SYS_PWM_J				37
+#define CLKID_SYS_GIC				38
+#define CLKID_SYS_PWM_I				39
+#define CLKID_SYS_PWM_H				40
+#define CLKID_SYS_PWM_G				41
+#define CLKID_SYS_PWM_F				42
+#define CLKID_SYS_PWM_E				43
+#define CLKID_SYS_PWM_D				44
+#define CLKID_SYS_PWM_C				45
+#define CLKID_SYS_PWM_B				46
+#define CLKID_SYS_PWM_A				47
+#define CLKID_RTC_DUALDIV_IN			48
+#define CLKID_RTC_DUALDIV_DIV			49
+#define CLKID_RTC_DUALDIV_SEL			50
+#define CLKID_RTC_DUALDIV			51
+#define CLKID_RTC				52
+#define CLKID_SYSCLK_A_SEL			53
+#define CLKID_SYSCLK_A_DIV			54
+#define CLKID_SYSCLK_A				55
+#define CLKID_SYSCLK_B_SEL			56
+#define CLKID_SYSCLK_B_DIV			57
+#define CLKID_SYSCLK_B				58
+#define CLKID_SYS_CLK				59
+#define CLKID_AXICLK_A_SEL			60
+#define CLKID_AXICLK_A_DIV			61
+#define CLKID_AXICLK_A				62
+#define CLKID_AXICLK_B_SEL			63
+#define CLKID_AXICLK_B_DIV			64
+#define CLKID_AXICLK_B				65
+#define CLKID_AXI_CLK				66
+#define CLKID_AXI_SYS_NIC			67
+#define CLKID_AXI_SRAM				68
+#define CLKID_AXI_DEV0_MMC			69
+#define CLKID_CECB_DUALDIV_IN			70
+#define CLKID_CECB_DUALDIV_DIV			71
+#define CLKID_CECB_DUALDIV_SEL			72
+#define CLKID_CECB_DUALDIV			73
+#define CLKID_CECB				74
+#define CLKID_SC_PRE_SEL			75
+#define CLKID_SC_PRE_DIV			76
+#define CLKID_SC_PRE				77
+#define CLKID_SC				78
+#define CLKID_CLK24M_IN				79
+#define CLKID_CLK12_24M				80
+#define CLKID_SD_EMMC_A_SEL			81
+#define CLKID_SD_EMMC_A_DIV			82
+#define CLKID_SD_EMMC_A				83
+#define CLKID_SD_EMMC_B_SEL			84
+#define CLKID_SD_EMMC_B_DIV			85
+#define CLKID_SD_EMMC_B				86
+#define CLKID_SD_EMMC_C_SEL			87
+#define CLKID_SD_EMMC_C_DIV			88
+#define CLKID_SD_EMMC_C				89
+#define CLKID_SPICC_SEL				90
+#define CLKID_SPICC_DIV				91
+#define CLKID_SPICC				92
+#define CLKID_PWM_A_SEL				93
+#define CLKID_PWM_A_DIV				94
+#define CLKID_PWM_A				95
+#define CLKID_PWM_B_SEL				96
+#define CLKID_PWM_B_DIV				97
+#define CLKID_PWM_B				98
+#define CLKID_PWM_C_SEL				99
+#define CLKID_PWM_C_DIV				100
+#define CLKID_PWM_C				101
+#define CLKID_PWM_D_SEL				102
+#define CLKID_PWM_D_DIV				103
+#define CLKID_PWM_D				104
+#define CLKID_PWM_E_SEL				105
+#define CLKID_PWM_E_DIV				106
+#define CLKID_PWM_E				107
+#define CLKID_PWM_F_SEL				108
+#define CLKID_PWM_F_DIV				109
+#define CLKID_PWM_F				110
+#define CLKID_SAR_ADC_SEL			111
+#define CLKID_SAR_ADC_DIV			112
+#define CLKID_SAR_ADC				113
+#define CLKID_GEN_SEL				114
+#define CLKID_GEN_DIV				115
+#define CLKID_GEN				116
+#define CLKID_TS_DIV				117
+#define CLKID_TS				118
+#define CLKID_ETH_125M_DIV			119
+#define CLKID_ETH_125M				120
+#define CLKID_ETH_RMII_SEL			121
+#define CLKID_ETH_RMII_DIV			122
+#define CLKID_ETH_RMII				123
+#define CLKID_MALI_0_SEL			124
+#define CLKID_MALI_0_DIV			125
+#define CLKID_MALI_0				126
+#define CLKID_MALI_1_SEL			127
+#define CLKID_MALI_1_DIV			128
+#define CLKID_MALI_1				129
+#define CLKID_MALI				130
+#define CLKID_VDEC_0_SEL			131
+#define CLKID_VDEC_0_DIV			132
+#define CLKID_VDEC_0				133
+#define CLKID_VDEC_1_SEL			134
+#define CLKID_VDEC_1_DIV			135
+#define CLKID_VDEC_1				136
+#define CLKID_VDEC				137
+#define CLKID_HEVCF_0_SEL			138
+#define CLKID_HEVCF_0_DIV			139
+#define CLKID_HEVCF_0				140
+#define CLKID_HEVCF_1_SEL			141
+#define CLKID_HEVCF_1_DIV			142
+#define CLKID_HEVCF_1				143
+#define CLKID_HEVCF				144
+#define CLKID_VPU_0_SEL				145
+#define CLKID_VPU_0_DIV				146
+#define CLKID_VPU_0				147
+#define CLKID_VPU_1_SEL				148
+#define CLKID_VPU_1_DIV				149
+#define CLKID_VPU_1				150
+#define CLKID_VPU				151
+#define CLKID_VPU_CLKB_TMP_SEL			152
+#define CLKID_VPU_CLKB_TMP_DIV			153
+#define CLKID_VPU_CLKB_TMP			154
+#define CLKID_VPU_CLKB_DIV			155
+#define CLKID_VPU_CLKB				156
+#define CLKID_VPU_CLKC_0_SEL			157
+#define CLKID_VPU_CLKC_0_DIV			158
+#define CLKID_VPU_CLKC_0			159
+#define CLKID_VPU_CLKC_1_SEL			160
+#define CLKID_VPU_CLKC_1_DIV			161
+#define CLKID_VPU_CLKC_1			162
+#define CLKID_VPU_CLKC				163
+#define CLKID_VAPB_0_SEL			164
+#define CLKID_VAPB_0_DIV			165
+#define CLKID_VAPB_0				166
+#define CLKID_VAPB_1_SEL			167
+#define CLKID_VAPB_1_DIV			168
+#define CLKID_VAPB_1				169
+#define CLKID_VAPB				170
+#define CLKID_GE2D				171
+#define CLKID_HDMITX_SYS_SEL			172
+#define CLKID_HDMITX_SYS_DIV			173
+#define CLKID_HDMITX_SYS			174
+#define CLKID_HDMITX_PRIF_SEL			175
+#define CLKID_HDMITX_PRIF_DIV			176
+#define CLKID_HDMITX_PRIF			177
+#define CLKID_HDMITX_200M_SEL			178
+#define CLKID_HDMITX_200M_DIV			179
+#define CLKID_HDMITX_200M			180
+#define CLKID_HDMITX_AUD_SEL			181
+#define CLKID_HDMITX_AUD_DIV			182
+#define CLKID_HDMITX_AUD			183
+#define CLKID_VDIN_MEAS_SEL			184
+#define CLKID_VDIN_MEAS_DIV			185
+#define CLKID_VDIN_MEAS				186
+#define CLKID_CDAC_SEL				187
+#define CLKID_CDAC_DIV				188
+#define CLKID_CDAC				189
+#define CLKID_VID_PLL_DIV			190
+#define CLKID_VID_PLL_SEL			191
+#define CLKID_VID_PLL				192
+#define CLKID_VCLK_SEL				193
+#define CLKID_VCLK2_SEL				194
+#define CLKID_VCLK_INPUT			195
+#define CLKID_VCLK2_INPUT			196
+#define CLKID_VCLK_DIV				197
+#define CLKID_VCLK2_DIV				198
+#define CLKID_VCLK				199
+#define CLKID_VCLK2				200
+#define CLKID_VCLK_DIV1				201
+#define CLKID_VCLK_DIV2_EN			202
+#define CLKID_VCLK_DIV4_EN			203
+#define CLKID_VCLK_DIV6_EN			204
+#define CLKID_VCLK_DIV12_EN			205
+#define CLKID_VCLK2_DIV1			206
+#define CLKID_VCLK2_DIV2_EN			207
+#define CLKID_VCLK2_DIV4_EN			208
+#define CLKID_VCLK2_DIV6_EN			209
+#define CLKID_VCLK2_DIV12_EN			210
+#define CLKID_VCLK_DIV2				211
+#define CLKID_VCLK_DIV4				212
+#define CLKID_VCLK_DIV6				213
+#define CLKID_VCLK_DIV12			214
+#define CLKID_VCLK2_DIV2			215
+#define CLKID_VCLK2_DIV4			216
+#define CLKID_VCLK2_DIV6			217
+#define CLKID_VCLK2_DIV12			218
+#define CLKID_ENCI_SEL				219
+#define CLKID_ENCP_SEL				220
+#define CLKID_ENCL_SEL				221
+#define CLKID_VDAC_SEL				222
+#define CLKID_VDAC_PRE_SEL			223
+#define CLKID_HDMITX_PIXEL_SEL			224
+#define CLKID_HDMITX_FE_SEL			225
+#define CLKID_ENCI				226
+#define CLKID_ENCP				227
+#define CLKID_ENCL				228
+#define CLKID_VDAC				229
+#define CLKID_HDMITX_PIXEL			230
+#define CLKID_HDMITX_FE				231
+#define CLKID_VID_LOCK_SEL			232
+#define CLKID_VID_LOCK_DIV			233
+#define CLKID_VID_LOCK				234
+
+#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_S7_PERIPHERALS_CLKC_H */

-- 
2.56.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 7/7] clk: amlogic: Add S7 peripherals clock controller driver
  2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
                   ` (5 preceding siblings ...)
  2026-11-06  8:30 ` [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller Carlo Caione
@ 2026-11-06  8:30 ` Carlo Caione
  6 siblings, 0 replies; 15+ messages in thread
From: Carlo Caione @ 2026-11-06  8:30 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Carlo Caione
  Cc: Jian Hu, Chuan Liu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

The S7 peripheral clock tree is derived from S4, but its clock sources
and routing differ.

Add support for the S7 controller so peripheral drivers can obtain
and manage their clocks through the common clock framework.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
 drivers/clk/meson/Kconfig          |   16 +
 drivers/clk/meson/Makefile         |    1 +
 drivers/clk/meson/s7-peripherals.c | 2149 ++++++++++++++++++++++++++++++++++++
 3 files changed, 2166 insertions(+)

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 35f2971448af..43de3653afc3 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -229,6 +229,22 @@ config COMMON_CLK_S4_PERIPHERALS
 	  Support for the peripherals clock controller on Amlogic S805X2 and S905Y4
 	  devices, AKA S4. Say Y if you want S4 peripherals clock controller to work.
 
+config COMMON_CLK_S7_PERIPHERALS
+	tristate "Amlogic S7 SoC peripherals clock controller support"
+	depends on ARM64 || COMPILE_TEST
+	default ARCH_MESON
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_CLKC_UTILS
+	select COMMON_CLK_MESON_DUALDIV
+	select COMMON_CLK_MESON_VID_PLL_DIV
+	imply COMMON_CLK_SCMI
+	help
+	  Support for the peripherals clock controller on Amlogic S805X3 based
+	  devices, AKA S7. This controller provides the clocks of most
+	  peripherals (eMMC/SD, PWM, SPI, I2C, UART, Ethernet, video and
+	  multimedia blocks). Say Y if you want S7 peripherals clock
+	  controller to work.
+
 config COMMON_CLK_S7_PLL
 	tristate "Amlogic S7 SoC PLL controller support"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 9d439106d11c..5a684f4d6a6c 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
 obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o
 obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o
+obj-$(CONFIG_COMMON_CLK_S7_PERIPHERALS) += s7-peripherals.o
 obj-$(CONFIG_COMMON_CLK_S7_PLL) += s7-pll.o
 obj-$(CONFIG_COMMON_CLK_T7_PLL) += t7-pll.o
 obj-$(CONFIG_COMMON_CLK_T7_PERIPHERALS) += t7-peripherals.o
diff --git a/drivers/clk/meson/s7-peripherals.c b/drivers/clk/meson/s7-peripherals.c
new file mode 100644
index 000000000000..d5413fc20d05
--- /dev/null
+++ b/drivers/clk/meson/s7-peripherals.c
@@ -0,0 +1,2149 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Amlogic S7 Peripherals Clock Controller Driver
+ *
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Carlo Caione <ccaione@baylibre.com>
+ */
+
+#include <dt-bindings/clock/amlogic,s7-peripherals-clkc.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+#include "vid-pll-div.h"
+
+#define RTC_BY_OSCIN_CTRL0			0x008
+#define RTC_BY_OSCIN_CTRL1			0x00c
+#define RTC_CTRL				0x010
+#define SYS_CLK_CTRL0				0x040
+#define SYS_CLK_EN0_REG0			0x044
+#define SYS_CLK_EN0_REG1			0x048
+#define SYS_CLK_EN0_REG2			0x04c
+#define SYS_CLK_EN0_REG3			0x050
+#define AXI_CLK_CTRL0				0x06c
+#define CECB_CTRL0				0x090
+#define CECB_CTRL1				0x094
+#define SC_CLK_CTRL				0x098
+#define CLK12_24_CTRL				0x0a8
+#define AXI_CLK_EN0				0x0ac
+#define VID_CLK_CTRL				0x0c0
+#define VID_CLK_CTRL2				0x0c4
+#define VID_CLK_DIV				0x0c8
+#define VIID_CLK_DIV				0x0cc
+#define VIID_CLK_CTRL				0x0d0
+#define HDMI_CLK_CTRL				0x0e0
+#define VID_PLL_CLK_DIV				0x0e4
+#define VPU_CLK_CTRL				0x0e8
+#define VPU_CLKB_CTRL				0x0ec
+#define VPU_CLKC_CTRL				0x0f0
+#define VID_LOCK_CLK_CTRL			0x0f4
+#define VDIN_MEAS_CLK_CTRL			0x0f8
+#define VAPB_CLK_CTRL				0x0fc
+#define CDAC_CLK_CTRL				0x108
+#define HTX_CLK_CTRL0				0x11c
+#define HTX_CLK_CTRL1				0x120
+#define VDEC_CLK_CTRL				0x140
+#define VDEC2_CLK_CTRL				0x144
+#define VDEC3_CLK_CTRL				0x148
+#define VDEC4_CLK_CTRL				0x14c
+#define TS_CLK_CTRL				0x158
+#define MALI_CLK_CTRL				0x15c
+#define ETH_CLK_CTRL				0x164
+#define NAND_CLK_CTRL				0x168
+#define SD_EMMC_CLK_CTRL			0x16c
+#define SPICC_CLK_CTRL				0x174
+#define GEN_CLK_CTRL				0x178
+#define SAR_CLK_CTRL0				0x17c
+#define PWM_CLK_AB_CTRL				0x180
+#define PWM_CLK_CD_CTRL				0x184
+#define PWM_CLK_EF_CTRL				0x188
+
+#define S7_COMP_SEL(_name, _reg, _shift, _mask, _pdata, _table) \
+	MESON_COMP_SEL(s7_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)
+
+#define S7_COMP_DIV(_name, _reg, _shift, _width) \
+	MESON_COMP_DIV(s7_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
+
+#define S7_COMP_GATE(_name, _reg, _bit, _iflags) \
+	MESON_COMP_GATE(s7_, _name, _reg, _bit, CLK_SET_RATE_PARENT | (_iflags))
+
+static struct clk_regmap s7_rtc_dualdiv_in = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_dualdiv_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct meson_clk_dualdiv_param s7_32k_div_table[] = {
+	{ 733, 732, 8, 11, 1 },
+	{ /* sentinel */ }
+};
+
+static struct clk_regmap s7_rtc_dualdiv_div = {
+	.data = &(struct meson_clk_dualdiv_data) {
+		.n1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = s7_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_dualdiv_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_rtc_dualdiv_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_rtc_dualdiv_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = RTC_BY_OSCIN_CTRL1,
+		.mask = 0x1,
+		.shift = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_dualdiv_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_rtc_dualdiv_div.hw,
+			&s7_rtc_dualdiv_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_rtc_dualdiv = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_dualdiv",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_rtc_dualdiv_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_rtc = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = RTC_CTRL,
+		.mask = 0x3,
+		.shift = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .fw_name = "xtal", },
+			{ .hw = &s7_rtc_dualdiv.hw },
+			{ .fw_name = "ext_32k", },
+		},
+		.num_parents = 3,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 s7_sysclk_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+static const struct clk_parent_data s7_sysclk_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "axi_frcpu", },
+	{ .hw = &s7_rtc.hw }
+};
+
+static struct clk_regmap s7_sysclk_a_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = s7_sysclk_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sysclk_a_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = s7_sysclk_parents,
+		.num_parents = ARRAY_SIZE(s7_sysclk_parents),
+	},
+};
+
+static struct clk_regmap s7_sysclk_a_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = SYS_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+		.flags = CLK_DIVIDER_READ_ONLY,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sysclk_a_div",
+		.ops = &clk_regmap_divider_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_sysclk_a_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_sysclk_a = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sysclk_a",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_sysclk_a_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_sysclk_b_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = s7_sysclk_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sysclk_b_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = s7_sysclk_parents,
+		.num_parents = ARRAY_SIZE(s7_sysclk_parents),
+	},
+};
+
+static struct clk_regmap s7_sysclk_b_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = SYS_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+		.flags = CLK_DIVIDER_READ_ONLY,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sysclk_b_div",
+		.ops = &clk_regmap_divider_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_sysclk_b_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_sysclk_b = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sysclk_b",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_sysclk_b_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_sys_clk = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_clk",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_sysclk_a.hw,
+			&s7_sysclk_b.hw
+		},
+		.num_parents = 2,
+	},
+};
+
+static struct clk_regmap s7_axiclk_a_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = AXI_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = s7_sysclk_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axiclk_a_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = s7_sysclk_parents,
+		.num_parents = ARRAY_SIZE(s7_sysclk_parents),
+	},
+};
+
+static struct clk_regmap s7_axiclk_a_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = AXI_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+		.flags = CLK_DIVIDER_READ_ONLY,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axiclk_a_div",
+		.ops = &clk_regmap_divider_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_axiclk_a_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_axiclk_a = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = AXI_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axiclk_a",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_axiclk_a_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_axiclk_b_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = AXI_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = s7_sysclk_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axiclk_b_sel",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_data = s7_sysclk_parents,
+		.num_parents = ARRAY_SIZE(s7_sysclk_parents),
+	},
+};
+
+static struct clk_regmap s7_axiclk_b_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = AXI_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+		.flags = CLK_DIVIDER_READ_ONLY,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axiclk_b_div",
+		.ops = &clk_regmap_divider_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_axiclk_b_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_axiclk_b = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = AXI_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axiclk_b",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_axiclk_b_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_axi_clk = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = AXI_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axi_clk",
+		.ops = &clk_regmap_mux_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_axiclk_a.hw,
+			&s7_axiclk_b.hw
+		},
+		.num_parents = 2,
+	},
+};
+
+static const struct clk_parent_data s7_sys_pclk_parents = { .hw = &s7_sys_clk.hw };
+
+#define S7_SYS_PCLK(_name, _reg, _bit, _flags) \
+	MESON_PCLK(s7_##_name, _reg, _bit, &s7_sys_pclk_parents, _flags)
+
+#define S7_SYS_PCLK_RO(_name, _reg, _bit) \
+	MESON_PCLK_RO(s7_##_name, _reg, _bit, &s7_sys_pclk_parents, 0)
+
+/* Named ddr in S4 and in older datasheets: the Amlogic bus to AXI bridge clock */
+static S7_SYS_PCLK(sys_am_axi,		SYS_CLK_EN0_REG0, 0, 0);
+static S7_SYS_PCLK(sys_dos,		SYS_CLK_EN0_REG0, 1, 0);
+static S7_SYS_PCLK(sys_eth_phy,		SYS_CLK_EN0_REG0, 4, 0);
+static S7_SYS_PCLK(sys_mali,		SYS_CLK_EN0_REG0, 6, 0);
+/* The always-on co-processor runs its own firmware, which needs this clock */
+static S7_SYS_PCLK(sys_aocpu,		SYS_CLK_EN0_REG0, 13, CLK_IS_CRITICAL);
+static S7_SYS_PCLK(sys_aucpu,		SYS_CLK_EN0_REG0, 14, 0);
+static S7_SYS_PCLK(sys_cec,		SYS_CLK_EN0_REG0, 16, 0);
+static S7_SYS_PCLK(sys_sd_emmc_a,	SYS_CLK_EN0_REG0, 24, 0);
+static S7_SYS_PCLK(sys_sd_emmc_b,	SYS_CLK_EN0_REG0, 25, 0);
+static S7_SYS_PCLK(sys_sd_emmc_c,	SYS_CLK_EN0_REG0, 26, 0);
+static S7_SYS_PCLK(sys_sc,		SYS_CLK_EN0_REG0, 27, 0);
+static S7_SYS_PCLK(sys_acodec,		SYS_CLK_EN0_REG0, 28, 0);
+static S7_SYS_PCLK(sys_msr,		SYS_CLK_EN0_REG0, 30, 0);
+static S7_SYS_PCLK(sys_ir_ctrl,		SYS_CLK_EN0_REG0, 31, 0);
+static S7_SYS_PCLK(sys_audio,		SYS_CLK_EN0_REG1, 0, 0);
+static S7_SYS_PCLK(sys_eth,		SYS_CLK_EN0_REG1, 3, 0);
+static S7_SYS_PCLK(sys_uart_a,		SYS_CLK_EN0_REG1, 5, 0);
+static S7_SYS_PCLK(sys_uart_b,		SYS_CLK_EN0_REG1, 6, 0);
+static S7_SYS_PCLK(sys_uart_c,		SYS_CLK_EN0_REG1, 7, 0);
+static S7_SYS_PCLK(sys_uart_d,		SYS_CLK_EN0_REG1, 8, 0);
+static S7_SYS_PCLK(sys_uart_e,		SYS_CLK_EN0_REG1, 9, 0);
+static S7_SYS_PCLK(sys_ts_pll,		SYS_CLK_EN0_REG1, 16, 0);
+static S7_SYS_PCLK(sys_ge2d,		SYS_CLK_EN0_REG1, 20, 0);
+static S7_SYS_PCLK(sys_spicc,		SYS_CLK_EN0_REG1, 21, 0);
+static S7_SYS_PCLK(sys_usb,		SYS_CLK_EN0_REG1, 26, 0);
+static S7_SYS_PCLK(sys_i2c_m_a,		SYS_CLK_EN0_REG1, 30, 0);
+static S7_SYS_PCLK(sys_i2c_m_b,		SYS_CLK_EN0_REG1, 31, 0);
+static S7_SYS_PCLK(sys_i2c_m_c,		SYS_CLK_EN0_REG2, 0, 0);
+static S7_SYS_PCLK(sys_i2c_m_d,		SYS_CLK_EN0_REG2, 1, 0);
+static S7_SYS_PCLK(sys_i2c_m_e,		SYS_CLK_EN0_REG2, 2, 0);
+static S7_SYS_PCLK(sys_hdmitx_apb,	SYS_CLK_EN0_REG2, 4, 0);
+static S7_SYS_PCLK(sys_i2c_s_a,		SYS_CLK_EN0_REG2, 5, 0);
+static S7_SYS_PCLK(sys_hdmi20_aes,	SYS_CLK_EN0_REG2, 9, 0);
+/* APB clock of the DDR PHY and controller ("MMC" is the memory controller) */
+static S7_SYS_PCLK_RO(sys_mmc_apb,	SYS_CLK_EN0_REG2, 11);
+static S7_SYS_PCLK(sys_cpu_apb,		SYS_CLK_EN0_REG2, 19, 0);
+static S7_SYS_PCLK(sys_vpu_intr,	SYS_CLK_EN0_REG2, 25, 0);
+static S7_SYS_PCLK(sys_sar_adc,		SYS_CLK_EN0_REG2, 28, 0);
+static S7_SYS_PCLK_RO(sys_pwm_j,	SYS_CLK_EN0_REG2, 29);
+/* The GIC driver does not claim its clock, and interrupts need it */
+static S7_SYS_PCLK(sys_gic,		SYS_CLK_EN0_REG2, 30, CLK_IS_CRITICAL);
+static S7_SYS_PCLK(sys_pwm_i,		SYS_CLK_EN0_REG2, 31, 0);
+static S7_SYS_PCLK_RO(sys_pwm_h,	SYS_CLK_EN0_REG3, 0);
+static S7_SYS_PCLK(sys_pwm_g,		SYS_CLK_EN0_REG3, 1, 0);
+static S7_SYS_PCLK(sys_pwm_f,		SYS_CLK_EN0_REG3, 2, 0);
+static S7_SYS_PCLK(sys_pwm_e,		SYS_CLK_EN0_REG3, 3, 0);
+static S7_SYS_PCLK(sys_pwm_d,		SYS_CLK_EN0_REG3, 4, 0);
+static S7_SYS_PCLK(sys_pwm_c,		SYS_CLK_EN0_REG3, 5, 0);
+static S7_SYS_PCLK(sys_pwm_b,		SYS_CLK_EN0_REG3, 6, 0);
+static S7_SYS_PCLK(sys_pwm_a,		SYS_CLK_EN0_REG3, 7, 0);
+
+static const struct clk_parent_data s7_axi_pclk_parents = { .hw = &s7_axi_clk.hw };
+
+static MESON_PCLK_RO(s7_axi_sys_nic, AXI_CLK_EN0, 0, &s7_axi_pclk_parents, 0);
+static MESON_PCLK_RO(s7_axi_sram, AXI_CLK_EN0, 1, &s7_axi_pclk_parents, 0);
+static MESON_PCLK_RO(s7_axi_dev0_mmc, AXI_CLK_EN0, 2, &s7_axi_pclk_parents, 0);
+
+static struct clk_regmap s7_cecb_dualdiv_in = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = CECB_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb_dualdiv_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_cecb_dualdiv_div = {
+	.data = &(struct meson_clk_dualdiv_data) {
+		.n1 = {
+			.reg_off = CECB_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = CECB_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = CECB_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = CECB_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = CECB_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = s7_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb_dualdiv_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_cecb_dualdiv_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_cecb_dualdiv_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CTRL1,
+		.mask = 0x1,
+		.shift = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb_dualdiv_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_cecb_dualdiv_div.hw,
+			&s7_cecb_dualdiv_in.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_cecb_dualdiv = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = CECB_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb_dualdiv",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_cecb_dualdiv_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_cecb = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = CECB_CTRL1,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "cecb",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_cecb_dualdiv.hw,
+			&s7_rtc.hw,
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/* Unlike S4, channel 0 is fclk_div2 (the datasheet table says fclk_div4) */
+static const struct clk_parent_data s7_sc_parents[] = {
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "xtal", }
+};
+
+static S7_COMP_SEL(sc_pre, SC_CLK_CTRL, 9, 0x3, s7_sc_parents, NULL);
+static S7_COMP_DIV(sc_pre, SC_CLK_CTRL, 0, 8);
+static S7_COMP_GATE(sc_pre, SC_CLK_CTRL, 8, 0);
+
+static struct clk_regmap s7_sc = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = SC_CLK_CTRL,
+		.shift = 16,
+		.width = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sc",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_sc_pre.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_24m_in = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "24m_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_12_24m = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = CLK12_24_CTRL,
+		.shift = 10,
+		.width = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "12_24m",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_24m_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static u32 s7_sd_emmc_parents_val_table[] = { 0, 1, 2, 3, 4, 6, 7 };
+static const struct clk_parent_data s7_sd_emmc_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "fclk_div2p5", },
+	{ .fw_name = "gp1_pll", },
+	{ .fw_name = "gp0_pll", }
+};
+
+static S7_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL, 9, 0x7, s7_sd_emmc_parents,
+		   s7_sd_emmc_parents_val_table);
+static S7_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL, 7, 0);
+
+static S7_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL, 25, 0x7, s7_sd_emmc_parents,
+		   s7_sd_emmc_parents_val_table);
+static S7_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL, 16, 7);
+static S7_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL, 23, 0);
+
+static S7_COMP_SEL(sd_emmc_c, NAND_CLK_CTRL, 9, 0x7, s7_sd_emmc_parents,
+		   s7_sd_emmc_parents_val_table);
+static S7_COMP_DIV(sd_emmc_c, NAND_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(sd_emmc_c, NAND_CLK_CTRL, 7, 0);
+
+static const struct clk_parent_data s7_spicc_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &s7_sys_clk.hw },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+	{ .fw_name = "gp1_pll", }
+};
+
+static S7_COMP_SEL(spicc, SPICC_CLK_CTRL, 7, 0x7, s7_spicc_parents, NULL);
+static S7_COMP_DIV(spicc, SPICC_CLK_CTRL, 0, 6);
+static S7_COMP_GATE(spicc, SPICC_CLK_CTRL, 6, 0);
+
+static struct clk_regmap s7_vid_pll_div = {
+	.data = &(struct meson_vid_pll_div_data) {
+		.val = {
+			.reg_off = VID_PLL_CLK_DIV,
+			.shift   = 0,
+			.width   = 15,
+		},
+		.sel = {
+			.reg_off = VID_PLL_CLK_DIV,
+			.shift   = 16,
+			.width   = 2,
+		},
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vid_pll_div",
+		.ops = &meson_vid_pll_div_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "hdmi_pll",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_vid_pll_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VID_PLL_CLK_DIV,
+		.mask = 0x1,
+		.shift = 18,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vid_pll_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &s7_vid_pll_div.hw },
+			{ .fw_name = "hdmi_pll", }
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vid_pll = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_PLL_CLK_DIV,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vid_pll",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vid_pll_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_vclk_parents[] = {
+	{ .hw = &s7_vid_pll.hw },
+	{ .fw_name = "gp1_pll", },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "vid_pix", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", }
+};
+
+static struct clk_regmap s7_vclk_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VID_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = s7_vclk_parents,
+		.num_parents = ARRAY_SIZE(s7_vclk_parents),
+	},
+};
+
+static struct clk_regmap s7_vclk_input = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = VID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk_div1 = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk_div2_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk_div4_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk_div6_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk_div12_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk_div2_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk_div4_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk_div6_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk_div12_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VIID_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = s7_vclk_parents,
+		.num_parents = ARRAY_SIZE(s7_vclk_parents),
+	},
+};
+
+static struct clk_regmap s7_vclk2_input = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VIID_CLK_DIV,
+		.bit_idx = 16,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_input",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = VIID_CLK_DIV,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2_input.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2 = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VIID_CLK_CTRL,
+		.bit_idx = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2_div1 = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VIID_CLK_CTRL,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2_div2_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VIID_CLK_CTRL,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div2_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2_div4_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VIID_CLK_CTRL,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div4_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2_div6_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VIID_CLK_CTRL,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div6_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vclk2_div12_en = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VIID_CLK_CTRL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div12_en",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk2_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div2",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2_div2_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk2_div4 = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div4",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2_div4_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk2_div6 = {
+	.mult = 1,
+	.div = 6,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div6",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2_div6_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_vclk2_div12 = {
+	.mult = 1,
+	.div = 12,
+	.hw.init = &(struct clk_init_data) {
+		.name = "vclk2_div12",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vclk2_div12_en.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 s7_cts_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
+static const struct clk_hw *s7_cts_parents[] = {
+	&s7_vclk_div1.hw,
+	&s7_vclk_div2.hw,
+	&s7_vclk_div4.hw,
+	&s7_vclk_div6.hw,
+	&s7_vclk_div12.hw,
+	&s7_vclk2_div1.hw,
+	&s7_vclk2_div2.hw,
+	&s7_vclk2_div4.hw,
+	&s7_vclk2_div6.hw,
+	&s7_vclk2_div12.hw
+};
+
+static struct clk_regmap s7_enci_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VID_CLK_DIV,
+		.mask = 0xf,
+		.shift = 28,
+		.table = s7_cts_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "enci_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = s7_cts_parents,
+		.num_parents = ARRAY_SIZE(s7_cts_parents),
+	},
+};
+
+static struct clk_regmap s7_encp_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VID_CLK_DIV,
+		.mask = 0xf,
+		.shift = 24,
+		.table = s7_cts_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "encp_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = s7_cts_parents,
+		.num_parents = ARRAY_SIZE(s7_cts_parents),
+	},
+};
+
+static struct clk_regmap s7_encl_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VIID_CLK_DIV,
+		.mask = 0xf,
+		.shift = 12,
+		.table = s7_cts_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "encl_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = s7_cts_parents,
+		.num_parents = ARRAY_SIZE(s7_cts_parents),
+	},
+};
+
+static struct clk_regmap s7_vdac_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VIID_CLK_DIV,
+		.mask = 0xf,
+		.shift = 28,
+		.table = s7_cts_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vdac_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = s7_cts_parents,
+		.num_parents = ARRAY_SIZE(s7_cts_parents),
+	},
+};
+
+static struct clk_regmap s7_hdmitx_pixel_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = HDMI_CLK_CTRL,
+		.mask = 0xf,
+		.shift = 16,
+		.table = s7_cts_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmitx_pixel_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = s7_cts_parents,
+		.num_parents = ARRAY_SIZE(s7_cts_parents),
+	},
+};
+
+static struct clk_regmap s7_hdmitx_fe_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = HDMI_CLK_CTRL,
+		.mask = 0xf,
+		.shift = 20,
+		.table = s7_cts_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmitx_fe_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = s7_cts_parents,
+		.num_parents = ARRAY_SIZE(s7_cts_parents),
+	},
+};
+
+/* VIID_CLK_DIV[19] (documented as adc_pll_clk_b2) selects fclk_div7 for the VDAC */
+static struct clk_regmap s7_vdac_pre_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VIID_CLK_DIV,
+		.mask = 0x1,
+		.shift = 19,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vdac_pre_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = (const struct clk_parent_data []) {
+			{ .hw = &s7_vdac_sel.hw },
+			{ .fw_name = "fclk_div7", }
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_enci = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL2,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "enci",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_enci_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_encp = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL2,
+		.bit_idx = 2,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "encp",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_encp_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_encl = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL2,
+		.bit_idx = 3,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "encl",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_encl_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vdac = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL2,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vdac",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vdac_pre_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_hdmitx_pixel = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL2,
+		.bit_idx = 5,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmitx_pixel",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmitx_pixel_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_hdmitx_fe = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VID_CLK_CTRL2,
+		.bit_idx = 9,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hdmitx_fe",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hdmitx_fe_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_vid_lock_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &s7_encl.hw },
+	{ .hw = &s7_enci.hw },
+	{ .hw = &s7_encp.hw }
+};
+
+static S7_COMP_SEL(vid_lock, VID_LOCK_CLK_CTRL, 8, 0x3, s7_vid_lock_parents, NULL);
+static S7_COMP_DIV(vid_lock, VID_LOCK_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(vid_lock, VID_LOCK_CLK_CTRL, 7, 0);
+
+static const struct clk_parent_data s7_pwm_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &s7_vid_pll.hw },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div3", }
+};
+
+static S7_COMP_SEL(pwm_a, PWM_CLK_AB_CTRL, 9, 0x3, s7_pwm_parents, NULL);
+static S7_COMP_DIV(pwm_a, PWM_CLK_AB_CTRL, 0, 8);
+static S7_COMP_GATE(pwm_a, PWM_CLK_AB_CTRL, 8, 0);
+
+static S7_COMP_SEL(pwm_b, PWM_CLK_AB_CTRL, 25, 0x3, s7_pwm_parents, NULL);
+static S7_COMP_DIV(pwm_b, PWM_CLK_AB_CTRL, 16, 8);
+static S7_COMP_GATE(pwm_b, PWM_CLK_AB_CTRL, 24, 0);
+
+static S7_COMP_SEL(pwm_c, PWM_CLK_CD_CTRL, 9, 0x3, s7_pwm_parents, NULL);
+static S7_COMP_DIV(pwm_c, PWM_CLK_CD_CTRL, 0, 8);
+static S7_COMP_GATE(pwm_c, PWM_CLK_CD_CTRL, 8, 0);
+
+static S7_COMP_SEL(pwm_d, PWM_CLK_CD_CTRL, 25, 0x3, s7_pwm_parents, NULL);
+static S7_COMP_DIV(pwm_d, PWM_CLK_CD_CTRL, 16, 8);
+static S7_COMP_GATE(pwm_d, PWM_CLK_CD_CTRL, 24, 0);
+
+static S7_COMP_SEL(pwm_e, PWM_CLK_EF_CTRL, 9, 0x3, s7_pwm_parents, NULL);
+static S7_COMP_DIV(pwm_e, PWM_CLK_EF_CTRL, 0, 8);
+static S7_COMP_GATE(pwm_e, PWM_CLK_EF_CTRL, 8, 0);
+
+static S7_COMP_SEL(pwm_f, PWM_CLK_EF_CTRL, 25, 0x3, s7_pwm_parents, NULL);
+static S7_COMP_DIV(pwm_f, PWM_CLK_EF_CTRL, 16, 8);
+static S7_COMP_GATE(pwm_f, PWM_CLK_EF_CTRL, 24, 0);
+
+static const struct clk_parent_data s7_sar_adc_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &s7_sys_clk.hw }
+};
+
+static S7_COMP_SEL(sar_adc, SAR_CLK_CTRL0, 9, 0x3, s7_sar_adc_parents, NULL);
+static S7_COMP_DIV(sar_adc, SAR_CLK_CTRL0, 0, 8);
+static S7_COMP_GATE(sar_adc, SAR_CLK_CTRL0, 8, 0);
+
+static u32 s7_gen_parents_val_table[] = { 0, 1, 4, 5, 6, 7, 8, 16, 19, 20, 21,
+					  22, 23, 24 };
+static const struct clk_parent_data s7_gen_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .hw = &s7_rtc.hw },
+	{ .hw = &s7_vid_pll.hw },
+	{ .fw_name = "gp0_pll", },
+	{ .fw_name = "hifi1_pll", },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "gp1_pll", },
+	{ .fw_name = "acodec_dac", },
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "fclk_div2p5", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", }
+};
+
+static S7_COMP_SEL(gen, GEN_CLK_CTRL, 12, 0x1f, s7_gen_parents,
+		   s7_gen_parents_val_table);
+static S7_COMP_DIV(gen, GEN_CLK_CTRL, 0, 11);
+static S7_COMP_GATE(gen, GEN_CLK_CTRL, 11, 0);
+
+static struct clk_regmap s7_ts_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = TS_CLK_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ts_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_ts = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = TS_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ts",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_ts_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor s7_eth_125m_div = {
+	.mult = 1,
+	.div = 8,
+	.hw.init = &(struct clk_init_data) {
+		.name = "eth_125m_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "fclk_div2",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap s7_eth_125m = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = ETH_CLK_CTRL,
+		.bit_idx = 7,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "eth_125m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_eth_125m_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 s7_eth_rmii_parents_val_table[] = { 0, 7 };
+static const struct clk_parent_data s7_eth_rmii_parents[] = {
+	{ .fw_name = "fclk_div2", },
+	{ .fw_name = "ext_rmii", }
+};
+
+static struct clk_regmap s7_eth_rmii_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = ETH_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = s7_eth_rmii_parents_val_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "eth_rmii_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = s7_eth_rmii_parents,
+		.num_parents = ARRAY_SIZE(s7_eth_rmii_parents),
+		.flags = CLK_SET_RATE_NO_REPARENT,
+	},
+};
+
+static struct clk_regmap s7_eth_rmii_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = ETH_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "eth_rmii_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_eth_rmii_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_eth_rmii = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = ETH_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "eth_rmii",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_eth_rmii_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_mali_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "gp1_pll", },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "fclk_div2p5", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", }
+};
+
+static S7_COMP_SEL(mali_0, MALI_CLK_CTRL, 9, 0x7, s7_mali_parents, NULL);
+static S7_COMP_DIV(mali_0, MALI_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(mali_0, MALI_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static S7_COMP_SEL(mali_1, MALI_CLK_CTRL, 25, 0x7, s7_mali_parents, NULL);
+static S7_COMP_DIV(mali_1, MALI_CLK_CTRL, 16, 7);
+static S7_COMP_GATE(mali_1, MALI_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap s7_mali = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = MALI_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "mali",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_mali_0.hw,
+			&s7_mali_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_dec_parents[] = {
+	{ .fw_name = "fclk_div2p5", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "gp1_pll", },
+	{ .fw_name = "xtal", }
+};
+
+static S7_COMP_SEL(vdec_0, VDEC_CLK_CTRL, 9, 0x7, s7_dec_parents, NULL);
+static S7_COMP_DIV(vdec_0, VDEC_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(vdec_0, VDEC_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static S7_COMP_SEL(vdec_1, VDEC3_CLK_CTRL, 9, 0x7, s7_dec_parents, NULL);
+static S7_COMP_DIV(vdec_1, VDEC3_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(vdec_1, VDEC3_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static struct clk_regmap s7_vdec = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VDEC3_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vdec",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vdec_0.hw,
+			&s7_vdec_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static S7_COMP_SEL(hevcf_0, VDEC2_CLK_CTRL, 9, 0x7, s7_dec_parents, NULL);
+static S7_COMP_DIV(hevcf_0, VDEC2_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(hevcf_0, VDEC2_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static S7_COMP_SEL(hevcf_1, VDEC4_CLK_CTRL, 9, 0x7, s7_dec_parents, NULL);
+static S7_COMP_DIV(hevcf_1, VDEC4_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(hevcf_1, VDEC4_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static struct clk_regmap s7_hevcf = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VDEC4_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hevcf",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_hevcf_0.hw,
+			&s7_hevcf_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_vpu_parents[] = {
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+	{ .fw_name = "fclk_div2", },
+	{ .hw = &s7_vid_pll.hw },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "gp1_pll", }
+};
+
+static S7_COMP_SEL(vpu_0, VPU_CLK_CTRL, 9, 0x7, s7_vpu_parents, NULL);
+static S7_COMP_DIV(vpu_0, VPU_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(vpu_0, VPU_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static S7_COMP_SEL(vpu_1, VPU_CLK_CTRL, 25, 0x7, s7_vpu_parents, NULL);
+static S7_COMP_DIV(vpu_1, VPU_CLK_CTRL, 16, 7);
+static S7_COMP_GATE(vpu_1, VPU_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap s7_vpu = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VPU_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vpu_0.hw,
+			&s7_vpu_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_vpu_clkb_tmp_parents[] = {
+	{ .hw = &s7_vpu.hw },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", }
+};
+
+static S7_COMP_SEL(vpu_clkb_tmp, VPU_CLKB_CTRL, 20, 0x3, s7_vpu_clkb_tmp_parents, NULL);
+static S7_COMP_DIV(vpu_clkb_tmp, VPU_CLKB_CTRL, 16, 4);
+static S7_COMP_GATE(vpu_clkb_tmp, VPU_CLKB_CTRL, 24, 0);
+
+static struct clk_regmap s7_vpu_clkb_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = VPU_CLKB_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_clkb_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vpu_clkb_tmp.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_vpu_clkb = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VPU_CLKB_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_clkb",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vpu_clkb_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_vpu_clkc_parents[] = {
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+	{ .fw_name = "fclk_div2", },
+	{ .hw = &s7_vid_pll.hw },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "gp1_pll", }
+};
+
+static S7_COMP_SEL(vpu_clkc_0, VPU_CLKC_CTRL, 9, 0x7, s7_vpu_clkc_parents, NULL);
+static S7_COMP_DIV(vpu_clkc_0, VPU_CLKC_CTRL, 0, 7);
+static S7_COMP_GATE(vpu_clkc_0, VPU_CLKC_CTRL, 8, CLK_SET_RATE_GATE);
+
+static S7_COMP_SEL(vpu_clkc_1, VPU_CLKC_CTRL, 25, 0x7, s7_vpu_clkc_parents, NULL);
+static S7_COMP_DIV(vpu_clkc_1, VPU_CLKC_CTRL, 16, 7);
+static S7_COMP_GATE(vpu_clkc_1, VPU_CLKC_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap s7_vpu_clkc = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VPU_CLKC_CTRL,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vpu_clkc",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vpu_clkc_0.hw,
+			&s7_vpu_clkc_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_vapb_parents[] = {
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .fw_name = "fclk_div7", },
+	{ .fw_name = "fclk_div2", },
+	{ .hw = &s7_vid_pll.hw },
+	{ .fw_name = "hifi_pll", },
+	{ .fw_name = "fclk_div2p5", }
+};
+
+static S7_COMP_SEL(vapb_0, VAPB_CLK_CTRL, 9, 0x7, s7_vapb_parents, NULL);
+static S7_COMP_DIV(vapb_0, VAPB_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(vapb_0, VAPB_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static S7_COMP_SEL(vapb_1, VAPB_CLK_CTRL, 25, 0x7, s7_vapb_parents, NULL);
+static S7_COMP_DIV(vapb_1, VAPB_CLK_CTRL, 16, 7);
+static S7_COMP_GATE(vapb_1, VAPB_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap s7_vapb = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = VAPB_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vapb_0.hw,
+			&s7_vapb_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap s7_ge2d = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = VAPB_CLK_CTRL,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ge2d",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&s7_vapb.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data s7_hdmi_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", }
+};
+
+static S7_COMP_SEL(hdmitx_sys, HDMI_CLK_CTRL, 9, 0x3, s7_hdmi_parents, NULL);
+static S7_COMP_DIV(hdmitx_sys, HDMI_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(hdmitx_sys, HDMI_CLK_CTRL, 8, 0);
+
+static S7_COMP_SEL(hdmitx_prif, HTX_CLK_CTRL0, 9, 0x3, s7_hdmi_parents, NULL);
+static S7_COMP_DIV(hdmitx_prif, HTX_CLK_CTRL0, 0, 7);
+static S7_COMP_GATE(hdmitx_prif, HTX_CLK_CTRL0, 8, 0);
+
+static S7_COMP_SEL(hdmitx_200m, HTX_CLK_CTRL0, 25, 0x3, s7_hdmi_parents, NULL);
+static S7_COMP_DIV(hdmitx_200m, HTX_CLK_CTRL0, 16, 7);
+static S7_COMP_GATE(hdmitx_200m, HTX_CLK_CTRL0, 24, 0);
+
+static S7_COMP_SEL(hdmitx_aud, HTX_CLK_CTRL1, 9, 0x3, s7_hdmi_parents, NULL);
+static S7_COMP_DIV(hdmitx_aud, HTX_CLK_CTRL1, 0, 7);
+static S7_COMP_GATE(hdmitx_aud, HTX_CLK_CTRL1, 8, 0);
+
+static const struct clk_parent_data s7_vdin_meas_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div4", },
+	{ .fw_name = "fclk_div3", },
+	{ .fw_name = "fclk_div5", },
+	{ .hw = &s7_vid_pll.hw }
+};
+
+static S7_COMP_SEL(vdin_meas, VDIN_MEAS_CLK_CTRL, 9, 0x7, s7_vdin_meas_parents, NULL);
+static S7_COMP_DIV(vdin_meas, VDIN_MEAS_CLK_CTRL, 0, 7);
+static S7_COMP_GATE(vdin_meas, VDIN_MEAS_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data s7_cdac_parents[] = {
+	{ .fw_name = "xtal", },
+	{ .fw_name = "fclk_div5", }
+};
+
+static S7_COMP_SEL(cdac, CDAC_CLK_CTRL, 16, 0x3, s7_cdac_parents, NULL);
+static S7_COMP_DIV(cdac, CDAC_CLK_CTRL, 0, 16);
+static S7_COMP_GATE(cdac, CDAC_CLK_CTRL, 20, 0);
+
+static struct clk_hw *s7_peripherals_hw_clks[] = {
+	[CLKID_SYS_AM_AXI]		= &s7_sys_am_axi.hw,
+	[CLKID_SYS_DOS]			= &s7_sys_dos.hw,
+	[CLKID_SYS_ETH_PHY]		= &s7_sys_eth_phy.hw,
+	[CLKID_SYS_MALI]		= &s7_sys_mali.hw,
+	[CLKID_SYS_AOCPU]		= &s7_sys_aocpu.hw,
+	[CLKID_SYS_AUCPU]		= &s7_sys_aucpu.hw,
+	[CLKID_SYS_CEC]			= &s7_sys_cec.hw,
+	[CLKID_SYS_SD_EMMC_A]		= &s7_sys_sd_emmc_a.hw,
+	[CLKID_SYS_SD_EMMC_B]		= &s7_sys_sd_emmc_b.hw,
+	[CLKID_SYS_SD_EMMC_C]		= &s7_sys_sd_emmc_c.hw,
+	[CLKID_SYS_SC]			= &s7_sys_sc.hw,
+	[CLKID_SYS_ACODEC]		= &s7_sys_acodec.hw,
+	[CLKID_SYS_MSR]			= &s7_sys_msr.hw,
+	[CLKID_SYS_IR_CTRL]		= &s7_sys_ir_ctrl.hw,
+	[CLKID_SYS_AUDIO]		= &s7_sys_audio.hw,
+	[CLKID_SYS_ETH]			= &s7_sys_eth.hw,
+	[CLKID_SYS_UART_A]		= &s7_sys_uart_a.hw,
+	[CLKID_SYS_UART_B]		= &s7_sys_uart_b.hw,
+	[CLKID_SYS_UART_C]		= &s7_sys_uart_c.hw,
+	[CLKID_SYS_UART_D]		= &s7_sys_uart_d.hw,
+	[CLKID_SYS_UART_E]		= &s7_sys_uart_e.hw,
+	[CLKID_SYS_TS_PLL]		= &s7_sys_ts_pll.hw,
+	[CLKID_SYS_GE2D]		= &s7_sys_ge2d.hw,
+	[CLKID_SYS_SPICC]		= &s7_sys_spicc.hw,
+	[CLKID_SYS_USB]			= &s7_sys_usb.hw,
+	[CLKID_SYS_I2C_M_A]		= &s7_sys_i2c_m_a.hw,
+	[CLKID_SYS_I2C_M_B]		= &s7_sys_i2c_m_b.hw,
+	[CLKID_SYS_I2C_M_C]		= &s7_sys_i2c_m_c.hw,
+	[CLKID_SYS_I2C_M_D]		= &s7_sys_i2c_m_d.hw,
+	[CLKID_SYS_I2C_M_E]		= &s7_sys_i2c_m_e.hw,
+	[CLKID_SYS_HDMITX_APB]		= &s7_sys_hdmitx_apb.hw,
+	[CLKID_SYS_I2C_S_A]		= &s7_sys_i2c_s_a.hw,
+	[CLKID_SYS_HDMI20_AES]		= &s7_sys_hdmi20_aes.hw,
+	[CLKID_SYS_MMC_APB]		= &s7_sys_mmc_apb.hw,
+	[CLKID_SYS_CPU_APB]		= &s7_sys_cpu_apb.hw,
+	[CLKID_SYS_VPU_INTR]		= &s7_sys_vpu_intr.hw,
+	[CLKID_SYS_SAR_ADC]		= &s7_sys_sar_adc.hw,
+	[CLKID_SYS_PWM_J]		= &s7_sys_pwm_j.hw,
+	[CLKID_SYS_GIC]			= &s7_sys_gic.hw,
+	[CLKID_SYS_PWM_I]		= &s7_sys_pwm_i.hw,
+	[CLKID_SYS_PWM_H]		= &s7_sys_pwm_h.hw,
+	[CLKID_SYS_PWM_G]		= &s7_sys_pwm_g.hw,
+	[CLKID_SYS_PWM_F]		= &s7_sys_pwm_f.hw,
+	[CLKID_SYS_PWM_E]		= &s7_sys_pwm_e.hw,
+	[CLKID_SYS_PWM_D]		= &s7_sys_pwm_d.hw,
+	[CLKID_SYS_PWM_C]		= &s7_sys_pwm_c.hw,
+	[CLKID_SYS_PWM_B]		= &s7_sys_pwm_b.hw,
+	[CLKID_SYS_PWM_A]		= &s7_sys_pwm_a.hw,
+	[CLKID_RTC_DUALDIV_IN]		= &s7_rtc_dualdiv_in.hw,
+	[CLKID_RTC_DUALDIV_DIV]		= &s7_rtc_dualdiv_div.hw,
+	[CLKID_RTC_DUALDIV_SEL]		= &s7_rtc_dualdiv_sel.hw,
+	[CLKID_RTC_DUALDIV]		= &s7_rtc_dualdiv.hw,
+	[CLKID_RTC]			= &s7_rtc.hw,
+	[CLKID_SYSCLK_A_SEL]		= &s7_sysclk_a_sel.hw,
+	[CLKID_SYSCLK_A_DIV]		= &s7_sysclk_a_div.hw,
+	[CLKID_SYSCLK_A]		= &s7_sysclk_a.hw,
+	[CLKID_SYSCLK_B_SEL]		= &s7_sysclk_b_sel.hw,
+	[CLKID_SYSCLK_B_DIV]		= &s7_sysclk_b_div.hw,
+	[CLKID_SYSCLK_B]		= &s7_sysclk_b.hw,
+	[CLKID_SYS_CLK]			= &s7_sys_clk.hw,
+	[CLKID_AXICLK_A_SEL]		= &s7_axiclk_a_sel.hw,
+	[CLKID_AXICLK_A_DIV]		= &s7_axiclk_a_div.hw,
+	[CLKID_AXICLK_A]		= &s7_axiclk_a.hw,
+	[CLKID_AXICLK_B_SEL]		= &s7_axiclk_b_sel.hw,
+	[CLKID_AXICLK_B_DIV]		= &s7_axiclk_b_div.hw,
+	[CLKID_AXICLK_B]		= &s7_axiclk_b.hw,
+	[CLKID_AXI_CLK]			= &s7_axi_clk.hw,
+	[CLKID_AXI_SYS_NIC]		= &s7_axi_sys_nic.hw,
+	[CLKID_AXI_SRAM]		= &s7_axi_sram.hw,
+	[CLKID_AXI_DEV0_MMC]		= &s7_axi_dev0_mmc.hw,
+	[CLKID_CECB_DUALDIV_IN]		= &s7_cecb_dualdiv_in.hw,
+	[CLKID_CECB_DUALDIV_DIV]	= &s7_cecb_dualdiv_div.hw,
+	[CLKID_CECB_DUALDIV_SEL]	= &s7_cecb_dualdiv_sel.hw,
+	[CLKID_CECB_DUALDIV]		= &s7_cecb_dualdiv.hw,
+	[CLKID_CECB]			= &s7_cecb.hw,
+	[CLKID_SC_PRE_SEL]		= &s7_sc_pre_sel.hw,
+	[CLKID_SC_PRE_DIV]		= &s7_sc_pre_div.hw,
+	[CLKID_SC_PRE]			= &s7_sc_pre.hw,
+	[CLKID_SC]			= &s7_sc.hw,
+	[CLKID_CLK24M_IN]		= &s7_24m_in.hw,
+	[CLKID_CLK12_24M]		= &s7_12_24m.hw,
+	[CLKID_SD_EMMC_A_SEL]		= &s7_sd_emmc_a_sel.hw,
+	[CLKID_SD_EMMC_A_DIV]		= &s7_sd_emmc_a_div.hw,
+	[CLKID_SD_EMMC_A]		= &s7_sd_emmc_a.hw,
+	[CLKID_SD_EMMC_B_SEL]		= &s7_sd_emmc_b_sel.hw,
+	[CLKID_SD_EMMC_B_DIV]		= &s7_sd_emmc_b_div.hw,
+	[CLKID_SD_EMMC_B]		= &s7_sd_emmc_b.hw,
+	[CLKID_SD_EMMC_C_SEL]		= &s7_sd_emmc_c_sel.hw,
+	[CLKID_SD_EMMC_C_DIV]		= &s7_sd_emmc_c_div.hw,
+	[CLKID_SD_EMMC_C]		= &s7_sd_emmc_c.hw,
+	[CLKID_SPICC_SEL]		= &s7_spicc_sel.hw,
+	[CLKID_SPICC_DIV]		= &s7_spicc_div.hw,
+	[CLKID_SPICC]			= &s7_spicc.hw,
+	[CLKID_PWM_A_SEL]		= &s7_pwm_a_sel.hw,
+	[CLKID_PWM_A_DIV]		= &s7_pwm_a_div.hw,
+	[CLKID_PWM_A]			= &s7_pwm_a.hw,
+	[CLKID_PWM_B_SEL]		= &s7_pwm_b_sel.hw,
+	[CLKID_PWM_B_DIV]		= &s7_pwm_b_div.hw,
+	[CLKID_PWM_B]			= &s7_pwm_b.hw,
+	[CLKID_PWM_C_SEL]		= &s7_pwm_c_sel.hw,
+	[CLKID_PWM_C_DIV]		= &s7_pwm_c_div.hw,
+	[CLKID_PWM_C]			= &s7_pwm_c.hw,
+	[CLKID_PWM_D_SEL]		= &s7_pwm_d_sel.hw,
+	[CLKID_PWM_D_DIV]		= &s7_pwm_d_div.hw,
+	[CLKID_PWM_D]			= &s7_pwm_d.hw,
+	[CLKID_PWM_E_SEL]		= &s7_pwm_e_sel.hw,
+	[CLKID_PWM_E_DIV]		= &s7_pwm_e_div.hw,
+	[CLKID_PWM_E]			= &s7_pwm_e.hw,
+	[CLKID_PWM_F_SEL]		= &s7_pwm_f_sel.hw,
+	[CLKID_PWM_F_DIV]		= &s7_pwm_f_div.hw,
+	[CLKID_PWM_F]			= &s7_pwm_f.hw,
+	[CLKID_SAR_ADC_SEL]		= &s7_sar_adc_sel.hw,
+	[CLKID_SAR_ADC_DIV]		= &s7_sar_adc_div.hw,
+	[CLKID_SAR_ADC]			= &s7_sar_adc.hw,
+	[CLKID_GEN_SEL]			= &s7_gen_sel.hw,
+	[CLKID_GEN_DIV]			= &s7_gen_div.hw,
+	[CLKID_GEN]			= &s7_gen.hw,
+	[CLKID_TS_DIV]			= &s7_ts_div.hw,
+	[CLKID_TS]			= &s7_ts.hw,
+	[CLKID_ETH_125M_DIV]		= &s7_eth_125m_div.hw,
+	[CLKID_ETH_125M]		= &s7_eth_125m.hw,
+	[CLKID_ETH_RMII_SEL]		= &s7_eth_rmii_sel.hw,
+	[CLKID_ETH_RMII_DIV]		= &s7_eth_rmii_div.hw,
+	[CLKID_ETH_RMII]		= &s7_eth_rmii.hw,
+	[CLKID_MALI_0_SEL]		= &s7_mali_0_sel.hw,
+	[CLKID_MALI_0_DIV]		= &s7_mali_0_div.hw,
+	[CLKID_MALI_0]			= &s7_mali_0.hw,
+	[CLKID_MALI_1_SEL]		= &s7_mali_1_sel.hw,
+	[CLKID_MALI_1_DIV]		= &s7_mali_1_div.hw,
+	[CLKID_MALI_1]			= &s7_mali_1.hw,
+	[CLKID_MALI]			= &s7_mali.hw,
+	[CLKID_VDEC_0_SEL]		= &s7_vdec_0_sel.hw,
+	[CLKID_VDEC_0_DIV]		= &s7_vdec_0_div.hw,
+	[CLKID_VDEC_0]			= &s7_vdec_0.hw,
+	[CLKID_VDEC_1_SEL]		= &s7_vdec_1_sel.hw,
+	[CLKID_VDEC_1_DIV]		= &s7_vdec_1_div.hw,
+	[CLKID_VDEC_1]			= &s7_vdec_1.hw,
+	[CLKID_VDEC]			= &s7_vdec.hw,
+	[CLKID_HEVCF_0_SEL]		= &s7_hevcf_0_sel.hw,
+	[CLKID_HEVCF_0_DIV]		= &s7_hevcf_0_div.hw,
+	[CLKID_HEVCF_0]			= &s7_hevcf_0.hw,
+	[CLKID_HEVCF_1_SEL]		= &s7_hevcf_1_sel.hw,
+	[CLKID_HEVCF_1_DIV]		= &s7_hevcf_1_div.hw,
+	[CLKID_HEVCF_1]			= &s7_hevcf_1.hw,
+	[CLKID_HEVCF]			= &s7_hevcf.hw,
+	[CLKID_VPU_0_SEL]		= &s7_vpu_0_sel.hw,
+	[CLKID_VPU_0_DIV]		= &s7_vpu_0_div.hw,
+	[CLKID_VPU_0]			= &s7_vpu_0.hw,
+	[CLKID_VPU_1_SEL]		= &s7_vpu_1_sel.hw,
+	[CLKID_VPU_1_DIV]		= &s7_vpu_1_div.hw,
+	[CLKID_VPU_1]			= &s7_vpu_1.hw,
+	[CLKID_VPU]			= &s7_vpu.hw,
+	[CLKID_VPU_CLKB_TMP_SEL]	= &s7_vpu_clkb_tmp_sel.hw,
+	[CLKID_VPU_CLKB_TMP_DIV]	= &s7_vpu_clkb_tmp_div.hw,
+	[CLKID_VPU_CLKB_TMP]		= &s7_vpu_clkb_tmp.hw,
+	[CLKID_VPU_CLKB_DIV]		= &s7_vpu_clkb_div.hw,
+	[CLKID_VPU_CLKB]		= &s7_vpu_clkb.hw,
+	[CLKID_VPU_CLKC_0_SEL]		= &s7_vpu_clkc_0_sel.hw,
+	[CLKID_VPU_CLKC_0_DIV]		= &s7_vpu_clkc_0_div.hw,
+	[CLKID_VPU_CLKC_0]		= &s7_vpu_clkc_0.hw,
+	[CLKID_VPU_CLKC_1_SEL]		= &s7_vpu_clkc_1_sel.hw,
+	[CLKID_VPU_CLKC_1_DIV]		= &s7_vpu_clkc_1_div.hw,
+	[CLKID_VPU_CLKC_1]		= &s7_vpu_clkc_1.hw,
+	[CLKID_VPU_CLKC]		= &s7_vpu_clkc.hw,
+	[CLKID_VAPB_0_SEL]		= &s7_vapb_0_sel.hw,
+	[CLKID_VAPB_0_DIV]		= &s7_vapb_0_div.hw,
+	[CLKID_VAPB_0]			= &s7_vapb_0.hw,
+	[CLKID_VAPB_1_SEL]		= &s7_vapb_1_sel.hw,
+	[CLKID_VAPB_1_DIV]		= &s7_vapb_1_div.hw,
+	[CLKID_VAPB_1]			= &s7_vapb_1.hw,
+	[CLKID_VAPB]			= &s7_vapb.hw,
+	[CLKID_GE2D]			= &s7_ge2d.hw,
+	[CLKID_HDMITX_SYS_SEL]		= &s7_hdmitx_sys_sel.hw,
+	[CLKID_HDMITX_SYS_DIV]		= &s7_hdmitx_sys_div.hw,
+	[CLKID_HDMITX_SYS]		= &s7_hdmitx_sys.hw,
+	[CLKID_HDMITX_PRIF_SEL]		= &s7_hdmitx_prif_sel.hw,
+	[CLKID_HDMITX_PRIF_DIV]		= &s7_hdmitx_prif_div.hw,
+	[CLKID_HDMITX_PRIF]		= &s7_hdmitx_prif.hw,
+	[CLKID_HDMITX_200M_SEL]		= &s7_hdmitx_200m_sel.hw,
+	[CLKID_HDMITX_200M_DIV]		= &s7_hdmitx_200m_div.hw,
+	[CLKID_HDMITX_200M]		= &s7_hdmitx_200m.hw,
+	[CLKID_HDMITX_AUD_SEL]		= &s7_hdmitx_aud_sel.hw,
+	[CLKID_HDMITX_AUD_DIV]		= &s7_hdmitx_aud_div.hw,
+	[CLKID_HDMITX_AUD]		= &s7_hdmitx_aud.hw,
+	[CLKID_VDIN_MEAS_SEL]		= &s7_vdin_meas_sel.hw,
+	[CLKID_VDIN_MEAS_DIV]		= &s7_vdin_meas_div.hw,
+	[CLKID_VDIN_MEAS]		= &s7_vdin_meas.hw,
+	[CLKID_CDAC_SEL]		= &s7_cdac_sel.hw,
+	[CLKID_CDAC_DIV]		= &s7_cdac_div.hw,
+	[CLKID_CDAC]			= &s7_cdac.hw,
+	[CLKID_VID_PLL_DIV]		= &s7_vid_pll_div.hw,
+	[CLKID_VID_PLL_SEL]		= &s7_vid_pll_sel.hw,
+	[CLKID_VID_PLL]			= &s7_vid_pll.hw,
+	[CLKID_VCLK_SEL]		= &s7_vclk_sel.hw,
+	[CLKID_VCLK2_SEL]		= &s7_vclk2_sel.hw,
+	[CLKID_VCLK_INPUT]		= &s7_vclk_input.hw,
+	[CLKID_VCLK2_INPUT]		= &s7_vclk2_input.hw,
+	[CLKID_VCLK_DIV]		= &s7_vclk_div.hw,
+	[CLKID_VCLK2_DIV]		= &s7_vclk2_div.hw,
+	[CLKID_VCLK]			= &s7_vclk.hw,
+	[CLKID_VCLK2]			= &s7_vclk2.hw,
+	[CLKID_VCLK_DIV1]		= &s7_vclk_div1.hw,
+	[CLKID_VCLK_DIV2_EN]		= &s7_vclk_div2_en.hw,
+	[CLKID_VCLK_DIV4_EN]		= &s7_vclk_div4_en.hw,
+	[CLKID_VCLK_DIV6_EN]		= &s7_vclk_div6_en.hw,
+	[CLKID_VCLK_DIV12_EN]		= &s7_vclk_div12_en.hw,
+	[CLKID_VCLK2_DIV1]		= &s7_vclk2_div1.hw,
+	[CLKID_VCLK2_DIV2_EN]		= &s7_vclk2_div2_en.hw,
+	[CLKID_VCLK2_DIV4_EN]		= &s7_vclk2_div4_en.hw,
+	[CLKID_VCLK2_DIV6_EN]		= &s7_vclk2_div6_en.hw,
+	[CLKID_VCLK2_DIV12_EN]		= &s7_vclk2_div12_en.hw,
+	[CLKID_VCLK_DIV2]		= &s7_vclk_div2.hw,
+	[CLKID_VCLK_DIV4]		= &s7_vclk_div4.hw,
+	[CLKID_VCLK_DIV6]		= &s7_vclk_div6.hw,
+	[CLKID_VCLK_DIV12]		= &s7_vclk_div12.hw,
+	[CLKID_VCLK2_DIV2]		= &s7_vclk2_div2.hw,
+	[CLKID_VCLK2_DIV4]		= &s7_vclk2_div4.hw,
+	[CLKID_VCLK2_DIV6]		= &s7_vclk2_div6.hw,
+	[CLKID_VCLK2_DIV12]		= &s7_vclk2_div12.hw,
+	[CLKID_ENCI_SEL]		= &s7_enci_sel.hw,
+	[CLKID_ENCP_SEL]		= &s7_encp_sel.hw,
+	[CLKID_ENCL_SEL]		= &s7_encl_sel.hw,
+	[CLKID_VDAC_SEL]		= &s7_vdac_sel.hw,
+	[CLKID_VDAC_PRE_SEL]		= &s7_vdac_pre_sel.hw,
+	[CLKID_HDMITX_PIXEL_SEL]	= &s7_hdmitx_pixel_sel.hw,
+	[CLKID_HDMITX_FE_SEL]		= &s7_hdmitx_fe_sel.hw,
+	[CLKID_ENCI]			= &s7_enci.hw,
+	[CLKID_ENCP]			= &s7_encp.hw,
+	[CLKID_ENCL]			= &s7_encl.hw,
+	[CLKID_VDAC]			= &s7_vdac.hw,
+	[CLKID_HDMITX_PIXEL]		= &s7_hdmitx_pixel.hw,
+	[CLKID_HDMITX_FE]		= &s7_hdmitx_fe.hw,
+	[CLKID_VID_LOCK_SEL]		= &s7_vid_lock_sel.hw,
+	[CLKID_VID_LOCK_DIV]		= &s7_vid_lock_div.hw,
+	[CLKID_VID_LOCK]		= &s7_vid_lock.hw,
+};
+
+static const struct meson_clkc_data s7_peripherals_clkc_data = {
+	.hw_clks = {
+		.hws = s7_peripherals_hw_clks,
+		.num = ARRAY_SIZE(s7_peripherals_hw_clks),
+	},
+};
+
+static const struct of_device_id s7_peripherals_clkc_match_table[] = {
+	{
+		.compatible = "amlogic,s7-peripherals-clkc",
+		.data = &s7_peripherals_clkc_data,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, s7_peripherals_clkc_match_table);
+
+static struct platform_driver s7_peripherals_clkc_driver = {
+	.probe		= meson_clkc_mmio_probe,
+	.driver		= {
+		.name	= "s7-peripherals-clkc",
+		.of_match_table = s7_peripherals_clkc_match_table,
+	},
+};
+module_platform_driver(s7_peripherals_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic S7 Peripherals Clock Controller driver");
+MODULE_AUTHOR("Carlo Caione <ccaione@baylibre.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");

-- 
2.56.0


_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/7] clk: meson: pll: Support PLLs without a pre-divider
  2026-11-06  8:30 ` [PATCH 2/7] clk: meson: pll: Support PLLs without a pre-divider Carlo Caione
@ 2026-11-06  8:35   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-11-06  8:35 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-clk, devicetree, linux-amlogic, robh, conor+dt, neil.armstrong

Thank you for your contribution! Sashiko AI review found no new issues
in this patch, but noticed 1 related pre-existing issue it does not
introduce:
- [High] clk: meson: 32-bit integer overflow in
  meson_clk_get_pll_range_index() [1]
--

commit 241035ecfdb206acdcf290a5e288104a056a3f8b
Author: Carlo Caione <ccaione@baylibre.com>

clk: meson: pll: Support PLLs without a pre-divider

This commit makes the PLL pre-divider parameter optional in the common Meson
PLL driver, defaulting the divider to 1 when the parameter is not applicable.

> diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
> index 1ea6579a760f3..44b33051405f5 100644
> --- a/drivers/clk/meson/clk-pll.c
> +++ b/drivers/clk/meson/clk-pll.c

[ ... ]

> @@ -174,7 +176,7 @@ static int meson_clk_get_pll_range_index(unsigned long rate,
>  	*n = index + 1;
>  
>  	/* Check the predivider range */
> -	if (*n >= (1 << pll->n.width))
> +	if (*n >= (MESON_PARM_APPLICABLE(&pll->n) ? 1 << pll->n.width : 2))
>  		return -EINVAL;
>  
>  	if (*n == 1) {

[Severity: High]
This problem wasn't introduced by this patch, but can `pll->range->max *
parent_rate` in meson_clk_get_pll_range_index() and `parent_rate * m` in
__pll_params_with_frac() overflow 32-bit unsigned long arithmetic [1]?

drivers/clk/meson/clk-pll.c:meson_clk_get_pll_range_index() {
	...
	if (*n == 1) {
		/* Get the boundaries out the way */
		if (rate <= pll->range->min * parent_rate) {
			*m = pll->range->min;
			return -ENODATA;
		} else if (rate >= pll->range->max * parent_rate) {
			*m = pll->range->max;
			return -ENODATA;
		}
	}
	...
}

drivers/clk/meson/clk-pll.c:__pll_params_with_frac() {
	...
	/* Bail out if we are already over the requested rate */
	if (rate < parent_rate * m / n)
		return 0;
	...
}

On 32-bit architectures, multiplying a 24 MHz `parent_rate` by a typical
multiplier (such as `pll->range->max` of 250) reaches 6,000,000,000 and wraps
around 32-bit `ULONG_MAX`.  This causes the range check in
meson_clk_get_pll_range_index() to miscalculate `m` and the guard in
__pll_params_with_frac() to be bypassed, underflowing `val -= m * frac_max`
and writing corrupted multiplier and fractional values to the PLL hardware.

[1] https://sashiko.dev/#/bug/linux-8a5ec432-efbd-4d3f-83c7-2a50fc2850c7

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-upstream-s7-clk-v1-0-7d501d62621f@baylibre.com?part=2

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 5/7] clk: amlogic: Add S7 PLL clock controller driver
  2026-11-06  8:30 ` [PATCH 5/7] clk: amlogic: Add S7 PLL clock controller driver Carlo Caione
@ 2026-11-06  8:51   ` sashiko-bot
  0 siblings, 0 replies; 15+ messages in thread
From: sashiko-bot @ 2026-11-06  8:51 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-clk, devicetree, linux-amlogic, robh, conor+dt, neil.armstrong

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] clk: meson: s7-pll: HDMIPLL_CTRL1 initialized after
  s7_hdmi_pll_div0p5 rate
--

commit 6a51c26cbe37d4a7e3b2407e903405378e1e348b
Author: Carlo Caione <ccaione@baylibre.com>

clk: amlogic: Add S7 PLL clock controller driver

This commit adds the PLL clock controller driver for the Amlogic S7 SoC,
providing the fixed PLL and its dividers, the GP0, HIFI0 and HIFI1 PLLs,
and the HDMI PLL.

> diff --git a/drivers/clk/meson/s7-pll.c b/drivers/clk/meson/s7-pll.c
> new file mode 100644
> index 0000000000000..2aa253a5f2111
> --- /dev/null
> +++ b/drivers/clk/meson/s7-pll.c

[ ... ]

> +static const struct reg_sequence s7_hdmi_pll_init_regs[] = {
> +	{ .reg = HDMIPLL_CTRL0,	.def = 0x00881000 },
> +	{ .reg = HDMIPLL_CTRL1,	.def = 0x2c6011cc },
> +	{ .reg = HDMIPLL_CTRL2,	.def = 0x86801000 },
> +	{ .reg = HDMIPLL_CTRL3,	.def = 0x00000000 },
> +};
> +
> +static const struct clk_div_table s7_hdmi_pll_div0p5_table[] = {
> +	{ .val = 0, .div = 1 },
> +	{ .val = 1, .div = 2 },
> +	{ /* sentinel */ }
> +};
> +
> +static struct clk_regmap s7_hdmi_pll_div0p5 = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = HDMIPLL_CTRL1,
> +		.shift = 19,
> +		.width = 1,
> +		.table = s7_hdmi_pll_div0p5_table,
> +		.flags = CLK_DIVIDER_READ_ONLY,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hdmi_pll_div0p5",
> +		.ops = &clk_regmap_divider_ro_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "hdmi",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap s7_hdmi_pll_vco = {
> +	.data = &(struct meson_clk_pll_data) {
> +		.en = {
> +			.reg_off = HDMIPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = HDMIPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.frac = {
> +			.reg_off = HDMIPLL_CTRL3,
> +			.shift   = 0,
> +			.width   = 17,
> +		},
> +		.l = {
> +			.reg_off = HDMIPLL_STS,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = HDMIPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.range = &s7_hdmi_pll_mult_range,
> +		.init_regs = s7_hdmi_pll_init_regs,
> +		.init_count = ARRAY_SIZE(s7_hdmi_pll_init_regs),
> +		.flags = CLK_MESON_PLL_RST_ACTIVE_LOW |
> +			 CLK_MESON_PLL_NOINIT_ENABLED,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hdmi_pll_vco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&s7_hdmi_pll_div0p5.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};

[ ... ]

> +static struct clk_hw *s7_pll_hws[] = {

[ ... ]

> +	[CLKID_HDMI_PLL_DIV0P5]		= &s7_hdmi_pll_div0p5.hw,
> +	[CLKID_HDMI_PLL_VCO]		= &s7_hdmi_pll_vco.hw,

[Severity: Medium]
Can s7_hdmi_pll_div0p5 cache a stale divide-by-2 rate before
s7_hdmi_pll_vco initializes HDMIPLL_CTRL1?

meson_clkc_init() registers s7_pll_hws[] in index order, so
s7_hdmi_pll_div0p5 reads HDMIPLL_CTRL1 bit 19 and caches its rate before
s7_hdmi_pll_vco runs meson_clk_pll_init() and writes
s7_hdmi_pll_init_regs (which clears HDMIPLL_CTRL1 bit 19 to 0 when the
PLL is not already enabled by firmware). Because s7_hdmi_pll_div0p5 uses
clk_regmap_divider_ro_ops without CLK_GET_RATE_NOCACHE, its cached rate
is never updated after HDMIPLL_CTRL1 is overwritten, which would leave
s7_hdmi_pll_vco and all downstream HDMI PLL clocks calculating rates off
by a factor of 2 if bit 19 was set prior to initialization.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-upstream-s7-clk-v1-0-7d501d62621f@baylibre.com?part=5

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller
  2026-11-06  8:30 ` [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller Carlo Caione
@ 2026-11-06 17:34   ` Conor Dooley
  2026-11-06 19:34     ` Carlo Caione
  0 siblings, 1 reply; 15+ messages in thread
From: Conor Dooley @ 2026-11-06 17:34 UTC (permalink / raw)
  To: Carlo Caione
  Cc: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Jian Hu, Chuan Liu,
	linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 14351 bytes --]

On Fri, Nov 06, 2026 at 09:30:29AM +0100, Carlo Caione wrote:
> The S7 peripherals clock controller supplies the SoC buses and
> peripherals, using sources from both the PLL controller and firmware.
> 
> Add the binding and clock identifiers so peripheral devices can
> reference their clocks in devicetree.
> 
> Signed-off-by: Carlo Caione <ccaione@baylibre.com>
> ---
>  .../clock/amlogic,s7-peripherals-clkc.yaml         | 126 +++++++++++
>  .../clock/amlogic,s7-peripherals-clkc.h            | 245 +++++++++++++++++++++
>  2 files changed, 371 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,s7-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s7-peripherals-clkc.yaml
> new file mode 100644
> index 000000000000..980a215ed4dd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,s7-peripherals-clkc.yaml
> @@ -0,0 +1,126 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (c) 2026 BayLibre, SAS.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/amlogic,s7-peripherals-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic S7 Series Peripherals Clock Controller
> +
> +maintainers:
> +  - Neil Armstrong <neil.armstrong@linaro.org>
> +  - Jerome Brunet <jbrunet@baylibre.com>
> +  - Carlo Caione <ccaione@baylibre.com>
> +
> +description:
> +  The peripherals clock controller provides the system (bus) clock, the bus
> +  clock gates and the clocks of the peripherals. Its inputs are the board
> +  oscillator, the fixed PLL dividers and the GP0, HIFI0 and HIFI1 PLLs of the
> +  PLL block, the GP1 PLL and the CPU AXI clock provided by the firmware, the
> +  HDMI PLL and its pixel clock, and a few optional sources from outside the
> +  clock controllers (pads, audio codec).
> +
> +properties:
> +  compatible:
> +    const: amlogic,s7-peripherals-clkc
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#clock-cells':
> +    const: 1
> +
> +  clocks:
> +    minItems: 14
> +    items:
> +      - description: input fixed pll div2
> +      - description: input fixed pll div2p5
> +      - description: input fixed pll div3
> +      - description: input fixed pll div4
> +      - description: input fixed pll div5
> +      - description: input fixed pll div7
> +      - description: input hifi pll
> +      - description: input gp0 pll
> +      - description: input hifi1 pll
> +      - description: input gp1 pll
> +      - description: input hdmi pll
> +      - description: input hdmi pll pixel clk
> +      - description: input oscillator (usually at 24MHz)
> +      - description: input axi clk from the cpu
> +      - description: input external 32kHz reference (optional)
> +      - description: input external rmii reference (optional)
> +      - description: input audio codec dac clk (optional)
> +
> +  clock-names:
> +    minItems: 14
> +    items:
> +      - const: fclk_div2
> +      - const: fclk_div2p5
> +      - const: fclk_div3
> +      - const: fclk_div4
> +      - const: fclk_div5
> +      - const: fclk_div7
> +      - const: hifi_pll
> +      - const: gp0_pll
> +      - const: hifi1_pll
> +      - const: gp1_pll
> +      - const: hdmi_pll
> +      - const: vid_pix
> +      - const: xtal
> +      - const: axi_frcpu
> +      - const: ext_32k
> +      - const: ext_rmii
> +      - const: acodec_dac
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#clock-cells'
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/amlogic,s7-pll-clkc.h>
> +    #include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        clock-controller@0 {
> +            compatible = "amlogic,s7-peripherals-clkc";
> +            reg = <0x0 0x0 0x0 0x49c>;

What's with the weird numbers in this example?

Examples don't have to be real, but when it looks like this the
immediate thought is that the modelling of the device might be
incorrec.t

> +            #clock-cells = <1>;
> +            clocks = <&clkc_pll CLKID_FCLK_DIV2>,
> +                     <&clkc_pll CLKID_FCLK_DIV2P5>,
> +                     <&clkc_pll CLKID_FCLK_DIV3>,
> +                     <&clkc_pll CLKID_FCLK_DIV4>,
> +                     <&clkc_pll CLKID_FCLK_DIV5>,
> +                     <&clkc_pll CLKID_FCLK_DIV7>,
> +                     <&clkc_pll CLKID_HIFI_PLL>,
> +                     <&clkc_pll CLKID_GP0_PLL>,
> +                     <&clkc_pll CLKID_HIFI1_PLL>,
> +                     <&scmi_clk CLKID_GP1_PLL>,
> +                     <&clkc_pll CLKID_HDMI_PLL>,
> +                     <&clkc_pll CLKID_HDMI_PLL_PIX>,
> +                     <&xtal>,
> +                     <&scmi_clk CLKID_ACLKM>;
> +            clock-names = "fclk_div2",
> +                          "fclk_div2p5",
> +                          "fclk_div3",
> +                          "fclk_div4",
> +                          "fclk_div5",
> +                          "fclk_div7",
> +                          "hifi_pll",
> +                          "gp0_pll",
> +                          "hifi1_pll",
> +                          "gp1_pll",
> +                          "hdmi_pll",
> +                          "vid_pix",
> +                          "xtal",
> +                          "axi_frcpu";
> +        };
> +    };
> diff --git a/include/dt-bindings/clock/amlogic,s7-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s7-peripherals-clkc.h
> new file mode 100644
> index 000000000000..44bf1521e25e
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,s7-peripherals-clkc.h
> @@ -0,0 +1,245 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2026 BayLibre, SAS.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S7_PERIPHERALS_CLKC_H
> +#define _DT_BINDINGS_CLOCK_AMLOGIC_S7_PERIPHERALS_CLKC_H
> +
> +#define CLKID_SYS_AM_AXI			0
> +#define CLKID_SYS_DOS				1
> +#define CLKID_SYS_ETH_PHY			2
> +#define CLKID_SYS_MALI				3
> +#define CLKID_SYS_AOCPU				4
> +#define CLKID_SYS_AUCPU				5
> +#define CLKID_SYS_CEC				6
> +#define CLKID_SYS_SD_EMMC_A			7
> +#define CLKID_SYS_SD_EMMC_B			8
> +#define CLKID_SYS_SD_EMMC_C			9
> +#define CLKID_SYS_SC				10
> +#define CLKID_SYS_ACODEC			11
> +#define CLKID_SYS_MSR				12
> +#define CLKID_SYS_IR_CTRL			13
> +#define CLKID_SYS_AUDIO				14
> +#define CLKID_SYS_ETH				15
> +#define CLKID_SYS_UART_A			16
> +#define CLKID_SYS_UART_B			17
> +#define CLKID_SYS_UART_C			18
> +#define CLKID_SYS_UART_D			19
> +#define CLKID_SYS_UART_E			20
> +#define CLKID_SYS_TS_PLL			21
> +#define CLKID_SYS_GE2D				22
> +#define CLKID_SYS_SPICC				23
> +#define CLKID_SYS_USB				24
> +#define CLKID_SYS_I2C_M_A			25
> +#define CLKID_SYS_I2C_M_B			26
> +#define CLKID_SYS_I2C_M_C			27
> +#define CLKID_SYS_I2C_M_D			28
> +#define CLKID_SYS_I2C_M_E			29
> +#define CLKID_SYS_HDMITX_APB			30
> +#define CLKID_SYS_I2C_S_A			31
> +#define CLKID_SYS_HDMI20_AES			32
> +#define CLKID_SYS_MMC_APB			33
> +#define CLKID_SYS_CPU_APB			34
> +#define CLKID_SYS_VPU_INTR			35
> +#define CLKID_SYS_SAR_ADC			36
> +#define CLKID_SYS_PWM_J				37
> +#define CLKID_SYS_GIC				38
> +#define CLKID_SYS_PWM_I				39
> +#define CLKID_SYS_PWM_H				40
> +#define CLKID_SYS_PWM_G				41
> +#define CLKID_SYS_PWM_F				42
> +#define CLKID_SYS_PWM_E				43
> +#define CLKID_SYS_PWM_D				44
> +#define CLKID_SYS_PWM_C				45
> +#define CLKID_SYS_PWM_B				46
> +#define CLKID_SYS_PWM_A				47
> +#define CLKID_RTC_DUALDIV_IN			48
> +#define CLKID_RTC_DUALDIV_DIV			49
> +#define CLKID_RTC_DUALDIV_SEL			50
> +#define CLKID_RTC_DUALDIV			51
> +#define CLKID_RTC				52
> +#define CLKID_SYSCLK_A_SEL			53
> +#define CLKID_SYSCLK_A_DIV			54
> +#define CLKID_SYSCLK_A				55
> +#define CLKID_SYSCLK_B_SEL			56
> +#define CLKID_SYSCLK_B_DIV			57
> +#define CLKID_SYSCLK_B				58
> +#define CLKID_SYS_CLK				59
> +#define CLKID_AXICLK_A_SEL			60
> +#define CLKID_AXICLK_A_DIV			61
> +#define CLKID_AXICLK_A				62
> +#define CLKID_AXICLK_B_SEL			63
> +#define CLKID_AXICLK_B_DIV			64
> +#define CLKID_AXICLK_B				65
> +#define CLKID_AXI_CLK				66
> +#define CLKID_AXI_SYS_NIC			67
> +#define CLKID_AXI_SRAM				68
> +#define CLKID_AXI_DEV0_MMC			69
> +#define CLKID_CECB_DUALDIV_IN			70
> +#define CLKID_CECB_DUALDIV_DIV			71
> +#define CLKID_CECB_DUALDIV_SEL			72
> +#define CLKID_CECB_DUALDIV			73
> +#define CLKID_CECB				74
> +#define CLKID_SC_PRE_SEL			75
> +#define CLKID_SC_PRE_DIV			76
> +#define CLKID_SC_PRE				77
> +#define CLKID_SC				78
> +#define CLKID_CLK24M_IN				79
> +#define CLKID_CLK12_24M				80
> +#define CLKID_SD_EMMC_A_SEL			81
> +#define CLKID_SD_EMMC_A_DIV			82
> +#define CLKID_SD_EMMC_A				83
> +#define CLKID_SD_EMMC_B_SEL			84
> +#define CLKID_SD_EMMC_B_DIV			85
> +#define CLKID_SD_EMMC_B				86
> +#define CLKID_SD_EMMC_C_SEL			87
> +#define CLKID_SD_EMMC_C_DIV			88
> +#define CLKID_SD_EMMC_C				89
> +#define CLKID_SPICC_SEL				90
> +#define CLKID_SPICC_DIV				91
> +#define CLKID_SPICC				92
> +#define CLKID_PWM_A_SEL				93
> +#define CLKID_PWM_A_DIV				94
> +#define CLKID_PWM_A				95
> +#define CLKID_PWM_B_SEL				96
> +#define CLKID_PWM_B_DIV				97
> +#define CLKID_PWM_B				98
> +#define CLKID_PWM_C_SEL				99
> +#define CLKID_PWM_C_DIV				100
> +#define CLKID_PWM_C				101
> +#define CLKID_PWM_D_SEL				102
> +#define CLKID_PWM_D_DIV				103
> +#define CLKID_PWM_D				104
> +#define CLKID_PWM_E_SEL				105
> +#define CLKID_PWM_E_DIV				106
> +#define CLKID_PWM_E				107
> +#define CLKID_PWM_F_SEL				108
> +#define CLKID_PWM_F_DIV				109
> +#define CLKID_PWM_F				110
> +#define CLKID_SAR_ADC_SEL			111
> +#define CLKID_SAR_ADC_DIV			112
> +#define CLKID_SAR_ADC				113
> +#define CLKID_GEN_SEL				114
> +#define CLKID_GEN_DIV				115
> +#define CLKID_GEN				116
> +#define CLKID_TS_DIV				117
> +#define CLKID_TS				118
> +#define CLKID_ETH_125M_DIV			119
> +#define CLKID_ETH_125M				120
> +#define CLKID_ETH_RMII_SEL			121
> +#define CLKID_ETH_RMII_DIV			122
> +#define CLKID_ETH_RMII				123
> +#define CLKID_MALI_0_SEL			124
> +#define CLKID_MALI_0_DIV			125
> +#define CLKID_MALI_0				126
> +#define CLKID_MALI_1_SEL			127
> +#define CLKID_MALI_1_DIV			128
> +#define CLKID_MALI_1				129
> +#define CLKID_MALI				130
> +#define CLKID_VDEC_0_SEL			131
> +#define CLKID_VDEC_0_DIV			132
> +#define CLKID_VDEC_0				133
> +#define CLKID_VDEC_1_SEL			134
> +#define CLKID_VDEC_1_DIV			135
> +#define CLKID_VDEC_1				136
> +#define CLKID_VDEC				137
> +#define CLKID_HEVCF_0_SEL			138
> +#define CLKID_HEVCF_0_DIV			139
> +#define CLKID_HEVCF_0				140
> +#define CLKID_HEVCF_1_SEL			141
> +#define CLKID_HEVCF_1_DIV			142
> +#define CLKID_HEVCF_1				143
> +#define CLKID_HEVCF				144
> +#define CLKID_VPU_0_SEL				145
> +#define CLKID_VPU_0_DIV				146
> +#define CLKID_VPU_0				147
> +#define CLKID_VPU_1_SEL				148
> +#define CLKID_VPU_1_DIV				149
> +#define CLKID_VPU_1				150
> +#define CLKID_VPU				151
> +#define CLKID_VPU_CLKB_TMP_SEL			152
> +#define CLKID_VPU_CLKB_TMP_DIV			153
> +#define CLKID_VPU_CLKB_TMP			154
> +#define CLKID_VPU_CLKB_DIV			155
> +#define CLKID_VPU_CLKB				156
> +#define CLKID_VPU_CLKC_0_SEL			157
> +#define CLKID_VPU_CLKC_0_DIV			158
> +#define CLKID_VPU_CLKC_0			159
> +#define CLKID_VPU_CLKC_1_SEL			160
> +#define CLKID_VPU_CLKC_1_DIV			161
> +#define CLKID_VPU_CLKC_1			162
> +#define CLKID_VPU_CLKC				163
> +#define CLKID_VAPB_0_SEL			164
> +#define CLKID_VAPB_0_DIV			165
> +#define CLKID_VAPB_0				166
> +#define CLKID_VAPB_1_SEL			167
> +#define CLKID_VAPB_1_DIV			168
> +#define CLKID_VAPB_1				169
> +#define CLKID_VAPB				170
> +#define CLKID_GE2D				171
> +#define CLKID_HDMITX_SYS_SEL			172
> +#define CLKID_HDMITX_SYS_DIV			173
> +#define CLKID_HDMITX_SYS			174
> +#define CLKID_HDMITX_PRIF_SEL			175
> +#define CLKID_HDMITX_PRIF_DIV			176
> +#define CLKID_HDMITX_PRIF			177
> +#define CLKID_HDMITX_200M_SEL			178
> +#define CLKID_HDMITX_200M_DIV			179
> +#define CLKID_HDMITX_200M			180
> +#define CLKID_HDMITX_AUD_SEL			181
> +#define CLKID_HDMITX_AUD_DIV			182
> +#define CLKID_HDMITX_AUD			183
> +#define CLKID_VDIN_MEAS_SEL			184
> +#define CLKID_VDIN_MEAS_DIV			185
> +#define CLKID_VDIN_MEAS				186
> +#define CLKID_CDAC_SEL				187
> +#define CLKID_CDAC_DIV				188
> +#define CLKID_CDAC				189
> +#define CLKID_VID_PLL_DIV			190
> +#define CLKID_VID_PLL_SEL			191
> +#define CLKID_VID_PLL				192
> +#define CLKID_VCLK_SEL				193
> +#define CLKID_VCLK2_SEL				194
> +#define CLKID_VCLK_INPUT			195
> +#define CLKID_VCLK2_INPUT			196
> +#define CLKID_VCLK_DIV				197
> +#define CLKID_VCLK2_DIV				198
> +#define CLKID_VCLK				199
> +#define CLKID_VCLK2				200
> +#define CLKID_VCLK_DIV1				201
> +#define CLKID_VCLK_DIV2_EN			202
> +#define CLKID_VCLK_DIV4_EN			203
> +#define CLKID_VCLK_DIV6_EN			204
> +#define CLKID_VCLK_DIV12_EN			205
> +#define CLKID_VCLK2_DIV1			206
> +#define CLKID_VCLK2_DIV2_EN			207
> +#define CLKID_VCLK2_DIV4_EN			208
> +#define CLKID_VCLK2_DIV6_EN			209
> +#define CLKID_VCLK2_DIV12_EN			210
> +#define CLKID_VCLK_DIV2				211
> +#define CLKID_VCLK_DIV4				212
> +#define CLKID_VCLK_DIV6				213
> +#define CLKID_VCLK_DIV12			214
> +#define CLKID_VCLK2_DIV2			215
> +#define CLKID_VCLK2_DIV4			216
> +#define CLKID_VCLK2_DIV6			217
> +#define CLKID_VCLK2_DIV12			218
> +#define CLKID_ENCI_SEL				219
> +#define CLKID_ENCP_SEL				220
> +#define CLKID_ENCL_SEL				221
> +#define CLKID_VDAC_SEL				222
> +#define CLKID_VDAC_PRE_SEL			223
> +#define CLKID_HDMITX_PIXEL_SEL			224
> +#define CLKID_HDMITX_FE_SEL			225
> +#define CLKID_ENCI				226
> +#define CLKID_ENCP				227
> +#define CLKID_ENCL				228
> +#define CLKID_VDAC				229
> +#define CLKID_HDMITX_PIXEL			230
> +#define CLKID_HDMITX_FE				231
> +#define CLKID_VID_LOCK_SEL			232
> +#define CLKID_VID_LOCK_DIV			233
> +#define CLKID_VID_LOCK				234
> +
> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_S7_PERIPHERALS_CLKC_H */
> 
> -- 
> 2.56.0
> 

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 167 bytes --]

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 4/7] dt-bindings: clock: Add Amlogic S7 PLL clock controller
  2026-11-06  8:30 ` [PATCH 4/7] dt-bindings: clock: Add Amlogic S7 PLL clock controller Carlo Caione
@ 2026-11-06 17:35   ` Conor Dooley
  0 siblings, 0 replies; 15+ messages in thread
From: Conor Dooley @ 2026-11-06 17:35 UTC (permalink / raw)
  To: Carlo Caione
  Cc: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Jian Hu, Chuan Liu,
	linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 4811 bytes --]

On Fri, Nov 06, 2026 at 09:30:27AM +0100, Carlo Caione wrote:
> The S7 PLL controller supplies clock sources for the peripheral clock
> tree and receives its reference clocks through firmware-controlled
> oscillator gates.
> 
> Add the binding and clock identifiers needed to describe this
> controller and its connections.
> 
> Signed-off-by: Carlo Caione <ccaione@baylibre.com>

This looks okay, but I don't want to sign off on it before seeing an
answer the my quesiton on the other binding.

Thanks,
Conor.

> ---
>  .../bindings/clock/amlogic,s7-pll-clkc.yaml        | 73 ++++++++++++++++++++++
>  include/dt-bindings/clock/amlogic,s7-pll-clkc.h    | 42 +++++++++++++
>  2 files changed, 115 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,s7-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,s7-pll-clkc.yaml
> new file mode 100644
> index 000000000000..e2b5ba5524a7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,s7-pll-clkc.yaml
> @@ -0,0 +1,73 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (c) 2026 BayLibre, SAS.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/amlogic,s7-pll-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic S7 Series PLL Clock Controller
> +
> +maintainers:
> +  - Neil Armstrong <neil.armstrong@linaro.org>
> +  - Jerome Brunet <jbrunet@baylibre.com>
> +  - Carlo Caione <ccaione@baylibre.com>
> +
> +properties:
> +  compatible:
> +    const: amlogic,s7-pll-clkc
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#clock-cells':
> +    const: 1
> +
> +  clocks:
> +    items:
> +      - description: input fixed pll
> +      - description: input gp0 pll
> +      - description: input hifi pll
> +      - description: input hifi1 pll
> +      - description: input hdmi pll
> +
> +  clock-names:
> +    items:
> +      - const: fix
> +      - const: gp0
> +      - const: hifi
> +      - const: hifi1
> +      - const: hdmi
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#clock-cells'
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        clock-controller@8000 {
> +            compatible = "amlogic,s7-pll-clkc";
> +            reg = <0x0 0x8000 0x0 0x1e8>;
> +            #clock-cells = <1>;
> +            clocks = <&scmi_clk CLKID_TOP_PLL_OSC>,
> +                     <&scmi_clk CLKID_TOP_PLL_OSC>,
> +                     <&scmi_clk CLKID_TOP_PLL_OSC>,
> +                     <&scmi_clk CLKID_TOP_PLL_OSC>,
> +                     <&scmi_clk CLKID_HDMI_PLL_OSC>;
> +            clock-names = "fix",
> +                          "gp0",
> +                          "hifi",
> +                          "hifi1",
> +                          "hdmi";
> +        };
> +    };
> diff --git a/include/dt-bindings/clock/amlogic,s7-pll-clkc.h b/include/dt-bindings/clock/amlogic,s7-pll-clkc.h
> new file mode 100644
> index 000000000000..4014314a3eb0
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,s7-pll-clkc.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2026 BayLibre, SAS.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_S7_PLL_CLKC_H
> +#define _DT_BINDINGS_CLOCK_AMLOGIC_S7_PLL_CLKC_H
> +
> +#define CLKID_FIXED_PLL_VCO			0
> +#define CLKID_FIXED_PLL				1
> +#define CLKID_FCLK_DIV2_DIV			2
> +#define CLKID_FCLK_DIV2				3
> +#define CLKID_FCLK_DIV3_DIV			4
> +#define CLKID_FCLK_DIV3				5
> +#define CLKID_FCLK_DIV4_DIV			6
> +#define CLKID_FCLK_DIV4				7
> +#define CLKID_FCLK_DIV5_DIV			8
> +#define CLKID_FCLK_DIV5				9
> +#define CLKID_FCLK_DIV7_DIV			10
> +#define CLKID_FCLK_DIV7				11
> +#define CLKID_FCLK_DIV2P5_DIV			12
> +#define CLKID_FCLK_DIV2P5			13
> +#define CLKID_GP0_PLL_DIV0P5			14
> +#define CLKID_GP0_PLL_VCO			15
> +#define CLKID_GP0_PLL				16
> +#define CLKID_HIFI_PLL_DIV0P5			17
> +#define CLKID_HIFI_PLL_VCO			18
> +#define CLKID_HIFI_PLL				19
> +#define CLKID_HIFI1_PLL_DIV0P5			20
> +#define CLKID_HIFI1_PLL_VCO			21
> +#define CLKID_HIFI1_PLL				22
> +#define CLKID_HDMI_PLL_DIV0P5			23
> +#define CLKID_HDMI_PLL_VCO			24
> +#define CLKID_HDMI_PLL_OD0			25
> +#define CLKID_HDMI_PLL_OD1			26
> +#define CLKID_HDMI_PLL				27
> +#define CLKID_HDMI_PLL_PIX_DIV5			28
> +#define CLKID_HDMI_PLL_PIX_DIV6P25		29
> +#define CLKID_HDMI_PLL_PIX_DIV7P5		30
> +#define CLKID_HDMI_PLL_PIX			31
> +
> +#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S7_PLL_CLKC_H */
> 
> -- 
> 2.56.0
> 

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 167 bytes --]

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller
  2026-11-06 17:34   ` Conor Dooley
@ 2026-11-06 19:34     ` Carlo Caione
  2026-11-06 20:48       ` Conor Dooley
  0 siblings, 1 reply; 15+ messages in thread
From: Carlo Caione @ 2026-11-06 19:34 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Jian Hu, Chuan Liu,
	linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

On Fri, Nov 06, 2026 at 17:34:14 +0100, Conor Dooley wrote:

> > +    #include <dt-bindings/clock/amlogic,s7-pll-clkc.h>
> > +    #include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
> > +
> > +    soc {
> > +        #address-cells = <2>;
> > +        #size-cells = <2>;
> > +
> > +        clock-controller@0 {
> > +            compatible = "amlogic,s7-peripherals-clkc";
> > +            reg = <0x0 0x0 0x0 0x49c>;
> 
> What's with the weird numbers in this example?
> 
> Examples don't have to be real, but when it looks like this the
> immediate thought is that the modelling of the device might be
> incorrec.t

The numbers are actually real, but the example simply lost their context
because I copied the node from the S7 dtsi (not yet submitted), where
the controller sits under the APB bus node (bus@fe000000) and the bus
ranges make the addresses relative to it.

		apb: bus@fe000000 {
			compatible = "simple-bus";
			reg = <0x0 0xfe000000 0x0 0x480000>;
			#address-cells = <2>;
			#size-cells = <2>;
			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;

			clkc_periphs: clock-controller@0 {
				compatible = "amlogic,s7-peripherals-clkc";
				reg = <0x0 0x0 0x0 0x49c>;
				#clock-cells = <1>;
				...

In V2 I'll use an absolute address for the sake of clarity (PLL has the
same issue).

Thanks,

--
Carlo Caione

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller
  2026-11-06 19:34     ` Carlo Caione
@ 2026-11-06 20:48       ` Conor Dooley
  2026-11-06 22:27         ` Carlo Caione
  0 siblings, 1 reply; 15+ messages in thread
From: Conor Dooley @ 2026-11-06 20:48 UTC (permalink / raw)
  To: Carlo Caione
  Cc: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Jian Hu, Chuan Liu,
	linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1603 bytes --]

On Fri, Nov 06, 2026 at 08:34:37PM +0100, Carlo Caione wrote:
> On Fri, Nov 06, 2026 at 17:34:14 +0100, Conor Dooley wrote:
> 
> > > +    #include <dt-bindings/clock/amlogic,s7-pll-clkc.h>
> > > +    #include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
> > > +
> > > +    soc {
> > > +        #address-cells = <2>;
> > > +        #size-cells = <2>;
> > > +
> > > +        clock-controller@0 {
> > > +            compatible = "amlogic,s7-peripherals-clkc";
> > > +            reg = <0x0 0x0 0x0 0x49c>;
> > 
> > What's with the weird numbers in this example?
> > 
> > Examples don't have to be real, but when it looks like this the
> > immediate thought is that the modelling of the device might be
> > incorrec.t
> 
> The numbers are actually real, but the example simply lost their context
> because I copied the node from the S7 dtsi (not yet submitted), where
> the controller sits under the APB bus node (bus@fe000000) and the bus
> ranges make the addresses relative to it.
> 
> 		apb: bus@fe000000 {
> 			compatible = "simple-bus";
> 			reg = <0x0 0xfe000000 0x0 0x480000>;
> 			#address-cells = <2>;
> 			#size-cells = <2>;
> 			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
> 
> 			clkc_periphs: clock-controller@0 {
> 				compatible = "amlogic,s7-peripherals-clkc";
> 				reg = <0x0 0x0 0x0 0x49c>;
> 				#clock-cells = <1>;
> 				...
> 
> In V2 I'll use an absolute address for the sake of clarity (PLL has the
> same issue).

Before you do that, can you please share with me the s7 dtsi? Cos surely
you've got it in some git repo online somewhere.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 167 bytes --]

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller
  2026-11-06 20:48       ` Conor Dooley
@ 2026-11-06 22:27         ` Carlo Caione
  0 siblings, 0 replies; 15+ messages in thread
From: Carlo Caione @ 2026-11-06 22:27 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Kevin Hilman, Martin Blumenstingl, Jian Hu, Chuan Liu,
	linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

On Fri, Nov 06, 2026 at 20:48:01 +0100, Conor Dooley wrote:
> On Fri, Nov 06, 2026 at 08:34:37PM +0100, Carlo Caione wrote:
> > On Fri, Nov 06, 2026 at 17:34:14 +0100, Conor Dooley wrote:
> > 
> > > > +    #include <dt-bindings/clock/amlogic,s7-pll-clkc.h>
> > > > +    #include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
> > > > +
> > > > +    soc {
> > > > +        #address-cells = <2>;
> > > > +        #size-cells = <2>;
> > > > +
> > > > +        clock-controller@0 {
> > > > +            compatible = "amlogic,s7-peripherals-clkc";
> > > > +            reg = <0x0 0x0 0x0 0x49c>;
> > > 
> > > What's with the weird numbers in this example?
> > > 
> > > Examples don't have to be real, but when it looks like this the
> > > immediate thought is that the modelling of the device might be
> > > incorrec.t
> > 
> > The numbers are actually real, but the example simply lost their context
> > because I copied the node from the S7 dtsi (not yet submitted), where
> > the controller sits under the APB bus node (bus@fe000000) and the bus
> > ranges make the addresses relative to it.
> > 
> > 		apb: bus@fe000000 {
> > 			compatible = "simple-bus";
> > 			reg = <0x0 0xfe000000 0x0 0x480000>;
> > 			#address-cells = <2>;
> > 			#size-cells = <2>;
> > 			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
> > 
> > 			clkc_periphs: clock-controller@0 {
> > 				compatible = "amlogic,s7-peripherals-clkc";
> > 				reg = <0x0 0x0 0x0 0x49c>;
> > 				#clock-cells = <1>;
> > 				...
> > 
> > In V2 I'll use an absolute address for the sake of clarity (PLL has the
> > same issue).
> 
> Before you do that, can you please share with me the s7 dtsi? Cos surely
> you've got it in some git repo online somewhere.

The S7 dtsi is already upstream at [0], the peripheral clock controller
and PLL will be enabled in that DTSI with a following series after the
bindings and the drivers in this set are acked, following the diffs that
will be submitted:

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi
index 2c204dcebbba..5f2a61f42cbd 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi
@@ -7,6 +7,8 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/amlogic,pinctrl.h>
+#include <dt-bindings/clock/amlogic,s7-pll-clkc.h>
+#include <dt-bindings/clock/amlogic,s7-scmi-clkc.h>
 #include <dt-bindings/power/amlogic,s7-pwrc.h>

 / {
@@ -160,6 +162,22 @@ apb: bus@fe000000 {
                        #size-cells = <2>;
                        ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;

+                       clkc_pll: clock-controller@8000 {
+                               compatible = "amlogic,s7-pll-clkc";
+                               reg = <0x0 0x8000 0x0 0x1e8>;
+                               #clock-cells = <1>;
+                               clocks = <&scmi_clk CLKID_TOP_PLL_OSC>,
+                                        <&scmi_clk CLKID_TOP_PLL_OSC>,
+                                        <&scmi_clk CLKID_TOP_PLL_OSC>,
+                                        <&scmi_clk CLKID_TOP_PLL_OSC>,
+                                        <&scmi_clk CLKID_HDMI_PLL_OSC>;
+                               clock-names = "fix",
+                                             "gp0",
+                                             "hifi",
+                                             "hifi1",
+                                             "hdmi";
+                       };
+
                        uart_b: serial@7a000 {
                                compatible = "amlogic,s7-uart",
                                             "amlogic,meson-s4-uart";

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi
index 5f2a61f42cbd..afc88abea301 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi
@@ -162,6 +162,40 @@ apb: bus@fe000000 {
                        #size-cells = <2>;
                        ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;

+                       clkc_periphs: clock-controller@0 {
+                               compatible = "amlogic,s7-peripherals-clkc";
+                               reg = <0x0 0x0 0x0 0x49c>;
+                               #clock-cells = <1>;
+                               clocks = <&clkc_pll CLKID_FCLK_DIV2>,
+                                        <&clkc_pll CLKID_FCLK_DIV2P5>,
+                                        <&clkc_pll CLKID_FCLK_DIV3>,
+                                        <&clkc_pll CLKID_FCLK_DIV4>,
+                                        <&clkc_pll CLKID_FCLK_DIV5>,
+                                        <&clkc_pll CLKID_FCLK_DIV7>,
+                                        <&clkc_pll CLKID_HIFI_PLL>,
+                                        <&clkc_pll CLKID_GP0_PLL>,
+                                        <&clkc_pll CLKID_HIFI1_PLL>,
+                                        <&scmi_clk CLKID_GP1_PLL>,
+                                        <&clkc_pll CLKID_HDMI_PLL>,
+                                        <&clkc_pll CLKID_HDMI_PLL_PIX>,
+                                        <&xtal>,
+                                        <&scmi_clk CLKID_ACLKM>;
+                               clock-names = "fclk_div2",
+                                             "fclk_div2p5",
+                                             "fclk_div3",
+                                             "fclk_div4",
+                                             "fclk_div5",
+                                             "fclk_div7",
+                                             "hifi_pll",
+                                             "gp0_pll",
+                                             "hifi1_pll",
+                                             "gp1_pll",
+                                             "hdmi_pll",
+                                             "vid_pix",
+                                             "xtal",
+                                             "axi_frcpu";
+                       };
+
                        clkc_pll: clock-controller@8000 {
                                compatible = "amlogic,s7-pll-clkc";
                                reg = <0x0 0x8000 0x0 0x1e8>;

[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi

--
Carlo Caione

_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-11-06 22:27 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-06  8:30 [PATCH 0/7] Add Amlogic S7 clock controllers Carlo Caione
2026-11-06  8:30 ` [PATCH 1/7] dt-bindings: clock: Add Amlogic S7 SCMI clock IDs Carlo Caione
2026-11-06  8:30 ` [PATCH 2/7] clk: meson: pll: Support PLLs without a pre-divider Carlo Caione
2026-11-06  8:35   ` sashiko-bot
2026-11-06  8:30 ` [PATCH 3/7] clk: meson: pll: Support active-low resets Carlo Caione
2026-11-06  8:30 ` [PATCH 4/7] dt-bindings: clock: Add Amlogic S7 PLL clock controller Carlo Caione
2026-11-06 17:35   ` Conor Dooley
2026-11-06  8:30 ` [PATCH 5/7] clk: amlogic: Add S7 PLL clock controller driver Carlo Caione
2026-11-06  8:51   ` sashiko-bot
2026-11-06  8:30 ` [PATCH 6/7] dt-bindings: clock: Add Amlogic S7 peripherals clock controller Carlo Caione
2026-11-06 17:34   ` Conor Dooley
2026-11-06 19:34     ` Carlo Caione
2026-11-06 20:48       ` Conor Dooley
2026-11-06 22:27         ` Carlo Caione
2026-11-06  8:30 ` [PATCH 7/7] clk: amlogic: Add S7 peripherals clock controller driver Carlo Caione

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®