linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock
@ 2025-10-28  9:52 Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support Chuan Liu via B4 Relay
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

The patchset adds support for the peripheral and PLL clock controller
on the Amlogic A5 SoC family, such as A113X2.

Due to work arrangements, I will take over this patchset and be
responsible for submitting and maintaining its subsequent revisions.

I previously resubmitted these patches in another patchset [1],
Jerome pointed out that it made tracking more difficult. Therefore,
I’m continuing the submission here based on Xianwei’s v3 version.
Sorry for this causes any inconvenience to anyone.

[1] https://lore.kernel.org/all/20250930-a4_a5_add_clock_driver-v1-0-a9acf7951589@amlogic.com/

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>

---
Changes in v4:
- dt-binding for peripheral clocks (kept Rob’s 'Reviewed-by' here):
  - Added optional clock source rtc pll.
  - Renamed rtc_clk’s clkid to better reflect its function.
- PLL/Clock driver:
  - Adapted to Jerome’s refactored driver interface, naming
conventions, and macros.
  - Updated related CONFIG entries in Kconfig.
- Added dts patch of PLL/Clock.
- Link to v3: https://lore.kernel.org/r/20250103-a5-clk-v3-0-a207ce83b9e9@amlogic.com

Changes in v3:
- Rename xtal_24m to xtal, and modify some description of Kconfig.
- Drop some comment of PLL source code.
- Move definition of A5_CLK_GATE_FW frome common code into A5 peripheral source code.
- Use hw instead of name to describe parent_data.
- Making SCMI binding the first to submit.
- Link to v2: https://lore.kernel.org/r/20241120-a5-clk-v2-0-1208621e961d@amlogic.com

Changes in v2:
- Move some sys clock and axi clock from peripheral to scmi impletement.
- Remove  ARM_SCMI_PROTOCOL in Kconfig and correct name A5 but not A4.
- Add two optional clock inputs for the peripheral(ddr pll and clk-measure)
- Make some changes and adjustments according to suggestions.
- Link to v1: https://lore.kernel.org/r/20240914-a5-clk-v1-0-5ee2c4f1b08c@amlogic.com

---
Chuan Liu (8):
      dt-bindings: clock: Add Amlogic A5 SCMI clock controller support
      dt-bindings: clock: Add Amlogic A5 PLL clock controller
      dt-bindings: clock: Add Amlogic A5 peripherals clock controller
      clk: amlogic: Add A5 PLL clock controller driver
      clk: amlogic: Add A5 clock peripherals controller driver
      arm64: dts: amlogic: A5: Add scmi-clk node
      arm64: dts: amlogic: A5: Add PLL controller node
      arm64: dts: amlogic: A5: Add peripheral clock controller node

 .../clock/amlogic,a5-peripherals-clkc.yaml         | 134 ++++
 .../bindings/clock/amlogic,a5-pll-clkc.yaml        |  63 ++
 arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi        |  86 ++
 drivers/clk/meson/Kconfig                          |  27 +
 drivers/clk/meson/Makefile                         |   2 +
 drivers/clk/meson/a5-peripherals.c                 | 883 +++++++++++++++++++++
 drivers/clk/meson/a5-pll.c                         | 476 +++++++++++
 .../clock/amlogic,a5-peripherals-clkc.h            | 132 +++
 include/dt-bindings/clock/amlogic,a5-pll-clkc.h    |  24 +
 include/dt-bindings/clock/amlogic,a5-scmi-clkc.h   |  44 +
 10 files changed, 1871 insertions(+)
---
base-commit: f7d2388eeec24966fc4d5cf32d706f0514f29ac5
change-id: 20240911-a5-clk-35c49acb34e1

Best regards,
-- 
Chuan Liu <chuan.liu@amlogic.com>




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

* [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  2025-12-23  8:59   ` Jerome Brunet
  2025-10-28  9:52 ` [PATCH v4 2/8] dt-bindings: clock: Add Amlogic A5 PLL clock controller Chuan Liu via B4 Relay
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add the SCMI clock controller dt-bindings for the Amlogic A5 SoC
family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 include/dt-bindings/clock/amlogic,a5-scmi-clkc.h | 44 ++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h
new file mode 100644
index 000000000000..1bf027d0110a
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#ifndef __AMLOGIC_A5_SCMI_CLKC_H
+#define __AMLOGIC_A5_SCMI_CLKC_H
+
+#define CLKID_OSC				0
+#define CLKID_SYS_CLK				1
+#define CLKID_AXI_CLK				2
+#define CLKID_CPU_CLK				3
+#define CLKID_DSU_CLK				4
+#define CLKID_GP1_PLL				5
+#define CLKID_FIXED_PLL_DCO			6
+#define CLKID_FIXED_PLL				7
+#define CLKID_ACLKM				8
+#define CLKID_SYS_PLL_DIV16			9
+#define CLKID_CPU_CLK_DIV16			10
+#define CLKID_FCLK_50M_PREDIV			11
+#define CLKID_FCLK_50M_DIV			12
+#define CLKID_FCLK_50M				13
+#define CLKID_FCLK_DIV2_DIV			14
+#define CLKID_FCLK_DIV2				15
+#define CLKID_FCLK_DIV2P5_DIV			16
+#define CLKID_FCLK_DIV2P5			17
+#define CLKID_FCLK_DIV3_DIV			18
+#define CLKID_FCLK_DIV3				19
+#define CLKID_FCLK_DIV4_DIV			20
+#define CLKID_FCLK_DIV4				21
+#define CLKID_FCLK_DIV5_DIV			22
+#define CLKID_FCLK_DIV5				23
+#define CLKID_FCLK_DIV7_DIV			24
+#define CLKID_FCLK_DIV7				25
+#define CLKID_SYS_MMC_PCLK			26
+#define CLKID_SYS_CPU_CTRL			27
+#define CLKID_SYS_IRQ_CTRL			28
+#define CLKID_SYS_GIC				29
+#define CLKID_SYS_BIG_NIC			30
+#define CLKID_AXI_SYS_NIC			31
+#define CLKID_AXI_CPU_DMC			32
+
+#endif /* __AMLOGIC_A5_SCMI_CLKC_H */

-- 
2.42.0




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

* [PATCH v4 2/8] dt-bindings: clock: Add Amlogic A5 PLL clock controller
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 3/8] dt-bindings: clock: Add Amlogic A5 peripherals " Chuan Liu via B4 Relay
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add the PLL clock controller dt-bindings for the Amlogic A5 SoC
family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 .../bindings/clock/amlogic,a5-pll-clkc.yaml        | 63 ++++++++++++++++++++++
 include/dt-bindings/clock/amlogic,a5-pll-clkc.h    | 24 +++++++++
 2 files changed, 87 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a5-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a5-pll-clkc.yaml
new file mode 100644
index 000000000000..d74570a90926
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a5-pll-clkc.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a5-pll-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A5 series PLL Clock Controller
+
+maintainers:
+  - Chuan Liu <chuan.liu@amlogic.com>
+  - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+  compatible:
+    const: amlogic,a5-pll-clkc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: input oscillator
+      - description: input fix pll dco
+      - description: input fix pll
+
+  clock-names:
+    items:
+      - const: xtal
+      - const: fix_dco
+      - const: fix
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,a5-scmi-clkc.h>
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@8000 {
+            compatible = "amlogic,a5-pll-clkc";
+            reg = <0x0 0x8000 0x0 0x1a4>;
+            clocks = <&xtal>,
+                     <&scmi_clk CLKID_FIXED_PLL_DCO>,
+                     <&scmi_clk CLKID_FIXED_PLL>;
+            clock-names = "xtal",
+                          "fix_dco",
+                          "fix";
+            #clock-cells = <1>;
+        };
+    };
diff --git a/include/dt-bindings/clock/amlogic,a5-pll-clkc.h b/include/dt-bindings/clock/amlogic,a5-pll-clkc.h
new file mode 100644
index 000000000000..a74c448a8d8a
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a5-pll-clkc.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_A5_PLL_CLKC_H
+#define _DT_BINDINGS_CLOCK_AMLOGIC_A5_PLL_CLKC_H
+
+#define CLKID_MPLL_PREDIV			0
+#define CLKID_MPLL0_DIV				1
+#define CLKID_MPLL0				2
+#define CLKID_MPLL1_DIV				3
+#define CLKID_MPLL1				4
+#define CLKID_MPLL2_DIV				5
+#define CLKID_MPLL2				6
+#define CLKID_MPLL3_DIV				7
+#define CLKID_MPLL3				8
+#define CLKID_GP0_PLL_DCO			9
+#define CLKID_GP0_PLL				10
+#define CLKID_HIFI_PLL_DCO			11
+#define CLKID_HIFI_PLL				12
+
+#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_A5_PLL_CLKC_H */

-- 
2.42.0




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

* [PATCH v4 3/8] dt-bindings: clock: Add Amlogic A5 peripherals clock controller
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 2/8] dt-bindings: clock: Add Amlogic A5 PLL clock controller Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 4/8] clk: amlogic: Add A5 PLL clock controller driver Chuan Liu via B4 Relay
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add the peripherals clock controller dt-bindings for the Amlogic A5
SoC family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 .../clock/amlogic,a5-peripherals-clkc.yaml         | 134 +++++++++++++++++++++
 .../clock/amlogic,a5-peripherals-clkc.h            | 132 ++++++++++++++++++++
 2 files changed, 266 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml
new file mode 100644
index 000000000000..88d71d9a72ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a5-peripherals-clkc.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a5-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A5 series Peripheral Clock Controller
+
+maintainers:
+  - Xianwei Zhao <xianwei.zhao@amlogic.com>
+  - Chuan Liu <chuan.liu@amlogic.com>
+
+properties:
+  compatible:
+    const: amlogic,a5-peripherals-clkc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 18
+    items:
+      - description: input oscillator
+      - description: input oscillators multiplexer
+      - description: input fix pll
+      - description: input fclk div 2
+      - description: input fclk div 2p5
+      - description: input fclk div 3
+      - description: input fclk div 4
+      - description: input fclk div 5
+      - description: input fclk div 7
+      - description: input mpll2
+      - description: input mpll3
+      - description: input gp0 pll
+      - description: input gp1 pll
+      - description: input hifi pll
+      - description: input sys clk
+      - description: input axi clk
+      - description: input sys pll div 16
+      - description: input cpu clk div 16
+      - description: input pad clock for rtc clk (optional)
+      - description: input ddr pll (optional)
+      - description: input source from clk-measure (optional)
+      - description: input rtc pll (optional)
+
+  clock-names:
+    minItems: 18
+    items:
+      - const: xtal
+      - const: oscin
+      - const: fix
+      - const: fdiv2
+      - const: fdiv2p5
+      - const: fdiv3
+      - const: fdiv4
+      - const: fdiv5
+      - const: fdiv7
+      - const: mpll2
+      - const: mpll3
+      - const: gp0
+      - const: gp1
+      - const: hifi
+      - const: sysclk
+      - const: axiclk
+      - const: sysplldiv16
+      - const: cpudiv16
+      - const: pad_osc
+      - const: ddr
+      - const: clkmsr
+      - const: rtc
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,a5-scmi-clkc.h>
+    #include <dt-bindings/clock/amlogic,a5-pll-clkc.h>
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clock-controller@0 {
+            compatible = "amlogic,a5-peripherals-clkc";
+            reg = <0x0 0x0 0x0 0x224>;
+            #clock-cells = <1>;
+            clocks = <&xtal>,
+                     <&scmi_clk CLKID_OSC>,
+                     <&scmi_clk CLKID_FIXED_PLL>,
+                     <&scmi_clk CLKID_FCLK_DIV2>,
+                     <&scmi_clk CLKID_FCLK_DIV2P5>,
+                     <&scmi_clk CLKID_FCLK_DIV3>,
+                     <&scmi_clk CLKID_FCLK_DIV4>,
+                     <&scmi_clk CLKID_FCLK_DIV5>,
+                     <&scmi_clk CLKID_FCLK_DIV7>,
+                     <&clkc_pll CLKID_MPLL2>,
+                     <&clkc_pll CLKID_MPLL3>,
+                     <&clkc_pll CLKID_GP0_PLL>,
+                     <&scmi_clk CLKID_GP1_PLL>,
+                     <&clkc_pll CLKID_HIFI_PLL>,
+                     <&scmi_clk CLKID_SYS_CLK>,
+                     <&scmi_clk CLKID_AXI_CLK>,
+                     <&scmi_clk CLKID_SYS_PLL_DIV16>,
+                     <&scmi_clk CLKID_CPU_CLK_DIV16>;
+            clock-names = "xtal",
+                          "oscin",
+                          "fix",
+                          "fdiv2",
+                          "fdiv2p5",
+                          "fdiv3",
+                          "fdiv4",
+                          "fdiv5",
+                          "fdiv7",
+                          "mpll2",
+                          "mpll3",
+                          "gp0",
+                          "gp1",
+                          "hifi",
+                          "sysclk",
+                          "axiclk",
+                          "sysplldiv16",
+                          "cpudiv16";
+        };
+    };
diff --git a/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h
new file mode 100644
index 000000000000..b8a68b7f29dc
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a5-peripherals-clkc.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H
+#define _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H
+
+#define CLKID_RTC_DUALDIV_CLKIN			0
+#define CLKID_RTC_DUALDIV			1
+#define CLKID_RTC_DUALDIV_SEL			2
+#define CLKID_RTC_DUALDIV_CLKOUT		3
+#define CLKID_RTC_CLK				4
+#define CLKID_SYS_RESET_CTRL			5
+#define CLKID_SYS_PWR_CTRL			6
+#define CLKID_SYS_PAD_CTRL			7
+#define CLKID_SYS_CTRL				8
+#define CLKID_SYS_TS_PLL			9
+#define CLKID_SYS_DEV_ARB			10
+#define CLKID_SYS_MAILBOX			11
+#define CLKID_SYS_JTAG_CTRL			12
+#define CLKID_SYS_IR_CTRL			13
+#define CLKID_SYS_MSR_CLK			14
+#define CLKID_SYS_ROM				15
+#define CLKID_SYS_CPU_ARB			16
+#define CLKID_SYS_RSA				17
+#define CLKID_SYS_SARADC			18
+#define CLKID_SYS_STARTUP			19
+#define CLKID_SYS_SECURE			20
+#define CLKID_SYS_SPIFC				21
+#define CLKID_SYS_DSPA				22
+#define CLKID_SYS_NNA				23
+#define CLKID_SYS_ETH_MAC			24
+#define CLKID_SYS_RAMA				25
+#define CLKID_SYS_RAMB				26
+#define CLKID_SYS_AUDIO_TOP			27
+#define CLKID_SYS_AUDIO_VAD			28
+#define CLKID_SYS_USB				29
+#define CLKID_SYS_SD_EMMC_A			30
+#define CLKID_SYS_SD_EMMC_C			31
+#define CLKID_SYS_PWM_AB			32
+#define CLKID_SYS_PWM_CD			33
+#define CLKID_SYS_PWM_EF			34
+#define CLKID_SYS_PWM_GH			35
+#define CLKID_SYS_SPICC_1			36
+#define CLKID_SYS_SPICC_0			37
+#define CLKID_SYS_UART_A			38
+#define CLKID_SYS_UART_B			39
+#define CLKID_SYS_UART_C			40
+#define CLKID_SYS_UART_D			41
+#define CLKID_SYS_UART_E			42
+#define CLKID_SYS_I2C_M_A			43
+#define CLKID_SYS_I2C_M_B			44
+#define CLKID_SYS_I2C_M_C			45
+#define CLKID_SYS_I2C_M_D			46
+#define CLKID_SYS_RTC				47
+#define CLKID_AXI_AUDIO_VAD			48
+#define CLKID_AXI_AUDIO_TOP			49
+#define CLKID_AXI_RAMB				50
+#define CLKID_AXI_RAMA				51
+#define CLKID_AXI_NNA				52
+#define CLKID_AXI_DEV1_DMC			53
+#define CLKID_AXI_DEV0_DMC			54
+#define CLKID_AXI_DSP_DMC			55
+#define CLKID_12_24M_IN				56
+#define CLKID_12M_24M				57
+#define CLKID_FCLK_25M_DIV			58
+#define CLKID_FCLK_25M				59
+#define CLKID_GEN_SEL				60
+#define CLKID_GEN_DIV				61
+#define CLKID_GEN				62
+#define CLKID_SARADC_SEL			63
+#define CLKID_SARADC_DIV			64
+#define CLKID_SARADC				65
+#define CLKID_PWM_A_SEL				66
+#define CLKID_PWM_A_DIV				67
+#define CLKID_PWM_A				68
+#define CLKID_PWM_B_SEL				69
+#define CLKID_PWM_B_DIV				70
+#define CLKID_PWM_B				71
+#define CLKID_PWM_C_SEL				72
+#define CLKID_PWM_C_DIV				73
+#define CLKID_PWM_C				74
+#define CLKID_PWM_D_SEL				75
+#define CLKID_PWM_D_DIV				76
+#define CLKID_PWM_D				77
+#define CLKID_PWM_E_SEL				78
+#define CLKID_PWM_E_DIV				79
+#define CLKID_PWM_E				80
+#define CLKID_PWM_F_SEL				81
+#define CLKID_PWM_F_DIV				82
+#define CLKID_PWM_F				83
+#define CLKID_PWM_G_SEL				84
+#define CLKID_PWM_G_DIV				85
+#define CLKID_PWM_G				86
+#define CLKID_PWM_H_SEL				87
+#define CLKID_PWM_H_DIV				88
+#define CLKID_PWM_H				89
+#define CLKID_SPICC_0_SEL			90
+#define CLKID_SPICC_0_DIV			91
+#define CLKID_SPICC_0				92
+#define CLKID_SPICC_1_SEL			93
+#define CLKID_SPICC_1_DIV			94
+#define CLKID_SPICC_1				95
+#define CLKID_SD_EMMC_A_SEL			96
+#define CLKID_SD_EMMC_A_DIV			97
+#define CLKID_SD_EMMC_A				98
+#define CLKID_SD_EMMC_C_SEL			99
+#define CLKID_SD_EMMC_C_DIV			100
+#define CLKID_SD_EMMC_C				101
+#define CLKID_TS_DIV				102
+#define CLKID_TS				103
+#define CLKID_ETH_125M_DIV			104
+#define CLKID_ETH_125M				105
+#define CLKID_ETH_RMII_DIV			106
+#define CLKID_ETH_RMII				107
+#define CLKID_DSPA_0_SEL			108
+#define CLKID_DSPA_0_DIV			109
+#define CLKID_DSPA_0				110
+#define CLKID_DSPA_1_SEL			111
+#define CLKID_DSPA_1_DIV			112
+#define CLKID_DSPA_1				113
+#define CLKID_DSPA				114
+#define CLKID_NNA_CORE_SEL			115
+#define CLKID_NNA_CORE_DIV			116
+#define CLKID_NNA_CORE				117
+#define CLKID_NNA_AXI_SEL			118
+#define CLKID_NNA_AXI_DIV			119
+#define CLKID_NNA_AXI				120
+
+#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_A5_PERIPHERALS_CLKC_H */

-- 
2.42.0




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

* [PATCH v4 4/8] clk: amlogic: Add A5 PLL clock controller driver
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
                   ` (2 preceding siblings ...)
  2025-10-28  9:52 ` [PATCH v4 3/8] dt-bindings: clock: Add Amlogic A5 peripherals " Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 5/8] clk: amlogic: Add A5 clock peripherals " Chuan Liu via B4 Relay
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add the PLL clock controller driver for the Amlogic A5 SoC family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 drivers/clk/meson/Kconfig  |  14 ++
 drivers/clk/meson/Makefile |   1 +
 drivers/clk/meson/a5-pll.c | 476 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 491 insertions(+)

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 71481607a6d5..b627821da081 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -132,6 +132,20 @@ config COMMON_CLK_A1_PERIPHERALS
 	  device, A1 SoC Family. Say Y if you want A1 Peripherals clock
 	  controller to work.
 
+config COMMON_CLK_A5_PLL
+	tristate "Amlogic A5 PLL clock controller"
+	depends on ARM64
+	default ARCH_MESON
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_PLL
+	select COMMON_CLK_MESON_MPLL
+	select COMMON_CLK_MESON_CLKC_UTILS
+	imply COMMON_CLK_SCMI
+	help
+	  Support for the PLL clock controller on Amlogic  A113X2 device, AKA A5.
+	  Say Y if you want the board to work, because PLLs are the parent
+	  of most peripherals.
+
 config COMMON_CLK_C3_PLL
 	tristate "Amlogic C3 PLL clock controller"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c6998e752c68..a074aa7e187f 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
 obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
 obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
+obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o
 obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
 obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a5-pll.c b/drivers/clk/meson/a5-pll.c
new file mode 100644
index 000000000000..1789a7e6470d
--- /dev/null
+++ b/drivers/clk/meson/a5-pll.c
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Amlogic A5 PLL Controller Driver
+ *
+ * Copyright (c) 2024-2025 Amlogic, inc.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-mpll.h"
+#include "meson-clkc-utils.h"
+#include <dt-bindings/clock/amlogic,a5-pll-clkc.h>
+
+#define GP0PLL_CTRL0			0x80
+#define GP0PLL_CTRL1			0x84
+#define GP0PLL_CTRL2			0x88
+#define GP0PLL_CTRL3			0x8c
+#define GP0PLL_CTRL4			0x90
+#define GP0PLL_CTRL5			0x94
+#define GP0PLL_CTRL6			0x98
+#define HIFIPLL_CTRL0			0x100
+#define HIFIPLL_CTRL1			0x104
+#define HIFIPLL_CTRL2			0x108
+#define HIFIPLL_CTRL3			0x10c
+#define HIFIPLL_CTRL4			0x110
+#define HIFIPLL_CTRL5			0x114
+#define HIFIPLL_CTRL6			0x118
+#define MPLL_CTRL0			0x180
+#define MPLL_CTRL1			0x184
+#define MPLL_CTRL2			0x188
+#define MPLL_CTRL3			0x18c
+#define MPLL_CTRL4			0x190
+#define MPLL_CTRL5			0x194
+#define MPLL_CTRL6			0x198
+#define MPLL_CTRL7			0x19c
+#define MPLL_CTRL8			0x1a0
+
+static struct clk_fixed_factor a5_mpll_prediv = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll_prediv",
+		.ops = &clk_fixed_factor_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "fix_dco"
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct reg_sequence a5_mpll0_init_regs[] = {
+	{ .reg = MPLL_CTRL2,	.def = 0x40000033 },
+};
+
+static struct clk_regmap a5_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = MPLL_CTRL1,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = MPLL_CTRL1,
+			.shift   = 30,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = MPLL_CTRL1,
+			.shift   = 20,
+			.width   = 9,
+		},
+		.ssen = {
+			.reg_off = MPLL_CTRL1,
+			.shift   = 29,
+			.width	 = 1,
+		},
+		.init_regs = a5_mpll0_init_regs,
+		.init_count = ARRAY_SIZE(a5_mpll0_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_mpll0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = MPLL_CTRL1,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &a5_mpll0_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence a5_mpll1_init_regs[] = {
+	{ .reg = MPLL_CTRL4,	.def = 0x40000033 },
+};
+
+static struct clk_regmap a5_mpll1_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = MPLL_CTRL3,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = MPLL_CTRL3,
+			.shift   = 30,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = MPLL_CTRL3,
+			.shift   = 20,
+			.width   = 9,
+		},
+		.ssen = {
+			.reg_off = MPLL_CTRL3,
+			.shift   = 29,
+			.width	 = 1,
+		},
+		.init_regs = a5_mpll1_init_regs,
+		.init_count = ARRAY_SIZE(a5_mpll1_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll1_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_mpll1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = MPLL_CTRL3,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "a5_mpll1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &a5_mpll1_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence a5_mpll2_init_regs[] = {
+	{ .reg = MPLL_CTRL6,	.def = 0x40000033 },
+};
+
+static struct clk_regmap a5_mpll2_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = MPLL_CTRL5,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = MPLL_CTRL5,
+			.shift   = 30,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = MPLL_CTRL5,
+			.shift   = 20,
+			.width   = 9,
+		},
+		.ssen = {
+			.reg_off = MPLL_CTRL5,
+			.shift   = 29,
+			.width	 = 1,
+		},
+		.init_regs = a5_mpll2_init_regs,
+		.init_count = ARRAY_SIZE(a5_mpll2_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll2_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_mpll2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = MPLL_CTRL5,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll2",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &a5_mpll2_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence a5_mpll3_init_regs[] = {
+	{ .reg = MPLL_CTRL8,	.def = 0x40000033 },
+};
+
+static struct clk_regmap a5_mpll3_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = MPLL_CTRL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = MPLL_CTRL7,
+			.shift   = 30,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = MPLL_CTRL7,
+			.shift   = 20,
+			.width   = 9,
+		},
+		.ssen = {
+			.reg_off = MPLL_CTRL7,
+			.shift   = 29,
+			.width	 = 1,
+		},
+		.init_regs = a5_mpll3_init_regs,
+		.init_count = ARRAY_SIZE(a5_mpll3_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll3_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_mpll3 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = MPLL_CTRL7,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll3",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) { &a5_mpll3_div.hw },
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence a5_gp0_init_regs[] = {
+	{ .reg = GP0PLL_CTRL3, .def = 0x6a295c00 },
+	{ .reg = GP0PLL_CTRL4, .def = 0x65771290 },
+	{ .reg = GP0PLL_CTRL5, .def = 0x3927200a },
+	{ .reg = GP0PLL_CTRL6, .def = 0x54540000 }
+};
+
+static const struct pll_mult_range a5_gp0_pll_mult_range = {
+	.min = 125,
+	.max = 250,
+};
+
+static struct clk_regmap a5_gp0_pll_dco = {
+	.data = &(struct meson_clk_pll_data) {
+		.en = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 0,
+			.width   = 8,
+		},
+		.frac = {
+			.reg_off = GP0PLL_CTRL1,
+			.shift   = 0,
+			.width   = 17,
+		},
+		.n = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 10,
+			.width   = 5,
+		},
+		.l = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = GP0PLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.range = &a5_gp0_pll_mult_range,
+		.init_regs = a5_gp0_init_regs,
+		.init_count = ARRAY_SIZE(a5_gp0_init_regs),
+		.frac_max = 100000,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gp0_pll_dco",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+/* The maximum frequency divider supports is 32, not 128(2^7) */
+static const struct clk_div_table a5_gp0_pll_od_table[] = {
+	{ 0,  1 },
+	{ 1,  2 },
+	{ 2,  4 },
+	{ 3,  8 },
+	{ 4, 16 },
+	{ 5, 32 },
+	{ /* sentinel */ }
+};
+
+static struct clk_regmap a5_gp0_pll = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = GP0PLL_CTRL0,
+		.shift = 16,
+		.width = 3,
+		.table = a5_gp0_pll_od_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gp0_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_gp0_pll_dco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence a5_hifi_init_regs[] = {
+	{ .reg = HIFIPLL_CTRL3, .def = 0x6a285c00 },
+	{ .reg = HIFIPLL_CTRL4, .def = 0x65771290 },
+	{ .reg = HIFIPLL_CTRL5, .def = 0x3927200a },
+	{ .reg = HIFIPLL_CTRL6, .def = 0x56540000 }
+};
+
+static const struct pll_mult_range a5_hifi_pll_mult_range = {
+	.min = 125,
+	.max = 250,
+};
+
+static struct clk_regmap a5_hifi_pll_dco = {
+	.data = &(struct meson_clk_pll_data) {
+		.en = {
+			.reg_off = HIFIPLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = HIFIPLL_CTRL0,
+			.shift   = 0,
+			.width   = 8,
+		},
+		.frac = {
+			.reg_off = HIFIPLL_CTRL1,
+			.shift   = 0,
+			.width   = 17,
+		},
+		.n = {
+			.reg_off = HIFIPLL_CTRL0,
+			.shift   = 10,
+			.width   = 5,
+		},
+		.l = {
+			.reg_off = HIFIPLL_CTRL0,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = HIFIPLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.range = &a5_hifi_pll_mult_range,
+		.init_regs = a5_hifi_init_regs,
+		.init_count = ARRAY_SIZE(a5_hifi_init_regs),
+		.frac_max = 100000,
+		.flags = CLK_MESON_PLL_ROUND_CLOSEST,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi_pll_dco",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_hifi_pll = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = HIFIPLL_CTRL0,
+		.shift = 16,
+		.width = 2,
+		.flags = CLK_DIVIDER_POWER_OF_TWO,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hifi_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_hifi_pll_dco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_hw *a5_pll_hw_clks[] = {
+	[CLKID_MPLL_PREDIV]	= &a5_mpll_prediv.hw,
+	[CLKID_MPLL0_DIV]	= &a5_mpll0_div.hw,
+	[CLKID_MPLL0]		= &a5_mpll0.hw,
+	[CLKID_MPLL1_DIV]	= &a5_mpll1_div.hw,
+	[CLKID_MPLL1]		= &a5_mpll1.hw,
+	[CLKID_MPLL2_DIV]	= &a5_mpll2_div.hw,
+	[CLKID_MPLL2]		= &a5_mpll2.hw,
+	[CLKID_MPLL3_DIV]	= &a5_mpll3_div.hw,
+	[CLKID_MPLL3]		= &a5_mpll3.hw,
+	[CLKID_GP0_PLL_DCO]	= &a5_gp0_pll_dco.hw,
+	[CLKID_GP0_PLL]		= &a5_gp0_pll.hw,
+	[CLKID_HIFI_PLL_DCO]	= &a5_hifi_pll_dco.hw,
+	[CLKID_HIFI_PLL]	= &a5_hifi_pll.hw
+};
+
+static const struct meson_clkc_data a5_pll_clkc_data = {
+	.hw_clks = {
+		.hws = a5_pll_hw_clks,
+		.num = ARRAY_SIZE(a5_pll_hw_clks),
+	},
+};
+
+static const struct of_device_id a5_pll_clkc_match_table[] = {
+	{
+		.compatible = "amlogic,a5-pll-clkc",
+		.data = &a5_pll_clkc_data,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, a5_pll_clkc_match_table);
+
+static struct platform_driver a5_pll_clkc_driver = {
+	.probe = meson_clkc_mmio_probe,
+	.driver = {
+		.name = "a5-pll-clkc",
+		.of_match_table = a5_pll_clkc_match_table,
+	},
+};
+module_platform_driver(a5_pll_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A5 PLL Clock Controller driver");
+MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");

-- 
2.42.0




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

* [PATCH v4 5/8] clk: amlogic: Add A5 clock peripherals controller driver
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
                   ` (3 preceding siblings ...)
  2025-10-28  9:52 ` [PATCH v4 4/8] clk: amlogic: Add A5 PLL clock controller driver Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  2025-12-23  9:16   ` Jerome Brunet
  2025-10-28  9:52 ` [PATCH v4 6/8] arm64: dts: amlogic: A5: Add scmi-clk node Chuan Liu via B4 Relay
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add the peripherals clock controller driver for the Amlogic A5 SoC
family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 drivers/clk/meson/Kconfig          |  13 +
 drivers/clk/meson/Makefile         |   1 +
 drivers/clk/meson/a5-peripherals.c | 883 +++++++++++++++++++++++++++++++++++++
 3 files changed, 897 insertions(+)

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index b627821da081..5576f351ef8c 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -146,6 +146,19 @@ config COMMON_CLK_A5_PLL
 	  Say Y if you want the board to work, because PLLs are the parent
 	  of most peripherals.
 
+config COMMON_CLK_A5_PERIPHERALS
+	tristate "Amlogic A5 peripherals clock controller"
+	depends on ARM64
+	default ARCH_MESON
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_DUALDIV
+	select COMMON_CLK_MESON_CLKC_UTILS
+	imply COMMON_CLK_SCMI
+	imply COMMON_CLK_A5_PLL
+	help
+	  Support for the Peripherals clock controller on Amlogic A113X2 device,
+	  AKA A5. Say Y if you want the peripherals clock to work.
+
 config COMMON_CLK_C3_PLL
 	tristate "Amlogic C3 PLL clock controller"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index a074aa7e187f..0432027d7e2e 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
 obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
 obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
 obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o
+obj-$(CONFIG_COMMON_CLK_A5_PERIPHERALS) += a5-peripherals.o
 obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
 obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a5-peripherals.c b/drivers/clk/meson/a5-peripherals.c
new file mode 100644
index 000000000000..eca9f3dcc256
--- /dev/null
+++ b/drivers/clk/meson/a5-peripherals.c
@@ -0,0 +1,883 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Amlogic A5 Peripherals Clock Controller Driver
+ *
+ * Copyright (c) 2024-2025 Amlogic, inc.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+#include <dt-bindings/clock/amlogic,a5-peripherals-clkc.h>
+
+#define RTC_BY_OSCIN_CTRL0		0x8
+#define RTC_BY_OSCIN_CTRL1		0xc
+#define RTC_CTRL			0x10
+#define SYS_CLK_EN0_REG0		0x44
+#define SYS_CLK_EN0_REG1		0x48
+#define DSPA_CLK_CTRL0			0x9c
+#define CLK12_24_CTRL			0xa8
+#define AXI_CLK_EN0			0xac
+#define TS_CLK_CTRL			0x158
+#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 PWM_CLK_GH_CTRL			0x18c
+#define NNA_CLK_CNTL			0x220
+
+static struct clk_regmap a5_rtc_dualdiv_clkin = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_dualdiv_clkin",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "oscin",
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct meson_clk_dualdiv_param a5_rtc_dualdiv_table[] = {
+	{ 733, 732, 8, 11, 1 },
+	{ /* sentinel */ }
+};
+
+static struct clk_regmap a5_rtc_dualdiv = {
+	.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 = a5_rtc_dualdiv_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_dualdiv",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_rtc_dualdiv_clkin.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct clk_parent_data a5_rtc_dualdiv_parent_data[] = {
+	{ .hw = &a5_rtc_dualdiv.hw },
+	{ .hw = &a5_rtc_dualdiv_clkin.hw }
+};
+
+static struct clk_regmap a5_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_data = a5_rtc_dualdiv_parent_data,
+		.num_parents = ARRAY_SIZE(a5_rtc_dualdiv_parent_data),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap a5_rtc_dualdiv_clkout = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_dualdiv_clkout",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_rtc_dualdiv_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data a5_rtc_clk_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .hw = &a5_rtc_dualdiv_clkout.hw },
+	{ .fw_name = "pad_osc" }
+};
+
+static struct clk_regmap a5_rtc_clk = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = RTC_CTRL,
+		.mask = 0x3,
+		.shift = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_clk",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = a5_rtc_clk_parent_data,
+		.num_parents = ARRAY_SIZE(a5_rtc_clk_parent_data),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+#define A5_PCLK(_name, _reg, _bit, _pdata, _flags)			\
+struct clk_regmap a5_##_name = {					\
+	.data = &(struct clk_regmap_gate_data) {			\
+		.offset = (_reg),					\
+		.bit_idx = (_bit),					\
+	},								\
+	.hw.init = &(struct clk_init_data) {				\
+		.name = #_name,						\
+		.ops = &clk_regmap_gate_ops,				\
+		.parent_data = (_pdata),				\
+		.num_parents = 1,					\
+		.flags = (_flags),					\
+	},								\
+}
+
+static const struct clk_parent_data a5_sys_pclk_parents = { .fw_name = "sysclk" };
+
+#define A5_SYS_PCLK(_name, _reg, _bit, _flags) \
+	A5_PCLK(_name, _reg, _bit, &a5_sys_pclk_parents, _flags)
+
+static A5_SYS_PCLK(sys_reset_ctrl,	SYS_CLK_EN0_REG0, 1, 0);
+static A5_SYS_PCLK(sys_pwr_ctrl,	SYS_CLK_EN0_REG0, 3, 0);
+static A5_SYS_PCLK(sys_pad_ctrl,	SYS_CLK_EN0_REG0, 4, 0);
+static A5_SYS_PCLK(sys_ctrl,		SYS_CLK_EN0_REG0, 5, 0);
+static A5_SYS_PCLK(sys_ts_pll,		SYS_CLK_EN0_REG0, 6, 0);
+
+/*
+ * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that
+ * access the AXI bus.
+ */
+static A5_SYS_PCLK(sys_dev_arb,		SYS_CLK_EN0_REG0, 7, 0);
+static A5_SYS_PCLK(sys_mailbox,		SYS_CLK_EN0_REG0, 10, 0);
+static A5_SYS_PCLK(sys_jtag_ctrl,	SYS_CLK_EN0_REG0, 12, 0);
+static A5_SYS_PCLK(sys_ir_ctrl,		SYS_CLK_EN0_REG0, 13, 0);
+static A5_SYS_PCLK(sys_msr_clk,		SYS_CLK_EN0_REG0, 15, 0);
+static A5_SYS_PCLK(sys_rom,		SYS_CLK_EN0_REG0, 16, 0);
+static A5_SYS_PCLK(sys_cpu_apb,		SYS_CLK_EN0_REG0, 18, 0);
+static A5_SYS_PCLK(sys_rsa,		SYS_CLK_EN0_REG0, 19, 0);
+static A5_SYS_PCLK(sys_saradc,		SYS_CLK_EN0_REG0, 20, 0);
+static A5_SYS_PCLK(sys_startup,		SYS_CLK_EN0_REG0, 21, 0);
+static A5_SYS_PCLK(sys_secure,		SYS_CLK_EN0_REG0, 22, 0);
+static A5_SYS_PCLK(sys_spifc,		SYS_CLK_EN0_REG0, 23, 0);
+static A5_SYS_PCLK(sys_dspa,		SYS_CLK_EN0_REG0, 24, 0);
+static A5_SYS_PCLK(sys_nna,		SYS_CLK_EN0_REG0, 25, 0);
+static A5_SYS_PCLK(sys_eth_mac,		SYS_CLK_EN0_REG0, 26, 0);
+static A5_SYS_PCLK(sys_rama,		SYS_CLK_EN0_REG0, 28, 0);
+static A5_SYS_PCLK(sys_ramb,		SYS_CLK_EN0_REG0, 30, 0);
+static A5_SYS_PCLK(sys_audio_top,	SYS_CLK_EN0_REG1, 0, 0);
+static A5_SYS_PCLK(sys_audio_vad,	SYS_CLK_EN0_REG1, 1, 0);
+static A5_SYS_PCLK(sys_usb,		SYS_CLK_EN0_REG1, 2, 0);
+static A5_SYS_PCLK(sys_sd_emmc_a,	SYS_CLK_EN0_REG1, 3, 0);
+static A5_SYS_PCLK(sys_sd_emmc_c,	SYS_CLK_EN0_REG1, 4, 0);
+static A5_SYS_PCLK(sys_pwm_ab,		SYS_CLK_EN0_REG1, 5, 0);
+static A5_SYS_PCLK(sys_pwm_cd,		SYS_CLK_EN0_REG1, 6, 0);
+static A5_SYS_PCLK(sys_pwm_ef,		SYS_CLK_EN0_REG1, 7, 0);
+static A5_SYS_PCLK(sys_pwm_gh,		SYS_CLK_EN0_REG1, 8, 0);
+static A5_SYS_PCLK(sys_spicc_1,		SYS_CLK_EN0_REG1, 9, 0);
+static A5_SYS_PCLK(sys_spicc_0,		SYS_CLK_EN0_REG1, 10, 0);
+static A5_SYS_PCLK(sys_uart_a,		SYS_CLK_EN0_REG1, 11, 0);
+static A5_SYS_PCLK(sys_uart_b,		SYS_CLK_EN0_REG1, 12, 0);
+static A5_SYS_PCLK(sys_uart_c,		SYS_CLK_EN0_REG1, 13, 0);
+static A5_SYS_PCLK(sys_uart_d,		SYS_CLK_EN0_REG1, 14, 0);
+static A5_SYS_PCLK(sys_uart_e,		SYS_CLK_EN0_REG1, 15, 0);
+static A5_SYS_PCLK(sys_i2c_m_a,		SYS_CLK_EN0_REG1, 16, 0);
+static A5_SYS_PCLK(sys_i2c_m_b,		SYS_CLK_EN0_REG1, 17, 0);
+static A5_SYS_PCLK(sys_i2c_m_c,		SYS_CLK_EN0_REG1, 18, 0);
+static A5_SYS_PCLK(sys_i2c_m_d,		SYS_CLK_EN0_REG1, 19, 0);
+static A5_SYS_PCLK(sys_rtc,		SYS_CLK_EN0_REG1, 21, 0);
+
+static const struct clk_parent_data a5_axi_clk_parents = { .fw_name = "axiclk" };
+
+#define A5_AXI_CLK(_name, _reg, _bit, _flags) \
+	A5_PCLK(_name, _reg, _bit, &a5_axi_clk_parents, _flags)
+
+static A5_AXI_CLK(axi_audio_vad,	AXI_CLK_EN0, 0, 0);
+static A5_AXI_CLK(axi_audio_top,	AXI_CLK_EN0, 1, 0);
+static A5_AXI_CLK(axi_ramb,		AXI_CLK_EN0, 5, 0);
+static A5_AXI_CLK(axi_rama,		AXI_CLK_EN0, 6, 0);
+static A5_AXI_CLK(axi_nna,		AXI_CLK_EN0, 12, 0);
+
+/*
+ * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO,
+ * sec_top, USB, Audio) to access the AXI bus of the DDR.
+ */
+static A5_AXI_CLK(axi_dev1_dmc,	AXI_CLK_EN0, 13, 0);
+
+/*
+ * NOTE: axi_dev0_dmc provides the clock for the peripherals(ETH and SPICC)
+ * to access the AXI bus of the DDR.
+ */
+static A5_AXI_CLK(axi_dev0_dmc,	AXI_CLK_EN0, 14, 0);
+static A5_AXI_CLK(axi_dsp_dmc,		AXI_CLK_EN0, 15, 0);
+
+static struct clk_regmap a5_clk_12_24m_in = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "clk_12_24m_in",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_clk_12_24m = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = CLK12_24_CTRL,
+		.shift = 10,
+		.width = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "clk_12_24m",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_clk_12_24m_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_fclk_25m_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = CLK12_24_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_25m_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "fix",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_fclk_25m = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = CLK12_24_CTRL,
+		.bit_idx = 12,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_25m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_fclk_25m_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * Channel 4 5 8 9 10 11 13 14 15 16 18 are not connected.
+ *
+ * gp1 is designed for DSU (DynamIQ Shared Unit) alone. It cannot be changed
+ * arbitrarily. gp1 is read-only in the kernel and is only open for debug
+ * purposes.
+ */
+static u32 a5_gen_parent_table[] = { 0, 1, 2, 3, 6, 7, 12, 17, 19, 20, 21, 22,
+				    23, 24, 25, 26, 27, 28};
+
+static const struct clk_parent_data a5_gen_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .hw = &a5_rtc_clk.hw },
+	{ .fw_name = "sysplldiv16" },
+	{ .fw_name = "ddr" },
+	{ .fw_name = "gp1" },
+	{ .fw_name = "hifi" },
+	{ .fw_name = "clkmsr" },
+	{ .fw_name = "cpudiv16" },
+	{ .fw_name = "fdiv2" },
+	{ .fw_name = "fdiv2p5" },
+	{ .fw_name = "fdiv3" },
+	{ .fw_name = "fdiv4" },
+	{ .fw_name = "fdiv5" },
+	{ .fw_name = "fdiv7" },
+	{ .fw_name = "mpll0" },
+	{ .fw_name = "mpll1" },
+	{ .fw_name = "mpll2" },
+	{ .fw_name = "mpll3" }
+};
+
+static struct clk_regmap a5_gen_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = GEN_CLK_CTRL,
+		.mask = 0x1f,
+		.shift = 12,
+		.table = a5_gen_parent_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gen_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = a5_gen_parent_data,
+		.num_parents = ARRAY_SIZE(a5_gen_parent_data),
+	},
+};
+
+static struct clk_regmap a5_gen_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = GEN_CLK_CTRL,
+		.shift = 0,
+		.width = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gen_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_gen_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap a5_gen = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = GEN_CLK_CTRL,
+		.bit_idx = 11,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "gen",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_gen_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+#define A5_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \
+	MESON_COMP_SEL(a5_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0)
+
+#define A5_COMP_DIV(_name, _reg, _shift, _width) \
+	MESON_COMP_DIV(a5_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
+
+#define A5_COMP_GATE(_name, _reg, _bit) \
+	MESON_COMP_GATE(a5_, _name, _reg, _bit, CLK_SET_RATE_PARENT)
+
+static const struct clk_parent_data a5_saradc_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .fw_name = "sysclk" }
+};
+
+static A5_COMP_SEL(saradc, SAR_CLK_CTRL0, 9, 0x3, a5_saradc_parent_data);
+static A5_COMP_DIV(saradc, SAR_CLK_CTRL0, 0, 8);
+static A5_COMP_GATE(saradc, SAR_CLK_CTRL0, 8);
+
+static const struct clk_parent_data a5_pwm_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .hw = &a5_rtc_clk.hw },
+	{ .fw_name = "fdiv4" },
+	{ .fw_name = "fdiv3" }
+};
+
+static A5_COMP_SEL(pwm_a, PWM_CLK_AB_CTRL, 9, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_a, PWM_CLK_AB_CTRL, 0, 8);
+static A5_COMP_GATE(pwm_a, PWM_CLK_AB_CTRL, 8);
+
+static A5_COMP_SEL(pwm_b, PWM_CLK_AB_CTRL, 25, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_b, PWM_CLK_AB_CTRL, 16, 8);
+static A5_COMP_GATE(pwm_b, PWM_CLK_AB_CTRL, 24);
+
+static A5_COMP_SEL(pwm_c, PWM_CLK_CD_CTRL, 9, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_c, PWM_CLK_CD_CTRL, 0, 8);
+static A5_COMP_GATE(pwm_c, PWM_CLK_CD_CTRL, 8);
+
+static A5_COMP_SEL(pwm_d, PWM_CLK_CD_CTRL, 25, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_d, PWM_CLK_CD_CTRL, 16, 8);
+static A5_COMP_GATE(pwm_d, PWM_CLK_CD_CTRL, 24);
+
+static A5_COMP_SEL(pwm_e, PWM_CLK_EF_CTRL, 9, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_e, PWM_CLK_EF_CTRL, 0, 8);
+static A5_COMP_GATE(pwm_e, PWM_CLK_EF_CTRL, 8);
+
+static A5_COMP_SEL(pwm_f, PWM_CLK_EF_CTRL, 25, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_f, PWM_CLK_EF_CTRL, 16, 8);
+static A5_COMP_GATE(pwm_f, PWM_CLK_EF_CTRL, 24);
+
+static A5_COMP_SEL(pwm_g, PWM_CLK_GH_CTRL, 9, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_g, PWM_CLK_GH_CTRL, 0, 8);
+static A5_COMP_GATE(pwm_g, PWM_CLK_GH_CTRL, 8);
+
+static A5_COMP_SEL(pwm_h, PWM_CLK_GH_CTRL, 25, 0x3, a5_pwm_parent_data);
+static A5_COMP_DIV(pwm_h, PWM_CLK_GH_CTRL, 16, 8);
+static A5_COMP_GATE(pwm_h, PWM_CLK_GH_CTRL, 24);
+
+/*
+ * NOTE: Channel 7 is gp1, because gp1 is designed for DSU, so spicc does not
+ * support this source in the driver.
+ */
+static const struct clk_parent_data a5_spicc_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .fw_name = "sysclk" },
+	{ .fw_name = "fdiv4" },
+	{ .fw_name = "fdiv3" },
+	{ .fw_name = "fdiv2" },
+	{ .fw_name = "fdiv5" },
+	{ .fw_name = "fdiv7" }
+};
+
+static A5_COMP_SEL(spicc_0, SPICC_CLK_CTRL, 7, 0x7, a5_spicc_parent_data);
+static A5_COMP_DIV(spicc_0, SPICC_CLK_CTRL, 0, 6);
+static A5_COMP_GATE(spicc_0, SPICC_CLK_CTRL, 6);
+
+static A5_COMP_SEL(spicc_1, SPICC_CLK_CTRL, 23, 0x7, a5_spicc_parent_data);
+static A5_COMP_DIV(spicc_1, SPICC_CLK_CTRL, 16, 6);
+static A5_COMP_GATE(spicc_1, SPICC_CLK_CTRL, 22);
+
+static const struct clk_parent_data a5_sd_emmc_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .fw_name = "fdiv2" },
+	{ .fw_name = "fdiv3" },
+	{ .fw_name = "hifi" },
+	{ .fw_name = "fdiv2p5" },
+	{ .fw_name = "mpll2" },
+	{ .fw_name = "mpll3" },
+	{ .fw_name = "gp0" }
+};
+
+static A5_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL, 9, 0x7, a5_sd_emmc_parent_data);
+static A5_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL, 0, 7);
+static A5_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL, 7);
+
+static A5_COMP_SEL(sd_emmc_c, NAND_CLK_CTRL, 9, 0x7, a5_sd_emmc_parent_data);
+static A5_COMP_DIV(sd_emmc_c, NAND_CLK_CTRL, 0, 7);
+static A5_COMP_GATE(sd_emmc_c, NAND_CLK_CTRL, 7);
+
+static struct clk_regmap a5_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 = "oscin",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_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 *[]) {
+			&a5_ts_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_fixed_factor a5_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 = "fdiv2",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_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 *[]) {
+			&a5_eth_125m_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_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_data = &(const struct clk_parent_data) {
+			.fw_name = "fdiv2",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap a5_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 *[]) {
+			&a5_eth_rmii_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/* Channel 6 is gp1. */
+static u32 a5_dspa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};
+
+static const struct clk_parent_data a5_dspa_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .fw_name = "fdiv2p5" },
+	{ .fw_name = "fdiv3" },
+	{ .fw_name = "rtc" },  /* rtc_pll */
+	{ .fw_name = "hifi" },
+	{ .fw_name = "fdiv4" },
+	{ .hw = &a5_rtc_clk.hw }
+};
+
+static struct clk_regmap a5_dspa_0_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = a5_dspa_parent_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = a5_dspa_parent_data,
+		.num_parents = ARRAY_SIZE(a5_dspa_parent_data),
+	},
+};
+
+static struct clk_regmap a5_dspa_0_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_dspa_0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap a5_dspa_0 = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_dspa_0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap a5_dspa_1_sel = {
+	.data = &(struct clk_regmap_mux_data) {
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = a5_dspa_parent_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = a5_dspa_parent_data,
+		.num_parents = ARRAY_SIZE(a5_dspa_parent_data),
+	},
+};
+
+static struct clk_regmap a5_dspa_1_div = {
+	.data = &(struct clk_regmap_div_data) {
+		.offset = DSPA_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_dspa_1_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap a5_dspa_1 = {
+	.data = &(struct clk_regmap_gate_data) {
+		.offset = DSPA_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_dspa_1_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap a5_dspa = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DSPA_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dspa",
+		.ops = &clk_regmap_mux_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&a5_dspa_0.hw,
+			&a5_dspa_1.hw
+		},
+		.num_parents = 2,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+#define A5_COMP_SEL_WITH_TAB(_name, _reg, _shift, _mask, _pdata, _table) \
+	MESON_COMP_SEL(a5_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)
+
+/* Channel 6 is gp1. */
+static u32 a5_nna_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};
+
+static const struct clk_parent_data a5_nna_parent_data[] = {
+	{ .fw_name = "oscin" },
+	{ .fw_name = "fdiv2p5" },
+	{ .fw_name = "fdiv4" },
+	{ .fw_name = "fdiv3" },
+	{ .fw_name = "fdiv5" },
+	{ .fw_name = "fdiv2" },
+	{ .fw_name = "hifi" }
+};
+
+static A5_COMP_SEL_WITH_TAB(nna_core, NNA_CLK_CNTL, 9, 0x7,
+			    a5_nna_parent_data, a5_nna_parent_table);
+static A5_COMP_DIV(nna_core, NNA_CLK_CNTL, 0, 7);
+static A5_COMP_GATE(nna_core, NNA_CLK_CNTL, 8);
+
+static A5_COMP_SEL_WITH_TAB(nna_axi, NNA_CLK_CNTL, 25, 0x7,
+			    a5_nna_parent_data, a5_nna_parent_table);
+static A5_COMP_DIV(nna_axi, NNA_CLK_CNTL, 16, 7);
+static A5_COMP_GATE(nna_axi, NNA_CLK_CNTL, 24);
+
+static struct clk_hw *a5_peripherals_hw_clks[] = {
+	[CLKID_RTC_DUALDIV_CLKIN]	= &a5_rtc_dualdiv_clkin.hw,
+	[CLKID_RTC_DUALDIV]		= &a5_rtc_dualdiv.hw,
+	[CLKID_RTC_DUALDIV_SEL]		= &a5_rtc_dualdiv_sel.hw,
+	[CLKID_RTC_DUALDIV_CLKOUT]	= &a5_rtc_dualdiv_clkout.hw,
+	[CLKID_RTC_CLK]			= &a5_rtc_clk.hw,
+	[CLKID_SYS_RESET_CTRL]		= &a5_sys_reset_ctrl.hw,
+	[CLKID_SYS_PWR_CTRL]		= &a5_sys_pwr_ctrl.hw,
+	[CLKID_SYS_PAD_CTRL]		= &a5_sys_pad_ctrl.hw,
+	[CLKID_SYS_CTRL]		= &a5_sys_ctrl.hw,
+	[CLKID_SYS_TS_PLL]		= &a5_sys_ts_pll.hw,
+	[CLKID_SYS_DEV_ARB]		= &a5_sys_dev_arb.hw,
+	[CLKID_SYS_MAILBOX]		= &a5_sys_mailbox.hw,
+	[CLKID_SYS_JTAG_CTRL]		= &a5_sys_jtag_ctrl.hw,
+	[CLKID_SYS_IR_CTRL]		= &a5_sys_ir_ctrl.hw,
+	[CLKID_SYS_MSR_CLK]		= &a5_sys_msr_clk.hw,
+	[CLKID_SYS_ROM]			= &a5_sys_rom.hw,
+	[CLKID_SYS_CPU_ARB]		= &a5_sys_cpu_apb.hw,
+	[CLKID_SYS_RSA]			= &a5_sys_rsa.hw,
+	[CLKID_SYS_SARADC]		= &a5_sys_saradc.hw,
+	[CLKID_SYS_STARTUP]		= &a5_sys_startup.hw,
+	[CLKID_SYS_SECURE]		= &a5_sys_secure.hw,
+	[CLKID_SYS_SPIFC]		= &a5_sys_spifc.hw,
+	[CLKID_SYS_DSPA]		= &a5_sys_dspa.hw,
+	[CLKID_SYS_NNA]			= &a5_sys_nna.hw,
+	[CLKID_SYS_ETH_MAC]		= &a5_sys_eth_mac.hw,
+	[CLKID_SYS_RAMA]		= &a5_sys_rama.hw,
+	[CLKID_SYS_RAMB]		= &a5_sys_ramb.hw,
+	[CLKID_SYS_AUDIO_TOP]		= &a5_sys_audio_top.hw,
+	[CLKID_SYS_AUDIO_VAD]		= &a5_sys_audio_vad.hw,
+	[CLKID_SYS_USB]			= &a5_sys_usb.hw,
+	[CLKID_SYS_SD_EMMC_A]		= &a5_sys_sd_emmc_a.hw,
+	[CLKID_SYS_SD_EMMC_C]		= &a5_sys_sd_emmc_c.hw,
+	[CLKID_SYS_PWM_AB]		= &a5_sys_pwm_ab.hw,
+	[CLKID_SYS_PWM_CD]		= &a5_sys_pwm_cd.hw,
+	[CLKID_SYS_PWM_EF]		= &a5_sys_pwm_ef.hw,
+	[CLKID_SYS_PWM_GH]		= &a5_sys_pwm_gh.hw,
+	[CLKID_SYS_SPICC_1]		= &a5_sys_spicc_1.hw,
+	[CLKID_SYS_SPICC_0]		= &a5_sys_spicc_0.hw,
+	[CLKID_SYS_UART_A]		= &a5_sys_uart_a.hw,
+	[CLKID_SYS_UART_B]		= &a5_sys_uart_b.hw,
+	[CLKID_SYS_UART_C]		= &a5_sys_uart_c.hw,
+	[CLKID_SYS_UART_D]		= &a5_sys_uart_d.hw,
+	[CLKID_SYS_UART_E]		= &a5_sys_uart_e.hw,
+	[CLKID_SYS_I2C_M_A]		= &a5_sys_i2c_m_a.hw,
+	[CLKID_SYS_I2C_M_B]		= &a5_sys_i2c_m_b.hw,
+	[CLKID_SYS_I2C_M_C]		= &a5_sys_i2c_m_c.hw,
+	[CLKID_SYS_I2C_M_D]		= &a5_sys_i2c_m_d.hw,
+	[CLKID_SYS_RTC]			= &a5_sys_rtc.hw,
+	[CLKID_AXI_AUDIO_VAD]		= &a5_axi_audio_vad.hw,
+	[CLKID_AXI_AUDIO_TOP]		= &a5_axi_audio_top.hw,
+	[CLKID_AXI_RAMB]		= &a5_axi_ramb.hw,
+	[CLKID_AXI_RAMA]		= &a5_axi_rama.hw,
+	[CLKID_AXI_NNA]			= &a5_axi_nna.hw,
+	[CLKID_AXI_DEV1_DMC]		= &a5_axi_dev1_dmc.hw,
+	[CLKID_AXI_DEV0_DMC]		= &a5_axi_dev0_dmc.hw,
+	[CLKID_AXI_DSP_DMC]		= &a5_axi_dsp_dmc.hw,
+	[CLKID_12_24M_IN]		= &a5_clk_12_24m_in.hw,
+	[CLKID_12M_24M]			= &a5_clk_12_24m.hw,
+	[CLKID_FCLK_25M_DIV]		= &a5_fclk_25m_div.hw,
+	[CLKID_FCLK_25M]		= &a5_fclk_25m.hw,
+	[CLKID_GEN_SEL]			= &a5_gen_sel.hw,
+	[CLKID_GEN_DIV]			= &a5_gen_div.hw,
+	[CLKID_GEN]			= &a5_gen.hw,
+	[CLKID_SARADC_SEL]		= &a5_saradc_sel.hw,
+	[CLKID_SARADC_DIV]		= &a5_saradc_div.hw,
+	[CLKID_SARADC]			= &a5_saradc.hw,
+	[CLKID_PWM_A_SEL]		= &a5_pwm_a_sel.hw,
+	[CLKID_PWM_A_DIV]		= &a5_pwm_a_div.hw,
+	[CLKID_PWM_A]			= &a5_pwm_a.hw,
+	[CLKID_PWM_B_SEL]		= &a5_pwm_b_sel.hw,
+	[CLKID_PWM_B_DIV]		= &a5_pwm_b_div.hw,
+	[CLKID_PWM_B]			= &a5_pwm_b.hw,
+	[CLKID_PWM_C_SEL]		= &a5_pwm_c_sel.hw,
+	[CLKID_PWM_C_DIV]		= &a5_pwm_c_div.hw,
+	[CLKID_PWM_C]			= &a5_pwm_c.hw,
+	[CLKID_PWM_D_SEL]		= &a5_pwm_d_sel.hw,
+	[CLKID_PWM_D_DIV]		= &a5_pwm_d_div.hw,
+	[CLKID_PWM_D]			= &a5_pwm_d.hw,
+	[CLKID_PWM_E_SEL]		= &a5_pwm_e_sel.hw,
+	[CLKID_PWM_E_DIV]		= &a5_pwm_e_div.hw,
+	[CLKID_PWM_E]			= &a5_pwm_e.hw,
+	[CLKID_PWM_F_SEL]		= &a5_pwm_f_sel.hw,
+	[CLKID_PWM_F_DIV]		= &a5_pwm_f_div.hw,
+	[CLKID_PWM_F]			= &a5_pwm_f.hw,
+	[CLKID_PWM_G_SEL]		= &a5_pwm_g_sel.hw,
+	[CLKID_PWM_G_DIV]		= &a5_pwm_g_div.hw,
+	[CLKID_PWM_G]			= &a5_pwm_g.hw,
+	[CLKID_PWM_H_SEL]		= &a5_pwm_h_sel.hw,
+	[CLKID_PWM_H_DIV]		= &a5_pwm_h_div.hw,
+	[CLKID_PWM_H]			= &a5_pwm_h.hw,
+	[CLKID_SPICC_0_SEL]		= &a5_spicc_0_sel.hw,
+	[CLKID_SPICC_0_DIV]		= &a5_spicc_0_div.hw,
+	[CLKID_SPICC_0]			= &a5_spicc_0.hw,
+	[CLKID_SPICC_1_SEL]		= &a5_spicc_1_sel.hw,
+	[CLKID_SPICC_1_DIV]		= &a5_spicc_1_div.hw,
+	[CLKID_SPICC_1]			= &a5_spicc_1.hw,
+	[CLKID_SD_EMMC_A_SEL]		= &a5_sd_emmc_a_sel.hw,
+	[CLKID_SD_EMMC_A_DIV]		= &a5_sd_emmc_a_div.hw,
+	[CLKID_SD_EMMC_A]		= &a5_sd_emmc_a.hw,
+	[CLKID_SD_EMMC_C_SEL]		= &a5_sd_emmc_c_sel.hw,
+	[CLKID_SD_EMMC_C_DIV]		= &a5_sd_emmc_c_div.hw,
+	[CLKID_SD_EMMC_C]		= &a5_sd_emmc_c.hw,
+	[CLKID_TS_DIV]			= &a5_ts_div.hw,
+	[CLKID_TS]			= &a5_ts.hw,
+	[CLKID_ETH_125M_DIV]		= &a5_eth_125m_div.hw,
+	[CLKID_ETH_125M]		= &a5_eth_125m.hw,
+	[CLKID_ETH_RMII_DIV]		= &a5_eth_rmii_div.hw,
+	[CLKID_ETH_RMII]		= &a5_eth_rmii.hw,
+	[CLKID_DSPA_0_SEL]		= &a5_dspa_0_sel.hw,
+	[CLKID_DSPA_0_DIV]		= &a5_dspa_0_div.hw,
+	[CLKID_DSPA_0]			= &a5_dspa_0.hw,
+	[CLKID_DSPA_1_SEL]		= &a5_dspa_1_sel.hw,
+	[CLKID_DSPA_1_DIV]		= &a5_dspa_1_div.hw,
+	[CLKID_DSPA_1]			= &a5_dspa_1.hw,
+	[CLKID_DSPA]			= &a5_dspa.hw,
+	[CLKID_NNA_CORE_SEL]		= &a5_nna_core_sel.hw,
+	[CLKID_NNA_CORE_DIV]		= &a5_nna_core_div.hw,
+	[CLKID_NNA_CORE]		= &a5_nna_core.hw,
+	[CLKID_NNA_AXI_SEL]		= &a5_nna_axi_sel.hw,
+	[CLKID_NNA_AXI_DIV]		= &a5_nna_axi_div.hw,
+	[CLKID_NNA_AXI]			= &a5_nna_axi.hw,
+};
+
+static const struct meson_clkc_data a5_peripherals_clkc_data = {
+	.hw_clks = {
+		.hws = a5_peripherals_hw_clks,
+		.num = ARRAY_SIZE(a5_peripherals_hw_clks),
+	},
+};
+
+static const struct of_device_id a5_peripherals_clkc_match_table[] = {
+	{
+		.compatible = "amlogic,a5-peripherals-clkc",
+		.data = &a5_peripherals_clkc_data,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, a5_peripherals_clkc_match_table);
+
+static struct platform_driver a5_peripherals_clkc_driver = {
+	.probe = meson_clkc_mmio_probe,
+	.driver = {
+		.name = "a5-peripherals-clkc",
+		.of_match_table = a5_peripherals_clkc_match_table,
+	},
+};
+module_platform_driver(a5_peripherals_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A5 Peripherals Clock Controller driver");
+MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");

-- 
2.42.0




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

* [PATCH v4 6/8] arm64: dts: amlogic: A5: Add scmi-clk node
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
                   ` (4 preceding siblings ...)
  2025-10-28  9:52 ` [PATCH v4 5/8] clk: amlogic: Add A5 clock peripherals " Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 7/8] arm64: dts: amlogic: A5: Add PLL controller node Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 8/8] arm64: dts: amlogic: A5: Add peripheral clock " Chuan Liu via B4 Relay
  7 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add scmi-clk device node information for the Amlogic A5 SoC family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
---
 arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi | 30 +++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
index 2b12d8284594..a6625508893d 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
@@ -7,6 +7,8 @@
 #include "amlogic-a5-reset.h"
 #include <dt-bindings/pinctrl/amlogic,pinctrl.h>
 #include <dt-bindings/power/amlogic,a5-pwrc.h>
+#include <dt-bindings/clock/amlogic,a5-scmi-clkc.h>
+
 / {
 	cpus {
 		#address-cells = <2>;
@@ -49,6 +51,34 @@ pwrc: power-controller {
 			#power-domain-cells = <1>;
 		};
 	};
+
+	sram0: sram@f702a000 {
+		compatible = "mmio-sram";
+		reg = <0x0 0xf702a000 0x0 0x100>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x0 0xf702a000 0x100>;
+
+		scmi_buf0: scmi-sram-section@0 {
+			compatible = "arm,scmi-shmem";
+			reg = <0x0 0x100>;
+		};
+	};
+
+	firmware {
+		scmi {
+			compatible = "arm,scmi-smc";
+			arm,smc-id = <0x820000C1>;
+			shmem = <&scmi_buf0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			scmi_clk: protocol@14 {
+				reg = <0x14>;
+				#clock-cells = <1>;
+			};
+		};
+	};
 };
 
 &apb {

-- 
2.42.0




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

* [PATCH v4 7/8] arm64: dts: amlogic: A5: Add PLL controller node
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
                   ` (5 preceding siblings ...)
  2025-10-28  9:52 ` [PATCH v4 6/8] arm64: dts: amlogic: A5: Add scmi-clk node Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  2025-10-28  9:52 ` [PATCH v4 8/8] arm64: dts: amlogic: A5: Add peripheral clock " Chuan Liu via B4 Relay
  7 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add PLL controller node for A5 SoC family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
---
 arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
index a6625508893d..70deeab220e0 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
@@ -8,6 +8,7 @@
 #include <dt-bindings/pinctrl/amlogic,pinctrl.h>
 #include <dt-bindings/power/amlogic,a5-pwrc.h>
 #include <dt-bindings/clock/amlogic,a5-scmi-clkc.h>
+#include <dt-bindings/clock/amlogic,a5-pll-clkc.h>
 
 / {
 	cpus {
@@ -187,4 +188,16 @@ gpio_intc: interrupt-controller@4080 {
 		amlogic,channel-interrupts =
 			<10 11 12 13 14 15 16 17 18 19 20 21>;
 	};
+
+	clkc_pll: clock-controller@8000 {
+		compatible = "amlogic,a5-pll-clkc";
+		reg = <0x0 0x8000 0x0 0x1a4>;
+		#clock-cells = <1>;
+		clocks = <&xtal>,
+			 <&scmi_clk CLKID_FIXED_PLL_DCO>,
+			 <&scmi_clk CLKID_FIXED_PLL>;
+		clock-names = "xtal",
+			      "fix_dco",
+			      "fix";
+	};
 };

-- 
2.42.0




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

* [PATCH v4 8/8] arm64: dts: amlogic: A5: Add peripheral clock controller node
  2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
                   ` (6 preceding siblings ...)
  2025-10-28  9:52 ` [PATCH v4 7/8] arm64: dts: amlogic: A5: Add PLL controller node Chuan Liu via B4 Relay
@ 2025-10-28  9:52 ` Chuan Liu via B4 Relay
  7 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu via B4 Relay @ 2025-10-28  9:52 UTC (permalink / raw)
  To: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Jerome Brunet,
	Xianwei Zhao, Kevin Hilman, Martin Blumenstingl
  Cc: linux-kernel, linux-clk, devicetree, linux-amlogic,
	linux-arm-kernel

From: Chuan Liu <chuan.liu@amlogic.com>

Add peripheral clock controller node for A5 SoC family.

Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
---
 arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi | 43 +++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
index 70deeab220e0..7324e427ed39 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/power/amlogic,a5-pwrc.h>
 #include <dt-bindings/clock/amlogic,a5-scmi-clkc.h>
 #include <dt-bindings/clock/amlogic,a5-pll-clkc.h>
+#include <dt-bindings/clock/amlogic,a5-peripherals-clkc.h>
 
 / {
 	cpus {
@@ -83,6 +84,48 @@ scmi_clk: protocol@14 {
 };
 
 &apb {
+	clkc_periphs: clock-controller@0 {
+		compatible = "amlogic,a5-peripherals-clkc";
+		reg = <0x0 0x0 0x0 0x224>;
+		#clock-cells = <1>;
+		clocks = <&xtal>,
+			 <&scmi_clk CLKID_OSC>,
+			 <&scmi_clk CLKID_FIXED_PLL>,
+			 <&scmi_clk CLKID_FCLK_DIV2>,
+			 <&scmi_clk CLKID_FCLK_DIV2P5>,
+			 <&scmi_clk CLKID_FCLK_DIV3>,
+			 <&scmi_clk CLKID_FCLK_DIV4>,
+			 <&scmi_clk CLKID_FCLK_DIV5>,
+			 <&scmi_clk CLKID_FCLK_DIV7>,
+			 <&clkc_pll CLKID_MPLL2>,
+			 <&clkc_pll CLKID_MPLL3>,
+			 <&clkc_pll CLKID_GP0_PLL>,
+			 <&scmi_clk CLKID_GP1_PLL>,
+			 <&clkc_pll CLKID_HIFI_PLL>,
+			 <&scmi_clk CLKID_SYS_CLK>,
+			 <&scmi_clk CLKID_AXI_CLK>,
+			 <&scmi_clk CLKID_SYS_PLL_DIV16>,
+			 <&scmi_clk CLKID_CPU_CLK_DIV16>;
+		clock-names = "xtal",
+			      "oscin",
+			      "fix",
+			      "fdiv2",
+			      "fdiv2p5",
+			      "fdiv3",
+			      "fdiv4",
+			      "fdiv5",
+			      "fdiv7",
+			      "mpll2",
+			      "mpll3",
+			      "gp0",
+			      "gp1",
+			      "hifi",
+			      "sysclk",
+			      "axiclk",
+			      "sysplldiv16",
+			      "cpudiv16";
+	};
+
 	reset: reset-controller@2000 {
 		compatible = "amlogic,a5-reset",
 			     "amlogic,meson-s4-reset";

-- 
2.42.0




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

* Re: [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support
  2025-10-28  9:52 ` [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support Chuan Liu via B4 Relay
@ 2025-12-23  8:59   ` Jerome Brunet
  2025-12-23 11:56     ` Chuan Liu
  0 siblings, 1 reply; 13+ messages in thread
From: Jerome Brunet @ 2025-12-23  8:59 UTC (permalink / raw)
  To: Chuan Liu via B4 Relay
  Cc: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Xianwei Zhao,
	Kevin Hilman, Martin Blumenstingl, linux-kernel, linux-clk,
	devicetree, linux-amlogic, linux-arm-kernel

On Tue 28 Oct 2025 at 17:52, Chuan Liu via B4 Relay <devnull+chuan.liu.amlogic.com@kernel.org> wrote:

> From: Chuan Liu <chuan.liu@amlogic.com>
>
> Add the SCMI clock controller dt-bindings for the Amlogic A5 SoC
> family.
>
> Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>

Please read:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.19-rc1#n503

and adjust your patches accordingly

> ---
>  include/dt-bindings/clock/amlogic,a5-scmi-clkc.h | 44 ++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
>
> diff --git a/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h
> new file mode 100644
> index 000000000000..1bf027d0110a
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h
> @@ -0,0 +1,44 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> + */
> +
> +#ifndef __AMLOGIC_A5_SCMI_CLKC_H
> +#define __AMLOGIC_A5_SCMI_CLKC_H
> +
> +#define CLKID_OSC				0
> +#define CLKID_SYS_CLK				1
> +#define CLKID_AXI_CLK				2
> +#define CLKID_CPU_CLK				3
> +#define CLKID_DSU_CLK				4
> +#define CLKID_GP1_PLL				5
> +#define CLKID_FIXED_PLL_DCO			6
> +#define CLKID_FIXED_PLL				7
> +#define CLKID_ACLKM				8
> +#define CLKID_SYS_PLL_DIV16			9
> +#define CLKID_CPU_CLK_DIV16			10
> +#define CLKID_FCLK_50M_PREDIV			11
> +#define CLKID_FCLK_50M_DIV			12
> +#define CLKID_FCLK_50M				13
> +#define CLKID_FCLK_DIV2_DIV			14
> +#define CLKID_FCLK_DIV2				15
> +#define CLKID_FCLK_DIV2P5_DIV			16
> +#define CLKID_FCLK_DIV2P5			17
> +#define CLKID_FCLK_DIV3_DIV			18
> +#define CLKID_FCLK_DIV3				19
> +#define CLKID_FCLK_DIV4_DIV			20
> +#define CLKID_FCLK_DIV4				21
> +#define CLKID_FCLK_DIV5_DIV			22
> +#define CLKID_FCLK_DIV5				23
> +#define CLKID_FCLK_DIV7_DIV			24
> +#define CLKID_FCLK_DIV7				25
> +#define CLKID_SYS_MMC_PCLK			26
> +#define CLKID_SYS_CPU_CTRL			27
> +#define CLKID_SYS_IRQ_CTRL			28
> +#define CLKID_SYS_GIC				29
> +#define CLKID_SYS_BIG_NIC			30
> +#define CLKID_AXI_SYS_NIC			31
> +#define CLKID_AXI_CPU_DMC			32
> +
> +#endif /* __AMLOGIC_A5_SCMI_CLKC_H */

-- 
Jerome


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

* Re: [PATCH v4 5/8] clk: amlogic: Add A5 clock peripherals controller driver
  2025-10-28  9:52 ` [PATCH v4 5/8] clk: amlogic: Add A5 clock peripherals " Chuan Liu via B4 Relay
@ 2025-12-23  9:16   ` Jerome Brunet
  2025-12-23 12:27     ` Chuan Liu
  0 siblings, 1 reply; 13+ messages in thread
From: Jerome Brunet @ 2025-12-23  9:16 UTC (permalink / raw)
  To: Chuan Liu via B4 Relay
  Cc: Chuan Liu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Xianwei Zhao,
	Kevin Hilman, Martin Blumenstingl, linux-kernel, linux-clk,
	devicetree, linux-amlogic, linux-arm-kernel

On Tue 28 Oct 2025 at 17:52, Chuan Liu via B4 Relay <devnull+chuan.liu.amlogic.com@kernel.org> wrote:

> From: Chuan Liu <chuan.liu@amlogic.com>
>
> Add the peripherals clock controller driver for the Amlogic A5 SoC
> family.
>
> Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> ---
>  drivers/clk/meson/Kconfig          |  13 +
>  drivers/clk/meson/Makefile         |   1 +
>  drivers/clk/meson/a5-peripherals.c | 883 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 897 insertions(+)
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index b627821da081..5576f351ef8c 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -146,6 +146,19 @@ config COMMON_CLK_A5_PLL
>  	  Say Y if you want the board to work, because PLLs are the parent
>  	  of most peripherals.
>  
> +config COMMON_CLK_A5_PERIPHERALS
> +	tristate "Amlogic A5 peripherals clock controller"
> +	depends on ARM64
> +	default ARCH_MESON
> +	select COMMON_CLK_MESON_REGMAP
> +	select COMMON_CLK_MESON_DUALDIV
> +	select COMMON_CLK_MESON_CLKC_UTILS
> +	imply COMMON_CLK_SCMI
> +	imply COMMON_CLK_A5_PLL
> +	help
> +	  Support for the Peripherals clock controller on Amlogic A113X2 device,
> +	  AKA A5. Say Y if you want the peripherals clock to work.
> +
>  config COMMON_CLK_C3_PLL
>  	tristate "Amlogic C3 PLL clock controller"
>  	depends on ARM64
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index a074aa7e187f..0432027d7e2e 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
>  obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
>  obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
>  obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o
> +obj-$(CONFIG_COMMON_CLK_A5_PERIPHERALS) += a5-peripherals.o
>  obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
>  obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>  obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
> diff --git a/drivers/clk/meson/a5-peripherals.c b/drivers/clk/meson/a5-peripherals.c
> new file mode 100644
> index 000000000000..eca9f3dcc256
> --- /dev/null
> +++ b/drivers/clk/meson/a5-peripherals.c
> @@ -0,0 +1,883 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Amlogic A5 Peripherals Clock Controller Driver
> + *
> + * Copyright (c) 2024-2025 Amlogic, inc.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +#include "clk-regmap.h"
> +#include "clk-dualdiv.h"
> +#include "meson-clkc-utils.h"
> +#include <dt-bindings/clock/amlogic,a5-peripherals-clkc.h>
> +
> +#define RTC_BY_OSCIN_CTRL0		0x8
> +#define RTC_BY_OSCIN_CTRL1		0xc
> +#define RTC_CTRL			0x10
> +#define SYS_CLK_EN0_REG0		0x44
> +#define SYS_CLK_EN0_REG1		0x48
> +#define DSPA_CLK_CTRL0			0x9c
> +#define CLK12_24_CTRL			0xa8
> +#define AXI_CLK_EN0			0xac
> +#define TS_CLK_CTRL			0x158
> +#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 PWM_CLK_GH_CTRL			0x18c
> +#define NNA_CLK_CNTL			0x220
> +
> +static struct clk_regmap a5_rtc_dualdiv_clkin = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = RTC_BY_OSCIN_CTRL0,
> +		.bit_idx = 31,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "rtc_dualdiv_clkin",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "oscin",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct meson_clk_dualdiv_param a5_rtc_dualdiv_table[] = {
> +	{ 733, 732, 8, 11, 1 },
> +	{ /* sentinel */ }
> +};
> +
> +static struct clk_regmap a5_rtc_dualdiv = {
> +	.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 = a5_rtc_dualdiv_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "rtc_dualdiv",
> +		.ops = &meson_clk_dualdiv_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_rtc_dualdiv_clkin.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct clk_parent_data a5_rtc_dualdiv_parent_data[] = {
> +	{ .hw = &a5_rtc_dualdiv.hw },
> +	{ .hw = &a5_rtc_dualdiv_clkin.hw }
> +};
> +
> +static struct clk_regmap a5_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_data = a5_rtc_dualdiv_parent_data,
> +		.num_parents = ARRAY_SIZE(a5_rtc_dualdiv_parent_data),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap a5_rtc_dualdiv_clkout = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = RTC_BY_OSCIN_CTRL0,
> +		.bit_idx = 30,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "rtc_dualdiv_clkout",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_rtc_dualdiv_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data a5_rtc_clk_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .hw = &a5_rtc_dualdiv_clkout.hw },
> +	{ .fw_name = "pad_osc" }
> +};
> +
> +static struct clk_regmap a5_rtc_clk = {
> +	.data = &(struct clk_regmap_mux_data) {
> +		.offset = RTC_CTRL,
> +		.mask = 0x3,
> +		.shift = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "rtc_clk",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = a5_rtc_clk_parent_data,
> +		.num_parents = ARRAY_SIZE(a5_rtc_clk_parent_data),
> +		.flags = CLK_SET_RATE_PARENT,

NO_REPARENT maybe ?

> +	},
> +};
> +
> +#define A5_PCLK(_name, _reg, _bit, _pdata, _flags)			\
> +struct clk_regmap a5_##_name = {					\
> +	.data = &(struct clk_regmap_gate_data) {			\
> +		.offset = (_reg),					\
> +		.bit_idx = (_bit),					\
> +	},								\
> +	.hw.init = &(struct clk_init_data) {				\
> +		.name = #_name,						\
> +		.ops = &clk_regmap_gate_ops,				\
> +		.parent_data = (_pdata),				\
> +		.num_parents = 1,					\
> +		.flags = (_flags),					\
> +	},								\
> +}

You've complained about the time it took to do the clean-up of amlogic
clocks, and yet, look what we have here ...

> +
> +static const struct clk_parent_data a5_sys_pclk_parents = { .fw_name = "sysclk" };
> +
> +#define A5_SYS_PCLK(_name, _reg, _bit, _flags) \
> +	A5_PCLK(_name, _reg, _bit, &a5_sys_pclk_parents, _flags)
> +
> +static A5_SYS_PCLK(sys_reset_ctrl,	SYS_CLK_EN0_REG0, 1, 0);
> +static A5_SYS_PCLK(sys_pwr_ctrl,	SYS_CLK_EN0_REG0, 3, 0);
> +static A5_SYS_PCLK(sys_pad_ctrl,	SYS_CLK_EN0_REG0, 4, 0);
> +static A5_SYS_PCLK(sys_ctrl,		SYS_CLK_EN0_REG0, 5, 0);
> +static A5_SYS_PCLK(sys_ts_pll,		SYS_CLK_EN0_REG0, 6, 0);
> +
> +/*
> + * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that
> + * access the AXI bus.
> + */
> +static A5_SYS_PCLK(sys_dev_arb,		SYS_CLK_EN0_REG0, 7, 0);
> +static A5_SYS_PCLK(sys_mailbox,		SYS_CLK_EN0_REG0, 10, 0);
> +static A5_SYS_PCLK(sys_jtag_ctrl,	SYS_CLK_EN0_REG0, 12, 0);
> +static A5_SYS_PCLK(sys_ir_ctrl,		SYS_CLK_EN0_REG0, 13, 0);
> +static A5_SYS_PCLK(sys_msr_clk,		SYS_CLK_EN0_REG0, 15, 0);
> +static A5_SYS_PCLK(sys_rom,		SYS_CLK_EN0_REG0, 16, 0);
> +static A5_SYS_PCLK(sys_cpu_apb,		SYS_CLK_EN0_REG0, 18, 0);
> +static A5_SYS_PCLK(sys_rsa,		SYS_CLK_EN0_REG0, 19, 0);
> +static A5_SYS_PCLK(sys_saradc,		SYS_CLK_EN0_REG0, 20, 0);
> +static A5_SYS_PCLK(sys_startup,		SYS_CLK_EN0_REG0, 21, 0);
> +static A5_SYS_PCLK(sys_secure,		SYS_CLK_EN0_REG0, 22, 0);
> +static A5_SYS_PCLK(sys_spifc,		SYS_CLK_EN0_REG0, 23, 0);
> +static A5_SYS_PCLK(sys_dspa,		SYS_CLK_EN0_REG0, 24, 0);
> +static A5_SYS_PCLK(sys_nna,		SYS_CLK_EN0_REG0, 25, 0);
> +static A5_SYS_PCLK(sys_eth_mac,		SYS_CLK_EN0_REG0, 26, 0);
> +static A5_SYS_PCLK(sys_rama,		SYS_CLK_EN0_REG0, 28, 0);
> +static A5_SYS_PCLK(sys_ramb,		SYS_CLK_EN0_REG0, 30, 0);
> +static A5_SYS_PCLK(sys_audio_top,	SYS_CLK_EN0_REG1, 0, 0);
> +static A5_SYS_PCLK(sys_audio_vad,	SYS_CLK_EN0_REG1, 1, 0);
> +static A5_SYS_PCLK(sys_usb,		SYS_CLK_EN0_REG1, 2, 0);
> +static A5_SYS_PCLK(sys_sd_emmc_a,	SYS_CLK_EN0_REG1, 3, 0);
> +static A5_SYS_PCLK(sys_sd_emmc_c,	SYS_CLK_EN0_REG1, 4, 0);
> +static A5_SYS_PCLK(sys_pwm_ab,		SYS_CLK_EN0_REG1, 5, 0);
> +static A5_SYS_PCLK(sys_pwm_cd,		SYS_CLK_EN0_REG1, 6, 0);
> +static A5_SYS_PCLK(sys_pwm_ef,		SYS_CLK_EN0_REG1, 7, 0);
> +static A5_SYS_PCLK(sys_pwm_gh,		SYS_CLK_EN0_REG1, 8, 0);
> +static A5_SYS_PCLK(sys_spicc_1,		SYS_CLK_EN0_REG1, 9, 0);
> +static A5_SYS_PCLK(sys_spicc_0,		SYS_CLK_EN0_REG1, 10, 0);
> +static A5_SYS_PCLK(sys_uart_a,		SYS_CLK_EN0_REG1, 11, 0);
> +static A5_SYS_PCLK(sys_uart_b,		SYS_CLK_EN0_REG1, 12, 0);
> +static A5_SYS_PCLK(sys_uart_c,		SYS_CLK_EN0_REG1, 13, 0);
> +static A5_SYS_PCLK(sys_uart_d,		SYS_CLK_EN0_REG1, 14, 0);
> +static A5_SYS_PCLK(sys_uart_e,		SYS_CLK_EN0_REG1, 15, 0);
> +static A5_SYS_PCLK(sys_i2c_m_a,		SYS_CLK_EN0_REG1, 16, 0);
> +static A5_SYS_PCLK(sys_i2c_m_b,		SYS_CLK_EN0_REG1, 17, 0);
> +static A5_SYS_PCLK(sys_i2c_m_c,		SYS_CLK_EN0_REG1, 18, 0);
> +static A5_SYS_PCLK(sys_i2c_m_d,		SYS_CLK_EN0_REG1, 19, 0);
> +static A5_SYS_PCLK(sys_rtc,		SYS_CLK_EN0_REG1, 21, 0);
> +
> +static const struct clk_parent_data a5_axi_clk_parents = { .fw_name = "axiclk" };
> +
> +#define A5_AXI_CLK(_name, _reg, _bit, _flags) \
> +	A5_PCLK(_name, _reg, _bit, &a5_axi_clk_parents, _flags)
> +
> +static A5_AXI_CLK(axi_audio_vad,	AXI_CLK_EN0, 0, 0);
> +static A5_AXI_CLK(axi_audio_top,	AXI_CLK_EN0, 1, 0);
> +static A5_AXI_CLK(axi_ramb,		AXI_CLK_EN0, 5, 0);
> +static A5_AXI_CLK(axi_rama,		AXI_CLK_EN0, 6, 0);
> +static A5_AXI_CLK(axi_nna,		AXI_CLK_EN0, 12, 0);
> +
> +/*
> + * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO,
> + * sec_top, USB, Audio) to access the AXI bus of the DDR.
> + */
> +static A5_AXI_CLK(axi_dev1_dmc,	AXI_CLK_EN0, 13, 0);
> +
> +/*
> + * NOTE: axi_dev0_dmc provides the clock for the peripherals(ETH and SPICC)
> + * to access the AXI bus of the DDR.
> + */
> +static A5_AXI_CLK(axi_dev0_dmc,	AXI_CLK_EN0, 14, 0);
> +static A5_AXI_CLK(axi_dsp_dmc,		AXI_CLK_EN0, 15, 0);
> +
> +static struct clk_regmap a5_clk_12_24m_in = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = CLK12_24_CTRL,
> +		.bit_idx = 11,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "clk_12_24m_in",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "xtal",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a5_clk_12_24m = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = CLK12_24_CTRL,
> +		.shift = 10,
> +		.width = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "clk_12_24m",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_clk_12_24m_in.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a5_fclk_25m_div = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = CLK12_24_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_25m_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "fix",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a5_fclk_25m = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = CLK12_24_CTRL,
> +		.bit_idx = 12,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_25m",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_fclk_25m_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +/*
> + * Channel 4 5 8 9 10 11 13 14 15 16 18 are not connected.
> + *
> + * gp1 is designed for DSU (DynamIQ Shared Unit) alone. It cannot be changed
> + * arbitrarily. gp1 is read-only in the kernel and is only open for debug
> + * purposes.
> + */
> +static u32 a5_gen_parent_table[] = { 0, 1, 2, 3, 6, 7, 12, 17, 19, 20, 21, 22,
> +				    23, 24, 25, 26, 27, 28};
> +
> +static const struct clk_parent_data a5_gen_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .hw = &a5_rtc_clk.hw },
> +	{ .fw_name = "sysplldiv16" },
> +	{ .fw_name = "ddr" },
> +	{ .fw_name = "gp1" },
> +	{ .fw_name = "hifi" },
> +	{ .fw_name = "clkmsr" },
> +	{ .fw_name = "cpudiv16" },
> +	{ .fw_name = "fdiv2" },
> +	{ .fw_name = "fdiv2p5" },
> +	{ .fw_name = "fdiv3" },
> +	{ .fw_name = "fdiv4" },
> +	{ .fw_name = "fdiv5" },
> +	{ .fw_name = "fdiv7" },
> +	{ .fw_name = "mpll0" },
> +	{ .fw_name = "mpll1" },
> +	{ .fw_name = "mpll2" },
> +	{ .fw_name = "mpll3" }
> +};
> +
> +static struct clk_regmap a5_gen_sel = {
> +	.data = &(struct clk_regmap_mux_data) {
> +		.offset = GEN_CLK_CTRL,
> +		.mask = 0x1f,
> +		.shift = 12,
> +		.table = a5_gen_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "gen_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = a5_gen_parent_data,
> +		.num_parents = ARRAY_SIZE(a5_gen_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap a5_gen_div = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = GEN_CLK_CTRL,
> +		.shift = 0,
> +		.width = 11,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "gen_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_gen_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap a5_gen = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = GEN_CLK_CTRL,
> +		.bit_idx = 11,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "gen",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_gen_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +#define A5_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \
> +	MESON_COMP_SEL(a5_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0)
> +
> +#define A5_COMP_DIV(_name, _reg, _shift, _width) \
> +	MESON_COMP_DIV(a5_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
> +
> +#define A5_COMP_GATE(_name, _reg, _bit) \
> +	MESON_COMP_GATE(a5_, _name, _reg, _bit, CLK_SET_RATE_PARENT)
> +
> +static const struct clk_parent_data a5_saradc_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .fw_name = "sysclk" }
> +};
> +
> +static A5_COMP_SEL(saradc, SAR_CLK_CTRL0, 9, 0x3, a5_saradc_parent_data);
> +static A5_COMP_DIV(saradc, SAR_CLK_CTRL0, 0, 8);
> +static A5_COMP_GATE(saradc, SAR_CLK_CTRL0, 8);
> +
> +static const struct clk_parent_data a5_pwm_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .hw = &a5_rtc_clk.hw },
> +	{ .fw_name = "fdiv4" },
> +	{ .fw_name = "fdiv3" }
> +};
> +
> +static A5_COMP_SEL(pwm_a, PWM_CLK_AB_CTRL, 9, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_a, PWM_CLK_AB_CTRL, 0, 8);
> +static A5_COMP_GATE(pwm_a, PWM_CLK_AB_CTRL, 8);
> +
> +static A5_COMP_SEL(pwm_b, PWM_CLK_AB_CTRL, 25, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_b, PWM_CLK_AB_CTRL, 16, 8);
> +static A5_COMP_GATE(pwm_b, PWM_CLK_AB_CTRL, 24);
> +
> +static A5_COMP_SEL(pwm_c, PWM_CLK_CD_CTRL, 9, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_c, PWM_CLK_CD_CTRL, 0, 8);
> +static A5_COMP_GATE(pwm_c, PWM_CLK_CD_CTRL, 8);
> +
> +static A5_COMP_SEL(pwm_d, PWM_CLK_CD_CTRL, 25, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_d, PWM_CLK_CD_CTRL, 16, 8);
> +static A5_COMP_GATE(pwm_d, PWM_CLK_CD_CTRL, 24);
> +
> +static A5_COMP_SEL(pwm_e, PWM_CLK_EF_CTRL, 9, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_e, PWM_CLK_EF_CTRL, 0, 8);
> +static A5_COMP_GATE(pwm_e, PWM_CLK_EF_CTRL, 8);
> +
> +static A5_COMP_SEL(pwm_f, PWM_CLK_EF_CTRL, 25, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_f, PWM_CLK_EF_CTRL, 16, 8);
> +static A5_COMP_GATE(pwm_f, PWM_CLK_EF_CTRL, 24);
> +
> +static A5_COMP_SEL(pwm_g, PWM_CLK_GH_CTRL, 9, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_g, PWM_CLK_GH_CTRL, 0, 8);
> +static A5_COMP_GATE(pwm_g, PWM_CLK_GH_CTRL, 8);
> +
> +static A5_COMP_SEL(pwm_h, PWM_CLK_GH_CTRL, 25, 0x3, a5_pwm_parent_data);
> +static A5_COMP_DIV(pwm_h, PWM_CLK_GH_CTRL, 16, 8);
> +static A5_COMP_GATE(pwm_h, PWM_CLK_GH_CTRL, 24);
> +
> +/*
> + * NOTE: Channel 7 is gp1, because gp1 is designed for DSU, so spicc does not
> + * support this source in the driver.
> + */
> +static const struct clk_parent_data a5_spicc_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .fw_name = "sysclk" },
> +	{ .fw_name = "fdiv4" },
> +	{ .fw_name = "fdiv3" },
> +	{ .fw_name = "fdiv2" },
> +	{ .fw_name = "fdiv5" },
> +	{ .fw_name = "fdiv7" }
> +};
> +
> +static A5_COMP_SEL(spicc_0, SPICC_CLK_CTRL, 7, 0x7, a5_spicc_parent_data);
> +static A5_COMP_DIV(spicc_0, SPICC_CLK_CTRL, 0, 6);
> +static A5_COMP_GATE(spicc_0, SPICC_CLK_CTRL, 6);
> +
> +static A5_COMP_SEL(spicc_1, SPICC_CLK_CTRL, 23, 0x7, a5_spicc_parent_data);
> +static A5_COMP_DIV(spicc_1, SPICC_CLK_CTRL, 16, 6);
> +static A5_COMP_GATE(spicc_1, SPICC_CLK_CTRL, 22);
> +
> +static const struct clk_parent_data a5_sd_emmc_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .fw_name = "fdiv2" },
> +	{ .fw_name = "fdiv3" },
> +	{ .fw_name = "hifi" },
> +	{ .fw_name = "fdiv2p5" },
> +	{ .fw_name = "mpll2" },
> +	{ .fw_name = "mpll3" },
> +	{ .fw_name = "gp0" }
> +};
> +
> +static A5_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL, 9, 0x7, a5_sd_emmc_parent_data);
> +static A5_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL, 0, 7);
> +static A5_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL, 7);
> +
> +static A5_COMP_SEL(sd_emmc_c, NAND_CLK_CTRL, 9, 0x7, a5_sd_emmc_parent_data);
> +static A5_COMP_DIV(sd_emmc_c, NAND_CLK_CTRL, 0, 7);
> +static A5_COMP_GATE(sd_emmc_c, NAND_CLK_CTRL, 7);
> +
> +static struct clk_regmap a5_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 = "oscin",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a5_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 *[]) {
> +			&a5_ts_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_fixed_factor a5_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 = "fdiv2",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a5_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 *[]) {
> +			&a5_eth_125m_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a5_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_data = &(const struct clk_parent_data) {
> +			.fw_name = "fdiv2",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a5_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 *[]) {
> +			&a5_eth_rmii_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +/* Channel 6 is gp1. */
> +static u32 a5_dspa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};

Considering there is no rate propagation from mux below, is it really a
problem to have gp1 in here ? 

> +
> +static const struct clk_parent_data a5_dspa_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .fw_name = "fdiv2p5" },
> +	{ .fw_name = "fdiv3" },
> +	{ .fw_name = "rtc" },  /* rtc_pll */
> +	{ .fw_name = "hifi" },
> +	{ .fw_name = "fdiv4" },
> +	{ .hw = &a5_rtc_clk.hw }
> +};
> +
> +static struct clk_regmap a5_dspa_0_sel = {
> +	.data = &(struct clk_regmap_mux_data) {
> +		.offset = DSPA_CLK_CTRL0,
> +		.mask = 0x7,
> +		.shift = 10,
> +		.table = a5_dspa_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dspa_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = a5_dspa_parent_data,
> +		.num_parents = ARRAY_SIZE(a5_dspa_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap a5_dspa_0_div = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = DSPA_CLK_CTRL0,
> +		.shift = 0,
> +		.width = 10,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dspa_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_dspa_0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};

Same comment as the t7 regarding naming and macro usage for the glitch
free composite clocks. Please adjust accordingly.

> +
> +static struct clk_regmap a5_dspa_0 = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = DSPA_CLK_CTRL0,
> +		.bit_idx = 13,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dspa_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_dspa_0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap a5_dspa_1_sel = {
> +	.data = &(struct clk_regmap_mux_data) {
> +		.offset = DSPA_CLK_CTRL0,
> +		.mask = 0x7,
> +		.shift = 26,
> +		.table = a5_dspa_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dspa_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = a5_dspa_parent_data,
> +		.num_parents = ARRAY_SIZE(a5_dspa_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap a5_dspa_1_div = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = DSPA_CLK_CTRL0,
> +		.shift = 16,
> +		.width = 10,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dspa_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_dspa_1_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap a5_dspa_1 = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = DSPA_CLK_CTRL0,
> +		.bit_idx = 29,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dspa_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_dspa_1_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap a5_dspa = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = DSPA_CLK_CTRL0,
> +		.mask = 0x1,
> +		.shift = 15,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dspa",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a5_dspa_0.hw,
> +			&a5_dspa_1.hw
> +		},
> +		.num_parents = 2,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +#define A5_COMP_SEL_WITH_TAB(_name, _reg, _shift, _mask, _pdata, _table) \

No, adjust your main macro.

> +	MESON_COMP_SEL(a5_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)
> +
> +/* Channel 6 is gp1. */
> +static u32 a5_nna_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};
> +
> +static const struct clk_parent_data a5_nna_parent_data[] = {
> +	{ .fw_name = "oscin" },
> +	{ .fw_name = "fdiv2p5" },
> +	{ .fw_name = "fdiv4" },
> +	{ .fw_name = "fdiv3" },
> +	{ .fw_name = "fdiv5" },
> +	{ .fw_name = "fdiv2" },
> +	{ .fw_name = "hifi" }
> +};
> +
> +static A5_COMP_SEL_WITH_TAB(nna_core, NNA_CLK_CNTL, 9, 0x7,
> +			    a5_nna_parent_data, a5_nna_parent_table);
> +static A5_COMP_DIV(nna_core, NNA_CLK_CNTL, 0, 7);
> +static A5_COMP_GATE(nna_core, NNA_CLK_CNTL, 8);
> +
> +static A5_COMP_SEL_WITH_TAB(nna_axi, NNA_CLK_CNTL, 25, 0x7,
> +			    a5_nna_parent_data, a5_nna_parent_table);
> +static A5_COMP_DIV(nna_axi, NNA_CLK_CNTL, 16, 7);
> +static A5_COMP_GATE(nna_axi, NNA_CLK_CNTL, 24);
> +
> +static struct clk_hw *a5_peripherals_hw_clks[] = {
> +	[CLKID_RTC_DUALDIV_CLKIN]	= &a5_rtc_dualdiv_clkin.hw,
> +	[CLKID_RTC_DUALDIV]		= &a5_rtc_dualdiv.hw,
> +	[CLKID_RTC_DUALDIV_SEL]		= &a5_rtc_dualdiv_sel.hw,
> +	[CLKID_RTC_DUALDIV_CLKOUT]	= &a5_rtc_dualdiv_clkout.hw,
> +	[CLKID_RTC_CLK]			= &a5_rtc_clk.hw,
> +	[CLKID_SYS_RESET_CTRL]		= &a5_sys_reset_ctrl.hw,
> +	[CLKID_SYS_PWR_CTRL]		= &a5_sys_pwr_ctrl.hw,
> +	[CLKID_SYS_PAD_CTRL]		= &a5_sys_pad_ctrl.hw,
> +	[CLKID_SYS_CTRL]		= &a5_sys_ctrl.hw,
> +	[CLKID_SYS_TS_PLL]		= &a5_sys_ts_pll.hw,
> +	[CLKID_SYS_DEV_ARB]		= &a5_sys_dev_arb.hw,
> +	[CLKID_SYS_MAILBOX]		= &a5_sys_mailbox.hw,
> +	[CLKID_SYS_JTAG_CTRL]		= &a5_sys_jtag_ctrl.hw,
> +	[CLKID_SYS_IR_CTRL]		= &a5_sys_ir_ctrl.hw,
> +	[CLKID_SYS_MSR_CLK]		= &a5_sys_msr_clk.hw,
> +	[CLKID_SYS_ROM]			= &a5_sys_rom.hw,
> +	[CLKID_SYS_CPU_ARB]		= &a5_sys_cpu_apb.hw,
> +	[CLKID_SYS_RSA]			= &a5_sys_rsa.hw,
> +	[CLKID_SYS_SARADC]		= &a5_sys_saradc.hw,
> +	[CLKID_SYS_STARTUP]		= &a5_sys_startup.hw,
> +	[CLKID_SYS_SECURE]		= &a5_sys_secure.hw,
> +	[CLKID_SYS_SPIFC]		= &a5_sys_spifc.hw,
> +	[CLKID_SYS_DSPA]		= &a5_sys_dspa.hw,
> +	[CLKID_SYS_NNA]			= &a5_sys_nna.hw,
> +	[CLKID_SYS_ETH_MAC]		= &a5_sys_eth_mac.hw,
> +	[CLKID_SYS_RAMA]		= &a5_sys_rama.hw,
> +	[CLKID_SYS_RAMB]		= &a5_sys_ramb.hw,
> +	[CLKID_SYS_AUDIO_TOP]		= &a5_sys_audio_top.hw,
> +	[CLKID_SYS_AUDIO_VAD]		= &a5_sys_audio_vad.hw,
> +	[CLKID_SYS_USB]			= &a5_sys_usb.hw,
> +	[CLKID_SYS_SD_EMMC_A]		= &a5_sys_sd_emmc_a.hw,
> +	[CLKID_SYS_SD_EMMC_C]		= &a5_sys_sd_emmc_c.hw,
> +	[CLKID_SYS_PWM_AB]		= &a5_sys_pwm_ab.hw,
> +	[CLKID_SYS_PWM_CD]		= &a5_sys_pwm_cd.hw,
> +	[CLKID_SYS_PWM_EF]		= &a5_sys_pwm_ef.hw,
> +	[CLKID_SYS_PWM_GH]		= &a5_sys_pwm_gh.hw,
> +	[CLKID_SYS_SPICC_1]		= &a5_sys_spicc_1.hw,
> +	[CLKID_SYS_SPICC_0]		= &a5_sys_spicc_0.hw,
> +	[CLKID_SYS_UART_A]		= &a5_sys_uart_a.hw,
> +	[CLKID_SYS_UART_B]		= &a5_sys_uart_b.hw,
> +	[CLKID_SYS_UART_C]		= &a5_sys_uart_c.hw,
> +	[CLKID_SYS_UART_D]		= &a5_sys_uart_d.hw,
> +	[CLKID_SYS_UART_E]		= &a5_sys_uart_e.hw,
> +	[CLKID_SYS_I2C_M_A]		= &a5_sys_i2c_m_a.hw,
> +	[CLKID_SYS_I2C_M_B]		= &a5_sys_i2c_m_b.hw,
> +	[CLKID_SYS_I2C_M_C]		= &a5_sys_i2c_m_c.hw,
> +	[CLKID_SYS_I2C_M_D]		= &a5_sys_i2c_m_d.hw,
> +	[CLKID_SYS_RTC]			= &a5_sys_rtc.hw,
> +	[CLKID_AXI_AUDIO_VAD]		= &a5_axi_audio_vad.hw,
> +	[CLKID_AXI_AUDIO_TOP]		= &a5_axi_audio_top.hw,
> +	[CLKID_AXI_RAMB]		= &a5_axi_ramb.hw,
> +	[CLKID_AXI_RAMA]		= &a5_axi_rama.hw,
> +	[CLKID_AXI_NNA]			= &a5_axi_nna.hw,
> +	[CLKID_AXI_DEV1_DMC]		= &a5_axi_dev1_dmc.hw,
> +	[CLKID_AXI_DEV0_DMC]		= &a5_axi_dev0_dmc.hw,
> +	[CLKID_AXI_DSP_DMC]		= &a5_axi_dsp_dmc.hw,
> +	[CLKID_12_24M_IN]		= &a5_clk_12_24m_in.hw,
> +	[CLKID_12M_24M]			= &a5_clk_12_24m.hw,
> +	[CLKID_FCLK_25M_DIV]		= &a5_fclk_25m_div.hw,
> +	[CLKID_FCLK_25M]		= &a5_fclk_25m.hw,
> +	[CLKID_GEN_SEL]			= &a5_gen_sel.hw,
> +	[CLKID_GEN_DIV]			= &a5_gen_div.hw,
> +	[CLKID_GEN]			= &a5_gen.hw,
> +	[CLKID_SARADC_SEL]		= &a5_saradc_sel.hw,
> +	[CLKID_SARADC_DIV]		= &a5_saradc_div.hw,
> +	[CLKID_SARADC]			= &a5_saradc.hw,
> +	[CLKID_PWM_A_SEL]		= &a5_pwm_a_sel.hw,
> +	[CLKID_PWM_A_DIV]		= &a5_pwm_a_div.hw,
> +	[CLKID_PWM_A]			= &a5_pwm_a.hw,
> +	[CLKID_PWM_B_SEL]		= &a5_pwm_b_sel.hw,
> +	[CLKID_PWM_B_DIV]		= &a5_pwm_b_div.hw,
> +	[CLKID_PWM_B]			= &a5_pwm_b.hw,
> +	[CLKID_PWM_C_SEL]		= &a5_pwm_c_sel.hw,
> +	[CLKID_PWM_C_DIV]		= &a5_pwm_c_div.hw,
> +	[CLKID_PWM_C]			= &a5_pwm_c.hw,
> +	[CLKID_PWM_D_SEL]		= &a5_pwm_d_sel.hw,
> +	[CLKID_PWM_D_DIV]		= &a5_pwm_d_div.hw,
> +	[CLKID_PWM_D]			= &a5_pwm_d.hw,
> +	[CLKID_PWM_E_SEL]		= &a5_pwm_e_sel.hw,
> +	[CLKID_PWM_E_DIV]		= &a5_pwm_e_div.hw,
> +	[CLKID_PWM_E]			= &a5_pwm_e.hw,
> +	[CLKID_PWM_F_SEL]		= &a5_pwm_f_sel.hw,
> +	[CLKID_PWM_F_DIV]		= &a5_pwm_f_div.hw,
> +	[CLKID_PWM_F]			= &a5_pwm_f.hw,
> +	[CLKID_PWM_G_SEL]		= &a5_pwm_g_sel.hw,
> +	[CLKID_PWM_G_DIV]		= &a5_pwm_g_div.hw,
> +	[CLKID_PWM_G]			= &a5_pwm_g.hw,
> +	[CLKID_PWM_H_SEL]		= &a5_pwm_h_sel.hw,
> +	[CLKID_PWM_H_DIV]		= &a5_pwm_h_div.hw,
> +	[CLKID_PWM_H]			= &a5_pwm_h.hw,
> +	[CLKID_SPICC_0_SEL]		= &a5_spicc_0_sel.hw,
> +	[CLKID_SPICC_0_DIV]		= &a5_spicc_0_div.hw,
> +	[CLKID_SPICC_0]			= &a5_spicc_0.hw,
> +	[CLKID_SPICC_1_SEL]		= &a5_spicc_1_sel.hw,
> +	[CLKID_SPICC_1_DIV]		= &a5_spicc_1_div.hw,
> +	[CLKID_SPICC_1]			= &a5_spicc_1.hw,
> +	[CLKID_SD_EMMC_A_SEL]		= &a5_sd_emmc_a_sel.hw,
> +	[CLKID_SD_EMMC_A_DIV]		= &a5_sd_emmc_a_div.hw,
> +	[CLKID_SD_EMMC_A]		= &a5_sd_emmc_a.hw,
> +	[CLKID_SD_EMMC_C_SEL]		= &a5_sd_emmc_c_sel.hw,
> +	[CLKID_SD_EMMC_C_DIV]		= &a5_sd_emmc_c_div.hw,
> +	[CLKID_SD_EMMC_C]		= &a5_sd_emmc_c.hw,
> +	[CLKID_TS_DIV]			= &a5_ts_div.hw,
> +	[CLKID_TS]			= &a5_ts.hw,
> +	[CLKID_ETH_125M_DIV]		= &a5_eth_125m_div.hw,
> +	[CLKID_ETH_125M]		= &a5_eth_125m.hw,
> +	[CLKID_ETH_RMII_DIV]		= &a5_eth_rmii_div.hw,
> +	[CLKID_ETH_RMII]		= &a5_eth_rmii.hw,
> +	[CLKID_DSPA_0_SEL]		= &a5_dspa_0_sel.hw,
> +	[CLKID_DSPA_0_DIV]		= &a5_dspa_0_div.hw,
> +	[CLKID_DSPA_0]			= &a5_dspa_0.hw,
> +	[CLKID_DSPA_1_SEL]		= &a5_dspa_1_sel.hw,
> +	[CLKID_DSPA_1_DIV]		= &a5_dspa_1_div.hw,
> +	[CLKID_DSPA_1]			= &a5_dspa_1.hw,
> +	[CLKID_DSPA]			= &a5_dspa.hw,
> +	[CLKID_NNA_CORE_SEL]		= &a5_nna_core_sel.hw,
> +	[CLKID_NNA_CORE_DIV]		= &a5_nna_core_div.hw,
> +	[CLKID_NNA_CORE]		= &a5_nna_core.hw,
> +	[CLKID_NNA_AXI_SEL]		= &a5_nna_axi_sel.hw,
> +	[CLKID_NNA_AXI_DIV]		= &a5_nna_axi_div.hw,
> +	[CLKID_NNA_AXI]			= &a5_nna_axi.hw,
> +};
> +
> +static const struct meson_clkc_data a5_peripherals_clkc_data = {
> +	.hw_clks = {
> +		.hws = a5_peripherals_hw_clks,
> +		.num = ARRAY_SIZE(a5_peripherals_hw_clks),
> +	},
> +};
> +
> +static const struct of_device_id a5_peripherals_clkc_match_table[] = {
> +	{
> +		.compatible = "amlogic,a5-peripherals-clkc",
> +		.data = &a5_peripherals_clkc_data,
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, a5_peripherals_clkc_match_table);
> +
> +static struct platform_driver a5_peripherals_clkc_driver = {
> +	.probe = meson_clkc_mmio_probe,
> +	.driver = {
> +		.name = "a5-peripherals-clkc",
> +		.of_match_table = a5_peripherals_clkc_match_table,
> +	},
> +};
> +module_platform_driver(a5_peripherals_clkc_driver);
> +
> +MODULE_DESCRIPTION("Amlogic A5 Peripherals Clock Controller driver");
> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("CLK_MESON");

-- 
Jerome


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

* Re: [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support
  2025-12-23  8:59   ` Jerome Brunet
@ 2025-12-23 11:56     ` Chuan Liu
  0 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu @ 2025-12-23 11:56 UTC (permalink / raw)
  To: Jerome Brunet, Chuan Liu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

Hi Jerome,
Thanks for coming back to review. Y

On 12/23/2025 4:59 PM, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Tue 28 Oct 2025 at 17:52, Chuan Liu via B4 Relay <devnull+chuan.liu.amlogic.com@kernel.org> wrote:
> 
>> From: Chuan Liu <chuan.liu@amlogic.com>
>>
>> Add the SCMI clock controller dt-bindings for the Amlogic A5 SoC
>> family.
>>
>> Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
>> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> 
> Please read:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.19-rc1#n503
> 
> and adjust your patches accordingly
> 

Thanks for pointing that out. I'll address it.

>> ---
>>   include/dt-bindings/clock/amlogic,a5-scmi-clkc.h | 44 ++++++++++++++++++++++++
>>   1 file changed, 44 insertions(+)
>>
>> diff --git a/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h
>> new file mode 100644
>> index 000000000000..1bf027d0110a
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/amlogic,a5-scmi-clkc.h
>> @@ -0,0 +1,44 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (c) 2024 Amlogic, Inc. All rights reserved.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>> + */
>> +
>> +#ifndef __AMLOGIC_A5_SCMI_CLKC_H
>> +#define __AMLOGIC_A5_SCMI_CLKC_H
>> +
>> +#define CLKID_OSC                            0
>> +#define CLKID_SYS_CLK                                1
>> +#define CLKID_AXI_CLK                                2
>> +#define CLKID_CPU_CLK                                3
>> +#define CLKID_DSU_CLK                                4
>> +#define CLKID_GP1_PLL                                5
>> +#define CLKID_FIXED_PLL_DCO                  6
>> +#define CLKID_FIXED_PLL                              7
>> +#define CLKID_ACLKM                          8
>> +#define CLKID_SYS_PLL_DIV16                  9
>> +#define CLKID_CPU_CLK_DIV16                  10
>> +#define CLKID_FCLK_50M_PREDIV                        11
>> +#define CLKID_FCLK_50M_DIV                   12
>> +#define CLKID_FCLK_50M                               13
>> +#define CLKID_FCLK_DIV2_DIV                  14
>> +#define CLKID_FCLK_DIV2                              15
>> +#define CLKID_FCLK_DIV2P5_DIV                        16
>> +#define CLKID_FCLK_DIV2P5                    17
>> +#define CLKID_FCLK_DIV3_DIV                  18
>> +#define CLKID_FCLK_DIV3                              19
>> +#define CLKID_FCLK_DIV4_DIV                  20
>> +#define CLKID_FCLK_DIV4                              21
>> +#define CLKID_FCLK_DIV5_DIV                  22
>> +#define CLKID_FCLK_DIV5                              23
>> +#define CLKID_FCLK_DIV7_DIV                  24
>> +#define CLKID_FCLK_DIV7                              25
>> +#define CLKID_SYS_MMC_PCLK                   26
>> +#define CLKID_SYS_CPU_CTRL                   27
>> +#define CLKID_SYS_IRQ_CTRL                   28
>> +#define CLKID_SYS_GIC                                29
>> +#define CLKID_SYS_BIG_NIC                    30
>> +#define CLKID_AXI_SYS_NIC                    31
>> +#define CLKID_AXI_CPU_DMC                    32
>> +
>> +#endif /* __AMLOGIC_A5_SCMI_CLKC_H */
> 
> --
> Jerome



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

* Re: [PATCH v4 5/8] clk: amlogic: Add A5 clock peripherals controller driver
  2025-12-23  9:16   ` Jerome Brunet
@ 2025-12-23 12:27     ` Chuan Liu
  0 siblings, 0 replies; 13+ messages in thread
From: Chuan Liu @ 2025-12-23 12:27 UTC (permalink / raw)
  To: Jerome Brunet, Chuan Liu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel

Hi Jerome,

On 12/23/2025 5:16 PM, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Tue 28 Oct 2025 at 17:52, Chuan Liu via B4 Relay <devnull+chuan.liu.amlogic.com@kernel.org> wrote:
> 
>> From: Chuan Liu <chuan.liu@amlogic.com>
>>
>> Add the peripherals clock controller driver for the Amlogic A5 SoC
>> family.
>>
>> Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>> ---
>>   drivers/clk/meson/Kconfig          |  13 +
>>   drivers/clk/meson/Makefile         |   1 +
>>   drivers/clk/meson/a5-peripherals.c | 883 +++++++++++++++++++++++++++++++++++++
>>   3 files changed, 897 insertions(+)
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index b627821da081..5576f351ef8c 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -146,6 +146,19 @@ config COMMON_CLK_A5_PLL
>>          Say Y if you want the board to work, because PLLs are the parent
>>          of most peripherals.
>>
>> +config COMMON_CLK_A5_PERIPHERALS
>> +     tristate "Amlogic A5 peripherals clock controller"
>> +     depends on ARM64
>> +     default ARCH_MESON
>> +     select COMMON_CLK_MESON_REGMAP
>> +     select COMMON_CLK_MESON_DUALDIV
>> +     select COMMON_CLK_MESON_CLKC_UTILS
>> +     imply COMMON_CLK_SCMI
>> +     imply COMMON_CLK_A5_PLL
>> +     help
>> +       Support for the Peripherals clock controller on Amlogic A113X2 device,
>> +       AKA A5. Say Y if you want the peripherals clock to work.
>> +
>>   config COMMON_CLK_C3_PLL
>>        tristate "Amlogic C3 PLL clock controller"
>>        depends on ARM64
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index a074aa7e187f..0432027d7e2e 100644
>> --- a/drivers/clk/meson/Makefile
>> +++ b/drivers/clk/meson/Makefile
>> @@ -20,6 +20,7 @@ obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
>>   obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
>>   obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_A5_PLL) += a5-pll.o
>> +obj-$(CONFIG_COMMON_CLK_A5_PERIPHERALS) += a5-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
>>   obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>> diff --git a/drivers/clk/meson/a5-peripherals.c b/drivers/clk/meson/a5-peripherals.c
>> new file mode 100644
>> index 000000000000..eca9f3dcc256
>> --- /dev/null
>> +++ b/drivers/clk/meson/a5-peripherals.c
>> @@ -0,0 +1,883 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Amlogic A5 Peripherals Clock Controller Driver
>> + *
>> + * Copyright (c) 2024-2025 Amlogic, inc.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/platform_device.h>
>> +#include "clk-regmap.h"
>> +#include "clk-dualdiv.h"
>> +#include "meson-clkc-utils.h"
>> +#include <dt-bindings/clock/amlogic,a5-peripherals-clkc.h>
>> +
>> +#define RTC_BY_OSCIN_CTRL0           0x8
>> +#define RTC_BY_OSCIN_CTRL1           0xc
>> +#define RTC_CTRL                     0x10
>> +#define SYS_CLK_EN0_REG0             0x44
>> +#define SYS_CLK_EN0_REG1             0x48
>> +#define DSPA_CLK_CTRL0                       0x9c
>> +#define CLK12_24_CTRL                        0xa8
>> +#define AXI_CLK_EN0                  0xac
>> +#define TS_CLK_CTRL                  0x158
>> +#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 PWM_CLK_GH_CTRL                      0x18c
>> +#define NNA_CLK_CNTL                 0x220
>> +
>> +static struct clk_regmap a5_rtc_dualdiv_clkin = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = RTC_BY_OSCIN_CTRL0,
>> +             .bit_idx = 31,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_dualdiv_clkin",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "oscin",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct meson_clk_dualdiv_param a5_rtc_dualdiv_table[] = {
>> +     { 733, 732, 8, 11, 1 },
>> +     { /* sentinel */ }
>> +};
>> +
>> +static struct clk_regmap a5_rtc_dualdiv = {
>> +     .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 = a5_rtc_dualdiv_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_dualdiv",
>> +             .ops = &meson_clk_dualdiv_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_rtc_dualdiv_clkin.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data a5_rtc_dualdiv_parent_data[] = {
>> +     { .hw = &a5_rtc_dualdiv.hw },
>> +     { .hw = &a5_rtc_dualdiv_clkin.hw }
>> +};
>> +
>> +static struct clk_regmap a5_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_data = a5_rtc_dualdiv_parent_data,
>> +             .num_parents = ARRAY_SIZE(a5_rtc_dualdiv_parent_data),
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_rtc_dualdiv_clkout = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = RTC_BY_OSCIN_CTRL0,
>> +             .bit_idx = 30,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_dualdiv_clkout",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_rtc_dualdiv_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data a5_rtc_clk_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .hw = &a5_rtc_dualdiv_clkout.hw },
>> +     { .fw_name = "pad_osc" }
>> +};
>> +
>> +static struct clk_regmap a5_rtc_clk = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = RTC_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 0,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_clk",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = a5_rtc_clk_parent_data,
>> +             .num_parents = ARRAY_SIZE(a5_rtc_clk_parent_data),
>> +             .flags = CLK_SET_RATE_PARENT,
> 
> NO_REPARENT maybe ?
> 

OK, I noticed your comment on T7, and it is reasonable. I will add it.

>> +     },
>> +};
>> +
>> +#define A5_PCLK(_name, _reg, _bit, _pdata, _flags)                   \
>> +struct clk_regmap a5_##_name = {                                     \
>> +     .data = &(struct clk_regmap_gate_data) {                        \
>> +             .offset = (_reg),                                       \
>> +             .bit_idx = (_bit),                                      \
>> +     },                                                              \
>> +     .hw.init = &(struct clk_init_data) {                            \
>> +             .name = #_name,                                         \
>> +             .ops = &clk_regmap_gate_ops,                            \
>> +             .parent_data = (_pdata),                                \
>> +             .num_parents = 1,                                       \
>> +             .flags = (_flags),                                      \
>> +     },                                                              \
>> +}
> 
> You've complained about the time it took to do the clean-up of amlogic
> clocks, and yet, look what we have here ...
> 

Yes, the previous clean-up was meaningful, as it helped simplify a large 
amount of duplicated code.

Here, I redefined a macro to avoid adding a SoC prefix to the "clock 
name", which does not seem necessary.

>> +
>> +static const struct clk_parent_data a5_sys_pclk_parents = { .fw_name = "sysclk" };
>> +
>> +#define A5_SYS_PCLK(_name, _reg, _bit, _flags) \
>> +     A5_PCLK(_name, _reg, _bit, &a5_sys_pclk_parents, _flags)
>> +
>> +static A5_SYS_PCLK(sys_reset_ctrl,   SYS_CLK_EN0_REG0, 1, 0);
>> +static A5_SYS_PCLK(sys_pwr_ctrl,     SYS_CLK_EN0_REG0, 3, 0);
>> +static A5_SYS_PCLK(sys_pad_ctrl,     SYS_CLK_EN0_REG0, 4, 0);
>> +static A5_SYS_PCLK(sys_ctrl,         SYS_CLK_EN0_REG0, 5, 0);
>> +static A5_SYS_PCLK(sys_ts_pll,               SYS_CLK_EN0_REG0, 6, 0);
>> +
>> +/*
>> + * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that
>> + * access the AXI bus.
>> + */
>> +static A5_SYS_PCLK(sys_dev_arb,              SYS_CLK_EN0_REG0, 7, 0);
>> +static A5_SYS_PCLK(sys_mailbox,              SYS_CLK_EN0_REG0, 10, 0);
>> +static A5_SYS_PCLK(sys_jtag_ctrl,    SYS_CLK_EN0_REG0, 12, 0);
>> +static A5_SYS_PCLK(sys_ir_ctrl,              SYS_CLK_EN0_REG0, 13, 0);
>> +static A5_SYS_PCLK(sys_msr_clk,              SYS_CLK_EN0_REG0, 15, 0);
>> +static A5_SYS_PCLK(sys_rom,          SYS_CLK_EN0_REG0, 16, 0);
>> +static A5_SYS_PCLK(sys_cpu_apb,              SYS_CLK_EN0_REG0, 18, 0);
>> +static A5_SYS_PCLK(sys_rsa,          SYS_CLK_EN0_REG0, 19, 0);
>> +static A5_SYS_PCLK(sys_saradc,               SYS_CLK_EN0_REG0, 20, 0);
>> +static A5_SYS_PCLK(sys_startup,              SYS_CLK_EN0_REG0, 21, 0);
>> +static A5_SYS_PCLK(sys_secure,               SYS_CLK_EN0_REG0, 22, 0);
>> +static A5_SYS_PCLK(sys_spifc,                SYS_CLK_EN0_REG0, 23, 0);
>> +static A5_SYS_PCLK(sys_dspa,         SYS_CLK_EN0_REG0, 24, 0);
>> +static A5_SYS_PCLK(sys_nna,          SYS_CLK_EN0_REG0, 25, 0);
>> +static A5_SYS_PCLK(sys_eth_mac,              SYS_CLK_EN0_REG0, 26, 0);
>> +static A5_SYS_PCLK(sys_rama,         SYS_CLK_EN0_REG0, 28, 0);
>> +static A5_SYS_PCLK(sys_ramb,         SYS_CLK_EN0_REG0, 30, 0);
>> +static A5_SYS_PCLK(sys_audio_top,    SYS_CLK_EN0_REG1, 0, 0);
>> +static A5_SYS_PCLK(sys_audio_vad,    SYS_CLK_EN0_REG1, 1, 0);
>> +static A5_SYS_PCLK(sys_usb,          SYS_CLK_EN0_REG1, 2, 0);
>> +static A5_SYS_PCLK(sys_sd_emmc_a,    SYS_CLK_EN0_REG1, 3, 0);
>> +static A5_SYS_PCLK(sys_sd_emmc_c,    SYS_CLK_EN0_REG1, 4, 0);
>> +static A5_SYS_PCLK(sys_pwm_ab,               SYS_CLK_EN0_REG1, 5, 0);
>> +static A5_SYS_PCLK(sys_pwm_cd,               SYS_CLK_EN0_REG1, 6, 0);
>> +static A5_SYS_PCLK(sys_pwm_ef,               SYS_CLK_EN0_REG1, 7, 0);
>> +static A5_SYS_PCLK(sys_pwm_gh,               SYS_CLK_EN0_REG1, 8, 0);
>> +static A5_SYS_PCLK(sys_spicc_1,              SYS_CLK_EN0_REG1, 9, 0);
>> +static A5_SYS_PCLK(sys_spicc_0,              SYS_CLK_EN0_REG1, 10, 0);
>> +static A5_SYS_PCLK(sys_uart_a,               SYS_CLK_EN0_REG1, 11, 0);
>> +static A5_SYS_PCLK(sys_uart_b,               SYS_CLK_EN0_REG1, 12, 0);
>> +static A5_SYS_PCLK(sys_uart_c,               SYS_CLK_EN0_REG1, 13, 0);
>> +static A5_SYS_PCLK(sys_uart_d,               SYS_CLK_EN0_REG1, 14, 0);
>> +static A5_SYS_PCLK(sys_uart_e,               SYS_CLK_EN0_REG1, 15, 0);
>> +static A5_SYS_PCLK(sys_i2c_m_a,              SYS_CLK_EN0_REG1, 16, 0);
>> +static A5_SYS_PCLK(sys_i2c_m_b,              SYS_CLK_EN0_REG1, 17, 0);
>> +static A5_SYS_PCLK(sys_i2c_m_c,              SYS_CLK_EN0_REG1, 18, 0);
>> +static A5_SYS_PCLK(sys_i2c_m_d,              SYS_CLK_EN0_REG1, 19, 0);
>> +static A5_SYS_PCLK(sys_rtc,          SYS_CLK_EN0_REG1, 21, 0);
>> +
>> +static const struct clk_parent_data a5_axi_clk_parents = { .fw_name = "axiclk" };
>> +
>> +#define A5_AXI_CLK(_name, _reg, _bit, _flags) \
>> +     A5_PCLK(_name, _reg, _bit, &a5_axi_clk_parents, _flags)
>> +
>> +static A5_AXI_CLK(axi_audio_vad,     AXI_CLK_EN0, 0, 0);
>> +static A5_AXI_CLK(axi_audio_top,     AXI_CLK_EN0, 1, 0);
>> +static A5_AXI_CLK(axi_ramb,          AXI_CLK_EN0, 5, 0);
>> +static A5_AXI_CLK(axi_rama,          AXI_CLK_EN0, 6, 0);
>> +static A5_AXI_CLK(axi_nna,           AXI_CLK_EN0, 12, 0);
>> +
>> +/*
>> + * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO,
>> + * sec_top, USB, Audio) to access the AXI bus of the DDR.
>> + */
>> +static A5_AXI_CLK(axi_dev1_dmc,      AXI_CLK_EN0, 13, 0);
>> +
>> +/*
>> + * NOTE: axi_dev0_dmc provides the clock for the peripherals(ETH and SPICC)
>> + * to access the AXI bus of the DDR.
>> + */
>> +static A5_AXI_CLK(axi_dev0_dmc,      AXI_CLK_EN0, 14, 0);
>> +static A5_AXI_CLK(axi_dsp_dmc,               AXI_CLK_EN0, 15, 0);
>> +
>> +static struct clk_regmap a5_clk_12_24m_in = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLK12_24_CTRL,
>> +             .bit_idx = 11,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "clk_12_24m_in",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "xtal",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_clk_12_24m = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLK12_24_CTRL,
>> +             .shift = 10,
>> +             .width = 1,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "clk_12_24m",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_clk_12_24m_in.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_fclk_25m_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = CLK12_24_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_25m_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "fix",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_fclk_25m = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = CLK12_24_CTRL,
>> +             .bit_idx = 12,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_25m",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_fclk_25m_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +/*
>> + * Channel 4 5 8 9 10 11 13 14 15 16 18 are not connected.
>> + *
>> + * gp1 is designed for DSU (DynamIQ Shared Unit) alone. It cannot be changed
>> + * arbitrarily. gp1 is read-only in the kernel and is only open for debug
>> + * purposes.
>> + */
>> +static u32 a5_gen_parent_table[] = { 0, 1, 2, 3, 6, 7, 12, 17, 19, 20, 21, 22,
>> +                                 23, 24, 25, 26, 27, 28};
>> +
>> +static const struct clk_parent_data a5_gen_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .hw = &a5_rtc_clk.hw },
>> +     { .fw_name = "sysplldiv16" },
>> +     { .fw_name = "ddr" },
>> +     { .fw_name = "gp1" },
>> +     { .fw_name = "hifi" },
>> +     { .fw_name = "clkmsr" },
>> +     { .fw_name = "cpudiv16" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv5" },
>> +     { .fw_name = "fdiv7" },
>> +     { .fw_name = "mpll0" },
>> +     { .fw_name = "mpll1" },
>> +     { .fw_name = "mpll2" },
>> +     { .fw_name = "mpll3" }
>> +};
>> +
>> +static struct clk_regmap a5_gen_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = GEN_CLK_CTRL,
>> +             .mask = 0x1f,
>> +             .shift = 12,
>> +             .table = a5_gen_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gen_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = a5_gen_parent_data,
>> +             .num_parents = ARRAY_SIZE(a5_gen_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_gen_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = GEN_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 11,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gen_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_gen_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_gen = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = GEN_CLK_CTRL,
>> +             .bit_idx = 11,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "gen",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_gen_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +#define A5_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \
>> +     MESON_COMP_SEL(a5_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0)
>> +
>> +#define A5_COMP_DIV(_name, _reg, _shift, _width) \
>> +     MESON_COMP_DIV(a5_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
>> +
>> +#define A5_COMP_GATE(_name, _reg, _bit) \
>> +     MESON_COMP_GATE(a5_, _name, _reg, _bit, CLK_SET_RATE_PARENT)
>> +
>> +static const struct clk_parent_data a5_saradc_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "sysclk" }
>> +};
>> +
>> +static A5_COMP_SEL(saradc, SAR_CLK_CTRL0, 9, 0x3, a5_saradc_parent_data);
>> +static A5_COMP_DIV(saradc, SAR_CLK_CTRL0, 0, 8);
>> +static A5_COMP_GATE(saradc, SAR_CLK_CTRL0, 8);
>> +
>> +static const struct clk_parent_data a5_pwm_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .hw = &a5_rtc_clk.hw },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv3" }
>> +};
>> +
>> +static A5_COMP_SEL(pwm_a, PWM_CLK_AB_CTRL, 9, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_a, PWM_CLK_AB_CTRL, 0, 8);
>> +static A5_COMP_GATE(pwm_a, PWM_CLK_AB_CTRL, 8);
>> +
>> +static A5_COMP_SEL(pwm_b, PWM_CLK_AB_CTRL, 25, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_b, PWM_CLK_AB_CTRL, 16, 8);
>> +static A5_COMP_GATE(pwm_b, PWM_CLK_AB_CTRL, 24);
>> +
>> +static A5_COMP_SEL(pwm_c, PWM_CLK_CD_CTRL, 9, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_c, PWM_CLK_CD_CTRL, 0, 8);
>> +static A5_COMP_GATE(pwm_c, PWM_CLK_CD_CTRL, 8);
>> +
>> +static A5_COMP_SEL(pwm_d, PWM_CLK_CD_CTRL, 25, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_d, PWM_CLK_CD_CTRL, 16, 8);
>> +static A5_COMP_GATE(pwm_d, PWM_CLK_CD_CTRL, 24);
>> +
>> +static A5_COMP_SEL(pwm_e, PWM_CLK_EF_CTRL, 9, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_e, PWM_CLK_EF_CTRL, 0, 8);
>> +static A5_COMP_GATE(pwm_e, PWM_CLK_EF_CTRL, 8);
>> +
>> +static A5_COMP_SEL(pwm_f, PWM_CLK_EF_CTRL, 25, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_f, PWM_CLK_EF_CTRL, 16, 8);
>> +static A5_COMP_GATE(pwm_f, PWM_CLK_EF_CTRL, 24);
>> +
>> +static A5_COMP_SEL(pwm_g, PWM_CLK_GH_CTRL, 9, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_g, PWM_CLK_GH_CTRL, 0, 8);
>> +static A5_COMP_GATE(pwm_g, PWM_CLK_GH_CTRL, 8);
>> +
>> +static A5_COMP_SEL(pwm_h, PWM_CLK_GH_CTRL, 25, 0x3, a5_pwm_parent_data);
>> +static A5_COMP_DIV(pwm_h, PWM_CLK_GH_CTRL, 16, 8);
>> +static A5_COMP_GATE(pwm_h, PWM_CLK_GH_CTRL, 24);
>> +
>> +/*
>> + * NOTE: Channel 7 is gp1, because gp1 is designed for DSU, so spicc does not
>> + * support this source in the driver.
>> + */
>> +static const struct clk_parent_data a5_spicc_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "sysclk" },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "fdiv5" },
>> +     { .fw_name = "fdiv7" }
>> +};
>> +
>> +static A5_COMP_SEL(spicc_0, SPICC_CLK_CTRL, 7, 0x7, a5_spicc_parent_data);
>> +static A5_COMP_DIV(spicc_0, SPICC_CLK_CTRL, 0, 6);
>> +static A5_COMP_GATE(spicc_0, SPICC_CLK_CTRL, 6);
>> +
>> +static A5_COMP_SEL(spicc_1, SPICC_CLK_CTRL, 23, 0x7, a5_spicc_parent_data);
>> +static A5_COMP_DIV(spicc_1, SPICC_CLK_CTRL, 16, 6);
>> +static A5_COMP_GATE(spicc_1, SPICC_CLK_CTRL, 22);
>> +
>> +static const struct clk_parent_data a5_sd_emmc_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "hifi" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "mpll2" },
>> +     { .fw_name = "mpll3" },
>> +     { .fw_name = "gp0" }
>> +};
>> +
>> +static A5_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL, 9, 0x7, a5_sd_emmc_parent_data);
>> +static A5_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL, 0, 7);
>> +static A5_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL, 7);
>> +
>> +static A5_COMP_SEL(sd_emmc_c, NAND_CLK_CTRL, 9, 0x7, a5_sd_emmc_parent_data);
>> +static A5_COMP_DIV(sd_emmc_c, NAND_CLK_CTRL, 0, 7);
>> +static A5_COMP_GATE(sd_emmc_c, NAND_CLK_CTRL, 7);
>> +
>> +static struct clk_regmap a5_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 = "oscin",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_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 *[]) {
>> +                     &a5_ts_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_fixed_factor a5_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 = "fdiv2",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_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 *[]) {
>> +                     &a5_eth_125m_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_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_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "fdiv2",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_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 *[]) {
>> +                     &a5_eth_rmii_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +/* Channel 6 is gp1. */
>> +static u32 a5_dspa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};
> 
> Considering there is no rate propagation from mux below, is it really a
> problem to have gp1 in here ?
> 

gp1 is used to provide the clock for the DSU, and the dsu_clk changes 
dynamically along with cpu_clk (cpufreq support is required). Although 
we do not have good cpufreq support upstream at the moment, it is very 
likely (and almost inevitable) that it will be supported in the future.

If the clocks of other modules are switched to gp1, and cpufreq later 
adjusts the gp1 frequency again, those modules that depend on gp1 may 
behave abnormally. Therefore, gp1 may not be suitable to be exposed to 
the clock tree for general peripherals.

>> +
>> +static const struct clk_parent_data a5_dspa_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "rtc" },  /* rtc_pll */
>> +     { .fw_name = "hifi" },
>> +     { .fw_name = "fdiv4" },
>> +     { .hw = &a5_rtc_clk.hw }
>> +};
>> +
>> +static struct clk_regmap a5_dspa_0_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = DSPA_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 10,
>> +             .table = a5_dspa_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_0_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = a5_dspa_parent_data,
>> +             .num_parents = ARRAY_SIZE(a5_dspa_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_dspa_0_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = DSPA_CLK_CTRL0,
>> +             .shift = 0,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_0_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_dspa_0_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
> 
> Same comment as the t7 regarding naming and macro usage for the glitch
> free composite clocks. Please adjust accordingly.
> 

Ok, got it.

>> +
>> +static struct clk_regmap a5_dspa_0 = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = DSPA_CLK_CTRL0,
>> +             .bit_idx = 13,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_dspa_0_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_dspa_1_sel = {
>> +     .data = &(struct clk_regmap_mux_data) {
>> +             .offset = DSPA_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 26,
>> +             .table = a5_dspa_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_1_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = a5_dspa_parent_data,
>> +             .num_parents = ARRAY_SIZE(a5_dspa_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_dspa_1_div = {
>> +     .data = &(struct clk_regmap_div_data) {
>> +             .offset = DSPA_CLK_CTRL0,
>> +             .shift = 16,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_1_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_dspa_1_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_dspa_1 = {
>> +     .data = &(struct clk_regmap_gate_data) {
>> +             .offset = DSPA_CLK_CTRL0,
>> +             .bit_idx = 29,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa_1",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_dspa_1_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap a5_dspa = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = DSPA_CLK_CTRL0,
>> +             .mask = 0x1,
>> +             .shift = 15,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dspa",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &a5_dspa_0.hw,
>> +                     &a5_dspa_1.hw
>> +             },
>> +             .num_parents = 2,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +#define A5_COMP_SEL_WITH_TAB(_name, _reg, _shift, _mask, _pdata, _table) \
> 
> No, adjust your main macro.
> 

Do you mean to unify this into a single macro here? Like this:

#define A5_COMP_SEL(_name, _reg, _shift, _mask, _pdata, _table) \
    MESON_COMP_SEL(a5_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)

>> +     MESON_COMP_SEL(a5_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)
>> +
>> +/* Channel 6 is gp1. */
>> +static u32 a5_nna_parent_table[] = { 0, 1, 2, 3, 4, 5, 7};
>> +
>> +static const struct clk_parent_data a5_nna_parent_data[] = {
>> +     { .fw_name = "oscin" },
>> +     { .fw_name = "fdiv2p5" },
>> +     { .fw_name = "fdiv4" },
>> +     { .fw_name = "fdiv3" },
>> +     { .fw_name = "fdiv5" },
>> +     { .fw_name = "fdiv2" },
>> +     { .fw_name = "hifi" }
>> +};
>> +
>> +static A5_COMP_SEL_WITH_TAB(nna_core, NNA_CLK_CNTL, 9, 0x7,
>> +                         a5_nna_parent_data, a5_nna_parent_table);
>> +static A5_COMP_DIV(nna_core, NNA_CLK_CNTL, 0, 7);
>> +static A5_COMP_GATE(nna_core, NNA_CLK_CNTL, 8);
>> +
>> +static A5_COMP_SEL_WITH_TAB(nna_axi, NNA_CLK_CNTL, 25, 0x7,
>> +                         a5_nna_parent_data, a5_nna_parent_table);
>> +static A5_COMP_DIV(nna_axi, NNA_CLK_CNTL, 16, 7);
>> +static A5_COMP_GATE(nna_axi, NNA_CLK_CNTL, 24);
>> +
>> +static struct clk_hw *a5_peripherals_hw_clks[] = {
>> +     [CLKID_RTC_DUALDIV_CLKIN]       = &a5_rtc_dualdiv_clkin.hw,
>> +     [CLKID_RTC_DUALDIV]             = &a5_rtc_dualdiv.hw,
>> +     [CLKID_RTC_DUALDIV_SEL]         = &a5_rtc_dualdiv_sel.hw,
>> +     [CLKID_RTC_DUALDIV_CLKOUT]      = &a5_rtc_dualdiv_clkout.hw,
>> +     [CLKID_RTC_CLK]                 = &a5_rtc_clk.hw,
>> +     [CLKID_SYS_RESET_CTRL]          = &a5_sys_reset_ctrl.hw,
>> +     [CLKID_SYS_PWR_CTRL]            = &a5_sys_pwr_ctrl.hw,
>> +     [CLKID_SYS_PAD_CTRL]            = &a5_sys_pad_ctrl.hw,
>> +     [CLKID_SYS_CTRL]                = &a5_sys_ctrl.hw,
>> +     [CLKID_SYS_TS_PLL]              = &a5_sys_ts_pll.hw,
>> +     [CLKID_SYS_DEV_ARB]             = &a5_sys_dev_arb.hw,
>> +     [CLKID_SYS_MAILBOX]             = &a5_sys_mailbox.hw,
>> +     [CLKID_SYS_JTAG_CTRL]           = &a5_sys_jtag_ctrl.hw,
>> +     [CLKID_SYS_IR_CTRL]             = &a5_sys_ir_ctrl.hw,
>> +     [CLKID_SYS_MSR_CLK]             = &a5_sys_msr_clk.hw,
>> +     [CLKID_SYS_ROM]                 = &a5_sys_rom.hw,
>> +     [CLKID_SYS_CPU_ARB]             = &a5_sys_cpu_apb.hw,
>> +     [CLKID_SYS_RSA]                 = &a5_sys_rsa.hw,
>> +     [CLKID_SYS_SARADC]              = &a5_sys_saradc.hw,
>> +     [CLKID_SYS_STARTUP]             = &a5_sys_startup.hw,
>> +     [CLKID_SYS_SECURE]              = &a5_sys_secure.hw,
>> +     [CLKID_SYS_SPIFC]               = &a5_sys_spifc.hw,
>> +     [CLKID_SYS_DSPA]                = &a5_sys_dspa.hw,
>> +     [CLKID_SYS_NNA]                 = &a5_sys_nna.hw,
>> +     [CLKID_SYS_ETH_MAC]             = &a5_sys_eth_mac.hw,
>> +     [CLKID_SYS_RAMA]                = &a5_sys_rama.hw,
>> +     [CLKID_SYS_RAMB]                = &a5_sys_ramb.hw,
>> +     [CLKID_SYS_AUDIO_TOP]           = &a5_sys_audio_top.hw,
>> +     [CLKID_SYS_AUDIO_VAD]           = &a5_sys_audio_vad.hw,
>> +     [CLKID_SYS_USB]                 = &a5_sys_usb.hw,
>> +     [CLKID_SYS_SD_EMMC_A]           = &a5_sys_sd_emmc_a.hw,
>> +     [CLKID_SYS_SD_EMMC_C]           = &a5_sys_sd_emmc_c.hw,
>> +     [CLKID_SYS_PWM_AB]              = &a5_sys_pwm_ab.hw,
>> +     [CLKID_SYS_PWM_CD]              = &a5_sys_pwm_cd.hw,
>> +     [CLKID_SYS_PWM_EF]              = &a5_sys_pwm_ef.hw,
>> +     [CLKID_SYS_PWM_GH]              = &a5_sys_pwm_gh.hw,
>> +     [CLKID_SYS_SPICC_1]             = &a5_sys_spicc_1.hw,
>> +     [CLKID_SYS_SPICC_0]             = &a5_sys_spicc_0.hw,
>> +     [CLKID_SYS_UART_A]              = &a5_sys_uart_a.hw,
>> +     [CLKID_SYS_UART_B]              = &a5_sys_uart_b.hw,
>> +     [CLKID_SYS_UART_C]              = &a5_sys_uart_c.hw,
>> +     [CLKID_SYS_UART_D]              = &a5_sys_uart_d.hw,
>> +     [CLKID_SYS_UART_E]              = &a5_sys_uart_e.hw,
>> +     [CLKID_SYS_I2C_M_A]             = &a5_sys_i2c_m_a.hw,
>> +     [CLKID_SYS_I2C_M_B]             = &a5_sys_i2c_m_b.hw,
>> +     [CLKID_SYS_I2C_M_C]             = &a5_sys_i2c_m_c.hw,
>> +     [CLKID_SYS_I2C_M_D]             = &a5_sys_i2c_m_d.hw,
>> +     [CLKID_SYS_RTC]                 = &a5_sys_rtc.hw,
>> +     [CLKID_AXI_AUDIO_VAD]           = &a5_axi_audio_vad.hw,
>> +     [CLKID_AXI_AUDIO_TOP]           = &a5_axi_audio_top.hw,
>> +     [CLKID_AXI_RAMB]                = &a5_axi_ramb.hw,
>> +     [CLKID_AXI_RAMA]                = &a5_axi_rama.hw,
>> +     [CLKID_AXI_NNA]                 = &a5_axi_nna.hw,
>> +     [CLKID_AXI_DEV1_DMC]            = &a5_axi_dev1_dmc.hw,
>> +     [CLKID_AXI_DEV0_DMC]            = &a5_axi_dev0_dmc.hw,
>> +     [CLKID_AXI_DSP_DMC]             = &a5_axi_dsp_dmc.hw,
>> +     [CLKID_12_24M_IN]               = &a5_clk_12_24m_in.hw,
>> +     [CLKID_12M_24M]                 = &a5_clk_12_24m.hw,
>> +     [CLKID_FCLK_25M_DIV]            = &a5_fclk_25m_div.hw,
>> +     [CLKID_FCLK_25M]                = &a5_fclk_25m.hw,
>> +     [CLKID_GEN_SEL]                 = &a5_gen_sel.hw,
>> +     [CLKID_GEN_DIV]                 = &a5_gen_div.hw,
>> +     [CLKID_GEN]                     = &a5_gen.hw,
>> +     [CLKID_SARADC_SEL]              = &a5_saradc_sel.hw,
>> +     [CLKID_SARADC_DIV]              = &a5_saradc_div.hw,
>> +     [CLKID_SARADC]                  = &a5_saradc.hw,
>> +     [CLKID_PWM_A_SEL]               = &a5_pwm_a_sel.hw,
>> +     [CLKID_PWM_A_DIV]               = &a5_pwm_a_div.hw,
>> +     [CLKID_PWM_A]                   = &a5_pwm_a.hw,
>> +     [CLKID_PWM_B_SEL]               = &a5_pwm_b_sel.hw,
>> +     [CLKID_PWM_B_DIV]               = &a5_pwm_b_div.hw,
>> +     [CLKID_PWM_B]                   = &a5_pwm_b.hw,
>> +     [CLKID_PWM_C_SEL]               = &a5_pwm_c_sel.hw,
>> +     [CLKID_PWM_C_DIV]               = &a5_pwm_c_div.hw,
>> +     [CLKID_PWM_C]                   = &a5_pwm_c.hw,
>> +     [CLKID_PWM_D_SEL]               = &a5_pwm_d_sel.hw,
>> +     [CLKID_PWM_D_DIV]               = &a5_pwm_d_div.hw,
>> +     [CLKID_PWM_D]                   = &a5_pwm_d.hw,
>> +     [CLKID_PWM_E_SEL]               = &a5_pwm_e_sel.hw,
>> +     [CLKID_PWM_E_DIV]               = &a5_pwm_e_div.hw,
>> +     [CLKID_PWM_E]                   = &a5_pwm_e.hw,
>> +     [CLKID_PWM_F_SEL]               = &a5_pwm_f_sel.hw,
>> +     [CLKID_PWM_F_DIV]               = &a5_pwm_f_div.hw,
>> +     [CLKID_PWM_F]                   = &a5_pwm_f.hw,
>> +     [CLKID_PWM_G_SEL]               = &a5_pwm_g_sel.hw,
>> +     [CLKID_PWM_G_DIV]               = &a5_pwm_g_div.hw,
>> +     [CLKID_PWM_G]                   = &a5_pwm_g.hw,
>> +     [CLKID_PWM_H_SEL]               = &a5_pwm_h_sel.hw,
>> +     [CLKID_PWM_H_DIV]               = &a5_pwm_h_div.hw,
>> +     [CLKID_PWM_H]                   = &a5_pwm_h.hw,
>> +     [CLKID_SPICC_0_SEL]             = &a5_spicc_0_sel.hw,
>> +     [CLKID_SPICC_0_DIV]             = &a5_spicc_0_div.hw,
>> +     [CLKID_SPICC_0]                 = &a5_spicc_0.hw,
>> +     [CLKID_SPICC_1_SEL]             = &a5_spicc_1_sel.hw,
>> +     [CLKID_SPICC_1_DIV]             = &a5_spicc_1_div.hw,
>> +     [CLKID_SPICC_1]                 = &a5_spicc_1.hw,
>> +     [CLKID_SD_EMMC_A_SEL]           = &a5_sd_emmc_a_sel.hw,
>> +     [CLKID_SD_EMMC_A_DIV]           = &a5_sd_emmc_a_div.hw,
>> +     [CLKID_SD_EMMC_A]               = &a5_sd_emmc_a.hw,
>> +     [CLKID_SD_EMMC_C_SEL]           = &a5_sd_emmc_c_sel.hw,
>> +     [CLKID_SD_EMMC_C_DIV]           = &a5_sd_emmc_c_div.hw,
>> +     [CLKID_SD_EMMC_C]               = &a5_sd_emmc_c.hw,
>> +     [CLKID_TS_DIV]                  = &a5_ts_div.hw,
>> +     [CLKID_TS]                      = &a5_ts.hw,
>> +     [CLKID_ETH_125M_DIV]            = &a5_eth_125m_div.hw,
>> +     [CLKID_ETH_125M]                = &a5_eth_125m.hw,
>> +     [CLKID_ETH_RMII_DIV]            = &a5_eth_rmii_div.hw,
>> +     [CLKID_ETH_RMII]                = &a5_eth_rmii.hw,
>> +     [CLKID_DSPA_0_SEL]              = &a5_dspa_0_sel.hw,
>> +     [CLKID_DSPA_0_DIV]              = &a5_dspa_0_div.hw,
>> +     [CLKID_DSPA_0]                  = &a5_dspa_0.hw,
>> +     [CLKID_DSPA_1_SEL]              = &a5_dspa_1_sel.hw,
>> +     [CLKID_DSPA_1_DIV]              = &a5_dspa_1_div.hw,
>> +     [CLKID_DSPA_1]                  = &a5_dspa_1.hw,
>> +     [CLKID_DSPA]                    = &a5_dspa.hw,
>> +     [CLKID_NNA_CORE_SEL]            = &a5_nna_core_sel.hw,
>> +     [CLKID_NNA_CORE_DIV]            = &a5_nna_core_div.hw,
>> +     [CLKID_NNA_CORE]                = &a5_nna_core.hw,
>> +     [CLKID_NNA_AXI_SEL]             = &a5_nna_axi_sel.hw,
>> +     [CLKID_NNA_AXI_DIV]             = &a5_nna_axi_div.hw,
>> +     [CLKID_NNA_AXI]                 = &a5_nna_axi.hw,
>> +};
>> +
>> +static const struct meson_clkc_data a5_peripherals_clkc_data = {
>> +     .hw_clks = {
>> +             .hws = a5_peripherals_hw_clks,
>> +             .num = ARRAY_SIZE(a5_peripherals_hw_clks),
>> +     },
>> +};
>> +
>> +static const struct of_device_id a5_peripherals_clkc_match_table[] = {
>> +     {
>> +             .compatible = "amlogic,a5-peripherals-clkc",
>> +             .data = &a5_peripherals_clkc_data,
>> +     },
>> +     {}
>> +};
>> +MODULE_DEVICE_TABLE(of, a5_peripherals_clkc_match_table);
>> +
>> +static struct platform_driver a5_peripherals_clkc_driver = {
>> +     .probe = meson_clkc_mmio_probe,
>> +     .driver = {
>> +             .name = "a5-peripherals-clkc",
>> +             .of_match_table = a5_peripherals_clkc_match_table,
>> +     },
>> +};
>> +module_platform_driver(a5_peripherals_clkc_driver);
>> +
>> +MODULE_DESCRIPTION("Amlogic A5 Peripherals Clock Controller driver");
>> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_IMPORT_NS("CLK_MESON");
> 
> --
> Jerome



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

end of thread, other threads:[~2025-12-23 12:28 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-28  9:52 [PATCH v4 0/8] clk: amlogic: Add A5 SoC PLLs and Peripheral clock Chuan Liu via B4 Relay
2025-10-28  9:52 ` [PATCH v4 1/8] dt-bindings: clock: Add Amlogic A5 SCMI clock controller support Chuan Liu via B4 Relay
2025-12-23  8:59   ` Jerome Brunet
2025-12-23 11:56     ` Chuan Liu
2025-10-28  9:52 ` [PATCH v4 2/8] dt-bindings: clock: Add Amlogic A5 PLL clock controller Chuan Liu via B4 Relay
2025-10-28  9:52 ` [PATCH v4 3/8] dt-bindings: clock: Add Amlogic A5 peripherals " Chuan Liu via B4 Relay
2025-10-28  9:52 ` [PATCH v4 4/8] clk: amlogic: Add A5 PLL clock controller driver Chuan Liu via B4 Relay
2025-10-28  9:52 ` [PATCH v4 5/8] clk: amlogic: Add A5 clock peripherals " Chuan Liu via B4 Relay
2025-12-23  9:16   ` Jerome Brunet
2025-12-23 12:27     ` Chuan Liu
2025-10-28  9:52 ` [PATCH v4 6/8] arm64: dts: amlogic: A5: Add scmi-clk node Chuan Liu via B4 Relay
2025-10-28  9:52 ` [PATCH v4 7/8] arm64: dts: amlogic: A5: Add PLL controller node Chuan Liu via B4 Relay
2025-10-28  9:52 ` [PATCH v4 8/8] arm64: dts: amlogic: A5: Add peripheral clock " Chuan Liu via B4 Relay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).