devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 0/4] Add C3 SoC PLLs and Peripheral clock
@ 2023-10-10  6:29 Xianwei Zhao
  2023-10-10  6:29 ` [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings Xianwei Zhao
                   ` (3 more replies)
  0 siblings, 4 replies; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-10  6:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel
  Cc: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu, Xianwei Zhao

Add C3 SoC PLLs and Peripheral clock controller dt-bindings.
Add PLLs and Peripheral clock controller driver for C3 SOC.

V1 -> V2:
 1. Fix errors when check binding by using "make dt_binding_check"
 2. Delete macro definition
          
Xianwei Zhao (4):
  dt-bindings: clock: add Amlogic C3 PLL clock controller bindings
  dt-bindings: clock: add Amlogic C3 peripherals clock controller
    bindings
  clk: meson: c3: add support for the C3 SoC PLL clock
  clk: meson: c3: add c3 clock peripherals controller driver

 .../clock/amlogic,c3-peripherals-clkc.yaml    |   92 +
 .../bindings/clock/amlogic,c3-pll-clkc.yaml   |   59 +
 drivers/clk/meson/Kconfig                     |   25 +
 drivers/clk/meson/Makefile                    |    2 +
 drivers/clk/meson/c3-peripherals.c            | 3096 +++++++++++++++++
 drivers/clk/meson/c3-peripherals.h            |   48 +
 drivers/clk/meson/c3-pll.c                    |  808 +++++
 drivers/clk/meson/c3-pll.h                    |   35 +
 .../clock/amlogic,c3-peripherals-clkc.h       |  230 ++
 .../dt-bindings/clock/amlogic,c3-pll-clkc.h   |   42 +
 10 files changed, 4437 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
 create mode 100644 drivers/clk/meson/c3-peripherals.c
 create mode 100644 drivers/clk/meson/c3-peripherals.h
 create mode 100644 drivers/clk/meson/c3-pll.c
 create mode 100644 drivers/clk/meson/c3-pll.h
 create mode 100644 include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
 create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h


base-commit: 57b55c76aaf1ba50ecc6dcee5cd6843dc4d85239
-- 
2.37.1


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

* [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings
  2023-10-10  6:29 [PATCH V2 0/4] Add C3 SoC PLLs and Peripheral clock Xianwei Zhao
@ 2023-10-10  6:29 ` Xianwei Zhao
  2023-10-10  7:22   ` Rob Herring
  2023-10-10 13:21   ` Rob Herring
  2023-10-10  6:29 ` [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals " Xianwei Zhao
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-10  6:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel
  Cc: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu, Xianwei Zhao

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

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
V1 -> V2: Fix errors when check dtbinding use "make dt_binding_check"
---
 .../bindings/clock/amlogic,c3-pll-clkc.yaml   | 59 +++++++++++++++++++
 .../dt-bindings/clock/amlogic,c3-pll-clkc.h   | 42 +++++++++++++
 2 files changed, 101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
new file mode 100644
index 000000000000..a646992917b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,c3-pll-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic C3 serials PLL Clock Controller
+
+maintainers:
+  - Chuan Liu <chuan.liu@amlogic.com>
+
+properties:
+  compatible:
+    const: amlogic,c3-pll-clkc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    items:
+      - description: input pll_in
+      - description: input mclk_pll_in
+
+  clock-names:
+    minItems: 1
+    items:
+      - const: pll_in
+      - const: mclk_pll_in
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clkc_pll: clock-controller@8000 {
+          compatible = "amlogic,c3-pll-clkc";
+          reg = <0x0 0x8000 0x0 0x1a4>;
+          clocks = <&clkc_periphs CLKID_PLL_IN>,
+                   <&clkc_periphs CLKID_MCLK_PLL_IN>;
+          clock-names = "pll_in", "mclk_pll_in";
+          #clock-cells = <1>;
+        };
+    };
diff --git a/include/dt-bindings/clock/amlogic,c3-pll-clkc.h b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
new file mode 100644
index 000000000000..aa731e8fae29
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
+#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
+
+#define CLKID_FIXED_PLL_DCO			0
+#define CLKID_FIXED_PLL				1
+#define CLKID_FCLK_DIV40_DIV			2
+#define CLKID_FCLK_DIV40			3
+#define CLKID_FCLK_DIV2_DIV			4
+#define CLKID_FCLK_DIV2				5
+#define CLKID_FCLK_DIV2P5_DIV			6
+#define CLKID_FCLK_DIV2P5			7
+#define CLKID_FCLK_DIV3_DIV			8
+#define CLKID_FCLK_DIV3				9
+#define CLKID_FCLK_DIV4_DIV			10
+#define CLKID_FCLK_DIV4				11
+#define CLKID_FCLK_DIV5_DIV			12
+#define CLKID_FCLK_DIV5				13
+#define CLKID_FCLK_DIV7_DIV			14
+#define CLKID_FCLK_DIV7				15
+#define CLKID_GP0_PLL_DCO			16
+#define CLKID_GP0_PLL				17
+#define CLKID_HIFI_PLL_DCO			18
+#define CLKID_HIFI_PLL				19
+#define CLKID_MCLK_PLL_DCO			20
+#define CLKID_MCLK_PLL				21
+#define CLKID_MCLK_PLL_CLK			22
+#define CLKID_MCLK0_SEL				23
+#define CLKID_MCLK0_SEL_OUT			24
+#define CLKID_MCLK0_DIV				25
+#define CLKID_MCLK0				26
+#define CLKID_MCLK1_SEL				27
+#define CLKID_MCLK1_SEL_OUT			28
+#define CLKID_MCLK1_DIV				29
+#define CLKID_MCLK1				30
+
+#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H */

base-commit: 57b55c76aaf1ba50ecc6dcee5cd6843dc4d85239
-- 
2.37.1


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

* [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals clock controller bindings
  2023-10-10  6:29 [PATCH V2 0/4] Add C3 SoC PLLs and Peripheral clock Xianwei Zhao
  2023-10-10  6:29 ` [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings Xianwei Zhao
@ 2023-10-10  6:29 ` Xianwei Zhao
  2023-10-10  7:22   ` Rob Herring
  2023-10-10 13:25   ` Rob Herring
  2023-10-10  6:29 ` [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock Xianwei Zhao
  2023-10-10  6:29 ` [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver Xianwei Zhao
  3 siblings, 2 replies; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-10  6:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel
  Cc: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu, Xianwei Zhao

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

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
V1 -> V2: Fix errors when check binding use "make dt_binding_check"
---
 .../clock/amlogic,c3-peripherals-clkc.yaml    |  92 +++++++
 .../clock/amlogic,c3-peripherals-clkc.h       | 230 ++++++++++++++++++
 2 files changed, 322 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
new file mode 100644
index 000000000000..a165f447ec41
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,c3-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic C serials Peripherals Clock Controller
+
+maintainers:
+  - Chuan Liu <chuan.liu@amlogic.com>
+
+properties:
+  compatible:
+    const: amlogic,c3-peripherals-clkc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 9
+    items:
+      - description: input oscillator (usually at 24MHz)
+      - description: input fixed pll
+      - description: input fixed pll div2
+      - description: input fixed pll div2p5
+      - description: input fixed pll div3
+      - description: input fixed pll div4
+      - description: input fixed pll div5
+      - description: input fixed pll div7
+      - description: input gp0 pll
+      - description: input hifi pll
+
+  clock-names:
+    minItems: 9
+    items:
+      - const: xtal
+      - const: fixed_pll
+      - const: fclk_div2
+      - const: fclk_div2p5
+      - const: fclk_div3
+      - const: fclk_div4
+      - const: fclk_div5
+      - const: fclk_div7
+      - const: gp0_pll
+      - const: hifi_pll
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
+    apb {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        clkc_periphs: clock-controller@0 {
+          compatible = "amlogic,c3-peripherals-clkc";
+          reg = <0x0 0x0 0x0 0x49c>;
+          #clock-cells = <1>;
+          clocks = <&xtal>,
+                   <&clkc_pll CLKID_FIXED_PLL>,
+                   <&clkc_pll CLKID_FCLK_DIV2>,
+                   <&clkc_pll CLKID_FCLK_DIV2P5>,
+                   <&clkc_pll CLKID_FCLK_DIV3>,
+                   <&clkc_pll CLKID_FCLK_DIV4>,
+                   <&clkc_pll CLKID_FCLK_DIV5>,
+                   <&clkc_pll CLKID_FCLK_DIV7>,
+                   <&clkc_pll CLKID_GP0_PLL>,
+                   <&clkc_pll CLKID_HIFI_PLL>;
+          clock-names = "xtal",
+                        "fixed_pll",
+                        "fclk_div2",
+                        "fclk_div2p5",
+                        "fclk_div3",
+                        "fclk_div4",
+                        "fclk_div5",
+                        "fclk_div7",
+                        "gp0_pll",
+                        "hifi_pll";
+        };
+    };
diff --git a/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
new file mode 100644
index 000000000000..82f9bf683ea0
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
@@ -0,0 +1,230 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
+#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
+
+#define CLKID_PLL_IN				0
+#define CLKID_MCLK_PLL_IN			1
+#define CLKID_RTC_XTAL_CLKIN			2
+#define CLKID_RTC_32K_DIV			3
+#define CLKID_RTC_32K_MUX			4
+#define CLKID_RTC_32K				5
+#define CLKID_RTC_CLK				6
+#define CLKID_SYS_A_SEL				7
+#define CLKID_SYS_A_DIV				8
+#define CLKID_SYS_A				9
+#define CLKID_SYS_B_SEL				10
+#define CLKID_SYS_B_DIV				11
+#define CLKID_SYS_B				12
+#define CLKID_SYS_CLK				13
+#define CLKID_AXI_A_SEL				14
+#define CLKID_AXI_A_DIV				15
+#define CLKID_AXI_A				16
+#define CLKID_AXI_B_SEL				17
+#define CLKID_AXI_B_DIV				18
+#define CLKID_AXI_B				19
+#define CLKID_AXI_CLK				20
+#define CLKID_SYS_RESET_CTRL			21
+#define CLKID_SYS_PWR_CTRL			22
+#define CLKID_SYS_PAD_CTRL			23
+#define CLKID_SYS_CTRL				24
+#define CLKID_SYS_TS_PLL			25
+#define CLKID_SYS_DEV_ARB			26
+#define CLKID_SYS_MMC_PCLK			27
+#define CLKID_SYS_CAPU				28
+#define CLKID_SYS_CPU_CTRL			29
+#define CLKID_SYS_JTAG_CTRL			30
+#define CLKID_SYS_IR_CTRL			31
+#define CLKID_SYS_IRQ_CTRL			32
+#define CLKID_SYS_MSR_CLK			33
+#define CLKID_SYS_ROM				34
+#define CLKID_SYS_UART_F			35
+#define CLKID_SYS_CPU_ARB			36
+#define CLKID_SYS_RSA				37
+#define CLKID_SYS_SAR_ADC			38
+#define CLKID_SYS_STARTUP			39
+#define CLKID_SYS_SECURE			40
+#define CLKID_SYS_SPIFC				41
+#define CLKID_SYS_NNA				42
+#define CLKID_SYS_ETH_MAC			43
+#define CLKID_SYS_GIC				44
+#define CLKID_SYS_RAMA				45
+#define CLKID_SYS_BIG_NIC			46
+#define CLKID_SYS_RAMB				47
+#define CLKID_SYS_AUDIO_PCLK			48
+#define CLKID_SYS_PWM_KL			49
+#define CLKID_SYS_PWM_IJ			50
+#define CLKID_SYS_USB				51
+#define CLKID_SYS_SD_EMMC_A			52
+#define CLKID_SYS_SD_EMMC_C			53
+#define CLKID_SYS_PWM_AB			54
+#define CLKID_SYS_PWM_CD			55
+#define CLKID_SYS_PWM_EF			56
+#define CLKID_SYS_PWM_GH			57
+#define CLKID_SYS_SPICC_1			58
+#define CLKID_SYS_SPICC_0			59
+#define CLKID_SYS_UART_A			60
+#define CLKID_SYS_UART_B			61
+#define CLKID_SYS_UART_C			62
+#define CLKID_SYS_UART_D			63
+#define CLKID_SYS_UART_E			64
+#define CLKID_SYS_I2C_M_A			65
+#define CLKID_SYS_I2C_M_B			66
+#define CLKID_SYS_I2C_M_C			67
+#define CLKID_SYS_I2C_M_D			68
+#define CLKID_SYS_I2S_S_A			69
+#define CLKID_SYS_RTC				70
+#define CLKID_SYS_GE2D				71
+#define CLKID_SYS_ISP				72
+#define CLKID_SYS_GPV_ISP_NIC			73
+#define CLKID_SYS_GPV_CVE_NIC			74
+#define CLKID_SYS_MIPI_DSI_HOST			75
+#define CLKID_SYS_MIPI_DSI_PHY			76
+#define CLKID_SYS_ETH_PHY			77
+#define CLKID_SYS_ACODEC			78
+#define CLKID_SYS_DWAP				79
+#define CLKID_SYS_DOS				80
+#define CLKID_SYS_CVE				81
+#define CLKID_SYS_VOUT				82
+#define CLKID_SYS_VC9000E			83
+#define CLKID_SYS_PWM_MN			84
+#define CLKID_SYS_SD_EMMC_B			85
+#define CLKID_AXI_SYS_NIC			86
+#define CLKID_AXI_ISP_NIC			87
+#define CLKID_AXI_CVE_NIC			88
+#define CLKID_AXI_RAMB				89
+#define CLKID_AXI_RAMA				90
+#define CLKID_AXI_CPU_DMC			91
+#define CLKID_AXI_NIC				92
+#define CLKID_AXI_DMA				93
+#define CLKID_AXI_MUX_NIC			94
+#define CLKID_AXI_CAPU				95
+#define CLKID_AXI_CVE				96
+#define CLKID_AXI_DEV1_DMC			97
+#define CLKID_AXI_DEV0_DMC			98
+#define CLKID_AXI_DSP_DMC			99
+#define CLKID_12_24M_IN				100
+#define CLKID_12M_24M				101
+#define CLKID_FCLK_25M_DIV			102
+#define CLKID_FCLK_25M				103
+#define CLKID_GEN_SEL				104
+#define CLKID_GEN_DIV				105
+#define CLKID_GEN				106
+#define CLKID_SARADC_SEL			107
+#define CLKID_SARADC_DIV			108
+#define CLKID_SARADC				109
+#define CLKID_PWM_A_SEL				110
+#define CLKID_PWM_A_DIV				111
+#define CLKID_PWM_A				112
+#define CLKID_PWM_B_SEL				113
+#define CLKID_PWM_B_DIV				114
+#define CLKID_PWM_B				115
+#define CLKID_PWM_C_SEL				116
+#define CLKID_PWM_C_DIV				117
+#define CLKID_PWM_C				118
+#define CLKID_PWM_D_SEL				119
+#define CLKID_PWM_D_DIV				120
+#define CLKID_PWM_D				121
+#define CLKID_PWM_E_SEL				122
+#define CLKID_PWM_E_DIV				123
+#define CLKID_PWM_E				124
+#define CLKID_PWM_F_SEL				125
+#define CLKID_PWM_F_DIV				126
+#define CLKID_PWM_F				127
+#define CLKID_PWM_G_SEL				128
+#define CLKID_PWM_G_DIV				129
+#define CLKID_PWM_G				130
+#define CLKID_PWM_H_SEL				131
+#define CLKID_PWM_H_DIV				132
+#define CLKID_PWM_H				133
+#define CLKID_PWM_I_SEL				134
+#define CLKID_PWM_I_DIV				135
+#define CLKID_PWM_I				136
+#define CLKID_PWM_J_SEL				137
+#define CLKID_PWM_J_DIV				138
+#define CLKID_PWM_J				139
+#define CLKID_PWM_K_SEL				140
+#define CLKID_PWM_K_DIV				141
+#define CLKID_PWM_K				142
+#define CLKID_PWM_L_SEL				143
+#define CLKID_PWM_L_DIV				144
+#define CLKID_PWM_L				145
+#define CLKID_PWM_M_SEL				146
+#define CLKID_PWM_M_DIV				147
+#define CLKID_PWM_M				148
+#define CLKID_PWM_N_SEL				149
+#define CLKID_PWM_N_DIV				150
+#define CLKID_PWM_N				151
+#define CLKID_SPICC_A_SEL			152
+#define CLKID_SPICC_A_DIV			153
+#define CLKID_SPICC_A				154
+#define CLKID_SPICC_B_SEL			155
+#define CLKID_SPICC_B_DIV			156
+#define CLKID_SPICC_B				157
+#define CLKID_SPIFC_SEL				158
+#define CLKID_SPIFC_DIV				159
+#define CLKID_SPIFC				160
+#define CLKID_SD_EMMC_A_SEL			161
+#define CLKID_SD_EMMC_A_DIV			162
+#define CLKID_SD_EMMC_A				163
+#define CLKID_SD_EMMC_B_SEL			164
+#define CLKID_SD_EMMC_B_DIV			165
+#define CLKID_SD_EMMC_B				166
+#define CLKID_SD_EMMC_C_SEL			167
+#define CLKID_SD_EMMC_C_DIV			168
+#define CLKID_SD_EMMC_C				169
+#define CLKID_TS_DIV				170
+#define CLKID_TS				171
+#define CLKID_ETH_125M_DIV			172
+#define CLKID_ETH_125M				173
+#define CLKID_ETH_RMII_DIV			174
+#define CLKID_ETH_RMII				175
+#define CLKID_MIPI_DSI_MEAS_SEL			176
+#define CLKID_MIPI_DSI_MEAS_DIV			177
+#define CLKID_MIPI_DSI_MEAS			178
+#define CLKID_DSI_PHY_SEL			179
+#define CLKID_DSI_PHY_DIV			180
+#define CLKID_DSI_PHY				181
+#define CLKID_VOUT_MCLK_SEL			182
+#define CLKID_VOUT_MCLK_DIV			183
+#define CLKID_VOUT_MCLK				184
+#define CLKID_VOUT_ENC_SEL			185
+#define CLKID_VOUT_ENC_DIV			186
+#define CLKID_VOUT_ENC				187
+#define CLKID_HCODEC_0_SEL			188
+#define CLKID_HCODEC_0_DIV			189
+#define CLKID_HCODEC_0				190
+#define CLKID_HCODEC_1_SEL			191
+#define CLKID_HCODEC_1_DIV			192
+#define CLKID_HCODEC_1				193
+#define CLKID_HCODEC				194
+#define CLKID_VC9000E_ACLK_SEL			195
+#define CLKID_VC9000E_ACLK_DIV			196
+#define CLKID_VC9000E_ACLK			197
+#define CLKID_VC9000E_CORE_SEL			198
+#define CLKID_VC9000E_CORE_DIV			199
+#define CLKID_VC9000E_CORE			200
+#define CLKID_CSI_PHY0_SEL			201
+#define CLKID_CSI_PHY0_DIV			202
+#define CLKID_CSI_PHY0				203
+#define CLKID_DEWARPA_SEL			204
+#define CLKID_DEWARPA_DIV			205
+#define CLKID_DEWARPA				206
+#define CLKID_ISP0_SEL				207
+#define CLKID_ISP0_DIV				208
+#define CLKID_ISP0				209
+#define CLKID_NNA_CORE_SEL			210
+#define CLKID_NNA_CORE_DIV			211
+#define CLKID_NNA_CORE				212
+#define CLKID_GE2D_SEL				213
+#define CLKID_GE2D_DIV				214
+#define CLKID_GE2D				215
+#define CLKID_VAPB_SEL				216
+#define CLKID_VAPB_DIV				217
+#define CLKID_VAPB				218
+
+#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H */
-- 
2.37.1


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

* [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock
  2023-10-10  6:29 [PATCH V2 0/4] Add C3 SoC PLLs and Peripheral clock Xianwei Zhao
  2023-10-10  6:29 ` [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings Xianwei Zhao
  2023-10-10  6:29 ` [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals " Xianwei Zhao
@ 2023-10-10  6:29 ` Xianwei Zhao
  2023-10-13  7:49   ` Jerome Brunet
  2023-10-10  6:29 ` [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver Xianwei Zhao
  3 siblings, 1 reply; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-10  6:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel
  Cc: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu, Xianwei Zhao

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

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
V1 -> V2: Delete macro definition.
---
 drivers/clk/meson/Kconfig  |  12 +
 drivers/clk/meson/Makefile |   1 +
 drivers/clk/meson/c3-pll.c | 808 +++++++++++++++++++++++++++++++++++++
 drivers/clk/meson/c3-pll.h |  35 ++
 4 files changed, 856 insertions(+)
 create mode 100644 drivers/clk/meson/c3-pll.c
 create mode 100644 drivers/clk/meson/c3-pll.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index c5303e4c1604..76be4bbd2afb 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -128,6 +128,18 @@ config COMMON_CLK_A1_PERIPHERALS
 	  device, A1 SoC Family. Say Y if you want A1 Peripherals clock
 	  controller to work.
 
+config COMMON_CLK_C3_PLL
+	tristate "Amlogic C3 PLL clock controller"
+	default y
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_PLL
+	select COMMON_CLK_MESON_CLKC_UTILS
+	help
+	  Support for the PLL clock controller on Amlogic C302X and C308L devices,
+	  AKA c3. Amlogic C302X and C308L devices include AW402, AW409 and AW419.
+	  Say Y if you want the board to work, because PLLs are the parent of most
+	  peripherals.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 9ee4b954c896..4420af628b31 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_C3_PLL) += c3-pll.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c
new file mode 100644
index 000000000000..97619bc7ab79
--- /dev/null
+++ b/drivers/clk/meson/c3-pll.c
@@ -0,0 +1,808 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Amlogic C3 PLL Controller Driver
+ *
+ * Copyright (c) 2023 Amlogic, inc.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "c3-pll.h"
+#include "meson-clkc-utils.h"
+#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
+
+static const struct clk_parent_data pll_dco_parent = {
+	.fw_name = "pll_in",
+};
+
+static const struct clk_parent_data mclk_pll_dco_parent = {
+	.fw_name = "mclk_pll_in",
+};
+
+static struct clk_regmap fixed_pll_dco = {
+	.data = &(struct meson_clk_pll_data){
+		.en = {
+			.reg_off = ANACTRL_FIXPLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = ANACTRL_FIXPLL_CTRL0,
+			.shift   = 0,
+			.width   = 8,
+		},
+		.n = {
+			.reg_off = ANACTRL_FIXPLL_CTRL0,
+			.shift   = 16,
+			.width   = 5,
+		},
+		.l = {
+			.reg_off = ANACTRL_FIXPLL_CTRL0,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = ANACTRL_FIXPLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fixed_pll_dco",
+		.ops = &meson_clk_pll_ro_ops,
+		.parent_data = &pll_dco_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fixed_pll = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ANACTRL_FIXPLL_CTRL0,
+		.shift = 12,
+		.width = 3,
+		.flags = CLK_DIVIDER_POWER_OF_TWO,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "fixed_pll",
+		.ops = &clk_regmap_divider_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll_dco.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor fclk_div40_div = {
+	.mult = 1,
+	.div = 40,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div40_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div40 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL4,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_div40",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div40_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor fclk_div2_div = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL4,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_div2",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor fclk_div2p5_div = {
+	.mult = 2,
+	.div = 5,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div2p5_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div2p5 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL4,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_div2p5",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div2p5_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor fclk_div3_div = {
+	.mult = 1,
+	.div = 3,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div3_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div3 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL4,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_div3",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div3_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor fclk_div4_div = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div4_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div4 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL4,
+		.bit_idx = 21,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_div4",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div4_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor fclk_div5_div = {
+	.mult = 1,
+	.div = 5,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div5_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div5 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL4,
+		.bit_idx = 22,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_div5",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div5_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_fixed_factor fclk_div7_div = {
+	.mult = 1,
+	.div = 7,
+	.hw.init = &(struct clk_init_data){
+		.name = "fclk_div7_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fixed_pll.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap fclk_div7 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_FIXPLL_CTRL4,
+		.bit_idx = 23,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "fclk_div7",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&fclk_div7_div.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct reg_sequence c3_gp0_init_regs[] = {
+	{ .reg = ANACTRL_GP0PLL_CTRL1,	.def = 0x0 },
+	{ .reg = ANACTRL_GP0PLL_CTRL2,	.def = 0x0 },
+	{ .reg = ANACTRL_GP0PLL_CTRL3,	.def = 0x48681c00 },
+	{ .reg = ANACTRL_GP0PLL_CTRL4,  .def = 0x88770290 },
+	{ .reg = ANACTRL_GP0PLL_CTRL5,  .def = 0x3927200a },
+	{ .reg = ANACTRL_GP0PLL_CTRL6,	.def = 0x56540000, .delay_us = 10 },
+	{ .reg = ANACTRL_GP0PLL_CTRL0,	.def = 0x080304fa },
+	{ .reg = ANACTRL_GP0PLL_CTRL0,	.def = 0x380304fa, .delay_us = 10 },
+	{ .reg = ANACTRL_GP0PLL_CTRL0,	.def = 0X180304fa }
+};
+
+static const struct pll_params_table c3_gp0_pll_params_table[] = {
+	PLL_PARAMS(150, 1), /* DCO = 3600M */
+	PLL_PARAMS(130, 1), /* DCO = 3120M */
+	PLL_PARAMS(192, 1), /* DCO = 4608M */
+	PLL_PARAMS(125, 1), /* DCO = 3000M */
+	{ /* sentinel */  }
+};
+
+/* The maximum frequency divider supports is 32, not 128(2^7) */
+static const struct clk_div_table c3_gp0_pll_od_table[] = {
+	{ 0,  1 },
+	{ 1,  2 },
+	{ 2,  4 },
+	{ 3,  8 },
+	{ 4, 16 },
+	{ 5, 32 },
+	{ /* sentinel */ }
+};
+
+static struct clk_regmap gp0_pll_dco = {
+	.data = &(struct meson_clk_pll_data){
+		.en = {
+			.reg_off = ANACTRL_GP0PLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = ANACTRL_GP0PLL_CTRL0,
+			.shift   = 0,
+			.width   = 9,
+		},
+		.frac = {
+			.reg_off = ANACTRL_GP0PLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.n = {
+			.reg_off = ANACTRL_GP0PLL_CTRL0,
+			.shift   = 10,
+			.width   = 5,
+		},
+		.l = {
+			.reg_off = ANACTRL_GP0PLL_CTRL0,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = ANACTRL_GP0PLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.table = c3_gp0_pll_params_table,
+		.init_regs = c3_gp0_init_regs,
+		.init_count = ARRAY_SIZE(c3_gp0_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gp0_pll_dco",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &pll_dco_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gp0_pll = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ANACTRL_GP0PLL_CTRL0,
+		.shift = 16,
+		.width = 3,
+		.table = c3_gp0_pll_od_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gp0_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gp0_pll_dco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence c3_hifi_init_regs[] = {
+	{ .reg = ANACTRL_HIFIPLL_CTRL0,	.def = 0x08010496 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL0,	.def = 0x38010496 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL1,	.def = 0x0000ce40 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL2,	.def = 0x00000000 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL3,	.def = 0x6a285c00 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
+	{ .reg = ANACTRL_HIFIPLL_CTRL6,	.def = 0x56540000, .delay_us = 50 },
+	{ .reg = ANACTRL_HIFIPLL_CTRL0,	.def = 0x18010496, .delay_us = 20 },
+};
+
+static const struct pll_params_table c3_hifi_pll_params_table[] = {
+	PLL_PARAMS(150, 1), /* DCO = 3600M */
+	PLL_PARAMS(130, 1), /* DCO = 3120M */
+	PLL_PARAMS(192, 1), /* DCO = 4608M */
+	PLL_PARAMS(125, 1), /* DCO = 3000M */
+	{ /* sentinel */  }
+};
+
+static struct clk_regmap hifi_pll_dco = {
+	.data = &(struct meson_clk_pll_data){
+		.en = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 0,
+			.width   = 8,
+		},
+		.frac = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL1,
+			.shift   = 0,
+			.width   = 19,
+		},
+		.n = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 10,
+			.width   = 5,
+		},
+		.l = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = ANACTRL_HIFIPLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.table = c3_hifi_pll_params_table,
+		.init_regs = c3_hifi_init_regs,
+		.init_count = ARRAY_SIZE(c3_hifi_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hifi_pll_dco",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &pll_dco_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap hifi_pll = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ANACTRL_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 *[]) {
+			&hifi_pll_dco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct reg_sequence c3_mclk_init_regs[] = {
+	{ .reg = ANACTRL_MPLL_CTRL0,	.def = 0x20011063 },
+	{ .reg = ANACTRL_MPLL_CTRL0,	.def = 0x30011063 },
+	{ .reg = ANACTRL_MPLL_CTRL1,	.def = 0x1420500f },
+	{ .reg = ANACTRL_MPLL_CTRL2,	.def = 0x00023041 },
+	{ .reg = ANACTRL_MPLL_CTRL3,	.def = 0x18180000 },
+	{ .reg = ANACTRL_MPLL_CTRL0,	.def = 0x10011063 },
+	{ .reg = ANACTRL_MPLL_CTRL2,	.def = 0x00023001 }
+};
+
+static const struct pll_params_table c3_mclk_pll_params_table[] = {
+	PLL_PARAMS(99, 1), /* VCO = 2376M */
+	{ /* sentinel */  }
+};
+
+static const struct clk_div_table c3_mpll_od_table[] = {
+	{ 0,  1 },
+	{ 1,  2 },
+	{ 2,  4 },
+	{ 3,  8 },
+	{ 4, 16 },
+	{ /* sentinel */ }
+};
+
+static struct clk_regmap mclk_pll_dco = {
+	.data = &(struct meson_clk_pll_data){
+		.en = {
+			.reg_off = ANACTRL_MPLL_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.m = {
+			.reg_off = ANACTRL_MPLL_CTRL0,
+			.shift   = 0,
+			.width   = 9,
+		},
+		.n = {
+			.reg_off = ANACTRL_MPLL_CTRL0,
+			.shift   = 10,
+			.width   = 5,
+		},
+		.l = {
+			.reg_off = ANACTRL_MPLL_CTRL0,
+			.shift   = 31,
+			.width   = 1,
+		},
+		.rst = {
+			.reg_off = ANACTRL_MPLL_CTRL0,
+			.shift   = 29,
+			.width   = 1,
+		},
+		.table = c3_mclk_pll_params_table,
+		.init_regs = c3_mclk_init_regs,
+		.init_count = ARRAY_SIZE(c3_mclk_init_regs),
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mclk_pll_dco",
+		.ops = &meson_clk_pll_ops,
+		.parent_data = &mclk_pll_dco_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap mclk_pll = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ANACTRL_MPLL_CTRL0,
+		.shift = 12,
+		.width = 3,
+		.table = c3_mpll_od_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mclk_pll",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk_pll_dco.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap mclk_pll_clk = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.shift = 16,
+		.width = 5,
+		.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mclk_pll_clk",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk_pll.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data mclk_parent[] = {
+	{ .hw = &mclk_pll_clk.hw },
+	{ .fw_name = "mclk_pll_in" },
+	{ .hw = &fclk_div40.hw }
+};
+
+static struct clk_regmap mclk0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.mask = 0x3,
+		.shift = 4,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mclk0_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = mclk_parent,
+		.num_parents = ARRAY_SIZE(mclk_parent),
+	},
+};
+
+static struct clk_regmap mclk0_sel_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.bit_idx = 1,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "mclk0_sel_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap mclk0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.shift = 2,
+		.width = 1,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mclk0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk0_sel_out.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap mclk0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.bit_idx = 0,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "mclk0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap mclk1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.mask = 0x3,
+		.shift = 12,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mclk1_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = mclk_parent,
+		.num_parents = ARRAY_SIZE(mclk_parent),
+	},
+};
+
+static struct clk_regmap mclk1_sel_out = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.bit_idx = 9,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "mclk1_sel_out",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk1_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap mclk1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.shift = 10,
+		.width = 1,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mclk1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk1_sel_out.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap mclk1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ANACTRL_MPLL_CTRL4,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "mclk1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mclk1_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_hw *c3_pll_hw_clks[] = {
+	[CLKID_FIXED_PLL_DCO]	= &fixed_pll_dco.hw,
+	[CLKID_FIXED_PLL]	= &fixed_pll.hw,
+	[CLKID_FCLK_DIV40_DIV]	= &fclk_div40_div.hw,
+	[CLKID_FCLK_DIV40]	= &fclk_div40.hw,
+	[CLKID_FCLK_DIV2_DIV]	= &fclk_div2_div.hw,
+	[CLKID_FCLK_DIV2]	= &fclk_div2.hw,
+	[CLKID_FCLK_DIV2P5_DIV]	= &fclk_div2p5_div.hw,
+	[CLKID_FCLK_DIV2P5]	= &fclk_div2p5.hw,
+	[CLKID_FCLK_DIV3_DIV]	= &fclk_div3_div.hw,
+	[CLKID_FCLK_DIV3]	= &fclk_div3.hw,
+	[CLKID_FCLK_DIV4_DIV]	= &fclk_div4_div.hw,
+	[CLKID_FCLK_DIV4]	= &fclk_div4.hw,
+	[CLKID_FCLK_DIV5_DIV]	= &fclk_div5_div.hw,
+	[CLKID_FCLK_DIV5]	= &fclk_div5.hw,
+	[CLKID_FCLK_DIV7_DIV]	= &fclk_div7_div.hw,
+	[CLKID_FCLK_DIV7]	= &fclk_div7.hw,
+	[CLKID_GP0_PLL_DCO]	= &gp0_pll_dco.hw,
+	[CLKID_GP0_PLL]		= &gp0_pll.hw,
+	[CLKID_HIFI_PLL_DCO]	= &hifi_pll_dco.hw,
+	[CLKID_HIFI_PLL]	= &hifi_pll.hw,
+	[CLKID_MCLK_PLL_DCO]	= &mclk_pll_dco.hw,
+	[CLKID_MCLK_PLL]	= &mclk_pll.hw,
+	[CLKID_MCLK_PLL_CLK]	= &mclk_pll_clk.hw,
+	[CLKID_MCLK0_SEL]	= &mclk0_sel.hw,
+	[CLKID_MCLK0_SEL_OUT]	= &mclk0_sel_out.hw,
+	[CLKID_MCLK0_DIV]	= &mclk0_div.hw,
+	[CLKID_MCLK0]		= &mclk0.hw,
+	[CLKID_MCLK1_SEL]	= &mclk1_sel.hw,
+	[CLKID_MCLK1_SEL_OUT]	= &mclk1_sel_out.hw,
+	[CLKID_MCLK1_DIV]	= &mclk1_div.hw,
+	[CLKID_MCLK1]		= &mclk1.hw
+};
+
+/* Convenience table to populate regmap in .probe */
+static struct clk_regmap *const c3_pll_clk_regmaps[] = {
+	&fixed_pll_dco,
+	&fixed_pll,
+	&fclk_div40,
+	&fclk_div2,
+	&fclk_div2p5,
+	&fclk_div3,
+	&fclk_div4,
+	&fclk_div5,
+	&fclk_div7,
+	&gp0_pll_dco,
+	&gp0_pll,
+	&hifi_pll_dco,
+	&hifi_pll,
+	&mclk_pll_dco,
+	&mclk_pll,
+	&mclk_pll_clk,
+	&mclk0_sel,
+	&mclk0_sel_out,
+	&mclk0_div,
+	&mclk0,
+	&mclk1_sel,
+	&mclk1_sel_out,
+	&mclk1_div,
+	&mclk1,
+};
+
+static struct regmap_config clkc_regmap_config = {
+	.reg_bits       = 32,
+	.val_bits       = 32,
+	.reg_stride     = 4,
+};
+
+static struct meson_clk_hw_data c3_pll_clks = {
+	.hws = c3_pll_hw_clks,
+	.num = ARRAY_SIZE(c3_pll_hw_clks),
+};
+
+static int aml_c3_pll_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct regmap *regmap;
+	void __iomem *base;
+	int clkid, ret, i;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(c3_pll_clk_regmaps); i++)
+		c3_pll_clk_regmaps[i]->map = regmap;
+
+	for (clkid = 0; clkid < c3_pll_clks.num; clkid++) {
+		/* array might be sparse */
+		if (!c3_pll_clks.hws[clkid])
+			continue;
+
+		ret = devm_clk_hw_register(dev, c3_pll_clks.hws[clkid]);
+		if (ret) {
+			dev_err(dev, "Clock registration failed\n");
+			return ret;
+		}
+	}
+
+	return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
+					   &c3_pll_clks);
+}
+
+static const struct of_device_id c3_pll_clkc_match_table[] = {
+	{
+		.compatible = "amlogic,c3-pll-clkc",
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, c3_pll_clkc_match_table);
+
+static struct platform_driver c3_pll_driver = {
+	.probe		= aml_c3_pll_probe,
+	.driver		= {
+		.name	= "c3-pll-clkc",
+		.of_match_table = c3_pll_clkc_match_table,
+	},
+};
+
+module_platform_driver(c3_pll_driver);
+MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/c3-pll.h b/drivers/clk/meson/c3-pll.h
new file mode 100644
index 000000000000..92a08196a46f
--- /dev/null
+++ b/drivers/clk/meson/c3-pll.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2023 Amlogic, inc.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#ifndef __AML_C3_PLL_H__
+#define __AML_C3_PLL_H__
+
+#define ANACTRL_FIXPLL_CTRL0			0x0040
+#define ANACTRL_FIXPLL_CTRL4			0x0050
+#define ANACTRL_GP0PLL_CTRL0			0x0080
+#define ANACTRL_GP0PLL_CTRL1			0x0084
+#define ANACTRL_GP0PLL_CTRL2			0x0088
+#define ANACTRL_GP0PLL_CTRL3			0x008c
+#define ANACTRL_GP0PLL_CTRL4			0x0090
+#define ANACTRL_GP0PLL_CTRL5			0x0094
+#define ANACTRL_GP0PLL_CTRL6			0x0098
+#define ANACTRL_GP0PLL_STS			0x009c
+#define ANACTRL_HIFIPLL_CTRL0			0x0100
+#define ANACTRL_HIFIPLL_CTRL1			0x0104
+#define ANACTRL_HIFIPLL_CTRL2			0x0108
+#define ANACTRL_HIFIPLL_CTRL3			0x010c
+#define ANACTRL_HIFIPLL_CTRL4			0x0110
+#define ANACTRL_HIFIPLL_CTRL5			0x0114
+#define ANACTRL_HIFIPLL_CTRL6			0x0118
+#define ANACTRL_HIFIPLL_STS			0x011c
+#define ANACTRL_MPLL_CTRL0			0x0180
+#define ANACTRL_MPLL_CTRL1			0x0184
+#define ANACTRL_MPLL_CTRL2			0x0188
+#define ANACTRL_MPLL_CTRL3			0x018c
+#define ANACTRL_MPLL_CTRL4			0x0190
+#define ANACTRL_MPLL_STS			0x01a4
+
+#endif  /* __AML_C3_PLL_H__ */
-- 
2.37.1


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

* [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-10  6:29 [PATCH V2 0/4] Add C3 SoC PLLs and Peripheral clock Xianwei Zhao
                   ` (2 preceding siblings ...)
  2023-10-10  6:29 ` [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock Xianwei Zhao
@ 2023-10-10  6:29 ` Xianwei Zhao
  2023-10-12 23:51   ` Stephen Boyd
  2023-10-13  8:46   ` Jerome Brunet
  3 siblings, 2 replies; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-10  6:29 UTC (permalink / raw)
  To: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel
  Cc: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu, Xianwei Zhao

Add the C3 peripherals clock controller driver in the C3 SoC family.

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
V1 -> V2: Delete macro definition.
---
 drivers/clk/meson/Kconfig          |   13 +
 drivers/clk/meson/Makefile         |    1 +
 drivers/clk/meson/c3-peripherals.c | 3096 ++++++++++++++++++++++++++++
 drivers/clk/meson/c3-peripherals.h |   48 +
 4 files changed, 3158 insertions(+)
 create mode 100644 drivers/clk/meson/c3-peripherals.c
 create mode 100644 drivers/clk/meson/c3-peripherals.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 76be4bbd2afb..c8d59d28c8ff 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
 	  Say Y if you want the board to work, because PLLs are the parent of most
 	  peripherals.
 
+config COMMON_CLK_C3_PERIPHERALS
+	tristate "Amlogic C3 peripherals clock controller"
+	default y
+	select COMMON_CLK_MESON_REGMAP
+	select COMMON_CLK_MESON_DUALDIV
+	select COMMON_CLK_MESON_CLKC_UTILS
+	select COMMON_CLK_C3_PLL
+	help
+	  Support for the Peripherals clock controller on Amlogic C302X and
+	  C308L devices, AKA c3. Amlogic C302X and C308L devices include
+	  AW402, AW409 and AW419. Say Y if you want the peripherals clock
+	  to work.
+
 config COMMON_CLK_G12A
 	tristate "G12 and SM1 SoC clock controllers support"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 4420af628b31..20ad9482c892 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_C3_PLL) += c3-pll.o
+obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c
new file mode 100644
index 000000000000..2931cb20299a
--- /dev/null
+++ b/drivers/clk/meson/c3-peripherals.c
@@ -0,0 +1,3096 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Amlogic C3 Peripherals Clock Controller Driver
+ *
+ * Copyright (c) 2023 Amlogic, inc.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "c3-peripherals.h"
+#include "meson-clkc-utils.h"
+#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
+
+static struct clk_regmap pll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = OSCIN_CTRL,
+		.bit_idx = 4,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pll_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap mclk_pll_in = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = OSCIN_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "mclk_pll_in",
+		.ops = &clk_regmap_gate_ro_ops,
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "xtal",
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct clk_parent_data rtc_xtal_clkin_parent = {
+	.fw_name = "xtal",
+};
+
+static struct clk_regmap rtc_xtal_clkin = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 31,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_xtal_clkin",
+		.ops = &clk_regmap_gate_ops,
+		.parent_data = &rtc_xtal_clkin_parent,
+		.num_parents = 1,
+	},
+};
+
+static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = {
+	{ 733, 732, 8, 11, 1 },
+	{ /* sentinel */ }
+};
+
+static struct clk_regmap rtc_32k_div = {
+	.data = &(struct meson_clk_dualdiv_data){
+		.n1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.n2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.m1 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 0,
+			.width   = 12,
+		},
+		.m2 = {
+			.reg_off = RTC_BY_OSCIN_CTRL1,
+			.shift   = 12,
+			.width   = 12,
+		},
+		.dual = {
+			.reg_off = RTC_BY_OSCIN_CTRL0,
+			.shift   = 28,
+			.width   = 1,
+		},
+		.table = rtc_32k_div_table,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k_div",
+		.ops = &meson_clk_dualdiv_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_xtal_clkin.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct clk_parent_data rtc_32k_mux_parent_data[] = {
+	{ .hw = &rtc_32k_div.hw },
+	{ .hw = &rtc_xtal_clkin.hw }
+};
+
+static struct clk_regmap rtc_32k_mux = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = RTC_BY_OSCIN_CTRL1,
+		.mask = 0x1,
+		.shift = 24,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "rtc_32k_mux",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = rtc_32k_mux_parent_data,
+		.num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap rtc_32k = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = RTC_BY_OSCIN_CTRL0,
+		.bit_idx = 30,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "rtc_32k",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&rtc_32k_mux.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data rtc_clk_mux_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .hw = &rtc_32k.hw }
+};
+
+static struct clk_regmap 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 = rtc_clk_mux_parent_data,
+		.num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/*
+ * Some clocks have multiple clock sources, and the parent clock and index are
+ * discontinuous, Some channels corresponding to the clock index are not
+ * actually connected inside the chip, or the clock source is invalid.
+ */
+
+static u32 sys_axi_parent_table[] = { 0, 2, 3, 4, 7 };
+
+static const struct clk_parent_data sys_axi_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .hw = &rtc_clk.hw }
+};
+
+static struct clk_regmap sys_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = sys_axi_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sys_axi_parent_data,
+		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
+	},
+};
+
+static struct clk_regmap sys_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap sys_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap sys_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = sys_axi_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sys_axi_parent_data,
+		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
+	},
+};
+
+static struct clk_regmap sys_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SYS_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap sys_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SYS_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sys_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sys_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+};
+
+static const struct clk_parent_data sys_clk_parent_data[] = {
+	{ .hw = &sys_a.hw },
+	{ .hw = &sys_b.hw }
+};
+
+static struct clk_regmap sys_clk = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SYS_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sys_clk",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sys_clk_parent_data,
+		.num_parents = ARRAY_SIZE(sys_clk_parent_data),
+	},
+};
+
+static struct clk_regmap axi_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = AXI_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 10,
+		.table = sys_axi_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "axi_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sys_axi_parent_data,
+		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
+	},
+};
+
+static struct clk_regmap axi_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = AXI_CLK_CTRL0,
+		.shift = 0,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "axi_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axi_a_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap axi_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = AXI_CLK_CTRL0,
+		.bit_idx = 13,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axi_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axi_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+};
+
+static struct clk_regmap axi_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = AXI_CLK_CTRL0,
+		.mask = 0x7,
+		.shift = 26,
+		.table = sys_axi_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "axi_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = sys_axi_parent_data,
+		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
+	},
+};
+
+static struct clk_regmap axi_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = AXI_CLK_CTRL0,
+		.shift = 16,
+		.width = 10,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "axi_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axi_b_sel.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap axi_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = AXI_CLK_CTRL0,
+		.bit_idx = 29,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "axi_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&axi_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED,
+	},
+};
+
+static const struct clk_parent_data axi_clk_parent_data[] = {
+	{ .hw = &axi_a.hw },
+	{ .hw = &axi_b.hw }
+};
+
+static struct clk_regmap axi_clk = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = AXI_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "axi_clk",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = axi_clk_parent_data,
+		.num_parents = ARRAY_SIZE(axi_clk_parent_data),
+	},
+};
+
+#define AML_CLK_GATE_SYS_CLK(_name, _reg, _bit)\
+	MESON_PCLK(_name, _reg, _bit, &sys_clk.hw)
+#define AML_CLK_GATE_AXI_CLK(_name, _reg, _bit)\
+	MESON_PCLK(_name, _reg, _bit, &axi_clk.hw)
+
+AML_CLK_GATE_SYS_CLK(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1);
+AML_CLK_GATE_SYS_CLK(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3);
+AML_CLK_GATE_SYS_CLK(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4);
+AML_CLK_GATE_SYS_CLK(sys_ctrl, SYS_CLK_EN0_REG0, 5);
+AML_CLK_GATE_SYS_CLK(sys_ts_pll, SYS_CLK_EN0_REG0, 6);
+AML_CLK_GATE_SYS_CLK(sys_dev_arb, SYS_CLK_EN0_REG0, 7);
+AML_CLK_GATE_SYS_CLK(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
+AML_CLK_GATE_SYS_CLK(sys_capu, SYS_CLK_EN0_REG0, 9);
+AML_CLK_GATE_SYS_CLK(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11);
+AML_CLK_GATE_SYS_CLK(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12);
+AML_CLK_GATE_SYS_CLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13);
+AML_CLK_GATE_SYS_CLK(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14);
+AML_CLK_GATE_SYS_CLK(sys_msr_clk, SYS_CLK_EN0_REG0, 15);
+AML_CLK_GATE_SYS_CLK(sys_rom, SYS_CLK_EN0_REG0, 16);
+AML_CLK_GATE_SYS_CLK(sys_uart_f, SYS_CLK_EN0_REG0, 17);
+AML_CLK_GATE_SYS_CLK(sys_cpu_apb, SYS_CLK_EN0_REG0, 18);
+AML_CLK_GATE_SYS_CLK(sys_rsa, SYS_CLK_EN0_REG0, 19);
+AML_CLK_GATE_SYS_CLK(sys_sar_adc, SYS_CLK_EN0_REG0, 20);
+AML_CLK_GATE_SYS_CLK(sys_startup, SYS_CLK_EN0_REG0, 21);
+AML_CLK_GATE_SYS_CLK(sys_secure, SYS_CLK_EN0_REG0, 22);
+AML_CLK_GATE_SYS_CLK(sys_spifc, SYS_CLK_EN0_REG0, 23);
+AML_CLK_GATE_SYS_CLK(sys_nna, SYS_CLK_EN0_REG0, 25);
+AML_CLK_GATE_SYS_CLK(sys_eth_mac, SYS_CLK_EN0_REG0, 26);
+AML_CLK_GATE_SYS_CLK(sys_gic, SYS_CLK_EN0_REG0, 27);
+AML_CLK_GATE_SYS_CLK(sys_rama, SYS_CLK_EN0_REG0, 28);
+AML_CLK_GATE_SYS_CLK(sys_big_nic, SYS_CLK_EN0_REG0, 29);
+AML_CLK_GATE_SYS_CLK(sys_ramb, SYS_CLK_EN0_REG0, 30);
+AML_CLK_GATE_SYS_CLK(sys_audio_pclk, SYS_CLK_EN0_REG0, 31);
+AML_CLK_GATE_SYS_CLK(sys_pwm_kl, SYS_CLK_EN0_REG1, 0);
+AML_CLK_GATE_SYS_CLK(sys_pwm_ij, SYS_CLK_EN0_REG1, 1);
+AML_CLK_GATE_SYS_CLK(sys_usb, SYS_CLK_EN0_REG1, 2);
+AML_CLK_GATE_SYS_CLK(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3);
+AML_CLK_GATE_SYS_CLK(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4);
+AML_CLK_GATE_SYS_CLK(sys_pwm_ab, SYS_CLK_EN0_REG1, 5);
+AML_CLK_GATE_SYS_CLK(sys_pwm_cd, SYS_CLK_EN0_REG1, 6);
+AML_CLK_GATE_SYS_CLK(sys_pwm_ef, SYS_CLK_EN0_REG1, 7);
+AML_CLK_GATE_SYS_CLK(sys_pwm_gh, SYS_CLK_EN0_REG1, 8);
+AML_CLK_GATE_SYS_CLK(sys_spicc_1, SYS_CLK_EN0_REG1, 9);
+AML_CLK_GATE_SYS_CLK(sys_spicc_0, SYS_CLK_EN0_REG1, 10);
+AML_CLK_GATE_SYS_CLK(sys_uart_a, SYS_CLK_EN0_REG1, 11);
+AML_CLK_GATE_SYS_CLK(sys_uart_b, SYS_CLK_EN0_REG1, 12);
+AML_CLK_GATE_SYS_CLK(sys_uart_c, SYS_CLK_EN0_REG1, 13);
+AML_CLK_GATE_SYS_CLK(sys_uart_d, SYS_CLK_EN0_REG1, 14);
+AML_CLK_GATE_SYS_CLK(sys_uart_e, SYS_CLK_EN0_REG1, 15);
+AML_CLK_GATE_SYS_CLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16);
+AML_CLK_GATE_SYS_CLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17);
+AML_CLK_GATE_SYS_CLK(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18);
+AML_CLK_GATE_SYS_CLK(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19);
+AML_CLK_GATE_SYS_CLK(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20);
+AML_CLK_GATE_SYS_CLK(sys_rtc, SYS_CLK_EN0_REG1, 21);
+AML_CLK_GATE_SYS_CLK(sys_ge2d, SYS_CLK_EN0_REG1, 22);
+AML_CLK_GATE_SYS_CLK(sys_isp, SYS_CLK_EN0_REG1, 23);
+AML_CLK_GATE_SYS_CLK(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24);
+AML_CLK_GATE_SYS_CLK(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25);
+AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26);
+AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27);
+AML_CLK_GATE_SYS_CLK(sys_eth_phy, SYS_CLK_EN0_REG1, 28);
+AML_CLK_GATE_SYS_CLK(sys_acodec, SYS_CLK_EN0_REG1, 29);
+AML_CLK_GATE_SYS_CLK(sys_dwap, SYS_CLK_EN0_REG1, 30);
+AML_CLK_GATE_SYS_CLK(sys_dos, SYS_CLK_EN0_REG1, 31);
+AML_CLK_GATE_SYS_CLK(sys_cve, SYS_CLK_EN0_REG2, 0);
+AML_CLK_GATE_SYS_CLK(sys_vout, SYS_CLK_EN0_REG2, 1);
+AML_CLK_GATE_SYS_CLK(sys_vc9000e, SYS_CLK_EN0_REG2, 2);
+AML_CLK_GATE_SYS_CLK(sys_pwm_mn, SYS_CLK_EN0_REG2, 3);
+AML_CLK_GATE_SYS_CLK(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4);
+AML_CLK_GATE_AXI_CLK(axi_sys_nic, AXI_CLK_EN0, 2);
+AML_CLK_GATE_AXI_CLK(axi_isp_nic, AXI_CLK_EN0, 3);
+AML_CLK_GATE_AXI_CLK(axi_cve_nic, AXI_CLK_EN0, 4);
+AML_CLK_GATE_AXI_CLK(axi_ramb, AXI_CLK_EN0, 5);
+AML_CLK_GATE_AXI_CLK(axi_rama, AXI_CLK_EN0, 6);
+AML_CLK_GATE_AXI_CLK(axi_cpu_dmc, AXI_CLK_EN0, 7);
+AML_CLK_GATE_AXI_CLK(axi_nic, AXI_CLK_EN0, 8);
+AML_CLK_GATE_AXI_CLK(axi_dma, AXI_CLK_EN0, 9);
+AML_CLK_GATE_AXI_CLK(axi_mux_nic, AXI_CLK_EN0, 10);
+AML_CLK_GATE_AXI_CLK(axi_capu, AXI_CLK_EN0, 11);
+AML_CLK_GATE_AXI_CLK(axi_cve, AXI_CLK_EN0, 12);
+AML_CLK_GATE_AXI_CLK(axi_dev1_dmc, AXI_CLK_EN0, 13);
+AML_CLK_GATE_AXI_CLK(axi_dev0_dmc, AXI_CLK_EN0, 14);
+AML_CLK_GATE_AXI_CLK(axi_dsp_dmc, AXI_CLK_EN0, 15);
+
+/*
+ * clk_12_24m model
+ *
+ *          |------|     |-----| clk_12m_24m |-----|
+ * xtal---->| gate |---->| div |------------>| pad |
+ *          |------|     |-----|             |-----|
+ */
+static const struct clk_parent_data clk_12_24m_in_parent = {
+	.fw_name = "xtal",
+};
+
+static struct clk_regmap 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 = &clk_12_24m_in_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap 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 *[]) {
+			&clk_12_24m_in.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static const struct clk_parent_data fclk_25m_div_parent = {
+	.fw_name = "fixed_pll",
+};
+
+static struct clk_regmap 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 = &fclk_25m_div_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap 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 *[]) {
+			&fclk_25m_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/* generate clock output */
+static u32 gen_parent_table[] = { 0, 1, 5, 7 };
+
+static const struct clk_parent_data gen_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .hw = &rtc_clk.hw },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "hifi_pll" }
+};
+
+static struct clk_regmap gen_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = GEN_CLK_CTRL,
+		.mask = 0x1f,
+		.shift = 12,
+		.table = gen_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "gen_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = gen_parent_data,
+		.num_parents = ARRAY_SIZE(gen_parent_data),
+	},
+};
+
+static struct clk_regmap 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 *[]) {
+			&gen_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap 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 *[]) {
+			&gen_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data saradc_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .hw = &sys_clk.hw }
+};
+
+static struct clk_regmap saradc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SAR_CLK_CTRL0,
+		.mask = 0x1,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "saradc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = saradc_parent_data,
+		.num_parents = ARRAY_SIZE(saradc_parent_data),
+	},
+};
+
+static struct clk_regmap saradc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SAR_CLK_CTRL0,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "saradc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&saradc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap saradc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SAR_CLK_CTRL0,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "saradc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&saradc_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 pwm_parent_table[] = { 0, 2, 3 };
+
+static const struct clk_parent_data pwm_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div3" }
+};
+
+static struct clk_regmap pwm_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.shift = 16,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_AB_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_c_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_c_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_c_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_c_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_c = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_c",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_c_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_d_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_d_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.shift = 16,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_d_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_d_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_d = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_CD_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_d",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_d_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_e_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_e_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_e_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_e_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_e_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_e = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_e",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_e_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_f_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_f_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.shift = 16,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_f_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_f_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_f = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_EF_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_f",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_f_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_g_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_GH_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_g_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_g_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_GH_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_g_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_g_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_g = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_GH_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_g",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_g_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_h_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_GH_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_h_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_h_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_GH_CTRL,
+		.shift = 16,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_h_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_h_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_h = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_GH_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_h",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_h_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_i_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_IJ_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_i_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_i_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_IJ_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_i_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_i_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_i = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_IJ_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_i",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_i_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_j_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_IJ_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_j_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_j_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_IJ_CTRL,
+		.shift = 16,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_j_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_j_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_j = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_IJ_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_j",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_j_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_k_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_KL_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_k_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_k_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_KL_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_k_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_k_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_k = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_KL_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_k",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_k_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_l_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_KL_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_l_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_l_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_KL_CTRL,
+		.shift = 16,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_l_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_l_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_l = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_KL_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_l",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_l_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_m_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_MN_CTRL,
+		.mask = 0x3,
+		.shift = 9,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_m_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_m_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_MN_CTRL,
+		.shift = 0,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_m_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_m_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_m = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_MN_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_m",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_m_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_n_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = PWM_CLK_MN_CTRL,
+		.mask = 0x3,
+		.shift = 25,
+		.table = pwm_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_n_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = pwm_parent_data,
+		.num_parents = ARRAY_SIZE(pwm_parent_data),
+	},
+};
+
+static struct clk_regmap pwm_n_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = PWM_CLK_MN_CTRL,
+		.shift = 16,
+		.width = 8,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "pwm_n_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_n_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap pwm_n = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = PWM_CLK_MN_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "pwm_n",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&pwm_n_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data spicc_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .hw = &sys_clk.hw },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "fclk_div7" }
+};
+
+static struct clk_regmap spicc_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_parent_data,
+		.num_parents = ARRAY_SIZE(spicc_parent_data),
+	},
+};
+
+static struct clk_regmap spicc_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPICC_CLK_CTRL,
+		.shift = 0,
+		.width = 6,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPICC_CLK_CTRL,
+		.bit_idx = 6,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spicc_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPICC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 23,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spicc_parent_data,
+		.num_parents = ARRAY_SIZE(spicc_parent_data),
+	},
+};
+
+static struct clk_regmap spicc_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPICC_CLK_CTRL,
+		.shift = 16,
+		.width = 6,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spicc_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spicc_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPICC_CLK_CTRL,
+		.bit_idx = 22,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spicc_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spicc_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data spifc_parent_data[] = {
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "fclk_div7" }
+};
+
+static struct clk_regmap spifc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SPIFC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = spifc_parent_data,
+		.num_parents = ARRAY_SIZE(spifc_parent_data),
+	},
+};
+
+static struct clk_regmap spifc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SPIFC_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "spifc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap spifc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SPIFC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "spifc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&spifc_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 emmc_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+
+static const struct clk_parent_data emmc_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "gp0_pll" }
+};
+
+static struct clk_regmap sd_emmc_a_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = emmc_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_a_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = emmc_parent_data,
+		.num_parents = ARRAY_SIZE(emmc_parent_data),
+	},
+};
+
+static struct clk_regmap sd_emmc_a_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_a_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_a_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_a = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.bit_idx = 7,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sd_emmc_a",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_a_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_b_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 25,
+		.table = emmc_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_b_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = emmc_parent_data,
+		.num_parents = ARRAY_SIZE(emmc_parent_data),
+	},
+};
+
+static struct clk_regmap sd_emmc_b_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_b_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_b_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_b = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = SD_EMMC_CLK_CTRL,
+		.bit_idx = 23,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sd_emmc_b",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_b_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_c_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = NAND_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = emmc_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_c_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = emmc_parent_data,
+		.num_parents = ARRAY_SIZE(emmc_parent_data),
+	},
+};
+
+static struct clk_regmap sd_emmc_c_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = NAND_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "sd_emmc_c_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_c_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap sd_emmc_c = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = NAND_CLK_CTRL,
+		.bit_idx = 7,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "sd_emmc_c",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&sd_emmc_c_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+/* temperature sensor */
+static const struct clk_parent_data ts_parent = {
+	.fw_name = "xtal",
+};
+
+static struct clk_regmap 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 = &ts_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap 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 *[]) {
+			&ts_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data eth_parent = {
+	.fw_name = "fclk_div2",
+};
+
+static struct clk_fixed_factor eth_125m_div = {
+	.mult = 1,
+	.div = 8,
+	.hw.init = &(struct clk_init_data){
+		.name = "eth_125m_div",
+		.ops = &clk_fixed_factor_ops,
+		.parent_data = &eth_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap 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 *[]) {
+			&eth_125m_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap 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 = &eth_parent,
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap 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 *[]) {
+			&eth_rmii_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 mipi_dsi_meas_parent_table[] = { 0, 1, 2, 3, 5, 6, 7 };
+
+static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div7" }
+};
+
+static struct clk_regmap mipi_dsi_meas_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VDIN_MEAS_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 21,
+		.table = mipi_dsi_meas_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mipi_dsi_meas_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = mipi_dsi_meas_parent_data,
+		.num_parents = ARRAY_SIZE(mipi_dsi_meas_parent_data),
+	},
+};
+
+static struct clk_regmap mipi_dsi_meas_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VDIN_MEAS_CLK_CTRL,
+		.shift = 12,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mipi_dsi_meas_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mipi_dsi_meas_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap mipi_dsi_meas = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = VDIN_MEAS_CLK_CTRL,
+		.bit_idx = 20,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "mipi_dsi_meas",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&mipi_dsi_meas_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 dsi_phy_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
+
+static const struct clk_parent_data dsi_phy_parent_data[] = {
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div7" }
+};
+
+static struct clk_regmap dsi_phy_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = MIPIDSI_PHY_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 12,
+		.table = dsi_phy_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dsi_phy_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dsi_phy_parent_data,
+		.num_parents = ARRAY_SIZE(dsi_phy_parent_data),
+	},
+};
+
+static struct clk_regmap dsi_phy_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = MIPIDSI_PHY_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dsi_phy_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dsi_phy_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dsi_phy = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = MIPIDSI_PHY_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dsi_phy",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dsi_phy_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 vout_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
+
+static const struct clk_parent_data vout_parent_data[] = {
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div7" }
+};
+
+static struct clk_regmap vout_mclk_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VOUTENC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = vout_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vout_mclk_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = vout_parent_data,
+		.num_parents = ARRAY_SIZE(vout_parent_data),
+	},
+};
+
+static struct clk_regmap vout_mclk_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VOUTENC_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vout_mclk_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vout_mclk_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap vout_mclk = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = MIPIDSI_PHY_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vout_mclk",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vout_mclk_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap vout_enc_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VOUTENC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 25,
+		.table = vout_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vout_enc_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = vout_parent_data,
+		.num_parents = ARRAY_SIZE(vout_parent_data),
+	},
+};
+
+static struct clk_regmap vout_enc_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VOUTENC_CLK_CTRL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vout_enc_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vout_enc_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap vout_enc = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = VOUTENC_CLK_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vout_enc",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vout_enc_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data hcodec_pre_parent_data[] = {
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "fclk_div7" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "xtal" }
+};
+
+static struct clk_regmap hcodec_0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VDEC_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hcodec_0_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = hcodec_pre_parent_data,
+		.num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
+	},
+};
+
+static struct clk_regmap hcodec_0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VDEC_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hcodec_0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&hcodec_0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap hcodec_0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = VDEC_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hcodec_0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&hcodec_0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap hcodec_1_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VDEC3_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hcodec_1_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = hcodec_pre_parent_data,
+		.num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
+	},
+};
+
+static struct clk_regmap hcodec_1_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VDEC3_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hcodec_1_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&hcodec_1_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap hcodec_1 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = VDEC3_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "hcodec_1",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&hcodec_1_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data hcodec_parent_data[] = {
+	{ .hw = &hcodec_0.hw },
+	{ .hw = &hcodec_1.hw }
+};
+
+
+static struct clk_regmap hcodec = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VDEC3_CLK_CTRL,
+		.mask = 0x1,
+		.shift = 15,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "hcodec",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = hcodec_parent_data,
+		.num_parents = ARRAY_SIZE(hcodec_parent_data),
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data vc9000e_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "fclk_div7" },
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "gp0_pll" }
+};
+
+static struct clk_regmap vc9000e_aclk_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VC9000E_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vc9000e_aclk_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = vc9000e_parent_data,
+		.num_parents = ARRAY_SIZE(vc9000e_parent_data),
+	},
+};
+
+static struct clk_regmap vc9000e_aclk_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VC9000E_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vc9000e_aclk_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vc9000e_aclk_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap vc9000e_aclk = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = VC9000E_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vc9000e_aclk",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vc9000e_aclk_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap vc9000e_core_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VC9000E_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 25,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vc9000e_core_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = vc9000e_parent_data,
+		.num_parents = ARRAY_SIZE(vc9000e_parent_data),
+	},
+};
+
+static struct clk_regmap vc9000e_core_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VC9000E_CLK_CTRL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vc9000e_core_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vc9000e_core_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap vc9000e_core = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = VC9000E_CLK_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vc9000e_core",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vc9000e_core_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 csi_phy_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+
+static const struct clk_parent_data csi_phy_parent_data[] = {
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "xtal" }
+};
+
+static struct clk_regmap csi_phy0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = ISP0_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 25,
+		.table = csi_phy_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "csi_phy0_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = csi_phy_parent_data,
+		.num_parents = ARRAY_SIZE(csi_phy_parent_data),
+	},
+};
+
+static struct clk_regmap csi_phy0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ISP0_CLK_CTRL,
+		.shift = 16,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "csi_phy0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&csi_phy0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap csi_phy0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ISP0_CLK_CTRL,
+		.bit_idx = 24,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "csi_phy0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&csi_phy0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 dewarpa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+
+static const struct clk_parent_data dewarpa_parent_data[] = {
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "fclk_div7" }
+};
+
+static struct clk_regmap dewarpa_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = DEWARPA_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = dewarpa_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dewarpa_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = dewarpa_parent_data,
+		.num_parents = ARRAY_SIZE(dewarpa_parent_data),
+	},
+};
+
+static struct clk_regmap dewarpa_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = DEWARPA_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "dewarpa_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dewarpa_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap dewarpa = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = DEWARPA_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "dewarpa",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&dewarpa_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 isp_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+
+static const struct clk_parent_data isp_parent_data[] = {
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "xtal" }
+};
+
+static struct clk_regmap isp0_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = ISP0_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = isp_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "isp0_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = isp_parent_data,
+		.num_parents = ARRAY_SIZE(isp_parent_data),
+	},
+};
+
+static struct clk_regmap isp0_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = ISP0_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "isp0_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&isp0_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap isp0 = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = ISP0_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "isp0",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&isp0_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 nna_core_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+
+static const struct clk_parent_data nna_core_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "fclk_div2" },
+	{ .fw_name = "hifi_pll" }
+};
+
+static struct clk_regmap nna_core_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = NNA_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = nna_core_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "nna_core_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = nna_core_parent_data,
+		.num_parents = ARRAY_SIZE(nna_core_parent_data),
+	},
+};
+
+static struct clk_regmap nna_core_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = NNA_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "nna_core_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&nna_core_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap nna_core = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = NNA_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "nna_core",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&nna_core_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static const struct clk_parent_data ge2d_parent_data[] = {
+	{ .fw_name = "xtal" },
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "gp0_pll" },
+	{ .hw = &rtc_clk.hw }
+};
+
+static struct clk_regmap ge2d_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = GE2D_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ge2d_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = ge2d_parent_data,
+		.num_parents = ARRAY_SIZE(ge2d_parent_data),
+	},
+};
+
+static struct clk_regmap ge2d_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = GE2D_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "ge2d_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ge2d_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap ge2d = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = GE2D_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "ge2d",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&ge2d_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static u32 c3_vapb_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+
+static const struct clk_parent_data vapb_parent_data[] = {
+	{ .fw_name = "fclk_div2p5" },
+	{ .fw_name = "fclk_div3" },
+	{ .fw_name = "fclk_div4" },
+	{ .fw_name = "fclk_div5" },
+	{ .fw_name = "gp0_pll" },
+	{ .fw_name = "hifi_pll" },
+	{ .fw_name = "xtal" }
+};
+
+static struct clk_regmap vapb_sel = {
+	.data = &(struct clk_regmap_mux_data){
+		.offset = VAPB_CLK_CTRL,
+		.mask = 0x7,
+		.shift = 9,
+		.table = c3_vapb_parent_table,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_sel",
+		.ops = &clk_regmap_mux_ops,
+		.parent_data = vapb_parent_data,
+		.num_parents = ARRAY_SIZE(vapb_parent_data),
+	},
+};
+
+static struct clk_regmap vapb_div = {
+	.data = &(struct clk_regmap_div_data){
+		.offset = VAPB_CLK_CTRL,
+		.shift = 0,
+		.width = 7,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "vapb_div",
+		.ops = &clk_regmap_divider_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vapb_sel.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_regmap vapb = {
+	.data = &(struct clk_regmap_gate_data){
+		.offset = VAPB_CLK_CTRL,
+		.bit_idx = 8,
+	},
+	.hw.init = &(struct clk_init_data) {
+		.name = "vapb",
+		.ops = &clk_regmap_gate_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&vapb_div.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+	},
+};
+
+static struct clk_hw *c3_periphs_hw_clks[] = {
+	[CLKID_PLL_IN]			= &pll_in.hw,
+	[CLKID_MCLK_PLL_IN]		= &mclk_pll_in.hw,
+	[CLKID_RTC_XTAL_CLKIN]		= &rtc_xtal_clkin.hw,
+	[CLKID_RTC_32K_DIV]		= &rtc_32k_div.hw,
+	[CLKID_RTC_32K_MUX]		= &rtc_32k_mux.hw,
+	[CLKID_RTC_32K]			= &rtc_32k.hw,
+	[CLKID_RTC_CLK]			= &rtc_clk.hw,
+	[CLKID_SYS_A_SEL]		= &sys_a_sel.hw,
+	[CLKID_SYS_A_DIV]		= &sys_a_div.hw,
+	[CLKID_SYS_A]			= &sys_a.hw,
+	[CLKID_SYS_B_SEL]		= &sys_b_sel.hw,
+	[CLKID_SYS_B_DIV]		= &sys_b_div.hw,
+	[CLKID_SYS_B]			= &sys_b.hw,
+	[CLKID_SYS_CLK]			= &sys_clk.hw,
+	[CLKID_AXI_A_SEL]		= &axi_a_sel.hw,
+	[CLKID_AXI_A_DIV]		= &axi_a_div.hw,
+	[CLKID_AXI_A]			= &axi_a.hw,
+	[CLKID_AXI_B_SEL]		= &axi_b_sel.hw,
+	[CLKID_AXI_B_DIV]		= &axi_b_div.hw,
+	[CLKID_AXI_B]			= &axi_b.hw,
+	[CLKID_AXI_CLK]			= &axi_clk.hw,
+	[CLKID_SYS_RESET_CTRL]		= &sys_reset_ctrl.hw,
+	[CLKID_SYS_PAD_CTRL]		= &sys_pwr_ctrl.hw,
+	[CLKID_SYS_CTRL]		= &sys_ctrl.hw,
+	[CLKID_SYS_TS_PLL]		= &sys_ts_pll.hw,
+	[CLKID_SYS_DEV_ARB]		= &sys_dev_arb.hw,
+	[CLKID_SYS_MMC_PCLK]		= &sys_mmc_pclk.hw,
+	[CLKID_SYS_CAPU]		= &sys_capu.hw,
+	[CLKID_SYS_CPU_CTRL]		= &sys_cpu_ctrl.hw,
+	[CLKID_SYS_JTAG_CTRL]		= &sys_jtag_ctrl.hw,
+	[CLKID_SYS_IR_CTRL]		= &sys_ir_ctrl.hw,
+	[CLKID_SYS_IRQ_CTRL]		= &sys_irq_ctrl.hw,
+	[CLKID_SYS_MSR_CLK]		= &sys_msr_clk.hw,
+	[CLKID_SYS_ROM]			= &sys_rom.hw,
+	[CLKID_SYS_UART_F]		= &sys_uart_f.hw,
+	[CLKID_SYS_CPU_ARB]		= &sys_cpu_apb.hw,
+	[CLKID_SYS_RSA]			= &sys_rsa.hw,
+	[CLKID_SYS_SAR_ADC]		= &sys_sar_adc.hw,
+	[CLKID_SYS_STARTUP]		= &sys_startup.hw,
+	[CLKID_SYS_SECURE]		= &sys_secure.hw,
+	[CLKID_SYS_SPIFC]		= &sys_spifc.hw,
+	[CLKID_SYS_NNA]			= &sys_nna.hw,
+	[CLKID_SYS_ETH_MAC]		= &sys_eth_mac.hw,
+	[CLKID_SYS_GIC]			= &sys_gic.hw,
+	[CLKID_SYS_RAMA]		= &sys_rama.hw,
+	[CLKID_SYS_BIG_NIC]		= &sys_big_nic.hw,
+	[CLKID_SYS_RAMB]		= &sys_ramb.hw,
+	[CLKID_SYS_AUDIO_PCLK]		= &sys_audio_pclk.hw,
+	[CLKID_SYS_PWM_KL]		= &sys_pwm_kl.hw,
+	[CLKID_SYS_PWM_IJ]		= &sys_pwm_ij.hw,
+	[CLKID_SYS_USB]			= &sys_usb.hw,
+	[CLKID_SYS_SD_EMMC_A]		= &sys_sd_emmc_a.hw,
+	[CLKID_SYS_SD_EMMC_C]		= &sys_sd_emmc_c.hw,
+	[CLKID_SYS_PWM_AB]		= &sys_pwm_ab.hw,
+	[CLKID_SYS_PWM_CD]		= &sys_pwm_cd.hw,
+	[CLKID_SYS_PWM_EF]		= &sys_pwm_ef.hw,
+	[CLKID_SYS_PWM_GH]		= &sys_pwm_gh.hw,
+	[CLKID_SYS_SPICC_1]		= &sys_spicc_1.hw,
+	[CLKID_SYS_SPICC_0]		= &sys_spicc_0.hw,
+	[CLKID_SYS_UART_A]		= &sys_uart_a.hw,
+	[CLKID_SYS_UART_B]		= &sys_uart_b.hw,
+	[CLKID_SYS_UART_C]		= &sys_uart_c.hw,
+	[CLKID_SYS_UART_D]		= &sys_uart_d.hw,
+	[CLKID_SYS_UART_E]		= &sys_uart_e.hw,
+	[CLKID_SYS_I2C_M_A]		= &sys_i2c_m_a.hw,
+	[CLKID_SYS_I2C_M_B]		= &sys_i2c_m_b.hw,
+	[CLKID_SYS_I2C_M_C]		= &sys_i2c_m_c.hw,
+	[CLKID_SYS_I2C_M_D]		= &sys_i2c_m_d.hw,
+	[CLKID_SYS_I2S_S_A]		= &sys_i2c_s_a.hw,
+	[CLKID_SYS_RTC]			= &sys_rtc.hw,
+	[CLKID_SYS_GE2D]		= &sys_ge2d.hw,
+	[CLKID_SYS_ISP]			= &sys_isp.hw,
+	[CLKID_SYS_GPV_ISP_NIC]		= &sys_gpv_isp_nic.hw,
+	[CLKID_SYS_GPV_CVE_NIC]		= &sys_gpv_cve_nic.hw,
+	[CLKID_SYS_MIPI_DSI_HOST]	= &sys_mipi_dsi_host.hw,
+	[CLKID_SYS_MIPI_DSI_PHY]	= &sys_mipi_dsi_phy.hw,
+	[CLKID_SYS_ETH_PHY]		= &sys_eth_phy.hw,
+	[CLKID_SYS_ACODEC]		= &sys_acodec.hw,
+	[CLKID_SYS_DWAP]		= &sys_dwap.hw,
+	[CLKID_SYS_DOS]			= &sys_dos.hw,
+	[CLKID_SYS_CVE]			= &sys_cve.hw,
+	[CLKID_SYS_VOUT]		= &sys_vout.hw,
+	[CLKID_SYS_VC9000E]		= &sys_vc9000e.hw,
+	[CLKID_SYS_PWM_MN]		= &sys_pwm_mn.hw,
+	[CLKID_SYS_SD_EMMC_B]		= &sys_sd_emmc_b.hw,
+	[CLKID_AXI_SYS_NIC]		= &axi_sys_nic.hw,
+	[CLKID_AXI_ISP_NIC]		= &axi_isp_nic.hw,
+	[CLKID_AXI_CVE_NIC]		= &axi_cve_nic.hw,
+	[CLKID_AXI_RAMB]		= &axi_ramb.hw,
+	[CLKID_AXI_RAMA]		= &axi_rama.hw,
+	[CLKID_AXI_CPU_DMC]		= &axi_cpu_dmc.hw,
+	[CLKID_AXI_NIC]			= &axi_nic.hw,
+	[CLKID_AXI_DMA]			= &axi_dma.hw,
+	[CLKID_AXI_MUX_NIC]		= &axi_mux_nic.hw,
+	[CLKID_AXI_CAPU]		= &axi_capu.hw,
+	[CLKID_AXI_CVE]			= &axi_cve.hw,
+	[CLKID_AXI_DEV1_DMC]		= &axi_dev1_dmc.hw,
+	[CLKID_AXI_DEV0_DMC]		= &axi_dev0_dmc.hw,
+	[CLKID_AXI_DSP_DMC]		= &axi_dsp_dmc.hw,
+	[CLKID_12_24M_IN]		= &clk_12_24m_in.hw,
+	[CLKID_12M_24M]			= &clk_12_24m.hw,
+	[CLKID_FCLK_25M_DIV]		= &fclk_25m_div.hw,
+	[CLKID_FCLK_25M]		= &fclk_25m.hw,
+	[CLKID_GEN_SEL]			= &gen_sel.hw,
+	[CLKID_GEN_DIV]			= &gen_div.hw,
+	[CLKID_GEN]			= &gen.hw,
+	[CLKID_SARADC_SEL]		= &saradc_sel.hw,
+	[CLKID_SARADC_DIV]		= &saradc_div.hw,
+	[CLKID_SARADC]			= &saradc.hw,
+	[CLKID_PWM_A_SEL]		= &pwm_a_sel.hw,
+	[CLKID_PWM_A_DIV]		= &pwm_a_div.hw,
+	[CLKID_PWM_A]			= &pwm_a.hw,
+	[CLKID_PWM_B_SEL]		= &pwm_b_sel.hw,
+	[CLKID_PWM_B_DIV]		= &pwm_b_div.hw,
+	[CLKID_PWM_B]			= &pwm_b.hw,
+	[CLKID_PWM_C_SEL]		= &pwm_c_sel.hw,
+	[CLKID_PWM_C_DIV]		= &pwm_c_div.hw,
+	[CLKID_PWM_C]			= &pwm_c.hw,
+	[CLKID_PWM_D_SEL]		= &pwm_d_sel.hw,
+	[CLKID_PWM_D_DIV]		= &pwm_d_div.hw,
+	[CLKID_PWM_D]			= &pwm_d.hw,
+	[CLKID_PWM_E_SEL]		= &pwm_e_sel.hw,
+	[CLKID_PWM_E_DIV]		= &pwm_e_div.hw,
+	[CLKID_PWM_E]			= &pwm_e.hw,
+	[CLKID_PWM_F_SEL]		= &pwm_f_sel.hw,
+	[CLKID_PWM_F_DIV]		= &pwm_f_div.hw,
+	[CLKID_PWM_F]			= &pwm_f.hw,
+	[CLKID_PWM_G_SEL]		= &pwm_g_sel.hw,
+	[CLKID_PWM_G_DIV]		= &pwm_g_div.hw,
+	[CLKID_PWM_G]			= &pwm_g.hw,
+	[CLKID_PWM_H_SEL]		= &pwm_h_sel.hw,
+	[CLKID_PWM_H_DIV]		= &pwm_h_div.hw,
+	[CLKID_PWM_H]			= &pwm_h.hw,
+	[CLKID_PWM_I_SEL]		= &pwm_i_sel.hw,
+	[CLKID_PWM_I_DIV]		= &pwm_i_div.hw,
+	[CLKID_PWM_I]			= &pwm_i.hw,
+	[CLKID_PWM_J_SEL]		= &pwm_j_sel.hw,
+	[CLKID_PWM_J_DIV]		= &pwm_j_div.hw,
+	[CLKID_PWM_J]			= &pwm_j.hw,
+	[CLKID_PWM_K_SEL]		= &pwm_k_sel.hw,
+	[CLKID_PWM_K_DIV]		= &pwm_k_div.hw,
+	[CLKID_PWM_K]			= &pwm_k.hw,
+	[CLKID_PWM_L_SEL]		= &pwm_l_sel.hw,
+	[CLKID_PWM_L_DIV]		= &pwm_l_div.hw,
+	[CLKID_PWM_L]			= &pwm_l.hw,
+	[CLKID_PWM_M_SEL]		= &pwm_m_sel.hw,
+	[CLKID_PWM_M_DIV]		= &pwm_m_div.hw,
+	[CLKID_PWM_M]			= &pwm_m.hw,
+	[CLKID_PWM_N_SEL]		= &pwm_n_sel.hw,
+	[CLKID_PWM_N_DIV]		= &pwm_n_div.hw,
+	[CLKID_PWM_N]			= &pwm_n.hw,
+	[CLKID_SPICC_A_SEL]		= &spicc_a_sel.hw,
+	[CLKID_SPICC_A_DIV]		= &spicc_a_div.hw,
+	[CLKID_SPICC_A]			= &spicc_a.hw,
+	[CLKID_SPICC_B_SEL]		= &spicc_b_sel.hw,
+	[CLKID_SPICC_B_DIV]		= &spicc_b_div.hw,
+	[CLKID_SPICC_B]			= &spicc_b.hw,
+	[CLKID_SPIFC_SEL]		= &spifc_sel.hw,
+	[CLKID_SPIFC_DIV]		= &spifc_div.hw,
+	[CLKID_SPIFC]			= &spifc.hw,
+	[CLKID_SD_EMMC_A_SEL]		= &sd_emmc_a_sel.hw,
+	[CLKID_SD_EMMC_A_DIV]		= &sd_emmc_a_div.hw,
+	[CLKID_SD_EMMC_A]		= &sd_emmc_a.hw,
+	[CLKID_SD_EMMC_B_SEL]		= &sd_emmc_b_sel.hw,
+	[CLKID_SD_EMMC_B_DIV]		= &sd_emmc_b_div.hw,
+	[CLKID_SD_EMMC_B]		= &sd_emmc_b.hw,
+	[CLKID_SD_EMMC_C_SEL]		= &sd_emmc_c_sel.hw,
+	[CLKID_SD_EMMC_C_DIV]		= &sd_emmc_c_div.hw,
+	[CLKID_SD_EMMC_C]		= &sd_emmc_c.hw,
+	[CLKID_TS_DIV]			= &ts_div.hw,
+	[CLKID_TS]			= &ts.hw,
+	[CLKID_ETH_125M_DIV]		= &eth_125m_div.hw,
+	[CLKID_ETH_125M]		= &eth_125m.hw,
+	[CLKID_ETH_RMII_DIV]		= &eth_rmii_div.hw,
+	[CLKID_ETH_RMII]		= &eth_rmii.hw,
+	[CLKID_MIPI_DSI_MEAS_SEL]	= &mipi_dsi_meas_sel.hw,
+	[CLKID_MIPI_DSI_MEAS_DIV]	= &mipi_dsi_meas_div.hw,
+	[CLKID_MIPI_DSI_MEAS]		= &mipi_dsi_meas.hw,
+	[CLKID_DSI_PHY_SEL]		= &dsi_phy_sel.hw,
+	[CLKID_DSI_PHY_DIV]		= &dsi_phy_div.hw,
+	[CLKID_DSI_PHY]			= &dsi_phy.hw,
+	[CLKID_VOUT_MCLK_SEL]		= &vout_mclk_sel.hw,
+	[CLKID_VOUT_MCLK_DIV]		= &vout_mclk_div.hw,
+	[CLKID_VOUT_MCLK]		= &vout_mclk.hw,
+	[CLKID_VOUT_ENC_SEL]		= &vout_enc_sel.hw,
+	[CLKID_VOUT_ENC_DIV]		= &vout_enc_div.hw,
+	[CLKID_VOUT_ENC]		= &vout_enc.hw,
+	[CLKID_HCODEC_0_SEL]		= &hcodec_0_sel.hw,
+	[CLKID_HCODEC_0_DIV]		= &hcodec_0_div.hw,
+	[CLKID_HCODEC_0]		= &hcodec_0.hw,
+	[CLKID_HCODEC_1_SEL]		= &hcodec_1_sel.hw,
+	[CLKID_HCODEC_1_DIV]		= &hcodec_1_div.hw,
+	[CLKID_HCODEC_1]		= &hcodec_1.hw,
+	[CLKID_HCODEC]			= &hcodec.hw,
+	[CLKID_VC9000E_ACLK_SEL]	= &vc9000e_aclk_sel.hw,
+	[CLKID_VC9000E_ACLK_DIV]	= &vc9000e_aclk_div.hw,
+	[CLKID_VC9000E_ACLK]		= &vc9000e_aclk.hw,
+	[CLKID_VC9000E_CORE_SEL]	= &vc9000e_core_sel.hw,
+	[CLKID_VC9000E_CORE_DIV]	= &vc9000e_core_div.hw,
+	[CLKID_VC9000E_CORE]		= &vc9000e_core.hw,
+	[CLKID_CSI_PHY0_SEL]		= &csi_phy0_sel.hw,
+	[CLKID_CSI_PHY0_DIV]		= &csi_phy0_div.hw,
+	[CLKID_CSI_PHY0]		= &csi_phy0.hw,
+	[CLKID_DEWARPA_SEL]		= &dewarpa_sel.hw,
+	[CLKID_DEWARPA_DIV]		= &dewarpa_div.hw,
+	[CLKID_DEWARPA]			= &dewarpa.hw,
+	[CLKID_ISP0_SEL]		= &isp0_sel.hw,
+	[CLKID_ISP0_DIV]		= &isp0_div.hw,
+	[CLKID_ISP0]			= &isp0.hw,
+	[CLKID_NNA_CORE_SEL]		= &nna_core_sel.hw,
+	[CLKID_NNA_CORE_DIV]		= &nna_core_div.hw,
+	[CLKID_NNA_CORE]		= &nna_core.hw,
+	[CLKID_GE2D_SEL]		= &ge2d_sel.hw,
+	[CLKID_GE2D_DIV]		= &ge2d_div.hw,
+	[CLKID_GE2D]			= &ge2d.hw,
+	[CLKID_VAPB_SEL]		= &vapb_sel.hw,
+	[CLKID_VAPB_DIV]		= &vapb_div.hw,
+	[CLKID_VAPB]			= &vapb.hw,
+};
+
+/* Convenience table to populate regmap in .probe */
+static struct clk_regmap *const c3_periphs_clk_regmaps[] = {
+	&pll_in,
+	&mclk_pll_in,
+	&rtc_xtal_clkin,
+	&rtc_32k_div,
+	&rtc_32k_mux,
+	&rtc_32k,
+	&rtc_clk,
+	&sys_a_sel,
+	&sys_a_div,
+	&sys_a,
+	&sys_b_sel,
+	&sys_b_div,
+	&sys_b,
+	&sys_clk,
+	&axi_a_sel,
+	&axi_a_div,
+	&axi_a,
+	&axi_b_sel,
+	&axi_b_div,
+	&axi_b,
+	&axi_clk,
+	&sys_reset_ctrl,
+	&sys_pwr_ctrl,
+	&sys_pad_ctrl,
+	&sys_ctrl,
+	&sys_ts_pll,
+	&sys_dev_arb,
+	&sys_mmc_pclk,
+	&sys_capu,
+	&sys_cpu_ctrl,
+	&sys_jtag_ctrl,
+	&sys_ir_ctrl,
+	&sys_irq_ctrl,
+	&sys_msr_clk,
+	&sys_rom,
+	&sys_uart_f,
+	&sys_cpu_apb,
+	&sys_rsa,
+	&sys_sar_adc,
+	&sys_startup,
+	&sys_secure,
+	&sys_spifc,
+	&sys_nna,
+	&sys_eth_mac,
+	&sys_gic,
+	&sys_rama,
+	&sys_big_nic,
+	&sys_ramb,
+	&sys_audio_pclk,
+	&sys_pwm_kl,
+	&sys_pwm_ij,
+	&sys_usb,
+	&sys_sd_emmc_a,
+	&sys_sd_emmc_c,
+	&sys_pwm_ab,
+	&sys_pwm_cd,
+	&sys_pwm_ef,
+	&sys_pwm_gh,
+	&sys_spicc_1,
+	&sys_spicc_0,
+	&sys_uart_a,
+	&sys_uart_b,
+	&sys_uart_c,
+	&sys_uart_d,
+	&sys_uart_e,
+	&sys_i2c_m_a,
+	&sys_i2c_m_b,
+	&sys_i2c_m_c,
+	&sys_i2c_m_d,
+	&sys_i2c_s_a,
+	&sys_rtc,
+	&sys_ge2d,
+	&sys_isp,
+	&sys_gpv_isp_nic,
+	&sys_gpv_cve_nic,
+	&sys_mipi_dsi_host,
+	&sys_mipi_dsi_phy,
+	&sys_eth_phy,
+	&sys_acodec,
+	&sys_dwap,
+	&sys_dos,
+	&sys_cve,
+	&sys_vout,
+	&sys_vc9000e,
+	&sys_pwm_mn,
+	&sys_sd_emmc_b,
+	&axi_sys_nic,
+	&axi_isp_nic,
+	&axi_cve_nic,
+	&axi_ramb,
+	&axi_rama,
+	&axi_cpu_dmc,
+	&axi_nic,
+	&axi_dma,
+	&axi_mux_nic,
+	&axi_capu,
+	&axi_cve,
+	&axi_dev1_dmc,
+	&axi_dev0_dmc,
+	&axi_dsp_dmc,
+	&clk_12_24m_in,
+	&clk_12_24m,
+	&fclk_25m_div,
+	&fclk_25m,
+	&gen_sel,
+	&gen_div,
+	&gen,
+	&saradc_sel,
+	&saradc_div,
+	&saradc,
+	&pwm_a_sel,
+	&pwm_a_div,
+	&pwm_a,
+	&pwm_b_sel,
+	&pwm_b_div,
+	&pwm_b,
+	&pwm_c_sel,
+	&pwm_c_div,
+	&pwm_c,
+	&pwm_d_sel,
+	&pwm_d_div,
+	&pwm_d,
+	&pwm_e_sel,
+	&pwm_e_div,
+	&pwm_e,
+	&pwm_f_sel,
+	&pwm_f_div,
+	&pwm_f,
+	&pwm_g_sel,
+	&pwm_g_div,
+	&pwm_g,
+	&pwm_h_sel,
+	&pwm_h_div,
+	&pwm_h,
+	&pwm_i_sel,
+	&pwm_i_div,
+	&pwm_i,
+	&pwm_j_sel,
+	&pwm_j_div,
+	&pwm_j,
+	&pwm_k_sel,
+	&pwm_k_div,
+	&pwm_k,
+	&pwm_l_sel,
+	&pwm_l_div,
+	&pwm_l,
+	&pwm_m_sel,
+	&pwm_m_div,
+	&pwm_m,
+	&pwm_n_sel,
+	&pwm_n_div,
+	&pwm_n,
+	&spicc_a_sel,
+	&spicc_a_div,
+	&spicc_a,
+	&spicc_b_sel,
+	&spicc_b_div,
+	&spicc_b,
+	&spifc_sel,
+	&spifc_div,
+	&spifc,
+	&sd_emmc_a_sel,
+	&sd_emmc_a_div,
+	&sd_emmc_a,
+	&sd_emmc_b_sel,
+	&sd_emmc_b_div,
+	&sd_emmc_b,
+	&sd_emmc_c_sel,
+	&sd_emmc_c_div,
+	&sd_emmc_c,
+	&ts_div,
+	&ts,
+	&eth_125m,
+	&eth_rmii_div,
+	&eth_rmii,
+	&mipi_dsi_meas_sel,
+	&mipi_dsi_meas_div,
+	&mipi_dsi_meas,
+	&dsi_phy_sel,
+	&dsi_phy_div,
+	&dsi_phy,
+	&vout_mclk_sel,
+	&vout_mclk_div,
+	&vout_mclk,
+	&vout_enc_sel,
+	&vout_enc_div,
+	&vout_enc,
+	&hcodec_0_sel,
+	&hcodec_0_div,
+	&hcodec_0,
+	&hcodec_1_sel,
+	&hcodec_1_div,
+	&hcodec_1,
+	&hcodec,
+	&vc9000e_aclk_sel,
+	&vc9000e_aclk_div,
+	&vc9000e_aclk,
+	&vc9000e_core_sel,
+	&vc9000e_core_div,
+	&vc9000e_core,
+	&csi_phy0_sel,
+	&csi_phy0_div,
+	&csi_phy0,
+	&dewarpa_sel,
+	&dewarpa_div,
+	&dewarpa,
+	&isp0_sel,
+	&isp0_div,
+	&isp0,
+	&nna_core_sel,
+	&nna_core_div,
+	&nna_core,
+	&ge2d_sel,
+	&ge2d_div,
+	&ge2d,
+	&vapb_sel,
+	&vapb_div,
+	&vapb,
+};
+
+static struct regmap_config clkc_regmap_config = {
+	.reg_bits       = 32,
+	.val_bits       = 32,
+	.reg_stride     = 4,
+};
+
+static struct meson_clk_hw_data c3_periphs_clks = {
+	.hws = c3_periphs_hw_clks,
+	.num = ARRAY_SIZE(c3_periphs_hw_clks),
+};
+
+static int aml_c3_peripherals_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct regmap *regmap;
+	void __iomem *base;
+	int clkid, ret, i;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	/* Populate regmap for the regmap backed clocks */
+	for (i = 0; i < ARRAY_SIZE(c3_periphs_clk_regmaps); i++)
+		c3_periphs_clk_regmaps[i]->map = regmap;
+
+	for (clkid = 0; clkid < c3_periphs_clks.num; clkid++) {
+		/* array might be sparse */
+		if (!c3_periphs_clks.hws[clkid])
+			continue;
+
+		ret = devm_clk_hw_register(dev, c3_periphs_clks.hws[clkid]);
+		if (ret) {
+			dev_err(dev, "Clock registration failed\n");
+			return ret;
+		}
+	}
+
+	return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
+					   &c3_periphs_clks);
+}
+
+static const struct of_device_id c3_peripherals_clkc_match_table[] = {
+	{
+		.compatible = "amlogic,c3-peripherals-clkc",
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, c3_peripherals_clkc_match_table);
+
+static struct platform_driver c3_peripherals_driver = {
+	.probe		= aml_c3_peripherals_probe,
+	.driver		= {
+		.name	= "c3-peripherals-clkc",
+		.of_match_table = c3_peripherals_clkc_match_table,
+	},
+};
+
+module_platform_driver(c3_peripherals_driver);
+MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/meson/c3-peripherals.h b/drivers/clk/meson/c3-peripherals.h
new file mode 100644
index 000000000000..ddcc23e25669
--- /dev/null
+++ b/drivers/clk/meson/c3-peripherals.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2023 Amlogic, inc.
+ * Author: Chuan Liu <chuan.liu@amlogic.com>
+ */
+
+#ifndef __AML_C3_PERIPHERALS_H__
+#define __AML_C3_PERIPHERALS_H__
+
+#define OSCIN_CTRL				0x0004
+#define RTC_BY_OSCIN_CTRL0			0x0008
+#define RTC_BY_OSCIN_CTRL1			0x000c
+#define RTC_CTRL				0x0010
+#define SYS_CLK_CTRL0				0x0040
+#define SYS_CLK_EN0_REG0			0x0044
+#define SYS_CLK_EN0_REG1			0x0048
+#define SYS_CLK_EN0_REG2			0x004c
+#define AXI_CLK_CTRL0				0x006c
+#define CLK12_24_CTRL				0x00a8
+#define AXI_CLK_EN0				0x00ac
+#define VDIN_MEAS_CLK_CTRL			0x00f8
+#define VAPB_CLK_CTRL				0x00fc
+#define MIPIDSI_PHY_CLK_CTRL			0x0104
+#define GE2D_CLK_CTRL				0x010c
+#define ISP0_CLK_CTRL				0x0110
+#define DEWARPA_CLK_CTRL			0x0114
+#define VOUTENC_CLK_CTRL			0x0118
+#define VDEC_CLK_CTRL				0x0140
+#define VDEC3_CLK_CTRL				0x0148
+#define TS_CLK_CTRL				0x0158
+#define ETH_CLK_CTRL				0x0164
+#define NAND_CLK_CTRL				0x0168
+#define SD_EMMC_CLK_CTRL			0x016c
+#define SPICC_CLK_CTRL				0x0174
+#define GEN_CLK_CTRL				0x0178
+#define SAR_CLK_CTRL0				0x017c
+#define PWM_CLK_AB_CTRL				0x0180
+#define PWM_CLK_CD_CTRL				0x0184
+#define PWM_CLK_EF_CTRL				0x0188
+#define PWM_CLK_GH_CTRL				0x018c
+#define PWM_CLK_IJ_CTRL				0x0190
+#define PWM_CLK_KL_CTRL				0x0194
+#define PWM_CLK_MN_CTRL				0x0198
+#define VC9000E_CLK_CTRL			0x019c
+#define SPIFC_CLK_CTRL				0x01a0
+#define NNA_CLK_CTRL				0x0220
+
+#endif  /* __AML_C3_PERIPHERALS_H__ */
-- 
2.37.1


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

* Re: [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings
  2023-10-10  6:29 ` [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings Xianwei Zhao
@ 2023-10-10  7:22   ` Rob Herring
  2023-10-10 13:21   ` Rob Herring
  1 sibling, 0 replies; 27+ messages in thread
From: Rob Herring @ 2023-10-10  7:22 UTC (permalink / raw)
  To: Xianwei Zhao
  Cc: Martin Blumenstingl, linux-clk, Chuan Liu, linux-amlogic,
	Kevin Hilman, linux-kernel, devicetree, Jerome Brunet,
	Krzysztof Kozlowski, Stephen Boyd, linux-arm-kernel,
	Michael Turquette, Rob Herring, Neil Armstrong


On Tue, 10 Oct 2023 14:29:14 +0800, Xianwei Zhao wrote:
> Add the C3 PLL clock controller dt-bindings for Amlogic C3 SoC family
> 
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> ---
> V1 -> V2: Fix errors when check dtbinding use "make dt_binding_check"
> ---
>  .../bindings/clock/amlogic,c3-pll-clkc.yaml   | 59 +++++++++++++++++++
>  .../dt-bindings/clock/amlogic,c3-pll-clkc.h   | 42 +++++++++++++
>  2 files changed, 101 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.example.dts:18:18: fatal error: dt-bindings/clock/amlogic,c3-peripherals-clkc.h: No such file or directory
   18 |         #include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1427: dt_binding_check] Error 2
make: *** [Makefile:234: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20231010062917.3624223-2-xianwei.zhao@amlogic.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


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

* Re: [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals clock controller bindings
  2023-10-10  6:29 ` [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals " Xianwei Zhao
@ 2023-10-10  7:22   ` Rob Herring
  2023-10-10 13:25   ` Rob Herring
  1 sibling, 0 replies; 27+ messages in thread
From: Rob Herring @ 2023-10-10  7:22 UTC (permalink / raw)
  To: Xianwei Zhao
  Cc: Jerome Brunet, Martin Blumenstingl, Krzysztof Kozlowski,
	Kevin Hilman, linux-kernel, Neil Armstrong, Chuan Liu,
	linux-arm-kernel, Michael Turquette, Stephen Boyd, Rob Herring,
	linux-amlogic, linux-clk, devicetree


On Tue, 10 Oct 2023 14:29:15 +0800, Xianwei Zhao wrote:
> Add the peripherals clock controller dt-bindings for Amlogic C3 SoC family
> 
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> ---
> V1 -> V2: Fix errors when check binding use "make dt_binding_check"
> ---
>  .../clock/amlogic,c3-peripherals-clkc.yaml    |  92 +++++++
>  .../clock/amlogic,c3-peripherals-clkc.h       | 230 ++++++++++++++++++
>  2 files changed, 322 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.example.dts:18:18: fatal error: dt-bindings/clock/amlogic,c3-pll-clkc.h: No such file or directory
   18 |         #include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1427: dt_binding_check] Error 2
make: *** [Makefile:234: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20231010062917.3624223-3-xianwei.zhao@amlogic.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


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

* Re: [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings
  2023-10-10  6:29 ` [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings Xianwei Zhao
  2023-10-10  7:22   ` Rob Herring
@ 2023-10-10 13:21   ` Rob Herring
  2023-10-11  2:50     ` Xianwei Zhao
  1 sibling, 1 reply; 27+ messages in thread
From: Rob Herring @ 2023-10-10 13:21 UTC (permalink / raw)
  To: Xianwei Zhao
  Cc: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel, Neil Armstrong, Jerome Brunet, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu

On Tue, Oct 10, 2023 at 02:29:14PM +0800, Xianwei Zhao wrote:
> Add the C3 PLL clock controller dt-bindings for Amlogic C3 SoC family
> 
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> ---
> V1 -> V2: Fix errors when check dtbinding use "make dt_binding_check"

Your patches aren't bisectable. It's fine if you want to combine patch 1 
and 2 into 1 patch. Or just use the raw numbers here instead of the 
header.

> ---
>  .../bindings/clock/amlogic,c3-pll-clkc.yaml   | 59 +++++++++++++++++++
>  .../dt-bindings/clock/amlogic,c3-pll-clkc.h   | 42 +++++++++++++
>  2 files changed, 101 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
> new file mode 100644
> index 000000000000..a646992917b7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
> @@ -0,0 +1,59 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/amlogic,c3-pll-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic C3 serials PLL Clock Controller

s/serials/Serials/

> +
> +maintainers:
> +  - Chuan Liu <chuan.liu@amlogic.com>
> +
> +properties:
> +  compatible:
> +    const: amlogic,c3-pll-clkc
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 1
> +    items:
> +      - description: input pll_in
> +      - description: input mclk_pll_in
> +
> +  clock-names:
> +    minItems: 1
> +    items:
> +      - const: pll_in
> +      - const: mclk_pll_in
> +
> +  "#clock-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - "#clock-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
> +    apb {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        clkc_pll: clock-controller@8000 {

Drop unused labels.

> +          compatible = "amlogic,c3-pll-clkc";

Your indentation is not consistent.

> +          reg = <0x0 0x8000 0x0 0x1a4>;
> +          clocks = <&clkc_periphs CLKID_PLL_IN>,
> +                   <&clkc_periphs CLKID_MCLK_PLL_IN>;
> +          clock-names = "pll_in", "mclk_pll_in";
> +          #clock-cells = <1>;
> +        };
> +    };
> diff --git a/include/dt-bindings/clock/amlogic,c3-pll-clkc.h b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
> new file mode 100644
> index 000000000000..aa731e8fae29
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
> @@ -0,0 +1,42 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
> +#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
> +
> +#define CLKID_FIXED_PLL_DCO			0
> +#define CLKID_FIXED_PLL				1
> +#define CLKID_FCLK_DIV40_DIV			2
> +#define CLKID_FCLK_DIV40			3
> +#define CLKID_FCLK_DIV2_DIV			4
> +#define CLKID_FCLK_DIV2				5
> +#define CLKID_FCLK_DIV2P5_DIV			6
> +#define CLKID_FCLK_DIV2P5			7
> +#define CLKID_FCLK_DIV3_DIV			8
> +#define CLKID_FCLK_DIV3				9
> +#define CLKID_FCLK_DIV4_DIV			10
> +#define CLKID_FCLK_DIV4				11
> +#define CLKID_FCLK_DIV5_DIV			12
> +#define CLKID_FCLK_DIV5				13
> +#define CLKID_FCLK_DIV7_DIV			14
> +#define CLKID_FCLK_DIV7				15
> +#define CLKID_GP0_PLL_DCO			16
> +#define CLKID_GP0_PLL				17
> +#define CLKID_HIFI_PLL_DCO			18
> +#define CLKID_HIFI_PLL				19
> +#define CLKID_MCLK_PLL_DCO			20
> +#define CLKID_MCLK_PLL				21
> +#define CLKID_MCLK_PLL_CLK			22
> +#define CLKID_MCLK0_SEL				23
> +#define CLKID_MCLK0_SEL_OUT			24
> +#define CLKID_MCLK0_DIV				25
> +#define CLKID_MCLK0				26
> +#define CLKID_MCLK1_SEL				27
> +#define CLKID_MCLK1_SEL_OUT			28
> +#define CLKID_MCLK1_DIV				29
> +#define CLKID_MCLK1				30
> +
> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H */
> 
> base-commit: 57b55c76aaf1ba50ecc6dcee5cd6843dc4d85239
> -- 
> 2.37.1
> 

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

* Re: [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals clock controller bindings
  2023-10-10  6:29 ` [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals " Xianwei Zhao
  2023-10-10  7:22   ` Rob Herring
@ 2023-10-10 13:25   ` Rob Herring
  2023-10-11  2:54     ` Xianwei Zhao
  1 sibling, 1 reply; 27+ messages in thread
From: Rob Herring @ 2023-10-10 13:25 UTC (permalink / raw)
  To: Xianwei Zhao
  Cc: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel, Neil Armstrong, Jerome Brunet, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu

On Tue, Oct 10, 2023 at 02:29:15PM +0800, Xianwei Zhao wrote:
> Add the peripherals clock controller dt-bindings for Amlogic C3 SoC family
> 
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> ---
> V1 -> V2: Fix errors when check binding use "make dt_binding_check"
> ---
>  .../clock/amlogic,c3-peripherals-clkc.yaml    |  92 +++++++
>  .../clock/amlogic,c3-peripherals-clkc.h       | 230 ++++++++++++++++++
>  2 files changed, 322 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
> new file mode 100644
> index 000000000000..a165f447ec41
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
> @@ -0,0 +1,92 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/amlogic,c3-peripherals-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic C serials Peripherals Clock Controller

C3?

Serials. Or just Serial as Peripherals is already plural?

> +
> +maintainers:
> +  - Chuan Liu <chuan.liu@amlogic.com>
> +
> +properties:
> +  compatible:
> +    const: amlogic,c3-peripherals-clkc
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 9
> +    items:
> +      - description: input oscillator (usually at 24MHz)
> +      - description: input fixed pll
> +      - description: input fixed pll div2
> +      - description: input fixed pll div2p5
> +      - description: input fixed pll div3
> +      - description: input fixed pll div4
> +      - description: input fixed pll div5
> +      - description: input fixed pll div7
> +      - description: input gp0 pll
> +      - description: input hifi pll
> +
> +  clock-names:
> +    minItems: 9
> +    items:
> +      - const: xtal
> +      - const: fixed_pll
> +      - const: fclk_div2
> +      - const: fclk_div2p5
> +      - const: fclk_div3
> +      - const: fclk_div4
> +      - const: fclk_div5
> +      - const: fclk_div7
> +      - const: gp0_pll
> +      - const: hifi_pll
> +
> +  "#clock-cells":
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - "#clock-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
> +    apb {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        clkc_periphs: clock-controller@0 {
> +          compatible = "amlogic,c3-peripherals-clkc";
> +          reg = <0x0 0x0 0x0 0x49c>;
> +          #clock-cells = <1>;
> +          clocks = <&xtal>,
> +                   <&clkc_pll CLKID_FIXED_PLL>,
> +                   <&clkc_pll CLKID_FCLK_DIV2>,
> +                   <&clkc_pll CLKID_FCLK_DIV2P5>,
> +                   <&clkc_pll CLKID_FCLK_DIV3>,
> +                   <&clkc_pll CLKID_FCLK_DIV4>,
> +                   <&clkc_pll CLKID_FCLK_DIV5>,
> +                   <&clkc_pll CLKID_FCLK_DIV7>,
> +                   <&clkc_pll CLKID_GP0_PLL>,
> +                   <&clkc_pll CLKID_HIFI_PLL>;
> +          clock-names = "xtal",
> +                        "fixed_pll",
> +                        "fclk_div2",
> +                        "fclk_div2p5",
> +                        "fclk_div3",
> +                        "fclk_div4",
> +                        "fclk_div5",
> +                        "fclk_div7",
> +                        "gp0_pll",
> +                        "hifi_pll";
> +        };
> +    };
> diff --git a/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
> new file mode 100644
> index 000000000000..82f9bf683ea0
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
> @@ -0,0 +1,230 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>

Should have a Co-developed-by tag if the author is different.

> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
> +#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
> +
> +#define CLKID_PLL_IN				0
> +#define CLKID_MCLK_PLL_IN			1
> +#define CLKID_RTC_XTAL_CLKIN			2
> +#define CLKID_RTC_32K_DIV			3
> +#define CLKID_RTC_32K_MUX			4
> +#define CLKID_RTC_32K				5
> +#define CLKID_RTC_CLK				6
> +#define CLKID_SYS_A_SEL				7
> +#define CLKID_SYS_A_DIV				8
> +#define CLKID_SYS_A				9
> +#define CLKID_SYS_B_SEL				10
> +#define CLKID_SYS_B_DIV				11
> +#define CLKID_SYS_B				12
> +#define CLKID_SYS_CLK				13
> +#define CLKID_AXI_A_SEL				14
> +#define CLKID_AXI_A_DIV				15
> +#define CLKID_AXI_A				16
> +#define CLKID_AXI_B_SEL				17
> +#define CLKID_AXI_B_DIV				18
> +#define CLKID_AXI_B				19
> +#define CLKID_AXI_CLK				20
> +#define CLKID_SYS_RESET_CTRL			21
> +#define CLKID_SYS_PWR_CTRL			22
> +#define CLKID_SYS_PAD_CTRL			23
> +#define CLKID_SYS_CTRL				24
> +#define CLKID_SYS_TS_PLL			25
> +#define CLKID_SYS_DEV_ARB			26
> +#define CLKID_SYS_MMC_PCLK			27
> +#define CLKID_SYS_CAPU				28
> +#define CLKID_SYS_CPU_CTRL			29
> +#define CLKID_SYS_JTAG_CTRL			30
> +#define CLKID_SYS_IR_CTRL			31
> +#define CLKID_SYS_IRQ_CTRL			32
> +#define CLKID_SYS_MSR_CLK			33
> +#define CLKID_SYS_ROM				34
> +#define CLKID_SYS_UART_F			35
> +#define CLKID_SYS_CPU_ARB			36
> +#define CLKID_SYS_RSA				37
> +#define CLKID_SYS_SAR_ADC			38
> +#define CLKID_SYS_STARTUP			39
> +#define CLKID_SYS_SECURE			40
> +#define CLKID_SYS_SPIFC				41
> +#define CLKID_SYS_NNA				42
> +#define CLKID_SYS_ETH_MAC			43
> +#define CLKID_SYS_GIC				44
> +#define CLKID_SYS_RAMA				45
> +#define CLKID_SYS_BIG_NIC			46
> +#define CLKID_SYS_RAMB				47
> +#define CLKID_SYS_AUDIO_PCLK			48
> +#define CLKID_SYS_PWM_KL			49
> +#define CLKID_SYS_PWM_IJ			50
> +#define CLKID_SYS_USB				51
> +#define CLKID_SYS_SD_EMMC_A			52
> +#define CLKID_SYS_SD_EMMC_C			53
> +#define CLKID_SYS_PWM_AB			54
> +#define CLKID_SYS_PWM_CD			55
> +#define CLKID_SYS_PWM_EF			56
> +#define CLKID_SYS_PWM_GH			57
> +#define CLKID_SYS_SPICC_1			58
> +#define CLKID_SYS_SPICC_0			59
> +#define CLKID_SYS_UART_A			60
> +#define CLKID_SYS_UART_B			61
> +#define CLKID_SYS_UART_C			62
> +#define CLKID_SYS_UART_D			63
> +#define CLKID_SYS_UART_E			64
> +#define CLKID_SYS_I2C_M_A			65
> +#define CLKID_SYS_I2C_M_B			66
> +#define CLKID_SYS_I2C_M_C			67
> +#define CLKID_SYS_I2C_M_D			68
> +#define CLKID_SYS_I2S_S_A			69
> +#define CLKID_SYS_RTC				70
> +#define CLKID_SYS_GE2D				71
> +#define CLKID_SYS_ISP				72
> +#define CLKID_SYS_GPV_ISP_NIC			73
> +#define CLKID_SYS_GPV_CVE_NIC			74
> +#define CLKID_SYS_MIPI_DSI_HOST			75
> +#define CLKID_SYS_MIPI_DSI_PHY			76
> +#define CLKID_SYS_ETH_PHY			77
> +#define CLKID_SYS_ACODEC			78
> +#define CLKID_SYS_DWAP				79
> +#define CLKID_SYS_DOS				80
> +#define CLKID_SYS_CVE				81
> +#define CLKID_SYS_VOUT				82
> +#define CLKID_SYS_VC9000E			83
> +#define CLKID_SYS_PWM_MN			84
> +#define CLKID_SYS_SD_EMMC_B			85
> +#define CLKID_AXI_SYS_NIC			86
> +#define CLKID_AXI_ISP_NIC			87
> +#define CLKID_AXI_CVE_NIC			88
> +#define CLKID_AXI_RAMB				89
> +#define CLKID_AXI_RAMA				90
> +#define CLKID_AXI_CPU_DMC			91
> +#define CLKID_AXI_NIC				92
> +#define CLKID_AXI_DMA				93
> +#define CLKID_AXI_MUX_NIC			94
> +#define CLKID_AXI_CAPU				95
> +#define CLKID_AXI_CVE				96
> +#define CLKID_AXI_DEV1_DMC			97
> +#define CLKID_AXI_DEV0_DMC			98
> +#define CLKID_AXI_DSP_DMC			99
> +#define CLKID_12_24M_IN				100
> +#define CLKID_12M_24M				101
> +#define CLKID_FCLK_25M_DIV			102
> +#define CLKID_FCLK_25M				103
> +#define CLKID_GEN_SEL				104
> +#define CLKID_GEN_DIV				105
> +#define CLKID_GEN				106
> +#define CLKID_SARADC_SEL			107
> +#define CLKID_SARADC_DIV			108
> +#define CLKID_SARADC				109
> +#define CLKID_PWM_A_SEL				110
> +#define CLKID_PWM_A_DIV				111
> +#define CLKID_PWM_A				112
> +#define CLKID_PWM_B_SEL				113
> +#define CLKID_PWM_B_DIV				114
> +#define CLKID_PWM_B				115
> +#define CLKID_PWM_C_SEL				116
> +#define CLKID_PWM_C_DIV				117
> +#define CLKID_PWM_C				118
> +#define CLKID_PWM_D_SEL				119
> +#define CLKID_PWM_D_DIV				120
> +#define CLKID_PWM_D				121
> +#define CLKID_PWM_E_SEL				122
> +#define CLKID_PWM_E_DIV				123
> +#define CLKID_PWM_E				124
> +#define CLKID_PWM_F_SEL				125
> +#define CLKID_PWM_F_DIV				126
> +#define CLKID_PWM_F				127
> +#define CLKID_PWM_G_SEL				128
> +#define CLKID_PWM_G_DIV				129
> +#define CLKID_PWM_G				130
> +#define CLKID_PWM_H_SEL				131
> +#define CLKID_PWM_H_DIV				132
> +#define CLKID_PWM_H				133
> +#define CLKID_PWM_I_SEL				134
> +#define CLKID_PWM_I_DIV				135
> +#define CLKID_PWM_I				136
> +#define CLKID_PWM_J_SEL				137
> +#define CLKID_PWM_J_DIV				138
> +#define CLKID_PWM_J				139
> +#define CLKID_PWM_K_SEL				140
> +#define CLKID_PWM_K_DIV				141
> +#define CLKID_PWM_K				142
> +#define CLKID_PWM_L_SEL				143
> +#define CLKID_PWM_L_DIV				144
> +#define CLKID_PWM_L				145
> +#define CLKID_PWM_M_SEL				146
> +#define CLKID_PWM_M_DIV				147
> +#define CLKID_PWM_M				148
> +#define CLKID_PWM_N_SEL				149
> +#define CLKID_PWM_N_DIV				150
> +#define CLKID_PWM_N				151
> +#define CLKID_SPICC_A_SEL			152
> +#define CLKID_SPICC_A_DIV			153
> +#define CLKID_SPICC_A				154
> +#define CLKID_SPICC_B_SEL			155
> +#define CLKID_SPICC_B_DIV			156
> +#define CLKID_SPICC_B				157
> +#define CLKID_SPIFC_SEL				158
> +#define CLKID_SPIFC_DIV				159
> +#define CLKID_SPIFC				160
> +#define CLKID_SD_EMMC_A_SEL			161
> +#define CLKID_SD_EMMC_A_DIV			162
> +#define CLKID_SD_EMMC_A				163
> +#define CLKID_SD_EMMC_B_SEL			164
> +#define CLKID_SD_EMMC_B_DIV			165
> +#define CLKID_SD_EMMC_B				166
> +#define CLKID_SD_EMMC_C_SEL			167
> +#define CLKID_SD_EMMC_C_DIV			168
> +#define CLKID_SD_EMMC_C				169
> +#define CLKID_TS_DIV				170
> +#define CLKID_TS				171
> +#define CLKID_ETH_125M_DIV			172
> +#define CLKID_ETH_125M				173
> +#define CLKID_ETH_RMII_DIV			174
> +#define CLKID_ETH_RMII				175
> +#define CLKID_MIPI_DSI_MEAS_SEL			176
> +#define CLKID_MIPI_DSI_MEAS_DIV			177
> +#define CLKID_MIPI_DSI_MEAS			178
> +#define CLKID_DSI_PHY_SEL			179
> +#define CLKID_DSI_PHY_DIV			180
> +#define CLKID_DSI_PHY				181
> +#define CLKID_VOUT_MCLK_SEL			182
> +#define CLKID_VOUT_MCLK_DIV			183
> +#define CLKID_VOUT_MCLK				184
> +#define CLKID_VOUT_ENC_SEL			185
> +#define CLKID_VOUT_ENC_DIV			186
> +#define CLKID_VOUT_ENC				187
> +#define CLKID_HCODEC_0_SEL			188
> +#define CLKID_HCODEC_0_DIV			189
> +#define CLKID_HCODEC_0				190
> +#define CLKID_HCODEC_1_SEL			191
> +#define CLKID_HCODEC_1_DIV			192
> +#define CLKID_HCODEC_1				193
> +#define CLKID_HCODEC				194
> +#define CLKID_VC9000E_ACLK_SEL			195
> +#define CLKID_VC9000E_ACLK_DIV			196
> +#define CLKID_VC9000E_ACLK			197
> +#define CLKID_VC9000E_CORE_SEL			198
> +#define CLKID_VC9000E_CORE_DIV			199
> +#define CLKID_VC9000E_CORE			200
> +#define CLKID_CSI_PHY0_SEL			201
> +#define CLKID_CSI_PHY0_DIV			202
> +#define CLKID_CSI_PHY0				203
> +#define CLKID_DEWARPA_SEL			204
> +#define CLKID_DEWARPA_DIV			205
> +#define CLKID_DEWARPA				206
> +#define CLKID_ISP0_SEL				207
> +#define CLKID_ISP0_DIV				208
> +#define CLKID_ISP0				209
> +#define CLKID_NNA_CORE_SEL			210
> +#define CLKID_NNA_CORE_DIV			211
> +#define CLKID_NNA_CORE				212
> +#define CLKID_GE2D_SEL				213
> +#define CLKID_GE2D_DIV				214
> +#define CLKID_GE2D				215
> +#define CLKID_VAPB_SEL				216
> +#define CLKID_VAPB_DIV				217
> +#define CLKID_VAPB				218
> +
> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H */
> -- 
> 2.37.1
> 

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

* Re: [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings
  2023-10-10 13:21   ` Rob Herring
@ 2023-10-11  2:50     ` Xianwei Zhao
  2023-10-13  7:35       ` Jerome Brunet
  0 siblings, 1 reply; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-11  2:50 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel, Neil Armstrong, Jerome Brunet, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu

Hi Rob,
     Thanks for your advise.

On 2023/10/10 21:21, Rob Herring wrote:
> [ EXTERNAL EMAIL ]
> 
> On Tue, Oct 10, 2023 at 02:29:14PM +0800, Xianwei Zhao wrote:
>> Add the C3 PLL clock controller dt-bindings for Amlogic C3 SoC family
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>> ---
>> V1 -> V2: Fix errors when check dtbinding use "make dt_binding_check"
> 
> Your patches aren't bisectable. It's fine if you want to combine patch 1
> and 2 into 1 patch. Or just use the raw numbers here instead of the
> header.
> 
I will combine patch 1 and 2 into 1 patch in V3.
>> ---
>>   .../bindings/clock/amlogic,c3-pll-clkc.yaml   | 59 +++++++++++++++++++
>>   .../dt-bindings/clock/amlogic,c3-pll-clkc.h   | 42 +++++++++++++
>>   2 files changed, 101 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>>   create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>> new file mode 100644
>> index 000000000000..a646992917b7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>> @@ -0,0 +1,59 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/amlogic,c3-pll-clkc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic C3 serials PLL Clock Controller
> 
> s/serials/Serials/
> 
Will fix
>> +
>> +maintainers:
>> +  - Chuan Liu <chuan.liu@amlogic.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: amlogic,c3-pll-clkc
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    minItems: 1
>> +    items:
>> +      - description: input pll_in
>> +      - description: input mclk_pll_in
>> +
>> +  clock-names:
>> +    minItems: 1
>> +    items:
>> +      - const: pll_in
>> +      - const: mclk_pll_in
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - "#clock-cells"
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
>> +    apb {
>> +        #address-cells = <2>;
>> +        #size-cells = <2>;
>> +
>> +        clkc_pll: clock-controller@8000 {
> 
> Drop unused labels.
> 
Will delete clkc_pll.
>> +          compatible = "amlogic,c3-pll-clkc";
> 
> Your indentation is not consistent.
> 
Will fix it in V3.
>> +          reg = <0x0 0x8000 0x0 0x1a4>;
>> +          clocks = <&clkc_periphs CLKID_PLL_IN>,
>> +                   <&clkc_periphs CLKID_MCLK_PLL_IN>;
>> +          clock-names = "pll_in", "mclk_pll_in";
>> +          #clock-cells = <1>;
>> +        };
>> +    };
>> diff --git a/include/dt-bindings/clock/amlogic,c3-pll-clkc.h b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>> new file mode 100644
>> index 000000000000..aa731e8fae29
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>> @@ -0,0 +1,42 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>> + */
>> +
>> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
>> +#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
>> +
>> +#define CLKID_FIXED_PLL_DCO                  0
>> +#define CLKID_FIXED_PLL                              1
>> +#define CLKID_FCLK_DIV40_DIV                 2
>> +#define CLKID_FCLK_DIV40                     3
>> +#define CLKID_FCLK_DIV2_DIV                  4
>> +#define CLKID_FCLK_DIV2                              5
>> +#define CLKID_FCLK_DIV2P5_DIV                        6
>> +#define CLKID_FCLK_DIV2P5                    7
>> +#define CLKID_FCLK_DIV3_DIV                  8
>> +#define CLKID_FCLK_DIV3                              9
>> +#define CLKID_FCLK_DIV4_DIV                  10
>> +#define CLKID_FCLK_DIV4                              11
>> +#define CLKID_FCLK_DIV5_DIV                  12
>> +#define CLKID_FCLK_DIV5                              13
>> +#define CLKID_FCLK_DIV7_DIV                  14
>> +#define CLKID_FCLK_DIV7                              15
>> +#define CLKID_GP0_PLL_DCO                    16
>> +#define CLKID_GP0_PLL                                17
>> +#define CLKID_HIFI_PLL_DCO                   18
>> +#define CLKID_HIFI_PLL                               19
>> +#define CLKID_MCLK_PLL_DCO                   20
>> +#define CLKID_MCLK_PLL                               21
>> +#define CLKID_MCLK_PLL_CLK                   22
>> +#define CLKID_MCLK0_SEL                              23
>> +#define CLKID_MCLK0_SEL_OUT                  24
>> +#define CLKID_MCLK0_DIV                              25
>> +#define CLKID_MCLK0                          26
>> +#define CLKID_MCLK1_SEL                              27
>> +#define CLKID_MCLK1_SEL_OUT                  28
>> +#define CLKID_MCLK1_DIV                              29
>> +#define CLKID_MCLK1                          30
>> +
>> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H */
>>
>> base-commit: 57b55c76aaf1ba50ecc6dcee5cd6843dc4d85239
>> --
>> 2.37.1
>>

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

* Re: [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals clock controller bindings
  2023-10-10 13:25   ` Rob Herring
@ 2023-10-11  2:54     ` Xianwei Zhao
  0 siblings, 0 replies; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-11  2:54 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel, Neil Armstrong, Jerome Brunet, Michael Turquette,
	Stephen Boyd, Krzysztof Kozlowski, Kevin Hilman,
	Martin Blumenstingl, Chuan Liu

Hi Rob,
     Thanks for your advise.

On 2023/10/10 21:25, Rob Herring wrote:
> [ EXTERNAL EMAIL ]
> 
> On Tue, Oct 10, 2023 at 02:29:15PM +0800, Xianwei Zhao wrote:
>> Add the peripherals clock controller dt-bindings for Amlogic C3 SoC family
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>> ---
>> V1 -> V2: Fix errors when check binding use "make dt_binding_check"
>> ---
>>   .../clock/amlogic,c3-peripherals-clkc.yaml    |  92 +++++++
>>   .../clock/amlogic,c3-peripherals-clkc.h       | 230 ++++++++++++++++++
>>   2 files changed, 322 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
>>   create mode 100644 include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
>> new file mode 100644
>> index 000000000000..a165f447ec41
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
>> @@ -0,0 +1,92 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/amlogic,c3-peripherals-clkc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic C serials Peripherals Clock Controller
> 
> C3?
> 
> Serials. Or just Serial as Peripherals is already plural?
>
Will fix it.

>> +
>> +maintainers:
>> +  - Chuan Liu <chuan.liu@amlogic.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: amlogic,c3-peripherals-clkc
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    minItems: 9
>> +    items:
>> +      - description: input oscillator (usually at 24MHz)
>> +      - description: input fixed pll
>> +      - description: input fixed pll div2
>> +      - description: input fixed pll div2p5
>> +      - description: input fixed pll div3
>> +      - description: input fixed pll div4
>> +      - description: input fixed pll div5
>> +      - description: input fixed pll div7
>> +      - description: input gp0 pll
>> +      - description: input hifi pll
>> +
>> +  clock-names:
>> +    minItems: 9
>> +    items:
>> +      - const: xtal
>> +      - const: fixed_pll
>> +      - const: fclk_div2
>> +      - const: fclk_div2p5
>> +      - const: fclk_div3
>> +      - const: fclk_div4
>> +      - const: fclk_div5
>> +      - const: fclk_div7
>> +      - const: gp0_pll
>> +      - const: hifi_pll
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - clock-names
>> +  - "#clock-cells"
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
>> +    apb {
>> +        #address-cells = <2>;
>> +        #size-cells = <2>;
>> +
>> +        clkc_periphs: clock-controller@0 {
>> +          compatible = "amlogic,c3-peripherals-clkc";
>> +          reg = <0x0 0x0 0x0 0x49c>;
>> +          #clock-cells = <1>;
>> +          clocks = <&xtal>,
>> +                   <&clkc_pll CLKID_FIXED_PLL>,
>> +                   <&clkc_pll CLKID_FCLK_DIV2>,
>> +                   <&clkc_pll CLKID_FCLK_DIV2P5>,
>> +                   <&clkc_pll CLKID_FCLK_DIV3>,
>> +                   <&clkc_pll CLKID_FCLK_DIV4>,
>> +                   <&clkc_pll CLKID_FCLK_DIV5>,
>> +                   <&clkc_pll CLKID_FCLK_DIV7>,
>> +                   <&clkc_pll CLKID_GP0_PLL>,
>> +                   <&clkc_pll CLKID_HIFI_PLL>;
>> +          clock-names = "xtal",
>> +                        "fixed_pll",
>> +                        "fclk_div2",
>> +                        "fclk_div2p5",
>> +                        "fclk_div3",
>> +                        "fclk_div4",
>> +                        "fclk_div5",
>> +                        "fclk_div7",
>> +                        "gp0_pll",
>> +                        "hifi_pll";
>> +        };
>> +    };
>> diff --git a/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
>> new file mode 100644
>> index 000000000000..82f9bf683ea0
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
>> @@ -0,0 +1,230 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> 
> Should have a Co-developed-by tag if the author is different.
> 
Will add Co-developed-by tag.
>> + */
>> +
>> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
>> +#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
>> +
>> +#define CLKID_PLL_IN                         0
>> +#define CLKID_MCLK_PLL_IN                    1
>> +#define CLKID_RTC_XTAL_CLKIN                 2
>> +#define CLKID_RTC_32K_DIV                    3
>> +#define CLKID_RTC_32K_MUX                    4
>> +#define CLKID_RTC_32K                                5
>> +#define CLKID_RTC_CLK                                6
>> +#define CLKID_SYS_A_SEL                              7
>> +#define CLKID_SYS_A_DIV                              8
>> +#define CLKID_SYS_A                          9
>> +#define CLKID_SYS_B_SEL                              10
>> +#define CLKID_SYS_B_DIV                              11
>> +#define CLKID_SYS_B                          12
>> +#define CLKID_SYS_CLK                                13
>> +#define CLKID_AXI_A_SEL                              14
>> +#define CLKID_AXI_A_DIV                              15
>> +#define CLKID_AXI_A                          16
>> +#define CLKID_AXI_B_SEL                              17
>> +#define CLKID_AXI_B_DIV                              18
>> +#define CLKID_AXI_B                          19
>> +#define CLKID_AXI_CLK                                20
>> +#define CLKID_SYS_RESET_CTRL                 21
>> +#define CLKID_SYS_PWR_CTRL                   22
>> +#define CLKID_SYS_PAD_CTRL                   23
>> +#define CLKID_SYS_CTRL                               24
>> +#define CLKID_SYS_TS_PLL                     25
>> +#define CLKID_SYS_DEV_ARB                    26
>> +#define CLKID_SYS_MMC_PCLK                   27
>> +#define CLKID_SYS_CAPU                               28
>> +#define CLKID_SYS_CPU_CTRL                   29
>> +#define CLKID_SYS_JTAG_CTRL                  30
>> +#define CLKID_SYS_IR_CTRL                    31
>> +#define CLKID_SYS_IRQ_CTRL                   32
>> +#define CLKID_SYS_MSR_CLK                    33
>> +#define CLKID_SYS_ROM                                34
>> +#define CLKID_SYS_UART_F                     35
>> +#define CLKID_SYS_CPU_ARB                    36
>> +#define CLKID_SYS_RSA                                37
>> +#define CLKID_SYS_SAR_ADC                    38
>> +#define CLKID_SYS_STARTUP                    39
>> +#define CLKID_SYS_SECURE                     40
>> +#define CLKID_SYS_SPIFC                              41
>> +#define CLKID_SYS_NNA                                42
>> +#define CLKID_SYS_ETH_MAC                    43
>> +#define CLKID_SYS_GIC                                44
>> +#define CLKID_SYS_RAMA                               45
>> +#define CLKID_SYS_BIG_NIC                    46
>> +#define CLKID_SYS_RAMB                               47
>> +#define CLKID_SYS_AUDIO_PCLK                 48
>> +#define CLKID_SYS_PWM_KL                     49
>> +#define CLKID_SYS_PWM_IJ                     50
>> +#define CLKID_SYS_USB                                51
>> +#define CLKID_SYS_SD_EMMC_A                  52
>> +#define CLKID_SYS_SD_EMMC_C                  53
>> +#define CLKID_SYS_PWM_AB                     54
>> +#define CLKID_SYS_PWM_CD                     55
>> +#define CLKID_SYS_PWM_EF                     56
>> +#define CLKID_SYS_PWM_GH                     57
>> +#define CLKID_SYS_SPICC_1                    58
>> +#define CLKID_SYS_SPICC_0                    59
>> +#define CLKID_SYS_UART_A                     60
>> +#define CLKID_SYS_UART_B                     61
>> +#define CLKID_SYS_UART_C                     62
>> +#define CLKID_SYS_UART_D                     63
>> +#define CLKID_SYS_UART_E                     64
>> +#define CLKID_SYS_I2C_M_A                    65
>> +#define CLKID_SYS_I2C_M_B                    66
>> +#define CLKID_SYS_I2C_M_C                    67
>> +#define CLKID_SYS_I2C_M_D                    68
>> +#define CLKID_SYS_I2S_S_A                    69
>> +#define CLKID_SYS_RTC                                70
>> +#define CLKID_SYS_GE2D                               71
>> +#define CLKID_SYS_ISP                                72
>> +#define CLKID_SYS_GPV_ISP_NIC                        73
>> +#define CLKID_SYS_GPV_CVE_NIC                        74
>> +#define CLKID_SYS_MIPI_DSI_HOST                      75
>> +#define CLKID_SYS_MIPI_DSI_PHY                       76
>> +#define CLKID_SYS_ETH_PHY                    77
>> +#define CLKID_SYS_ACODEC                     78
>> +#define CLKID_SYS_DWAP                               79
>> +#define CLKID_SYS_DOS                                80
>> +#define CLKID_SYS_CVE                                81
>> +#define CLKID_SYS_VOUT                               82
>> +#define CLKID_SYS_VC9000E                    83
>> +#define CLKID_SYS_PWM_MN                     84
>> +#define CLKID_SYS_SD_EMMC_B                  85
>> +#define CLKID_AXI_SYS_NIC                    86
>> +#define CLKID_AXI_ISP_NIC                    87
>> +#define CLKID_AXI_CVE_NIC                    88
>> +#define CLKID_AXI_RAMB                               89
>> +#define CLKID_AXI_RAMA                               90
>> +#define CLKID_AXI_CPU_DMC                    91
>> +#define CLKID_AXI_NIC                                92
>> +#define CLKID_AXI_DMA                                93
>> +#define CLKID_AXI_MUX_NIC                    94
>> +#define CLKID_AXI_CAPU                               95
>> +#define CLKID_AXI_CVE                                96
>> +#define CLKID_AXI_DEV1_DMC                   97
>> +#define CLKID_AXI_DEV0_DMC                   98
>> +#define CLKID_AXI_DSP_DMC                    99
>> +#define CLKID_12_24M_IN                              100
>> +#define CLKID_12M_24M                                101
>> +#define CLKID_FCLK_25M_DIV                   102
>> +#define CLKID_FCLK_25M                               103
>> +#define CLKID_GEN_SEL                                104
>> +#define CLKID_GEN_DIV                                105
>> +#define CLKID_GEN                            106
>> +#define CLKID_SARADC_SEL                     107
>> +#define CLKID_SARADC_DIV                     108
>> +#define CLKID_SARADC                         109
>> +#define CLKID_PWM_A_SEL                              110
>> +#define CLKID_PWM_A_DIV                              111
>> +#define CLKID_PWM_A                          112
>> +#define CLKID_PWM_B_SEL                              113
>> +#define CLKID_PWM_B_DIV                              114
>> +#define CLKID_PWM_B                          115
>> +#define CLKID_PWM_C_SEL                              116
>> +#define CLKID_PWM_C_DIV                              117
>> +#define CLKID_PWM_C                          118
>> +#define CLKID_PWM_D_SEL                              119
>> +#define CLKID_PWM_D_DIV                              120
>> +#define CLKID_PWM_D                          121
>> +#define CLKID_PWM_E_SEL                              122
>> +#define CLKID_PWM_E_DIV                              123
>> +#define CLKID_PWM_E                          124
>> +#define CLKID_PWM_F_SEL                              125
>> +#define CLKID_PWM_F_DIV                              126
>> +#define CLKID_PWM_F                          127
>> +#define CLKID_PWM_G_SEL                              128
>> +#define CLKID_PWM_G_DIV                              129
>> +#define CLKID_PWM_G                          130
>> +#define CLKID_PWM_H_SEL                              131
>> +#define CLKID_PWM_H_DIV                              132
>> +#define CLKID_PWM_H                          133
>> +#define CLKID_PWM_I_SEL                              134
>> +#define CLKID_PWM_I_DIV                              135
>> +#define CLKID_PWM_I                          136
>> +#define CLKID_PWM_J_SEL                              137
>> +#define CLKID_PWM_J_DIV                              138
>> +#define CLKID_PWM_J                          139
>> +#define CLKID_PWM_K_SEL                              140
>> +#define CLKID_PWM_K_DIV                              141
>> +#define CLKID_PWM_K                          142
>> +#define CLKID_PWM_L_SEL                              143
>> +#define CLKID_PWM_L_DIV                              144
>> +#define CLKID_PWM_L                          145
>> +#define CLKID_PWM_M_SEL                              146
>> +#define CLKID_PWM_M_DIV                              147
>> +#define CLKID_PWM_M                          148
>> +#define CLKID_PWM_N_SEL                              149
>> +#define CLKID_PWM_N_DIV                              150
>> +#define CLKID_PWM_N                          151
>> +#define CLKID_SPICC_A_SEL                    152
>> +#define CLKID_SPICC_A_DIV                    153
>> +#define CLKID_SPICC_A                                154
>> +#define CLKID_SPICC_B_SEL                    155
>> +#define CLKID_SPICC_B_DIV                    156
>> +#define CLKID_SPICC_B                                157
>> +#define CLKID_SPIFC_SEL                              158
>> +#define CLKID_SPIFC_DIV                              159
>> +#define CLKID_SPIFC                          160
>> +#define CLKID_SD_EMMC_A_SEL                  161
>> +#define CLKID_SD_EMMC_A_DIV                  162
>> +#define CLKID_SD_EMMC_A                              163
>> +#define CLKID_SD_EMMC_B_SEL                  164
>> +#define CLKID_SD_EMMC_B_DIV                  165
>> +#define CLKID_SD_EMMC_B                              166
>> +#define CLKID_SD_EMMC_C_SEL                  167
>> +#define CLKID_SD_EMMC_C_DIV                  168
>> +#define CLKID_SD_EMMC_C                              169
>> +#define CLKID_TS_DIV                         170
>> +#define CLKID_TS                             171
>> +#define CLKID_ETH_125M_DIV                   172
>> +#define CLKID_ETH_125M                               173
>> +#define CLKID_ETH_RMII_DIV                   174
>> +#define CLKID_ETH_RMII                               175
>> +#define CLKID_MIPI_DSI_MEAS_SEL                      176
>> +#define CLKID_MIPI_DSI_MEAS_DIV                      177
>> +#define CLKID_MIPI_DSI_MEAS                  178
>> +#define CLKID_DSI_PHY_SEL                    179
>> +#define CLKID_DSI_PHY_DIV                    180
>> +#define CLKID_DSI_PHY                                181
>> +#define CLKID_VOUT_MCLK_SEL                  182
>> +#define CLKID_VOUT_MCLK_DIV                  183
>> +#define CLKID_VOUT_MCLK                              184
>> +#define CLKID_VOUT_ENC_SEL                   185
>> +#define CLKID_VOUT_ENC_DIV                   186
>> +#define CLKID_VOUT_ENC                               187
>> +#define CLKID_HCODEC_0_SEL                   188
>> +#define CLKID_HCODEC_0_DIV                   189
>> +#define CLKID_HCODEC_0                               190
>> +#define CLKID_HCODEC_1_SEL                   191
>> +#define CLKID_HCODEC_1_DIV                   192
>> +#define CLKID_HCODEC_1                               193
>> +#define CLKID_HCODEC                         194
>> +#define CLKID_VC9000E_ACLK_SEL                       195
>> +#define CLKID_VC9000E_ACLK_DIV                       196
>> +#define CLKID_VC9000E_ACLK                   197
>> +#define CLKID_VC9000E_CORE_SEL                       198
>> +#define CLKID_VC9000E_CORE_DIV                       199
>> +#define CLKID_VC9000E_CORE                   200
>> +#define CLKID_CSI_PHY0_SEL                   201
>> +#define CLKID_CSI_PHY0_DIV                   202
>> +#define CLKID_CSI_PHY0                               203
>> +#define CLKID_DEWARPA_SEL                    204
>> +#define CLKID_DEWARPA_DIV                    205
>> +#define CLKID_DEWARPA                                206
>> +#define CLKID_ISP0_SEL                               207
>> +#define CLKID_ISP0_DIV                               208
>> +#define CLKID_ISP0                           209
>> +#define CLKID_NNA_CORE_SEL                   210
>> +#define CLKID_NNA_CORE_DIV                   211
>> +#define CLKID_NNA_CORE                               212
>> +#define CLKID_GE2D_SEL                               213
>> +#define CLKID_GE2D_DIV                               214
>> +#define CLKID_GE2D                           215
>> +#define CLKID_VAPB_SEL                               216
>> +#define CLKID_VAPB_DIV                               217
>> +#define CLKID_VAPB                           218
>> +
>> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H */
>> --
>> 2.37.1
>>

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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-10  6:29 ` [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver Xianwei Zhao
@ 2023-10-12 23:51   ` Stephen Boyd
  2023-10-13  7:38     ` Jerome Brunet
  2023-10-13  8:46   ` Jerome Brunet
  1 sibling, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2023-10-12 23:51 UTC (permalink / raw)
  To: Xianwei Zhao, devicetree, linux-amlogic, linux-arm-kernel,
	linux-clk, linux-kernel
  Cc: Neil Armstrong, Jerome Brunet, Michael Turquette, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu,
	Xianwei Zhao

Quoting Xianwei Zhao (2023-10-09 23:29:17)
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 76be4bbd2afb..c8d59d28c8ff 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
>           Say Y if you want the board to work, because PLLs are the parent of most
>           peripherals.
>  
> +config COMMON_CLK_C3_PERIPHERALS
> +       tristate "Amlogic C3 peripherals clock controller"
> +       default y

Why are these default y? They should depend on something like ARM64 and
even then I don't see why we want to enable them by default if we're
building the ARM64 kernel.

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

* Re: [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings
  2023-10-11  2:50     ` Xianwei Zhao
@ 2023-10-13  7:35       ` Jerome Brunet
  2023-10-16  6:41         ` Xianwei Zhao
  0 siblings, 1 reply; 27+ messages in thread
From: Jerome Brunet @ 2023-10-13  7:35 UTC (permalink / raw)
  To: Xianwei Zhao, Rob Herring
  Cc: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel, Neil Armstrong, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu


On Wed 11 Oct 2023 at 10:50, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:

> Hi Rob,
>     Thanks for your advise.
>
> On 2023/10/10 21:21, Rob Herring wrote:
>> [ EXTERNAL EMAIL ]
>> On Tue, Oct 10, 2023 at 02:29:14PM +0800, Xianwei Zhao wrote:
>>> Add the C3 PLL clock controller dt-bindings for Amlogic C3 SoC family
>>>
>>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>>> ---
>>> V1 -> V2: Fix errors when check dtbinding use "make dt_binding_check"
>> Your patches aren't bisectable. It's fine if you want to combine patch 1
>> and 2 into 1 patch. Or just use the raw numbers here instead of the
>> header.
>> 
> I will combine patch 1 and 2 into 1 patch in V3.

I'd prefer if you used raw ids or even fake node for the example, like
<&pll_in> and <&mpll_in> for readability, rather than combining the patches

>>> ---
>>>   .../bindings/clock/amlogic,c3-pll-clkc.yaml   | 59 +++++++++++++++++++
>>>   .../dt-bindings/clock/amlogic,c3-pll-clkc.h   | 42 +++++++++++++
>>>   2 files changed, 101 insertions(+)
>>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>>>   create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>>> new file mode 100644
>>> index 000000000000..a646992917b7
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>>> @@ -0,0 +1,59 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/clock/amlogic,c3-pll-clkc.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Amlogic C3 serials PLL Clock Controller
>> s/serials/Serials/
>> 
> Will fix
>>> +
>>> +maintainers:
>>> +  - Chuan Liu <chuan.liu@amlogic.com>
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: amlogic,c3-pll-clkc
>>> +
>>> +  reg:
>>> +    maxItems: 1
>>> +
>>> +  clocks:
>>> +    minItems: 1
>>> +    items:
>>> +      - description: input pll_in
>>> +      - description: input mclk_pll_in
>>> +
>>> +  clock-names:
>>> +    minItems: 1
>>> +    items:
>>> +      - const: pll_in
>>> +      - const: mclk_pll_in
>>> +
>>> +  "#clock-cells":
>>> +    const: 1
>>> +
>>> +required:
>>> +  - compatible
>>> +  - reg
>>> +  - clocks
>>> +  - clock-names
>>> +  - "#clock-cells"
>>> +
>>> +additionalProperties: false
>>> +
>>> +examples:
>>> +  - |
>>> +    #include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
>>> +    apb {
>>> +        #address-cells = <2>;
>>> +        #size-cells = <2>;
>>> +
>>> +        clkc_pll: clock-controller@8000 {
>> Drop unused labels.
>> 
> Will delete clkc_pll.
>>> +          compatible = "amlogic,c3-pll-clkc";
>> Your indentation is not consistent.
>> 
> Will fix it in V3.
>>> +          reg = <0x0 0x8000 0x0 0x1a4>;
>>> +          clocks = <&clkc_periphs CLKID_PLL_IN>,
>>> +                   <&clkc_periphs CLKID_MCLK_PLL_IN>;
>>> +          clock-names = "pll_in", "mclk_pll_in";
>>> +          #clock-cells = <1>;
>>> +        };
>>> +    };
>>> diff --git a/include/dt-bindings/clock/amlogic,c3-pll-clkc.h b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>>> new file mode 100644
>>> index 000000000000..aa731e8fae29
>>> --- /dev/null
>>> +++ b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>>> @@ -0,0 +1,42 @@
>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>>> +/*
>>> + * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>> + */
>>> +
>>> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
>>> +#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
>>> +
>>> +#define CLKID_FIXED_PLL_DCO                  0
>>> +#define CLKID_FIXED_PLL                              1
>>> +#define CLKID_FCLK_DIV40_DIV                 2
>>> +#define CLKID_FCLK_DIV40                     3
>>> +#define CLKID_FCLK_DIV2_DIV                  4
>>> +#define CLKID_FCLK_DIV2                              5
>>> +#define CLKID_FCLK_DIV2P5_DIV                        6
>>> +#define CLKID_FCLK_DIV2P5                    7
>>> +#define CLKID_FCLK_DIV3_DIV                  8
>>> +#define CLKID_FCLK_DIV3                              9
>>> +#define CLKID_FCLK_DIV4_DIV                  10
>>> +#define CLKID_FCLK_DIV4                              11
>>> +#define CLKID_FCLK_DIV5_DIV                  12
>>> +#define CLKID_FCLK_DIV5                              13
>>> +#define CLKID_FCLK_DIV7_DIV                  14
>>> +#define CLKID_FCLK_DIV7                              15
>>> +#define CLKID_GP0_PLL_DCO                    16
>>> +#define CLKID_GP0_PLL                                17
>>> +#define CLKID_HIFI_PLL_DCO                   18
>>> +#define CLKID_HIFI_PLL                               19
>>> +#define CLKID_MCLK_PLL_DCO                   20
>>> +#define CLKID_MCLK_PLL                               21
>>> +#define CLKID_MCLK_PLL_CLK                   22
>>> +#define CLKID_MCLK0_SEL                              23
>>> +#define CLKID_MCLK0_SEL_OUT                  24
>>> +#define CLKID_MCLK0_DIV                              25
>>> +#define CLKID_MCLK0                          26
>>> +#define CLKID_MCLK1_SEL                              27
>>> +#define CLKID_MCLK1_SEL_OUT                  28
>>> +#define CLKID_MCLK1_DIV                              29
>>> +#define CLKID_MCLK1                          30
>>> +
>>> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H */
>>>
>>> base-commit: 57b55c76aaf1ba50ecc6dcee5cd6843dc4d85239
>>> --
>>> 2.37.1
>>>


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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-12 23:51   ` Stephen Boyd
@ 2023-10-13  7:38     ` Jerome Brunet
  2023-10-13 22:01       ` Stephen Boyd
  0 siblings, 1 reply; 27+ messages in thread
From: Jerome Brunet @ 2023-10-13  7:38 UTC (permalink / raw)
  To: Stephen Boyd, Xianwei Zhao, devicetree, linux-amlogic,
	linux-arm-kernel, linux-clk, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu


On Thu 12 Oct 2023 at 16:51, Stephen Boyd <sboyd@kernel.org> wrote:

> Quoting Xianwei Zhao (2023-10-09 23:29:17)
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index 76be4bbd2afb..c8d59d28c8ff 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
>>           Say Y if you want the board to work, because PLLs are the parent of most
>>           peripherals.
>>  
>> +config COMMON_CLK_C3_PERIPHERALS
>> +       tristate "Amlogic C3 peripherals clock controller"
>> +       default y
>
> Why are these default y? They should depend on something like ARM64 and
> even then I don't see why we want to enable them by default if we're
> building the ARM64 kernel.

Should indeed depend on ARM64.

Those are the main clock controllers. Like for other AML SoC families,
they are necessary to boot the device which is why they use 'default y'

Is it a problem ?

The whole meson directory depends on ARCH_MESON, so the drivers will go
away if Amlogic support is removed on ARM64.

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

* Re: [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock
  2023-10-10  6:29 ` [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock Xianwei Zhao
@ 2023-10-13  7:49   ` Jerome Brunet
  2023-10-17  6:15     ` Xianwei Zhao
  0 siblings, 1 reply; 27+ messages in thread
From: Jerome Brunet @ 2023-10-13  7:49 UTC (permalink / raw)
  To: Xianwei Zhao, linux-arm-kernel, linux-amlogic, linux-clk,
	devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu


On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:

> Add the C3 PLL clock controller driver for the Amlogic C3 SoC family.
>
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> ---
> V1 -> V2: Delete macro definition.
> ---
>  drivers/clk/meson/Kconfig  |  12 +
>  drivers/clk/meson/Makefile |   1 +
>  drivers/clk/meson/c3-pll.c | 808 +++++++++++++++++++++++++++++++++++++
>  drivers/clk/meson/c3-pll.h |  35 ++
>  4 files changed, 856 insertions(+)
>  create mode 100644 drivers/clk/meson/c3-pll.c
>  create mode 100644 drivers/clk/meson/c3-pll.h
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index c5303e4c1604..76be4bbd2afb 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -128,6 +128,18 @@ config COMMON_CLK_A1_PERIPHERALS
>  	  device, A1 SoC Family. Say Y if you want A1 Peripherals clock
>  	  controller to work.
>  
> +config COMMON_CLK_C3_PLL
> +	tristate "Amlogic C3 PLL clock controller"
> +	default y
> +	select COMMON_CLK_MESON_REGMAP
> +	select COMMON_CLK_MESON_PLL
> +	select COMMON_CLK_MESON_CLKC_UTILS
> +	help
> +	  Support for the PLL clock controller on Amlogic C302X and C308L devices,
> +	  AKA c3. Amlogic C302X and C308L devices include AW402, AW409 and AW419.
> +	  Say Y if you want the board to work, because PLLs are the parent of most
> +	  peripherals.
> +
>  config COMMON_CLK_G12A
>  	tristate "G12 and SM1 SoC clock controllers support"
>  	depends on ARM64
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index 9ee4b954c896..4420af628b31 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_C3_PLL) += c3-pll.o
>  obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>  obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>  obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
> diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c
> new file mode 100644
> index 000000000000..97619bc7ab79
> --- /dev/null
> +++ b/drivers/clk/meson/c3-pll.c
> @@ -0,0 +1,808 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Amlogic C3 PLL Controller Driver
> + *
> + * Copyright (c) 2023 Amlogic, inc.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include "clk-regmap.h"
> +#include "clk-pll.h"
> +#include "c3-pll.h"
> +#include "meson-clkc-utils.h"
> +#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
> +
> +static const struct clk_parent_data pll_dco_parent = {
> +	.fw_name = "pll_in",
> +};
> +
> +static const struct clk_parent_data mclk_pll_dco_parent = {
> +	.fw_name = "mclk_pll_in",
> +};

I'm assuming this section relates to Documentation section 6.6.3.5 MPLL
because all the fixed clock looks very familiar.

Because of the naming of another clock below, I'm not quite sure. Please clarify

> +
> +static struct clk_regmap fixed_pll_dco = {
> +	.data = &(struct meson_clk_pll_data){
> +		.en = {
> +			.reg_off = ANACTRL_FIXPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = ANACTRL_FIXPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 8,
> +		},
> +		.n = {
> +			.reg_off = ANACTRL_FIXPLL_CTRL0,
> +			.shift   = 16,
> +			.width   = 5,
> +		},
> +		.l = {
> +			.reg_off = ANACTRL_FIXPLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = ANACTRL_FIXPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fixed_pll_dco",
> +		.ops = &meson_clk_pll_ro_ops,
> +		.parent_data = &pll_dco_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap fixed_pll = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ANACTRL_FIXPLL_CTRL0,
> +		.shift = 12,
> +		.width = 3,
> +		.flags = CLK_DIVIDER_POWER_OF_TWO,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fixed_pll",
> +		.ops = &clk_regmap_divider_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};

Need a comment about why this is using RO ops

> +
> +static struct clk_fixed_factor fclk_div40_div = {
> +	.mult = 1,
> +	.div = 40,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fclk_div40_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap fclk_div40 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_FIXPLL_CTRL4,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_div40",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fclk_div40_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};

Don't see div40 in the diagram, where does it come from ?

> +
> +static struct clk_fixed_factor fclk_div2_div = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fclk_div2_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap fclk_div2 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_FIXPLL_CTRL4,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_div2",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fclk_div2_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor fclk_div2p5_div = {
> +	.mult = 2,
> +	.div = 5,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fclk_div2p5_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};

This one is wrong if I follow the doc.
It is supposed to be fixed 8 divider taking it's source directly from
the DCO, skipping the OD post divider ... assuming the doc is up to date.

> +
> +static struct clk_regmap fclk_div2p5 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_FIXPLL_CTRL4,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_div2p5",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fclk_div2p5_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor fclk_div3_div = {
> +	.mult = 1,
> +	.div = 3,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fclk_div3_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap fclk_div3 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_FIXPLL_CTRL4,
> +		.bit_idx = 20,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_div3",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fclk_div3_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor fclk_div4_div = {
> +	.mult = 1,
> +	.div = 4,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fclk_div4_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap fclk_div4 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_FIXPLL_CTRL4,
> +		.bit_idx = 21,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_div4",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fclk_div4_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor fclk_div5_div = {
> +	.mult = 1,
> +	.div = 5,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fclk_div5_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap fclk_div5 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_FIXPLL_CTRL4,
> +		.bit_idx = 22,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_div5",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fclk_div5_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_fixed_factor fclk_div7_div = {
> +	.mult = 1,
> +	.div = 7,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "fclk_div7_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fixed_pll.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap fclk_div7 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_FIXPLL_CTRL4,
> +		.bit_idx = 23,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "fclk_div7",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&fclk_div7_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct reg_sequence c3_gp0_init_regs[] = {
> +	{ .reg = ANACTRL_GP0PLL_CTRL1,	.def = 0x0 },
> +	{ .reg = ANACTRL_GP0PLL_CTRL2,	.def = 0x0 },

This should re-init GP0 rate on boot which is not desirable in case the
bootloader had already set a rate (for splash screen for example)

Sugguest you drop these

> +	{ .reg = ANACTRL_GP0PLL_CTRL3,	.def = 0x48681c00 },
> +	{ .reg = ANACTRL_GP0PLL_CTRL4,  .def = 0x88770290 },
> +	{ .reg = ANACTRL_GP0PLL_CTRL5,  .def = 0x3927200a },
> +	{ .reg = ANACTRL_GP0PLL_CTRL6,	.def = 0x56540000, .delay_us = 10 },
> +	{ .reg = ANACTRL_GP0PLL_CTRL0,	.def = 0x080304fa },
> +	{ .reg = ANACTRL_GP0PLL_CTRL0,	.def = 0x380304fa, .delay_us = 10 },
> +	{ .reg = ANACTRL_GP0PLL_CTRL0,	.def = 0X180304fa }
> +};
> +
> +static const struct pll_params_table c3_gp0_pll_params_table[] = {
> +	PLL_PARAMS(150, 1), /* DCO = 3600M */
> +	PLL_PARAMS(130, 1), /* DCO = 3120M */
> +	PLL_PARAMS(192, 1), /* DCO = 4608M */
> +	PLL_PARAMS(125, 1), /* DCO = 3000M */
> +	{ /* sentinel */  }
> +};

Why can't C3 use mult_range for GP0, like the other SoC ?
Doc says DCO can do 3 to 6GHz

> +
> +/* The maximum frequency divider supports is 32, not 128(2^7) */
> +static const struct clk_div_table c3_gp0_pll_od_table[] = {
> +	{ 0,  1 },
> +	{ 1,  2 },
> +	{ 2,  4 },
> +	{ 3,  8 },
> +	{ 4, 16 },
> +	{ 5, 32 },
> +	{ /* sentinel */ }
> +};

Please put that table next to the related divider
Same for other instances

> +
> +static struct clk_regmap gp0_pll_dco = {
> +	.data = &(struct meson_clk_pll_data){
> +		.en = {
> +			.reg_off = ANACTRL_GP0PLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = ANACTRL_GP0PLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.frac = {
> +			.reg_off = ANACTRL_GP0PLL_CTRL1,
> +			.shift   = 0,
> +			.width   = 19,
> +		},
> +		.n = {
> +			.reg_off = ANACTRL_GP0PLL_CTRL0,
> +			.shift   = 10,
> +			.width   = 5,
> +		},
> +		.l = {
> +			.reg_off = ANACTRL_GP0PLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = ANACTRL_GP0PLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.table = c3_gp0_pll_params_table,
> +		.init_regs = c3_gp0_init_regs,
> +		.init_count = ARRAY_SIZE(c3_gp0_init_regs),
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "gp0_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_data = &pll_dco_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap gp0_pll = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ANACTRL_GP0PLL_CTRL0,
> +		.shift = 16,
> +		.width = 3,
> +		.table = c3_gp0_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "gp0_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&gp0_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct reg_sequence c3_hifi_init_regs[] = {
> +	{ .reg = ANACTRL_HIFIPLL_CTRL0,	.def = 0x08010496 },
> +	{ .reg = ANACTRL_HIFIPLL_CTRL0,	.def = 0x38010496 },

Same here, this an hidden hard coded rate init, with enable on top.
Please drop this

If you need a specific rate after the init, use assigned-rate in DT

> +	{ .reg = ANACTRL_HIFIPLL_CTRL1,	.def = 0x0000ce40 },
> +	{ .reg = ANACTRL_HIFIPLL_CTRL2,	.def = 0x00000000 },
> +	{ .reg = ANACTRL_HIFIPLL_CTRL3,	.def = 0x6a285c00 },
> +	{ .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
> +	{ .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
> +	{ .reg = ANACTRL_HIFIPLL_CTRL6,	.def = 0x56540000, .delay_us = 50 },
> +	{ .reg = ANACTRL_HIFIPLL_CTRL0,	.def = 0x18010496, .delay_us = 20 },
> +};
> +
> +static const struct pll_params_table c3_hifi_pll_params_table[] = {
> +	PLL_PARAMS(150, 1), /* DCO = 3600M */
> +	PLL_PARAMS(130, 1), /* DCO = 3120M */
> +	PLL_PARAMS(192, 1), /* DCO = 4608M */
> +	PLL_PARAMS(125, 1), /* DCO = 3000M */
> +	{ /* sentinel */  }
> +};

Again, why can't HiFi use mult range ?

> +
> +static struct clk_regmap hifi_pll_dco = {
> +	.data = &(struct meson_clk_pll_data){
> +		.en = {
> +			.reg_off = ANACTRL_HIFIPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = ANACTRL_HIFIPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 8,
> +		},
> +		.frac = {
> +			.reg_off = ANACTRL_HIFIPLL_CTRL1,
> +			.shift   = 0,
> +			.width   = 19,
> +		},
> +		.n = {
> +			.reg_off = ANACTRL_HIFIPLL_CTRL0,
> +			.shift   = 10,
> +			.width   = 5,
> +		},
> +		.l = {
> +			.reg_off = ANACTRL_HIFIPLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = ANACTRL_HIFIPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.table = c3_hifi_pll_params_table,
> +		.init_regs = c3_hifi_init_regs,
> +		.init_count = ARRAY_SIZE(c3_hifi_init_regs),
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hifi_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_data = &pll_dco_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap hifi_pll = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ANACTRL_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 *[]) {
> +			&hifi_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +

I cannot make out what all the mclk section below relates to in
documentation clock. Could you please clarify ?

> +static const struct reg_sequence c3_mclk_init_regs[] = {
> +	{ .reg = ANACTRL_MPLL_CTRL0,	.def = 0x20011063 },
> +	{ .reg = ANACTRL_MPLL_CTRL0,	.def = 0x30011063 },

Again, hidden rate set on init ...

> +	{ .reg = ANACTRL_MPLL_CTRL1,	.def = 0x1420500f },
> +	{ .reg = ANACTRL_MPLL_CTRL2,	.def = 0x00023041 },
> +	{ .reg = ANACTRL_MPLL_CTRL3,	.def = 0x18180000 },
> +	{ .reg = ANACTRL_MPLL_CTRL0,	.def = 0x10011063 },
> +	{ .reg = ANACTRL_MPLL_CTRL2,	.def = 0x00023001 }
> +};
> +
> +static const struct pll_params_table c3_mclk_pll_params_table[] = {
> +	PLL_PARAMS(99, 1), /* VCO = 2376M */
> +	{ /* sentinel */  }
> +};
> +
> +static const struct clk_div_table c3_mpll_od_table[] = {
> +	{ 0,  1 },
> +	{ 1,  2 },
> +	{ 2,  4 },
> +	{ 3,  8 },
> +	{ 4, 16 },
> +	{ /* sentinel */ }
> +};
> +
> +static struct clk_regmap mclk_pll_dco = {
> +	.data = &(struct meson_clk_pll_data){
> +		.en = {
> +			.reg_off = ANACTRL_MPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = ANACTRL_MPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.n = {
> +			.reg_off = ANACTRL_MPLL_CTRL0,
> +			.shift   = 10,
> +			.width   = 5,
> +		},
> +		.l = {
> +			.reg_off = ANACTRL_MPLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = ANACTRL_MPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.table = c3_mclk_pll_params_table,
> +		.init_regs = c3_mclk_init_regs,
> +		.init_count = ARRAY_SIZE(c3_mclk_init_regs),
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_data = &mclk_pll_dco_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap mclk_pll = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ANACTRL_MPLL_CTRL0,
> +		.shift = 12,
> +		.width = 3,
> +		.table = c3_mpll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap mclk_pll_clk = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.shift = 16,
> +		.width = 5,
> +		.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk_pll_clk",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk_pll.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};


"mclk_pll" then "mclk_pll_clk" ... that is confusing

> +
> +static const struct clk_parent_data mclk_parent[] = {
> +	{ .hw = &mclk_pll_clk.hw },
> +	{ .fw_name = "mclk_pll_in" },
> +	{ .hw = &fclk_div40.hw }
> +};
> +
> +static struct clk_regmap mclk0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.mask = 0x3,
> +		.shift = 4,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = mclk_parent,
> +		.num_parents = ARRAY_SIZE(mclk_parent),
> +	},
> +};
> +
> +static struct clk_regmap mclk0_sel_out = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.bit_idx = 1,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk0_sel_out",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap mclk0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.shift = 2,
> +		.width = 1,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk0_sel_out.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap mclk0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.bit_idx = 0,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap mclk1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.mask = 0x3,
> +		.shift = 12,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = mclk_parent,
> +		.num_parents = ARRAY_SIZE(mclk_parent),
> +	},
> +};
> +
> +static struct clk_regmap mclk1_sel_out = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.bit_idx = 9,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk1_sel_out",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk1_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap mclk1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.shift = 10,
> +		.width = 1,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk1_sel_out.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap mclk1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ANACTRL_MPLL_CTRL4,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mclk1_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_hw *c3_pll_hw_clks[] = {
> +	[CLKID_FIXED_PLL_DCO]	= &fixed_pll_dco.hw,
> +	[CLKID_FIXED_PLL]	= &fixed_pll.hw,
> +	[CLKID_FCLK_DIV40_DIV]	= &fclk_div40_div.hw,
> +	[CLKID_FCLK_DIV40]	= &fclk_div40.hw,
> +	[CLKID_FCLK_DIV2_DIV]	= &fclk_div2_div.hw,
> +	[CLKID_FCLK_DIV2]	= &fclk_div2.hw,
> +	[CLKID_FCLK_DIV2P5_DIV]	= &fclk_div2p5_div.hw,
> +	[CLKID_FCLK_DIV2P5]	= &fclk_div2p5.hw,
> +	[CLKID_FCLK_DIV3_DIV]	= &fclk_div3_div.hw,
> +	[CLKID_FCLK_DIV3]	= &fclk_div3.hw,
> +	[CLKID_FCLK_DIV4_DIV]	= &fclk_div4_div.hw,
> +	[CLKID_FCLK_DIV4]	= &fclk_div4.hw,
> +	[CLKID_FCLK_DIV5_DIV]	= &fclk_div5_div.hw,
> +	[CLKID_FCLK_DIV5]	= &fclk_div5.hw,
> +	[CLKID_FCLK_DIV7_DIV]	= &fclk_div7_div.hw,
> +	[CLKID_FCLK_DIV7]	= &fclk_div7.hw,
> +	[CLKID_GP0_PLL_DCO]	= &gp0_pll_dco.hw,
> +	[CLKID_GP0_PLL]		= &gp0_pll.hw,
> +	[CLKID_HIFI_PLL_DCO]	= &hifi_pll_dco.hw,
> +	[CLKID_HIFI_PLL]	= &hifi_pll.hw,
> +	[CLKID_MCLK_PLL_DCO]	= &mclk_pll_dco.hw,
> +	[CLKID_MCLK_PLL]	= &mclk_pll.hw,
> +	[CLKID_MCLK_PLL_CLK]	= &mclk_pll_clk.hw,
> +	[CLKID_MCLK0_SEL]	= &mclk0_sel.hw,
> +	[CLKID_MCLK0_SEL_OUT]	= &mclk0_sel_out.hw,
> +	[CLKID_MCLK0_DIV]	= &mclk0_div.hw,
> +	[CLKID_MCLK0]		= &mclk0.hw,
> +	[CLKID_MCLK1_SEL]	= &mclk1_sel.hw,
> +	[CLKID_MCLK1_SEL_OUT]	= &mclk1_sel_out.hw,
> +	[CLKID_MCLK1_DIV]	= &mclk1_div.hw,
> +	[CLKID_MCLK1]		= &mclk1.hw
> +};
> +
> +/* Convenience table to populate regmap in .probe */
> +static struct clk_regmap *const c3_pll_clk_regmaps[] = {
> +	&fixed_pll_dco,
> +	&fixed_pll,
> +	&fclk_div40,
> +	&fclk_div2,
> +	&fclk_div2p5,
> +	&fclk_div3,
> +	&fclk_div4,
> +	&fclk_div5,
> +	&fclk_div7,
> +	&gp0_pll_dco,
> +	&gp0_pll,
> +	&hifi_pll_dco,
> +	&hifi_pll,
> +	&mclk_pll_dco,
> +	&mclk_pll,
> +	&mclk_pll_clk,
> +	&mclk0_sel,
> +	&mclk0_sel_out,
> +	&mclk0_div,
> +	&mclk0,
> +	&mclk1_sel,
> +	&mclk1_sel_out,
> +	&mclk1_div,
> +	&mclk1,
> +};
> +
> +static struct regmap_config clkc_regmap_config = {
> +	.reg_bits       = 32,
> +	.val_bits       = 32,
> +	.reg_stride     = 4,
> +};
> +
> +static struct meson_clk_hw_data c3_pll_clks = {
> +	.hws = c3_pll_hw_clks,
> +	.num = ARRAY_SIZE(c3_pll_hw_clks),
> +};
> +
> +static int aml_c3_pll_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct regmap *regmap;
> +	void __iomem *base;
> +	int clkid, ret, i;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	/* Populate regmap for the regmap backed clocks */
> +	for (i = 0; i < ARRAY_SIZE(c3_pll_clk_regmaps); i++)
> +		c3_pll_clk_regmaps[i]->map = regmap;
> +
> +	for (clkid = 0; clkid < c3_pll_clks.num; clkid++) {
> +		/* array might be sparse */
> +		if (!c3_pll_clks.hws[clkid])
> +			continue;
> +
> +		ret = devm_clk_hw_register(dev, c3_pll_clks.hws[clkid]);
> +		if (ret) {
> +			dev_err(dev, "Clock registration failed\n");
> +			return ret;
> +		}
> +	}
> +
> +	return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
> +					   &c3_pll_clks);
> +}
> +
> +static const struct of_device_id c3_pll_clkc_match_table[] = {
> +	{
> +		.compatible = "amlogic,c3-pll-clkc",
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, c3_pll_clkc_match_table);
> +
> +static struct platform_driver c3_pll_driver = {
> +	.probe		= aml_c3_pll_probe,
> +	.driver		= {
> +		.name	= "c3-pll-clkc",
> +		.of_match_table = c3_pll_clkc_match_table,
> +	},
> +};
> +
> +module_platform_driver(c3_pll_driver);
> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/meson/c3-pll.h b/drivers/clk/meson/c3-pll.h
> new file mode 100644
> index 000000000000..92a08196a46f
> --- /dev/null
> +++ b/drivers/clk/meson/c3-pll.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (c) 2023 Amlogic, inc.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> + */
> +
> +#ifndef __AML_C3_PLL_H__
> +#define __AML_C3_PLL_H__
> +
> +#define ANACTRL_FIXPLL_CTRL0			0x0040
> +#define ANACTRL_FIXPLL_CTRL4			0x0050
> +#define ANACTRL_GP0PLL_CTRL0			0x0080
> +#define ANACTRL_GP0PLL_CTRL1			0x0084
> +#define ANACTRL_GP0PLL_CTRL2			0x0088
> +#define ANACTRL_GP0PLL_CTRL3			0x008c
> +#define ANACTRL_GP0PLL_CTRL4			0x0090
> +#define ANACTRL_GP0PLL_CTRL5			0x0094
> +#define ANACTRL_GP0PLL_CTRL6			0x0098
> +#define ANACTRL_GP0PLL_STS			0x009c
> +#define ANACTRL_HIFIPLL_CTRL0			0x0100
> +#define ANACTRL_HIFIPLL_CTRL1			0x0104
> +#define ANACTRL_HIFIPLL_CTRL2			0x0108
> +#define ANACTRL_HIFIPLL_CTRL3			0x010c
> +#define ANACTRL_HIFIPLL_CTRL4			0x0110
> +#define ANACTRL_HIFIPLL_CTRL5			0x0114
> +#define ANACTRL_HIFIPLL_CTRL6			0x0118
> +#define ANACTRL_HIFIPLL_STS			0x011c
> +#define ANACTRL_MPLL_CTRL0			0x0180
> +#define ANACTRL_MPLL_CTRL1			0x0184
> +#define ANACTRL_MPLL_CTRL2			0x0188
> +#define ANACTRL_MPLL_CTRL3			0x018c
> +#define ANACTRL_MPLL_CTRL4			0x0190
> +#define ANACTRL_MPLL_STS			0x01a4
> +
> +#endif  /* __AML_C3_PLL_H__ */


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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-10  6:29 ` [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver Xianwei Zhao
  2023-10-12 23:51   ` Stephen Boyd
@ 2023-10-13  8:46   ` Jerome Brunet
  2023-10-17  3:25     ` Xianwei Zhao
  1 sibling, 1 reply; 27+ messages in thread
From: Jerome Brunet @ 2023-10-13  8:46 UTC (permalink / raw)
  To: Xianwei Zhao, linux-arm-kernel, linux-amlogic, linux-clk,
	devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu


On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:

> Add the C3 peripherals clock controller driver in the C3 SoC family.
>
> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
> ---
> V1 -> V2: Delete macro definition.
> ---
>  drivers/clk/meson/Kconfig          |   13 +
>  drivers/clk/meson/Makefile         |    1 +
>  drivers/clk/meson/c3-peripherals.c | 3096 ++++++++++++++++++++++++++++
>  drivers/clk/meson/c3-peripherals.h |   48 +
>  4 files changed, 3158 insertions(+)
>  create mode 100644 drivers/clk/meson/c3-peripherals.c
>  create mode 100644 drivers/clk/meson/c3-peripherals.h
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 76be4bbd2afb..c8d59d28c8ff 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
>  	  Say Y if you want the board to work, because PLLs are the parent of most
>  	  peripherals.
>  
> +config COMMON_CLK_C3_PERIPHERALS
> +	tristate "Amlogic C3 peripherals clock controller"
> +	default y
> +	select COMMON_CLK_MESON_REGMAP
> +	select COMMON_CLK_MESON_DUALDIV
> +	select COMMON_CLK_MESON_CLKC_UTILS
> +	select COMMON_CLK_C3_PLL
> +	help
> +	  Support for the Peripherals clock controller on Amlogic C302X and
> +	  C308L devices, AKA c3. Amlogic C302X and C308L devices include
> +	  AW402, AW409 and AW419. Say Y if you want the peripherals clock
> +	  to work.
> +
>  config COMMON_CLK_G12A
>  	tristate "G12 and SM1 SoC clock controllers support"
>  	depends on ARM64
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index 4420af628b31..20ad9482c892 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_C3_PLL) += c3-pll.o
> +obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>  obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>  obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>  obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
> diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c
> new file mode 100644
> index 000000000000..2931cb20299a
> --- /dev/null
> +++ b/drivers/clk/meson/c3-peripherals.c
> @@ -0,0 +1,3096 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Amlogic C3 Peripherals Clock Controller Driver
> + *
> + * Copyright (c) 2023 Amlogic, inc.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include "clk-regmap.h"
> +#include "clk-dualdiv.h"
> +#include "c3-peripherals.h"
> +#include "meson-clkc-utils.h"
> +#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
> +
> +static struct clk_regmap pll_in = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = OSCIN_CTRL,
> +		.bit_idx = 4,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pll_in",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "xtal",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap mclk_pll_in = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = OSCIN_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk_pll_in",
> +		.ops = &clk_regmap_gate_ro_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "xtal",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct clk_parent_data rtc_xtal_clkin_parent = {
> +	.fw_name = "xtal",
> +};
> +
> +static struct clk_regmap rtc_xtal_clkin = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = RTC_BY_OSCIN_CTRL0,
> +		.bit_idx = 31,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "rtc_xtal_clkin",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_data = &rtc_xtal_clkin_parent,

Why can't you inline

		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},

like for the other clock ... please be consistent


> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = {
> +	{ 733, 732, 8, 11, 1 },
> +	{ /* sentinel */ }
> +};
> +
> +static struct clk_regmap rtc_32k_div = {
> +	.data = &(struct meson_clk_dualdiv_data){
> +		.n1 = {
> +			.reg_off = RTC_BY_OSCIN_CTRL0,
> +			.shift   = 0,
> +			.width   = 12,
> +		},
> +		.n2 = {
> +			.reg_off = RTC_BY_OSCIN_CTRL0,
> +			.shift   = 12,
> +			.width   = 12,
> +		},
> +		.m1 = {
> +			.reg_off = RTC_BY_OSCIN_CTRL1,
> +			.shift   = 0,
> +			.width   = 12,
> +		},
> +		.m2 = {
> +			.reg_off = RTC_BY_OSCIN_CTRL1,
> +			.shift   = 12,
> +			.width   = 12,
> +		},
> +		.dual = {
> +			.reg_off = RTC_BY_OSCIN_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.table = rtc_32k_div_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "rtc_32k_div",
> +		.ops = &meson_clk_dualdiv_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&rtc_xtal_clkin.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct clk_parent_data rtc_32k_mux_parent_data[] = {
> +	{ .hw = &rtc_32k_div.hw },
> +	{ .hw = &rtc_xtal_clkin.hw }
> +};
> +
> +static struct clk_regmap rtc_32k_mux = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = RTC_BY_OSCIN_CTRL1,
> +		.mask = 0x1,
> +		.shift = 24,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "rtc_32k_mux",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = rtc_32k_mux_parent_data,
> +		.num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap rtc_32k = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = RTC_BY_OSCIN_CTRL0,
> +		.bit_idx = 30,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "rtc_32k",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&rtc_32k_mux.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data rtc_clk_mux_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .hw = &rtc_32k.hw }
> +};
> +
> +static struct clk_regmap 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 = rtc_clk_mux_parent_data,
> +		.num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +/*
> + * Some clocks have multiple clock sources, and the parent clock and index are
> + * discontinuous, Some channels corresponding to the clock index are not
> + * actually connected inside the chip, or the clock source is invalid.
> + */
> +
> +static u32 sys_axi_parent_table[] = { 0, 2, 3, 4, 7 };
> +
> +static const struct clk_parent_data sys_axi_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .hw = &rtc_clk.hw }
> +};
> +
> +static struct clk_regmap sys_a_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SYS_CLK_CTRL0,
> +		.mask = 0x7,
> +		.shift = 10,
> +		.table = sys_axi_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sys_a_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = sys_axi_parent_data,
> +		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap sys_a_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SYS_CLK_CTRL0,
> +		.shift = 0,
> +		.width = 10,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sys_a_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sys_a_sel.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap sys_a = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SYS_CLK_CTRL0,
> +		.bit_idx = 13,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sys_a",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sys_a_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_IGNORE_UNUSED,

As usual, a comment is expected when using CLK_IGNORE_UNUSED.
It is very often not appropriate or justified.

Same goes for the other instances

> +	},
> +};
> +
> +static struct clk_regmap sys_b_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SYS_CLK_CTRL0,
> +		.mask = 0x7,
> +		.shift = 26,
> +		.table = sys_axi_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sys_b_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = sys_axi_parent_data,
> +		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap sys_b_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SYS_CLK_CTRL0,
> +		.shift = 16,
> +		.width = 10,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sys_b_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sys_b_sel.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap sys_b = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SYS_CLK_CTRL0,
> +		.bit_idx = 29,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sys_b",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sys_b_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static const struct clk_parent_data sys_clk_parent_data[] = {
> +	{ .hw = &sys_a.hw },
> +	{ .hw = &sys_b.hw }
> +};
> +
> +static struct clk_regmap sys_clk = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SYS_CLK_CTRL0,
> +		.mask = 0x1,
> +		.shift = 15,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sys_clk",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = sys_clk_parent_data,
> +		.num_parents = ARRAY_SIZE(sys_clk_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap axi_a_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = AXI_CLK_CTRL0,
> +		.mask = 0x7,
> +		.shift = 10,
> +		.table = sys_axi_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "axi_a_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = sys_axi_parent_data,
> +		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap axi_a_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = AXI_CLK_CTRL0,
> +		.shift = 0,
> +		.width = 10,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "axi_a_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axi_a_sel.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap axi_a = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = AXI_CLK_CTRL0,
> +		.bit_idx = 13,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "axi_a",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axi_a_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static struct clk_regmap axi_b_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = AXI_CLK_CTRL0,
> +		.mask = 0x7,
> +		.shift = 26,
> +		.table = sys_axi_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "axi_b_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = sys_axi_parent_data,
> +		.num_parents = ARRAY_SIZE(sys_axi_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap axi_b_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = AXI_CLK_CTRL0,
> +		.shift = 16,
> +		.width = 10,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "axi_b_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axi_b_sel.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap axi_b = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = AXI_CLK_CTRL0,
> +		.bit_idx = 29,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "axi_b",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&axi_b_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_IGNORE_UNUSED,
> +	},
> +};
> +
> +static const struct clk_parent_data axi_clk_parent_data[] = {
> +	{ .hw = &axi_a.hw },
> +	{ .hw = &axi_b.hw }
> +};
> +
> +static struct clk_regmap axi_clk = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = AXI_CLK_CTRL0,
> +		.mask = 0x1,
> +		.shift = 15,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "axi_clk",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = axi_clk_parent_data,
> +		.num_parents = ARRAY_SIZE(axi_clk_parent_data),
> +	},
> +};
> +
> +#define AML_CLK_GATE_SYS_CLK(_name, _reg, _bit)\
> +	MESON_PCLK(_name, _reg, _bit, &sys_clk.hw)
> +#define AML_CLK_GATE_AXI_CLK(_name, _reg, _bit)\
> +	MESON_PCLK(_name, _reg, _bit, &axi_clk.hw)
> +
> +AML_CLK_GATE_SYS_CLK(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1);
> +AML_CLK_GATE_SYS_CLK(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3);
> +AML_CLK_GATE_SYS_CLK(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4);
> +AML_CLK_GATE_SYS_CLK(sys_ctrl, SYS_CLK_EN0_REG0, 5);
> +AML_CLK_GATE_SYS_CLK(sys_ts_pll, SYS_CLK_EN0_REG0, 6);
> +AML_CLK_GATE_SYS_CLK(sys_dev_arb, SYS_CLK_EN0_REG0, 7);
> +AML_CLK_GATE_SYS_CLK(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
> +AML_CLK_GATE_SYS_CLK(sys_capu, SYS_CLK_EN0_REG0, 9);
> +AML_CLK_GATE_SYS_CLK(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11);
> +AML_CLK_GATE_SYS_CLK(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12);
> +AML_CLK_GATE_SYS_CLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13);
> +AML_CLK_GATE_SYS_CLK(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14);
> +AML_CLK_GATE_SYS_CLK(sys_msr_clk, SYS_CLK_EN0_REG0, 15);
> +AML_CLK_GATE_SYS_CLK(sys_rom, SYS_CLK_EN0_REG0, 16);
> +AML_CLK_GATE_SYS_CLK(sys_uart_f, SYS_CLK_EN0_REG0, 17);
> +AML_CLK_GATE_SYS_CLK(sys_cpu_apb, SYS_CLK_EN0_REG0, 18);
> +AML_CLK_GATE_SYS_CLK(sys_rsa, SYS_CLK_EN0_REG0, 19);
> +AML_CLK_GATE_SYS_CLK(sys_sar_adc, SYS_CLK_EN0_REG0, 20);
> +AML_CLK_GATE_SYS_CLK(sys_startup, SYS_CLK_EN0_REG0, 21);
> +AML_CLK_GATE_SYS_CLK(sys_secure, SYS_CLK_EN0_REG0, 22);
> +AML_CLK_GATE_SYS_CLK(sys_spifc, SYS_CLK_EN0_REG0, 23);
> +AML_CLK_GATE_SYS_CLK(sys_nna, SYS_CLK_EN0_REG0, 25);
> +AML_CLK_GATE_SYS_CLK(sys_eth_mac, SYS_CLK_EN0_REG0, 26);
> +AML_CLK_GATE_SYS_CLK(sys_gic, SYS_CLK_EN0_REG0, 27);
> +AML_CLK_GATE_SYS_CLK(sys_rama, SYS_CLK_EN0_REG0, 28);
> +AML_CLK_GATE_SYS_CLK(sys_big_nic, SYS_CLK_EN0_REG0, 29);
> +AML_CLK_GATE_SYS_CLK(sys_ramb, SYS_CLK_EN0_REG0, 30);
> +AML_CLK_GATE_SYS_CLK(sys_audio_pclk, SYS_CLK_EN0_REG0, 31);
> +AML_CLK_GATE_SYS_CLK(sys_pwm_kl, SYS_CLK_EN0_REG1, 0);
> +AML_CLK_GATE_SYS_CLK(sys_pwm_ij, SYS_CLK_EN0_REG1, 1);
> +AML_CLK_GATE_SYS_CLK(sys_usb, SYS_CLK_EN0_REG1, 2);
> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3);
> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4);
> +AML_CLK_GATE_SYS_CLK(sys_pwm_ab, SYS_CLK_EN0_REG1, 5);
> +AML_CLK_GATE_SYS_CLK(sys_pwm_cd, SYS_CLK_EN0_REG1, 6);
> +AML_CLK_GATE_SYS_CLK(sys_pwm_ef, SYS_CLK_EN0_REG1, 7);
> +AML_CLK_GATE_SYS_CLK(sys_pwm_gh, SYS_CLK_EN0_REG1, 8);
> +AML_CLK_GATE_SYS_CLK(sys_spicc_1, SYS_CLK_EN0_REG1, 9);
> +AML_CLK_GATE_SYS_CLK(sys_spicc_0, SYS_CLK_EN0_REG1, 10);
> +AML_CLK_GATE_SYS_CLK(sys_uart_a, SYS_CLK_EN0_REG1, 11);
> +AML_CLK_GATE_SYS_CLK(sys_uart_b, SYS_CLK_EN0_REG1, 12);
> +AML_CLK_GATE_SYS_CLK(sys_uart_c, SYS_CLK_EN0_REG1, 13);
> +AML_CLK_GATE_SYS_CLK(sys_uart_d, SYS_CLK_EN0_REG1, 14);
> +AML_CLK_GATE_SYS_CLK(sys_uart_e, SYS_CLK_EN0_REG1, 15);
> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16);
> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17);
> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18);
> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19);
> +AML_CLK_GATE_SYS_CLK(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20);
> +AML_CLK_GATE_SYS_CLK(sys_rtc, SYS_CLK_EN0_REG1, 21);
> +AML_CLK_GATE_SYS_CLK(sys_ge2d, SYS_CLK_EN0_REG1, 22);
> +AML_CLK_GATE_SYS_CLK(sys_isp, SYS_CLK_EN0_REG1, 23);
> +AML_CLK_GATE_SYS_CLK(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24);
> +AML_CLK_GATE_SYS_CLK(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25);
> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26);
> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27);
> +AML_CLK_GATE_SYS_CLK(sys_eth_phy, SYS_CLK_EN0_REG1, 28);
> +AML_CLK_GATE_SYS_CLK(sys_acodec, SYS_CLK_EN0_REG1, 29);
> +AML_CLK_GATE_SYS_CLK(sys_dwap, SYS_CLK_EN0_REG1, 30);
> +AML_CLK_GATE_SYS_CLK(sys_dos, SYS_CLK_EN0_REG1, 31);
> +AML_CLK_GATE_SYS_CLK(sys_cve, SYS_CLK_EN0_REG2, 0);
> +AML_CLK_GATE_SYS_CLK(sys_vout, SYS_CLK_EN0_REG2, 1);
> +AML_CLK_GATE_SYS_CLK(sys_vc9000e, SYS_CLK_EN0_REG2, 2);
> +AML_CLK_GATE_SYS_CLK(sys_pwm_mn, SYS_CLK_EN0_REG2, 3);
> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4);
> +AML_CLK_GATE_AXI_CLK(axi_sys_nic, AXI_CLK_EN0, 2);
> +AML_CLK_GATE_AXI_CLK(axi_isp_nic, AXI_CLK_EN0, 3);
> +AML_CLK_GATE_AXI_CLK(axi_cve_nic, AXI_CLK_EN0, 4);
> +AML_CLK_GATE_AXI_CLK(axi_ramb, AXI_CLK_EN0, 5);
> +AML_CLK_GATE_AXI_CLK(axi_rama, AXI_CLK_EN0, 6);
> +AML_CLK_GATE_AXI_CLK(axi_cpu_dmc, AXI_CLK_EN0, 7);
> +AML_CLK_GATE_AXI_CLK(axi_nic, AXI_CLK_EN0, 8);
> +AML_CLK_GATE_AXI_CLK(axi_dma, AXI_CLK_EN0, 9);
> +AML_CLK_GATE_AXI_CLK(axi_mux_nic, AXI_CLK_EN0, 10);
> +AML_CLK_GATE_AXI_CLK(axi_capu, AXI_CLK_EN0, 11);
> +AML_CLK_GATE_AXI_CLK(axi_cve, AXI_CLK_EN0, 12);
> +AML_CLK_GATE_AXI_CLK(axi_dev1_dmc, AXI_CLK_EN0, 13);
> +AML_CLK_GATE_AXI_CLK(axi_dev0_dmc, AXI_CLK_EN0, 14);
> +AML_CLK_GATE_AXI_CLK(axi_dsp_dmc, AXI_CLK_EN0, 15);
> +
> +/*
> + * clk_12_24m model
> + *
> + *          |------|     |-----| clk_12m_24m |-----|
> + * xtal---->| gate |---->| div |------------>| pad |
> + *          |------|     |-----|             |-----|
> + */
> +static const struct clk_parent_data clk_12_24m_in_parent = {
> +	.fw_name = "xtal",
> +};

Can't inline that ?

> +
> +static struct clk_regmap 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 = &clk_12_24m_in_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap 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 *[]) {
> +			&clk_12_24m_in.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct clk_parent_data fclk_25m_div_parent = {
> +	.fw_name = "fixed_pll",
> +};
> +
> +static struct clk_regmap 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 = &fclk_25m_div_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap 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 *[]) {
> +			&fclk_25m_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +/* generate clock output */

That comment is not helping much ... what did you mean ?

> +static u32 gen_parent_table[] = { 0, 1, 5, 7 };
> +
> +static const struct clk_parent_data gen_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .hw = &rtc_clk.hw },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "hifi_pll" }
> +};
> +
> +static struct clk_regmap gen_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = GEN_CLK_CTRL,
> +		.mask = 0x1f,
> +		.shift = 12,
> +		.table = gen_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "gen_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = gen_parent_data,
> +		.num_parents = ARRAY_SIZE(gen_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap 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 *[]) {
> +			&gen_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap 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 *[]) {
> +			&gen_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data saradc_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .hw = &sys_clk.hw }
> +};
> +
> +static struct clk_regmap saradc_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SAR_CLK_CTRL0,
> +		.mask = 0x1,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "saradc_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = saradc_parent_data,
> +		.num_parents = ARRAY_SIZE(saradc_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap saradc_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SAR_CLK_CTRL0,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "saradc_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&saradc_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap saradc = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SAR_CLK_CTRL0,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "saradc",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&saradc_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 pwm_parent_table[] = { 0, 2, 3 };

What's pwm parent 1, why can't it be used ?

> +
> +static const struct clk_parent_data pwm_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div3" }
> +};
> +
> +static struct clk_regmap pwm_a_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_AB_CTRL,
> +		.mask = 0x3,
> +		.shift = 9,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_a_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_a_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_AB_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_a_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_a_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_a = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_AB_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_a",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_a_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_b_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_AB_CTRL,
> +		.mask = 0x3,
> +		.shift = 25,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_b_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_b_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_AB_CTRL,
> +		.shift = 16,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_b_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_b_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_b = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_AB_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_b",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_b_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_c_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_CD_CTRL,
> +		.mask = 0x3,
> +		.shift = 9,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_c_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_c_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_CD_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_c_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_c_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_c = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_CD_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_c",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_c_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_d_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_CD_CTRL,
> +		.mask = 0x3,
> +		.shift = 25,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_d_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_d_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_CD_CTRL,
> +		.shift = 16,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_d_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_d_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_d = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_CD_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_d",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_d_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_e_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_EF_CTRL,
> +		.mask = 0x3,
> +		.shift = 9,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_e_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_e_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_EF_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_e_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_e_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_e = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_EF_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_e",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_e_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_f_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_EF_CTRL,
> +		.mask = 0x3,
> +		.shift = 25,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_f_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_f_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_EF_CTRL,
> +		.shift = 16,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_f_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_f_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_f = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_EF_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_f",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_f_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_g_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_GH_CTRL,
> +		.mask = 0x3,
> +		.shift = 9,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_g_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_g_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_GH_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_g_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_g_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_g = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_GH_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_g",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_g_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_h_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_GH_CTRL,
> +		.mask = 0x3,
> +		.shift = 25,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_h_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_h_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_GH_CTRL,
> +		.shift = 16,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_h_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_h_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_h = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_GH_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_h",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_h_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_i_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_IJ_CTRL,
> +		.mask = 0x3,
> +		.shift = 9,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_i_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_i_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_IJ_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_i_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_i_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_i = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_IJ_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_i",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_i_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_j_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_IJ_CTRL,
> +		.mask = 0x3,
> +		.shift = 25,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_j_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_j_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_IJ_CTRL,
> +		.shift = 16,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_j_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_j_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_j = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_IJ_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_j",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_j_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_k_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_KL_CTRL,
> +		.mask = 0x3,
> +		.shift = 9,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_k_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_k_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_KL_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_k_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_k_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_k = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_KL_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_k",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_k_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_l_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_KL_CTRL,
> +		.mask = 0x3,
> +		.shift = 25,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_l_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_l_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_KL_CTRL,
> +		.shift = 16,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_l_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_l_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_l = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_KL_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_l",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_l_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_m_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_MN_CTRL,
> +		.mask = 0x3,
> +		.shift = 9,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_m_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_m_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_MN_CTRL,
> +		.shift = 0,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_m_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_m_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_m = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_MN_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_m",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_m_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_n_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = PWM_CLK_MN_CTRL,
> +		.mask = 0x3,
> +		.shift = 25,
> +		.table = pwm_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_n_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = pwm_parent_data,
> +		.num_parents = ARRAY_SIZE(pwm_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap pwm_n_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = PWM_CLK_MN_CTRL,
> +		.shift = 16,
> +		.width = 8,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "pwm_n_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_n_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap pwm_n = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = PWM_CLK_MN_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "pwm_n",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&pwm_n_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};

Judging by the number of repeated block, a properly defined macro would
be acceptable for the PWM block

> +
> +static const struct clk_parent_data spicc_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .hw = &sys_clk.hw },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div2" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "fclk_div7" }
> +};
> +
> +static struct clk_regmap spicc_a_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SPICC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "spicc_a_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = spicc_parent_data,
> +		.num_parents = ARRAY_SIZE(spicc_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap spicc_a_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SPICC_CLK_CTRL,
> +		.shift = 0,
> +		.width = 6,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "spicc_a_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&spicc_a_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap spicc_a = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SPICC_CLK_CTRL,
> +		.bit_idx = 6,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "spicc_a",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&spicc_a_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap spicc_b_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SPICC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 23,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "spicc_b_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = spicc_parent_data,
> +		.num_parents = ARRAY_SIZE(spicc_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap spicc_b_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SPICC_CLK_CTRL,
> +		.shift = 16,
> +		.width = 6,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "spicc_b_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&spicc_b_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap spicc_b = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SPICC_CLK_CTRL,
> +		.bit_idx = 22,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "spicc_b",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&spicc_b_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data spifc_parent_data[] = {
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "fclk_div2" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "fclk_div7" }
> +};
> +
> +static struct clk_regmap spifc_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SPIFC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "spifc_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = spifc_parent_data,
> +		.num_parents = ARRAY_SIZE(spifc_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap spifc_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SPIFC_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "spifc_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&spifc_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap spifc = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SPIFC_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "spifc",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&spifc_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 emmc_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };

What's 6 ? why can't it be used ?

> +
> +static const struct clk_parent_data emmc_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .fw_name = "fclk_div2" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "gp0_pll" }
> +};
> +
> +static struct clk_regmap sd_emmc_a_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SD_EMMC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +		.table = emmc_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_a_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = emmc_parent_data,
> +		.num_parents = ARRAY_SIZE(emmc_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_a_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SD_EMMC_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_a_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sd_emmc_a_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_a = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SD_EMMC_CLK_CTRL,
> +		.bit_idx = 7,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_a",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sd_emmc_a_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_b_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = SD_EMMC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 25,
> +		.table = emmc_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_b_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = emmc_parent_data,
> +		.num_parents = ARRAY_SIZE(emmc_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_b_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = SD_EMMC_CLK_CTRL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_b_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sd_emmc_b_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_b = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = SD_EMMC_CLK_CTRL,
> +		.bit_idx = 23,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_b",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sd_emmc_b_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_c_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = NAND_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +		.table = emmc_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_c_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = emmc_parent_data,
> +		.num_parents = ARRAY_SIZE(emmc_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_c_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = NAND_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "sd_emmc_c_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sd_emmc_c_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap sd_emmc_c = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = NAND_CLK_CTRL,
> +		.bit_idx = 7,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "sd_emmc_c",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&sd_emmc_c_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +/* temperature sensor */
> +static const struct clk_parent_data ts_parent = {
> +	.fw_name = "xtal",
> +};

same  ...

> +
> +static struct clk_regmap 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 = &ts_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap 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 *[]) {
> +			&ts_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data eth_parent = {
> +	.fw_name = "fclk_div2",
> +};
> +
> +static struct clk_fixed_factor eth_125m_div = {
> +	.mult = 1,
> +	.div = 8,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "eth_125m_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_data = &eth_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap 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 *[]) {
> +			&eth_125m_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap 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 = &eth_parent,
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap 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 *[]) {
> +			&eth_rmii_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 mipi_dsi_meas_parent_table[] = { 0, 1, 2, 3, 5, 6, 7 };

What is 4 ? why can't it be used ?

> +
> +static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "fclk_div2" },
> +	{ .fw_name = "fclk_div7" }
> +};
> +
> +static struct clk_regmap mipi_dsi_meas_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VDIN_MEAS_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 21,
> +		.table = mipi_dsi_meas_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mipi_dsi_meas_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = mipi_dsi_meas_parent_data,
> +		.num_parents = ARRAY_SIZE(mipi_dsi_meas_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap mipi_dsi_meas_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VDIN_MEAS_CLK_CTRL,
> +		.shift = 12,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mipi_dsi_meas_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mipi_dsi_meas_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap mipi_dsi_meas = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = VDIN_MEAS_CLK_CTRL,
> +		.bit_idx = 20,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mipi_dsi_meas",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&mipi_dsi_meas_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 dsi_phy_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };

What about 0 ?

> +
> +static const struct clk_parent_data dsi_phy_parent_data[] = {
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div2" },
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div7" }
> +};
> +
> +static struct clk_regmap dsi_phy_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = MIPIDSI_PHY_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 12,
> +		.table = dsi_phy_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "dsi_phy_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = dsi_phy_parent_data,
> +		.num_parents = ARRAY_SIZE(dsi_phy_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap dsi_phy_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = MIPIDSI_PHY_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "dsi_phy_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&dsi_phy_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap dsi_phy = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = MIPIDSI_PHY_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dsi_phy",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&dsi_phy_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 vout_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };

same

> +
> +static const struct clk_parent_data vout_parent_data[] = {
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div7" }
> +};
> +
> +static struct clk_regmap vout_mclk_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VOUTENC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +		.table = vout_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vout_mclk_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = vout_parent_data,
> +		.num_parents = ARRAY_SIZE(vout_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap vout_mclk_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VOUTENC_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vout_mclk_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vout_mclk_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap vout_mclk = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = MIPIDSI_PHY_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vout_mclk",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vout_mclk_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap vout_enc_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VOUTENC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 25,
> +		.table = vout_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vout_enc_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = vout_parent_data,
> +		.num_parents = ARRAY_SIZE(vout_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap vout_enc_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VOUTENC_CLK_CTRL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vout_enc_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vout_enc_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap vout_enc = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = VOUTENC_CLK_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vout_enc",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vout_enc_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data hcodec_pre_parent_data[] = {
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "fclk_div7" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "xtal" }
> +};
> +
> +static struct clk_regmap hcodec_0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VDEC_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hcodec_0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = hcodec_pre_parent_data,
> +		.num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap hcodec_0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VDEC_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hcodec_0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&hcodec_0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap hcodec_0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = VDEC_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hcodec_0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&hcodec_0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap hcodec_1_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VDEC3_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hcodec_1_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = hcodec_pre_parent_data,
> +		.num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap hcodec_1_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VDEC3_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hcodec_1_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&hcodec_1_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap hcodec_1 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = VDEC3_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hcodec_1",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&hcodec_1_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data hcodec_parent_data[] = {
> +	{ .hw = &hcodec_0.hw },
> +	{ .hw = &hcodec_1.hw }
> +};
> +
> +

remove extra new lines

> +static struct clk_regmap hcodec = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VDEC3_CLK_CTRL,
> +		.mask = 0x1,
> +		.shift = 15,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hcodec",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = hcodec_parent_data,
> +		.num_parents = ARRAY_SIZE(hcodec_parent_data),
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data vc9000e_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "fclk_div7" },
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "gp0_pll" }
> +};
> +
> +static struct clk_regmap vc9000e_aclk_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VC9000E_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vc9000e_aclk_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = vc9000e_parent_data,
> +		.num_parents = ARRAY_SIZE(vc9000e_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap vc9000e_aclk_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VC9000E_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vc9000e_aclk_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vc9000e_aclk_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap vc9000e_aclk = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = VC9000E_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vc9000e_aclk",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vc9000e_aclk_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap vc9000e_core_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VC9000E_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 25,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vc9000e_core_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = vc9000e_parent_data,
> +		.num_parents = ARRAY_SIZE(vc9000e_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap vc9000e_core_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VC9000E_CLK_CTRL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vc9000e_core_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vc9000e_core_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap vc9000e_core = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = VC9000E_CLK_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vc9000e_core",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vc9000e_core_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 csi_phy_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };

Same here and all following instance

> +
> +static const struct clk_parent_data csi_phy_parent_data[] = {
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "xtal" }
> +};
> +
> +static struct clk_regmap csi_phy0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = ISP0_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 25,
> +		.table = csi_phy_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "csi_phy0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = csi_phy_parent_data,
> +		.num_parents = ARRAY_SIZE(csi_phy_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap csi_phy0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ISP0_CLK_CTRL,
> +		.shift = 16,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "csi_phy0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&csi_phy0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap csi_phy0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ISP0_CLK_CTRL,
> +		.bit_idx = 24,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "csi_phy0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&csi_phy0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 dewarpa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
> +
> +static const struct clk_parent_data dewarpa_parent_data[] = {
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "fclk_div7" }
> +};
> +
> +static struct clk_regmap dewarpa_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = DEWARPA_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +		.table = dewarpa_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "dewarpa_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = dewarpa_parent_data,
> +		.num_parents = ARRAY_SIZE(dewarpa_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap dewarpa_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = DEWARPA_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "dewarpa_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&dewarpa_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap dewarpa = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = DEWARPA_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "dewarpa",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&dewarpa_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 isp_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
> +
> +static const struct clk_parent_data isp_parent_data[] = {
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "xtal" }
> +};
> +
> +static struct clk_regmap isp0_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = ISP0_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +		.table = isp_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "isp0_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = isp_parent_data,
> +		.num_parents = ARRAY_SIZE(isp_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap isp0_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = ISP0_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "isp0_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&isp0_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap isp0 = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = ISP0_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "isp0",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&isp0_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 nna_core_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
> +
> +static const struct clk_parent_data nna_core_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "fclk_div2" },
> +	{ .fw_name = "hifi_pll" }
> +};
> +
> +static struct clk_regmap nna_core_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = NNA_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +		.table = nna_core_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "nna_core_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = nna_core_parent_data,
> +		.num_parents = ARRAY_SIZE(nna_core_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap nna_core_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = NNA_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "nna_core_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&nna_core_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap nna_core = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = NNA_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "nna_core",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&nna_core_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data ge2d_parent_data[] = {
> +	{ .fw_name = "xtal" },
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .hw = &rtc_clk.hw }
> +};
> +
> +static struct clk_regmap ge2d_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = GE2D_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "ge2d_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = ge2d_parent_data,
> +		.num_parents = ARRAY_SIZE(ge2d_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap ge2d_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = GE2D_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "ge2d_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&ge2d_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap ge2d = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = GE2D_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "ge2d",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&ge2d_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static u32 c3_vapb_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
> +
> +static const struct clk_parent_data vapb_parent_data[] = {
> +	{ .fw_name = "fclk_div2p5" },
> +	{ .fw_name = "fclk_div3" },
> +	{ .fw_name = "fclk_div4" },
> +	{ .fw_name = "fclk_div5" },
> +	{ .fw_name = "gp0_pll" },
> +	{ .fw_name = "hifi_pll" },
> +	{ .fw_name = "xtal" }
> +};
> +
> +static struct clk_regmap vapb_sel = {
> +	.data = &(struct clk_regmap_mux_data){
> +		.offset = VAPB_CLK_CTRL,
> +		.mask = 0x7,
> +		.shift = 9,
> +		.table = c3_vapb_parent_table,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_sel",
> +		.ops = &clk_regmap_mux_ops,
> +		.parent_data = vapb_parent_data,
> +		.num_parents = ARRAY_SIZE(vapb_parent_data),
> +	},
> +};
> +
> +static struct clk_regmap vapb_div = {
> +	.data = &(struct clk_regmap_div_data){
> +		.offset = VAPB_CLK_CTRL,
> +		.shift = 0,
> +		.width = 7,
> +	},
> +	.hw.init = &(struct clk_init_data){
> +		.name = "vapb_div",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vapb_sel.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_regmap vapb = {
> +	.data = &(struct clk_regmap_gate_data){
> +		.offset = VAPB_CLK_CTRL,
> +		.bit_idx = 8,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "vapb",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&vapb_div.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_hw *c3_periphs_hw_clks[] = {
> +	[CLKID_PLL_IN]			= &pll_in.hw,
> +	[CLKID_MCLK_PLL_IN]		= &mclk_pll_in.hw,
> +	[CLKID_RTC_XTAL_CLKIN]		= &rtc_xtal_clkin.hw,
> +	[CLKID_RTC_32K_DIV]		= &rtc_32k_div.hw,
> +	[CLKID_RTC_32K_MUX]		= &rtc_32k_mux.hw,
> +	[CLKID_RTC_32K]			= &rtc_32k.hw,
> +	[CLKID_RTC_CLK]			= &rtc_clk.hw,
> +	[CLKID_SYS_A_SEL]		= &sys_a_sel.hw,
> +	[CLKID_SYS_A_DIV]		= &sys_a_div.hw,
> +	[CLKID_SYS_A]			= &sys_a.hw,
> +	[CLKID_SYS_B_SEL]		= &sys_b_sel.hw,
> +	[CLKID_SYS_B_DIV]		= &sys_b_div.hw,
> +	[CLKID_SYS_B]			= &sys_b.hw,
> +	[CLKID_SYS_CLK]			= &sys_clk.hw,
> +	[CLKID_AXI_A_SEL]		= &axi_a_sel.hw,
> +	[CLKID_AXI_A_DIV]		= &axi_a_div.hw,
> +	[CLKID_AXI_A]			= &axi_a.hw,
> +	[CLKID_AXI_B_SEL]		= &axi_b_sel.hw,
> +	[CLKID_AXI_B_DIV]		= &axi_b_div.hw,
> +	[CLKID_AXI_B]			= &axi_b.hw,
> +	[CLKID_AXI_CLK]			= &axi_clk.hw,
> +	[CLKID_SYS_RESET_CTRL]		= &sys_reset_ctrl.hw,
> +	[CLKID_SYS_PAD_CTRL]		= &sys_pwr_ctrl.hw,
> +	[CLKID_SYS_CTRL]		= &sys_ctrl.hw,
> +	[CLKID_SYS_TS_PLL]		= &sys_ts_pll.hw,
> +	[CLKID_SYS_DEV_ARB]		= &sys_dev_arb.hw,
> +	[CLKID_SYS_MMC_PCLK]		= &sys_mmc_pclk.hw,
> +	[CLKID_SYS_CAPU]		= &sys_capu.hw,
> +	[CLKID_SYS_CPU_CTRL]		= &sys_cpu_ctrl.hw,
> +	[CLKID_SYS_JTAG_CTRL]		= &sys_jtag_ctrl.hw,
> +	[CLKID_SYS_IR_CTRL]		= &sys_ir_ctrl.hw,
> +	[CLKID_SYS_IRQ_CTRL]		= &sys_irq_ctrl.hw,
> +	[CLKID_SYS_MSR_CLK]		= &sys_msr_clk.hw,
> +	[CLKID_SYS_ROM]			= &sys_rom.hw,
> +	[CLKID_SYS_UART_F]		= &sys_uart_f.hw,
> +	[CLKID_SYS_CPU_ARB]		= &sys_cpu_apb.hw,
> +	[CLKID_SYS_RSA]			= &sys_rsa.hw,
> +	[CLKID_SYS_SAR_ADC]		= &sys_sar_adc.hw,
> +	[CLKID_SYS_STARTUP]		= &sys_startup.hw,
> +	[CLKID_SYS_SECURE]		= &sys_secure.hw,
> +	[CLKID_SYS_SPIFC]		= &sys_spifc.hw,
> +	[CLKID_SYS_NNA]			= &sys_nna.hw,
> +	[CLKID_SYS_ETH_MAC]		= &sys_eth_mac.hw,
> +	[CLKID_SYS_GIC]			= &sys_gic.hw,
> +	[CLKID_SYS_RAMA]		= &sys_rama.hw,
> +	[CLKID_SYS_BIG_NIC]		= &sys_big_nic.hw,
> +	[CLKID_SYS_RAMB]		= &sys_ramb.hw,
> +	[CLKID_SYS_AUDIO_PCLK]		= &sys_audio_pclk.hw,
> +	[CLKID_SYS_PWM_KL]		= &sys_pwm_kl.hw,
> +	[CLKID_SYS_PWM_IJ]		= &sys_pwm_ij.hw,
> +	[CLKID_SYS_USB]			= &sys_usb.hw,
> +	[CLKID_SYS_SD_EMMC_A]		= &sys_sd_emmc_a.hw,
> +	[CLKID_SYS_SD_EMMC_C]		= &sys_sd_emmc_c.hw,
> +	[CLKID_SYS_PWM_AB]		= &sys_pwm_ab.hw,
> +	[CLKID_SYS_PWM_CD]		= &sys_pwm_cd.hw,
> +	[CLKID_SYS_PWM_EF]		= &sys_pwm_ef.hw,
> +	[CLKID_SYS_PWM_GH]		= &sys_pwm_gh.hw,
> +	[CLKID_SYS_SPICC_1]		= &sys_spicc_1.hw,
> +	[CLKID_SYS_SPICC_0]		= &sys_spicc_0.hw,
> +	[CLKID_SYS_UART_A]		= &sys_uart_a.hw,
> +	[CLKID_SYS_UART_B]		= &sys_uart_b.hw,
> +	[CLKID_SYS_UART_C]		= &sys_uart_c.hw,
> +	[CLKID_SYS_UART_D]		= &sys_uart_d.hw,
> +	[CLKID_SYS_UART_E]		= &sys_uart_e.hw,
> +	[CLKID_SYS_I2C_M_A]		= &sys_i2c_m_a.hw,
> +	[CLKID_SYS_I2C_M_B]		= &sys_i2c_m_b.hw,
> +	[CLKID_SYS_I2C_M_C]		= &sys_i2c_m_c.hw,
> +	[CLKID_SYS_I2C_M_D]		= &sys_i2c_m_d.hw,
> +	[CLKID_SYS_I2S_S_A]		= &sys_i2c_s_a.hw,
> +	[CLKID_SYS_RTC]			= &sys_rtc.hw,
> +	[CLKID_SYS_GE2D]		= &sys_ge2d.hw,
> +	[CLKID_SYS_ISP]			= &sys_isp.hw,
> +	[CLKID_SYS_GPV_ISP_NIC]		= &sys_gpv_isp_nic.hw,
> +	[CLKID_SYS_GPV_CVE_NIC]		= &sys_gpv_cve_nic.hw,
> +	[CLKID_SYS_MIPI_DSI_HOST]	= &sys_mipi_dsi_host.hw,
> +	[CLKID_SYS_MIPI_DSI_PHY]	= &sys_mipi_dsi_phy.hw,
> +	[CLKID_SYS_ETH_PHY]		= &sys_eth_phy.hw,
> +	[CLKID_SYS_ACODEC]		= &sys_acodec.hw,
> +	[CLKID_SYS_DWAP]		= &sys_dwap.hw,
> +	[CLKID_SYS_DOS]			= &sys_dos.hw,
> +	[CLKID_SYS_CVE]			= &sys_cve.hw,
> +	[CLKID_SYS_VOUT]		= &sys_vout.hw,
> +	[CLKID_SYS_VC9000E]		= &sys_vc9000e.hw,
> +	[CLKID_SYS_PWM_MN]		= &sys_pwm_mn.hw,
> +	[CLKID_SYS_SD_EMMC_B]		= &sys_sd_emmc_b.hw,
> +	[CLKID_AXI_SYS_NIC]		= &axi_sys_nic.hw,
> +	[CLKID_AXI_ISP_NIC]		= &axi_isp_nic.hw,
> +	[CLKID_AXI_CVE_NIC]		= &axi_cve_nic.hw,
> +	[CLKID_AXI_RAMB]		= &axi_ramb.hw,
> +	[CLKID_AXI_RAMA]		= &axi_rama.hw,
> +	[CLKID_AXI_CPU_DMC]		= &axi_cpu_dmc.hw,
> +	[CLKID_AXI_NIC]			= &axi_nic.hw,
> +	[CLKID_AXI_DMA]			= &axi_dma.hw,
> +	[CLKID_AXI_MUX_NIC]		= &axi_mux_nic.hw,
> +	[CLKID_AXI_CAPU]		= &axi_capu.hw,
> +	[CLKID_AXI_CVE]			= &axi_cve.hw,
> +	[CLKID_AXI_DEV1_DMC]		= &axi_dev1_dmc.hw,
> +	[CLKID_AXI_DEV0_DMC]		= &axi_dev0_dmc.hw,
> +	[CLKID_AXI_DSP_DMC]		= &axi_dsp_dmc.hw,
> +	[CLKID_12_24M_IN]		= &clk_12_24m_in.hw,
> +	[CLKID_12M_24M]			= &clk_12_24m.hw,
> +	[CLKID_FCLK_25M_DIV]		= &fclk_25m_div.hw,
> +	[CLKID_FCLK_25M]		= &fclk_25m.hw,
> +	[CLKID_GEN_SEL]			= &gen_sel.hw,
> +	[CLKID_GEN_DIV]			= &gen_div.hw,
> +	[CLKID_GEN]			= &gen.hw,
> +	[CLKID_SARADC_SEL]		= &saradc_sel.hw,
> +	[CLKID_SARADC_DIV]		= &saradc_div.hw,
> +	[CLKID_SARADC]			= &saradc.hw,
> +	[CLKID_PWM_A_SEL]		= &pwm_a_sel.hw,
> +	[CLKID_PWM_A_DIV]		= &pwm_a_div.hw,
> +	[CLKID_PWM_A]			= &pwm_a.hw,
> +	[CLKID_PWM_B_SEL]		= &pwm_b_sel.hw,
> +	[CLKID_PWM_B_DIV]		= &pwm_b_div.hw,
> +	[CLKID_PWM_B]			= &pwm_b.hw,
> +	[CLKID_PWM_C_SEL]		= &pwm_c_sel.hw,
> +	[CLKID_PWM_C_DIV]		= &pwm_c_div.hw,
> +	[CLKID_PWM_C]			= &pwm_c.hw,
> +	[CLKID_PWM_D_SEL]		= &pwm_d_sel.hw,
> +	[CLKID_PWM_D_DIV]		= &pwm_d_div.hw,
> +	[CLKID_PWM_D]			= &pwm_d.hw,
> +	[CLKID_PWM_E_SEL]		= &pwm_e_sel.hw,
> +	[CLKID_PWM_E_DIV]		= &pwm_e_div.hw,
> +	[CLKID_PWM_E]			= &pwm_e.hw,
> +	[CLKID_PWM_F_SEL]		= &pwm_f_sel.hw,
> +	[CLKID_PWM_F_DIV]		= &pwm_f_div.hw,
> +	[CLKID_PWM_F]			= &pwm_f.hw,
> +	[CLKID_PWM_G_SEL]		= &pwm_g_sel.hw,
> +	[CLKID_PWM_G_DIV]		= &pwm_g_div.hw,
> +	[CLKID_PWM_G]			= &pwm_g.hw,
> +	[CLKID_PWM_H_SEL]		= &pwm_h_sel.hw,
> +	[CLKID_PWM_H_DIV]		= &pwm_h_div.hw,
> +	[CLKID_PWM_H]			= &pwm_h.hw,
> +	[CLKID_PWM_I_SEL]		= &pwm_i_sel.hw,
> +	[CLKID_PWM_I_DIV]		= &pwm_i_div.hw,
> +	[CLKID_PWM_I]			= &pwm_i.hw,
> +	[CLKID_PWM_J_SEL]		= &pwm_j_sel.hw,
> +	[CLKID_PWM_J_DIV]		= &pwm_j_div.hw,
> +	[CLKID_PWM_J]			= &pwm_j.hw,
> +	[CLKID_PWM_K_SEL]		= &pwm_k_sel.hw,
> +	[CLKID_PWM_K_DIV]		= &pwm_k_div.hw,
> +	[CLKID_PWM_K]			= &pwm_k.hw,
> +	[CLKID_PWM_L_SEL]		= &pwm_l_sel.hw,
> +	[CLKID_PWM_L_DIV]		= &pwm_l_div.hw,
> +	[CLKID_PWM_L]			= &pwm_l.hw,
> +	[CLKID_PWM_M_SEL]		= &pwm_m_sel.hw,
> +	[CLKID_PWM_M_DIV]		= &pwm_m_div.hw,
> +	[CLKID_PWM_M]			= &pwm_m.hw,
> +	[CLKID_PWM_N_SEL]		= &pwm_n_sel.hw,
> +	[CLKID_PWM_N_DIV]		= &pwm_n_div.hw,
> +	[CLKID_PWM_N]			= &pwm_n.hw,
> +	[CLKID_SPICC_A_SEL]		= &spicc_a_sel.hw,
> +	[CLKID_SPICC_A_DIV]		= &spicc_a_div.hw,
> +	[CLKID_SPICC_A]			= &spicc_a.hw,
> +	[CLKID_SPICC_B_SEL]		= &spicc_b_sel.hw,
> +	[CLKID_SPICC_B_DIV]		= &spicc_b_div.hw,
> +	[CLKID_SPICC_B]			= &spicc_b.hw,
> +	[CLKID_SPIFC_SEL]		= &spifc_sel.hw,
> +	[CLKID_SPIFC_DIV]		= &spifc_div.hw,
> +	[CLKID_SPIFC]			= &spifc.hw,
> +	[CLKID_SD_EMMC_A_SEL]		= &sd_emmc_a_sel.hw,
> +	[CLKID_SD_EMMC_A_DIV]		= &sd_emmc_a_div.hw,
> +	[CLKID_SD_EMMC_A]		= &sd_emmc_a.hw,
> +	[CLKID_SD_EMMC_B_SEL]		= &sd_emmc_b_sel.hw,
> +	[CLKID_SD_EMMC_B_DIV]		= &sd_emmc_b_div.hw,
> +	[CLKID_SD_EMMC_B]		= &sd_emmc_b.hw,
> +	[CLKID_SD_EMMC_C_SEL]		= &sd_emmc_c_sel.hw,
> +	[CLKID_SD_EMMC_C_DIV]		= &sd_emmc_c_div.hw,
> +	[CLKID_SD_EMMC_C]		= &sd_emmc_c.hw,
> +	[CLKID_TS_DIV]			= &ts_div.hw,
> +	[CLKID_TS]			= &ts.hw,
> +	[CLKID_ETH_125M_DIV]		= &eth_125m_div.hw,
> +	[CLKID_ETH_125M]		= &eth_125m.hw,
> +	[CLKID_ETH_RMII_DIV]		= &eth_rmii_div.hw,
> +	[CLKID_ETH_RMII]		= &eth_rmii.hw,
> +	[CLKID_MIPI_DSI_MEAS_SEL]	= &mipi_dsi_meas_sel.hw,
> +	[CLKID_MIPI_DSI_MEAS_DIV]	= &mipi_dsi_meas_div.hw,
> +	[CLKID_MIPI_DSI_MEAS]		= &mipi_dsi_meas.hw,
> +	[CLKID_DSI_PHY_SEL]		= &dsi_phy_sel.hw,
> +	[CLKID_DSI_PHY_DIV]		= &dsi_phy_div.hw,
> +	[CLKID_DSI_PHY]			= &dsi_phy.hw,
> +	[CLKID_VOUT_MCLK_SEL]		= &vout_mclk_sel.hw,
> +	[CLKID_VOUT_MCLK_DIV]		= &vout_mclk_div.hw,
> +	[CLKID_VOUT_MCLK]		= &vout_mclk.hw,
> +	[CLKID_VOUT_ENC_SEL]		= &vout_enc_sel.hw,
> +	[CLKID_VOUT_ENC_DIV]		= &vout_enc_div.hw,
> +	[CLKID_VOUT_ENC]		= &vout_enc.hw,
> +	[CLKID_HCODEC_0_SEL]		= &hcodec_0_sel.hw,
> +	[CLKID_HCODEC_0_DIV]		= &hcodec_0_div.hw,
> +	[CLKID_HCODEC_0]		= &hcodec_0.hw,
> +	[CLKID_HCODEC_1_SEL]		= &hcodec_1_sel.hw,
> +	[CLKID_HCODEC_1_DIV]		= &hcodec_1_div.hw,
> +	[CLKID_HCODEC_1]		= &hcodec_1.hw,
> +	[CLKID_HCODEC]			= &hcodec.hw,
> +	[CLKID_VC9000E_ACLK_SEL]	= &vc9000e_aclk_sel.hw,
> +	[CLKID_VC9000E_ACLK_DIV]	= &vc9000e_aclk_div.hw,
> +	[CLKID_VC9000E_ACLK]		= &vc9000e_aclk.hw,
> +	[CLKID_VC9000E_CORE_SEL]	= &vc9000e_core_sel.hw,
> +	[CLKID_VC9000E_CORE_DIV]	= &vc9000e_core_div.hw,
> +	[CLKID_VC9000E_CORE]		= &vc9000e_core.hw,
> +	[CLKID_CSI_PHY0_SEL]		= &csi_phy0_sel.hw,
> +	[CLKID_CSI_PHY0_DIV]		= &csi_phy0_div.hw,
> +	[CLKID_CSI_PHY0]		= &csi_phy0.hw,
> +	[CLKID_DEWARPA_SEL]		= &dewarpa_sel.hw,
> +	[CLKID_DEWARPA_DIV]		= &dewarpa_div.hw,
> +	[CLKID_DEWARPA]			= &dewarpa.hw,
> +	[CLKID_ISP0_SEL]		= &isp0_sel.hw,
> +	[CLKID_ISP0_DIV]		= &isp0_div.hw,
> +	[CLKID_ISP0]			= &isp0.hw,
> +	[CLKID_NNA_CORE_SEL]		= &nna_core_sel.hw,
> +	[CLKID_NNA_CORE_DIV]		= &nna_core_div.hw,
> +	[CLKID_NNA_CORE]		= &nna_core.hw,
> +	[CLKID_GE2D_SEL]		= &ge2d_sel.hw,
> +	[CLKID_GE2D_DIV]		= &ge2d_div.hw,
> +	[CLKID_GE2D]			= &ge2d.hw,
> +	[CLKID_VAPB_SEL]		= &vapb_sel.hw,
> +	[CLKID_VAPB_DIV]		= &vapb_div.hw,
> +	[CLKID_VAPB]			= &vapb.hw,
> +};
> +
> +/* Convenience table to populate regmap in .probe */
> +static struct clk_regmap *const c3_periphs_clk_regmaps[] = {
> +	&pll_in,
> +	&mclk_pll_in,
> +	&rtc_xtal_clkin,
> +	&rtc_32k_div,
> +	&rtc_32k_mux,
> +	&rtc_32k,
> +	&rtc_clk,
> +	&sys_a_sel,
> +	&sys_a_div,
> +	&sys_a,
> +	&sys_b_sel,
> +	&sys_b_div,
> +	&sys_b,
> +	&sys_clk,
> +	&axi_a_sel,
> +	&axi_a_div,
> +	&axi_a,
> +	&axi_b_sel,
> +	&axi_b_div,
> +	&axi_b,
> +	&axi_clk,
> +	&sys_reset_ctrl,
> +	&sys_pwr_ctrl,
> +	&sys_pad_ctrl,
> +	&sys_ctrl,
> +	&sys_ts_pll,
> +	&sys_dev_arb,
> +	&sys_mmc_pclk,
> +	&sys_capu,
> +	&sys_cpu_ctrl,
> +	&sys_jtag_ctrl,
> +	&sys_ir_ctrl,
> +	&sys_irq_ctrl,
> +	&sys_msr_clk,
> +	&sys_rom,
> +	&sys_uart_f,
> +	&sys_cpu_apb,
> +	&sys_rsa,
> +	&sys_sar_adc,
> +	&sys_startup,
> +	&sys_secure,
> +	&sys_spifc,
> +	&sys_nna,
> +	&sys_eth_mac,
> +	&sys_gic,
> +	&sys_rama,
> +	&sys_big_nic,
> +	&sys_ramb,
> +	&sys_audio_pclk,
> +	&sys_pwm_kl,
> +	&sys_pwm_ij,
> +	&sys_usb,
> +	&sys_sd_emmc_a,
> +	&sys_sd_emmc_c,
> +	&sys_pwm_ab,
> +	&sys_pwm_cd,
> +	&sys_pwm_ef,
> +	&sys_pwm_gh,
> +	&sys_spicc_1,
> +	&sys_spicc_0,
> +	&sys_uart_a,
> +	&sys_uart_b,
> +	&sys_uart_c,
> +	&sys_uart_d,
> +	&sys_uart_e,
> +	&sys_i2c_m_a,
> +	&sys_i2c_m_b,
> +	&sys_i2c_m_c,
> +	&sys_i2c_m_d,
> +	&sys_i2c_s_a,
> +	&sys_rtc,
> +	&sys_ge2d,
> +	&sys_isp,
> +	&sys_gpv_isp_nic,
> +	&sys_gpv_cve_nic,
> +	&sys_mipi_dsi_host,
> +	&sys_mipi_dsi_phy,
> +	&sys_eth_phy,
> +	&sys_acodec,
> +	&sys_dwap,
> +	&sys_dos,
> +	&sys_cve,
> +	&sys_vout,
> +	&sys_vc9000e,
> +	&sys_pwm_mn,
> +	&sys_sd_emmc_b,
> +	&axi_sys_nic,
> +	&axi_isp_nic,
> +	&axi_cve_nic,
> +	&axi_ramb,
> +	&axi_rama,
> +	&axi_cpu_dmc,
> +	&axi_nic,
> +	&axi_dma,
> +	&axi_mux_nic,
> +	&axi_capu,
> +	&axi_cve,
> +	&axi_dev1_dmc,
> +	&axi_dev0_dmc,
> +	&axi_dsp_dmc,
> +	&clk_12_24m_in,
> +	&clk_12_24m,
> +	&fclk_25m_div,
> +	&fclk_25m,
> +	&gen_sel,
> +	&gen_div,
> +	&gen,
> +	&saradc_sel,
> +	&saradc_div,
> +	&saradc,
> +	&pwm_a_sel,
> +	&pwm_a_div,
> +	&pwm_a,
> +	&pwm_b_sel,
> +	&pwm_b_div,
> +	&pwm_b,
> +	&pwm_c_sel,
> +	&pwm_c_div,
> +	&pwm_c,
> +	&pwm_d_sel,
> +	&pwm_d_div,
> +	&pwm_d,
> +	&pwm_e_sel,
> +	&pwm_e_div,
> +	&pwm_e,
> +	&pwm_f_sel,
> +	&pwm_f_div,
> +	&pwm_f,
> +	&pwm_g_sel,
> +	&pwm_g_div,
> +	&pwm_g,
> +	&pwm_h_sel,
> +	&pwm_h_div,
> +	&pwm_h,
> +	&pwm_i_sel,
> +	&pwm_i_div,
> +	&pwm_i,
> +	&pwm_j_sel,
> +	&pwm_j_div,
> +	&pwm_j,
> +	&pwm_k_sel,
> +	&pwm_k_div,
> +	&pwm_k,
> +	&pwm_l_sel,
> +	&pwm_l_div,
> +	&pwm_l,
> +	&pwm_m_sel,
> +	&pwm_m_div,
> +	&pwm_m,
> +	&pwm_n_sel,
> +	&pwm_n_div,
> +	&pwm_n,
> +	&spicc_a_sel,
> +	&spicc_a_div,
> +	&spicc_a,
> +	&spicc_b_sel,
> +	&spicc_b_div,
> +	&spicc_b,
> +	&spifc_sel,
> +	&spifc_div,
> +	&spifc,
> +	&sd_emmc_a_sel,
> +	&sd_emmc_a_div,
> +	&sd_emmc_a,
> +	&sd_emmc_b_sel,
> +	&sd_emmc_b_div,
> +	&sd_emmc_b,
> +	&sd_emmc_c_sel,
> +	&sd_emmc_c_div,
> +	&sd_emmc_c,
> +	&ts_div,
> +	&ts,
> +	&eth_125m,
> +	&eth_rmii_div,
> +	&eth_rmii,
> +	&mipi_dsi_meas_sel,
> +	&mipi_dsi_meas_div,
> +	&mipi_dsi_meas,
> +	&dsi_phy_sel,
> +	&dsi_phy_div,
> +	&dsi_phy,
> +	&vout_mclk_sel,
> +	&vout_mclk_div,
> +	&vout_mclk,
> +	&vout_enc_sel,
> +	&vout_enc_div,
> +	&vout_enc,
> +	&hcodec_0_sel,
> +	&hcodec_0_div,
> +	&hcodec_0,
> +	&hcodec_1_sel,
> +	&hcodec_1_div,
> +	&hcodec_1,
> +	&hcodec,
> +	&vc9000e_aclk_sel,
> +	&vc9000e_aclk_div,
> +	&vc9000e_aclk,
> +	&vc9000e_core_sel,
> +	&vc9000e_core_div,
> +	&vc9000e_core,
> +	&csi_phy0_sel,
> +	&csi_phy0_div,
> +	&csi_phy0,
> +	&dewarpa_sel,
> +	&dewarpa_div,
> +	&dewarpa,
> +	&isp0_sel,
> +	&isp0_div,
> +	&isp0,
> +	&nna_core_sel,
> +	&nna_core_div,
> +	&nna_core,
> +	&ge2d_sel,
> +	&ge2d_div,
> +	&ge2d,
> +	&vapb_sel,
> +	&vapb_div,
> +	&vapb,
> +};
> +
> +static struct regmap_config clkc_regmap_config = {
> +	.reg_bits       = 32,
> +	.val_bits       = 32,
> +	.reg_stride     = 4,
> +};
> +
> +static struct meson_clk_hw_data c3_periphs_clks = {
> +	.hws = c3_periphs_hw_clks,
> +	.num = ARRAY_SIZE(c3_periphs_hw_clks),
> +};
> +
> +static int aml_c3_peripherals_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct regmap *regmap;
> +	void __iomem *base;
> +	int clkid, ret, i;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
> +	if (IS_ERR(regmap))
> +		return PTR_ERR(regmap);
> +
> +	/* Populate regmap for the regmap backed clocks */
> +	for (i = 0; i < ARRAY_SIZE(c3_periphs_clk_regmaps); i++)
> +		c3_periphs_clk_regmaps[i]->map = regmap;
> +
> +	for (clkid = 0; clkid < c3_periphs_clks.num; clkid++) {
> +		/* array might be sparse */
> +		if (!c3_periphs_clks.hws[clkid])
> +			continue;
> +
> +		ret = devm_clk_hw_register(dev, c3_periphs_clks.hws[clkid]);
> +		if (ret) {
> +			dev_err(dev, "Clock registration failed\n");
> +			return ret;
> +		}
> +	}
> +
> +	return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
> +					   &c3_periphs_clks);
> +}
> +
> +static const struct of_device_id c3_peripherals_clkc_match_table[] = {
> +	{
> +		.compatible = "amlogic,c3-peripherals-clkc",
> +	},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(of, c3_peripherals_clkc_match_table);
> +
> +static struct platform_driver c3_peripherals_driver = {
> +	.probe		= aml_c3_peripherals_probe,
> +	.driver		= {
> +		.name	= "c3-peripherals-clkc",
> +		.of_match_table = c3_peripherals_clkc_match_table,
> +	},
> +};
> +
> +module_platform_driver(c3_peripherals_driver);
> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/meson/c3-peripherals.h b/drivers/clk/meson/c3-peripherals.h
> new file mode 100644
> index 000000000000..ddcc23e25669
> --- /dev/null
> +++ b/drivers/clk/meson/c3-peripherals.h
> @@ -0,0 +1,48 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (c) 2023 Amlogic, inc.
> + * Author: Chuan Liu <chuan.liu@amlogic.com>
> + */
> +
> +#ifndef __AML_C3_PERIPHERALS_H__
> +#define __AML_C3_PERIPHERALS_H__
> +
> +#define OSCIN_CTRL				0x0004
> +#define RTC_BY_OSCIN_CTRL0			0x0008
> +#define RTC_BY_OSCIN_CTRL1			0x000c
> +#define RTC_CTRL				0x0010
> +#define SYS_CLK_CTRL0				0x0040
> +#define SYS_CLK_EN0_REG0			0x0044
> +#define SYS_CLK_EN0_REG1			0x0048
> +#define SYS_CLK_EN0_REG2			0x004c
> +#define AXI_CLK_CTRL0				0x006c
> +#define CLK12_24_CTRL				0x00a8
> +#define AXI_CLK_EN0				0x00ac
> +#define VDIN_MEAS_CLK_CTRL			0x00f8
> +#define VAPB_CLK_CTRL				0x00fc
> +#define MIPIDSI_PHY_CLK_CTRL			0x0104
> +#define GE2D_CLK_CTRL				0x010c
> +#define ISP0_CLK_CTRL				0x0110
> +#define DEWARPA_CLK_CTRL			0x0114
> +#define VOUTENC_CLK_CTRL			0x0118
> +#define VDEC_CLK_CTRL				0x0140
> +#define VDEC3_CLK_CTRL				0x0148
> +#define TS_CLK_CTRL				0x0158
> +#define ETH_CLK_CTRL				0x0164
> +#define NAND_CLK_CTRL				0x0168
> +#define SD_EMMC_CLK_CTRL			0x016c
> +#define SPICC_CLK_CTRL				0x0174
> +#define GEN_CLK_CTRL				0x0178
> +#define SAR_CLK_CTRL0				0x017c
> +#define PWM_CLK_AB_CTRL				0x0180
> +#define PWM_CLK_CD_CTRL				0x0184
> +#define PWM_CLK_EF_CTRL				0x0188
> +#define PWM_CLK_GH_CTRL				0x018c
> +#define PWM_CLK_IJ_CTRL				0x0190
> +#define PWM_CLK_KL_CTRL				0x0194
> +#define PWM_CLK_MN_CTRL				0x0198
> +#define VC9000E_CLK_CTRL			0x019c
> +#define SPIFC_CLK_CTRL				0x01a0
> +#define NNA_CLK_CTRL				0x0220

Nitpick - the extra zero is not needed
Since this is used only by c3 periph clkc - do you really need an header
or can it be defined in the related .c file ?

(I know this is a pattern we have been using so far, but it is not
really justified. No reason to continue with it)

> +
> +#endif  /* __AML_C3_PERIPHERALS_H__ */


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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-13  7:38     ` Jerome Brunet
@ 2023-10-13 22:01       ` Stephen Boyd
  2023-10-16  6:49         ` Xianwei Zhao
  0 siblings, 1 reply; 27+ messages in thread
From: Stephen Boyd @ 2023-10-13 22:01 UTC (permalink / raw)
  To: Jerome Brunet, Xianwei Zhao, devicetree, linux-amlogic,
	linux-arm-kernel, linux-clk, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu

Quoting Jerome Brunet (2023-10-13 00:38:14)
> 
> On Thu 12 Oct 2023 at 16:51, Stephen Boyd <sboyd@kernel.org> wrote:
> 
> > Quoting Xianwei Zhao (2023-10-09 23:29:17)
> >> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> >> index 76be4bbd2afb..c8d59d28c8ff 100644
> >> --- a/drivers/clk/meson/Kconfig
> >> +++ b/drivers/clk/meson/Kconfig
> >> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
> >>           Say Y if you want the board to work, because PLLs are the parent of most
> >>           peripherals.
> >>  
> >> +config COMMON_CLK_C3_PERIPHERALS
> >> +       tristate "Amlogic C3 peripherals clock controller"
> >> +       default y
> >
> > Why are these default y? They should depend on something like ARM64 and
> > even then I don't see why we want to enable them by default if we're
> > building the ARM64 kernel.
> 
> Should indeed depend on ARM64.

Cool.

> 
> Those are the main clock controllers. Like for other AML SoC families,
> they are necessary to boot the device which is why they use 'default y'
> 
> Is it a problem ?
> 
> The whole meson directory depends on ARCH_MESON, so the drivers will go
> away if Amlogic support is removed on ARM64.

No it isn't a problem if the entire section is implicitly depending on
ARCH_MESON.

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

* Re: [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings
  2023-10-13  7:35       ` Jerome Brunet
@ 2023-10-16  6:41         ` Xianwei Zhao
  0 siblings, 0 replies; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-16  6:41 UTC (permalink / raw)
  To: Jerome Brunet, Rob Herring
  Cc: linux-arm-kernel, linux-amlogic, linux-clk, devicetree,
	linux-kernel, Neil Armstrong, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu

Hi Jerome,
     Thanks for your reply.

On 2023/10/13 15:35, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Wed 11 Oct 2023 at 10:50, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:
> 
>> Hi Rob,
>>      Thanks for your advise.
>>
>> On 2023/10/10 21:21, Rob Herring wrote:
>>> [ EXTERNAL EMAIL ]
>>> On Tue, Oct 10, 2023 at 02:29:14PM +0800, Xianwei Zhao wrote:
>>>> Add the C3 PLL clock controller dt-bindings for Amlogic C3 SoC family
>>>>
>>>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>>>> ---
>>>> V1 -> V2: Fix errors when check dtbinding use "make dt_binding_check"
>>> Your patches aren't bisectable. It's fine if you want to combine patch 1
>>> and 2 into 1 patch. Or just use the raw numbers here instead of the
>>> header.
>>>
>> I will combine patch 1 and 2 into 1 patch in V3.
> 
> I'd prefer if you used raw ids or even fake node for the example, like
> <&pll_in> and <&mpll_in> for readability, rather than combining the patches
> 
Will do.
>>>> ---
>>>>    .../bindings/clock/amlogic,c3-pll-clkc.yaml   | 59 +++++++++++++++++++
>>>>    .../dt-bindings/clock/amlogic,c3-pll-clkc.h   | 42 +++++++++++++
>>>>    2 files changed, 101 insertions(+)
>>>>    create mode 100644 Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>>>>    create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>>>> new file mode 100644
>>>> index 000000000000..a646992917b7
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,c3-pll-clkc.yaml
>>>> @@ -0,0 +1,59 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/clock/amlogic,c3-pll-clkc.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Amlogic C3 serials PLL Clock Controller
>>> s/serials/Serials/
>>>
>> Will fix
>>>> +
>>>> +maintainers:
>>>> +  - Chuan Liu <chuan.liu@amlogic.com>
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: amlogic,c3-pll-clkc
>>>> +
>>>> +  reg:
>>>> +    maxItems: 1
>>>> +
>>>> +  clocks:
>>>> +    minItems: 1
>>>> +    items:
>>>> +      - description: input pll_in
>>>> +      - description: input mclk_pll_in
>>>> +
>>>> +  clock-names:
>>>> +    minItems: 1
>>>> +    items:
>>>> +      - const: pll_in
>>>> +      - const: mclk_pll_in
>>>> +
>>>> +  "#clock-cells":
>>>> +    const: 1
>>>> +
>>>> +required:
>>>> +  - compatible
>>>> +  - reg
>>>> +  - clocks
>>>> +  - clock-names
>>>> +  - "#clock-cells"
>>>> +
>>>> +additionalProperties: false
>>>> +
>>>> +examples:
>>>> +  - |
>>>> +    #include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
>>>> +    apb {
>>>> +        #address-cells = <2>;
>>>> +        #size-cells = <2>;
>>>> +
>>>> +        clkc_pll: clock-controller@8000 {
>>> Drop unused labels.
>>>
>> Will delete clkc_pll.
>>>> +          compatible = "amlogic,c3-pll-clkc";
>>> Your indentation is not consistent.
>>>
>> Will fix it in V3.
>>>> +          reg = <0x0 0x8000 0x0 0x1a4>;
>>>> +          clocks = <&clkc_periphs CLKID_PLL_IN>,
>>>> +                   <&clkc_periphs CLKID_MCLK_PLL_IN>;
>>>> +          clock-names = "pll_in", "mclk_pll_in";
>>>> +          #clock-cells = <1>;
>>>> +        };
>>>> +    };
>>>> diff --git a/include/dt-bindings/clock/amlogic,c3-pll-clkc.h b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>>>> new file mode 100644
>>>> index 000000000000..aa731e8fae29
>>>> --- /dev/null
>>>> +++ b/include/dt-bindings/clock/amlogic,c3-pll-clkc.h
>>>> @@ -0,0 +1,42 @@
>>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>>>> +/*
>>>> + * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
>>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>>> + */
>>>> +
>>>> +#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
>>>> +#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H
>>>> +
>>>> +#define CLKID_FIXED_PLL_DCO                  0
>>>> +#define CLKID_FIXED_PLL                              1
>>>> +#define CLKID_FCLK_DIV40_DIV                 2
>>>> +#define CLKID_FCLK_DIV40                     3
>>>> +#define CLKID_FCLK_DIV2_DIV                  4
>>>> +#define CLKID_FCLK_DIV2                              5
>>>> +#define CLKID_FCLK_DIV2P5_DIV                        6
>>>> +#define CLKID_FCLK_DIV2P5                    7
>>>> +#define CLKID_FCLK_DIV3_DIV                  8
>>>> +#define CLKID_FCLK_DIV3                              9
>>>> +#define CLKID_FCLK_DIV4_DIV                  10
>>>> +#define CLKID_FCLK_DIV4                              11
>>>> +#define CLKID_FCLK_DIV5_DIV                  12
>>>> +#define CLKID_FCLK_DIV5                              13
>>>> +#define CLKID_FCLK_DIV7_DIV                  14
>>>> +#define CLKID_FCLK_DIV7                              15
>>>> +#define CLKID_GP0_PLL_DCO                    16
>>>> +#define CLKID_GP0_PLL                                17
>>>> +#define CLKID_HIFI_PLL_DCO                   18
>>>> +#define CLKID_HIFI_PLL                               19
>>>> +#define CLKID_MCLK_PLL_DCO                   20
>>>> +#define CLKID_MCLK_PLL                               21
>>>> +#define CLKID_MCLK_PLL_CLK                   22
>>>> +#define CLKID_MCLK0_SEL                              23
>>>> +#define CLKID_MCLK0_SEL_OUT                  24
>>>> +#define CLKID_MCLK0_DIV                              25
>>>> +#define CLKID_MCLK0                          26
>>>> +#define CLKID_MCLK1_SEL                              27
>>>> +#define CLKID_MCLK1_SEL_OUT                  28
>>>> +#define CLKID_MCLK1_DIV                              29
>>>> +#define CLKID_MCLK1                          30
>>>> +
>>>> +#endif  /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PLL_CLKC_H */
>>>>
>>>> base-commit: 57b55c76aaf1ba50ecc6dcee5cd6843dc4d85239
>>>> --
>>>> 2.37.1
>>>>
> 

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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-13 22:01       ` Stephen Boyd
@ 2023-10-16  6:49         ` Xianwei Zhao
  0 siblings, 0 replies; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-16  6:49 UTC (permalink / raw)
  To: Stephen Boyd, Jerome Brunet, devicetree, linux-amlogic,
	linux-arm-kernel, linux-clk, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu

Hi Stephen & Jerome,
        Thanks for your reply.

On 2023/10/14 06:01, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Jerome Brunet (2023-10-13 00:38:14)
>>
>> On Thu 12 Oct 2023 at 16:51, Stephen Boyd <sboyd@kernel.org> wrote:
>>
>>> Quoting Xianwei Zhao (2023-10-09 23:29:17)
>>>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>>>> index 76be4bbd2afb..c8d59d28c8ff 100644
>>>> --- a/drivers/clk/meson/Kconfig
>>>> +++ b/drivers/clk/meson/Kconfig
>>>> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
>>>>            Say Y if you want the board to work, because PLLs are the parent of most
>>>>            peripherals.
>>>>
>>>> +config COMMON_CLK_C3_PERIPHERALS
>>>> +       tristate "Amlogic C3 peripherals clock controller"
>>>> +       default y
>>>
>>> Why are these default y? They should depend on something like ARM64 and
>>> even then I don't see why we want to enable them by default if we're
>>> building the ARM64 kernel.
>>
>> Should indeed depend on ARM64.
> 
> Cool. >
Will add depend on ARM64  in next version.
>>
>> Those are the main clock controllers. Like for other AML SoC families,
>> they are necessary to boot the device which is why they use 'default y'
>>
>> Is it a problem ?
>>
>> The whole meson directory depends on ARCH_MESON, so the drivers will go
>> away if Amlogic support is removed on ARM64.
> 
> No it isn't a problem if the entire section is implicitly depending on
> ARCH_MESON.

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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-13  8:46   ` Jerome Brunet
@ 2023-10-17  3:25     ` Xianwei Zhao
  2023-10-17 13:28       ` Jerome Brunet
  0 siblings, 1 reply; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-17  3:25 UTC (permalink / raw)
  To: Jerome Brunet, linux-arm-kernel, linux-amlogic, linux-clk,
	devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu

Hi Jerome,
      Thank you for your reply.

On 2023/10/13 16:46, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:
> 
>> Add the C3 peripherals clock controller driver in the C3 SoC family.
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>> ---
>> V1 -> V2: Delete macro definition.
>> ---
>>   drivers/clk/meson/Kconfig          |   13 +
>>   drivers/clk/meson/Makefile         |    1 +
>>   drivers/clk/meson/c3-peripherals.c | 3096 ++++++++++++++++++++++++++++
>>   drivers/clk/meson/c3-peripherals.h |   48 +
>>   4 files changed, 3158 insertions(+)
>>   create mode 100644 drivers/clk/meson/c3-peripherals.c
>>   create mode 100644 drivers/clk/meson/c3-peripherals.h
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index 76be4bbd2afb..c8d59d28c8ff 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
>>          Say Y if you want the board to work, because PLLs are the parent of most
>>          peripherals.
>>
>> +config COMMON_CLK_C3_PERIPHERALS
>> +     tristate "Amlogic C3 peripherals clock controller"
>> +     default y
>> +     select COMMON_CLK_MESON_REGMAP
>> +     select COMMON_CLK_MESON_DUALDIV
>> +     select COMMON_CLK_MESON_CLKC_UTILS
>> +     select COMMON_CLK_C3_PLL
>> +     help
>> +       Support for the Peripherals clock controller on Amlogic C302X and
>> +       C308L devices, AKA c3. Amlogic C302X and C308L devices include
>> +       AW402, AW409 and AW419. Say Y if you want the peripherals clock
>> +       to work.
>> +
>>   config COMMON_CLK_G12A
>>        tristate "G12 and SM1 SoC clock controllers support"
>>        depends on ARM64
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index 4420af628b31..20ad9482c892 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_C3_PLL) += c3-pll.o
>> +obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>>   obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>>   obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>>   obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
>> diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c
>> new file mode 100644
>> index 000000000000..2931cb20299a
>> --- /dev/null
>> +++ b/drivers/clk/meson/c3-peripherals.c
>> @@ -0,0 +1,3096 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Amlogic C3 Peripherals Clock Controller Driver
>> + *
>> + * Copyright (c) 2023 Amlogic, inc.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/clk.h>
>> +#include "clk-regmap.h"
>> +#include "clk-dualdiv.h"
>> +#include "c3-peripherals.h"
>> +#include "meson-clkc-utils.h"
>> +#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
>> +
>> +static struct clk_regmap pll_in = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = OSCIN_CTRL,
>> +             .bit_idx = 4,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pll_in",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "xtal",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk_pll_in = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = OSCIN_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "mclk_pll_in",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_data = &(const struct clk_parent_data) {
>> +                     .fw_name = "xtal",
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data rtc_xtal_clkin_parent = {
>> +     .fw_name = "xtal",
>> +};
>> +
>> +static struct clk_regmap rtc_xtal_clkin = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = RTC_BY_OSCIN_CTRL0,
>> +             .bit_idx = 31,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_xtal_clkin",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_data = &rtc_xtal_clkin_parent,
> 
> Why can't you inline
> 
Will do
>                  .parent_data = &(const struct clk_parent_data) {
>                          .fw_name = "xtal",
>                  },
> 
> like for the other clock ... please be consistent
> 
> 
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = {
>> +     { 733, 732, 8, 11, 1 },
>> +     { /* sentinel */ }
>> +};
>> +
>> +static struct clk_regmap rtc_32k_div = {
>> +     .data = &(struct meson_clk_dualdiv_data){
>> +             .n1 = {
>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 12,
>> +             },
>> +             .n2 = {
>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>> +                     .shift   = 12,
>> +                     .width   = 12,
>> +             },
>> +             .m1 = {
>> +                     .reg_off = RTC_BY_OSCIN_CTRL1,
>> +                     .shift   = 0,
>> +                     .width   = 12,
>> +             },
>> +             .m2 = {
>> +                     .reg_off = RTC_BY_OSCIN_CTRL1,
>> +                     .shift   = 12,
>> +                     .width   = 12,
>> +             },
>> +             .dual = {
>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .table = rtc_32k_div_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_32k_div",
>> +             .ops = &meson_clk_dualdiv_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &rtc_xtal_clkin.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data rtc_32k_mux_parent_data[] = {
>> +     { .hw = &rtc_32k_div.hw },
>> +     { .hw = &rtc_xtal_clkin.hw }
>> +};
>> +
>> +static struct clk_regmap rtc_32k_mux = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = RTC_BY_OSCIN_CTRL1,
>> +             .mask = 0x1,
>> +             .shift = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "rtc_32k_mux",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = rtc_32k_mux_parent_data,
>> +             .num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data),
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap rtc_32k = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = RTC_BY_OSCIN_CTRL0,
>> +             .bit_idx = 30,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "rtc_32k",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &rtc_32k_mux.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data rtc_clk_mux_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .hw = &rtc_32k.hw }
>> +};
>> +
>> +static struct clk_regmap 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 = rtc_clk_mux_parent_data,
>> +             .num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data),
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +/*
>> + * Some clocks have multiple clock sources, and the parent clock and index are
>> + * discontinuous, Some channels corresponding to the clock index are not
>> + * actually connected inside the chip, or the clock source is invalid.
>> + */
>> +
>> +static u32 sys_axi_parent_table[] = { 0, 2, 3, 4, 7 };
>> +
>> +static const struct clk_parent_data sys_axi_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .hw = &rtc_clk.hw }
>> +};
>> +
>> +static struct clk_regmap sys_a_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SYS_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 10,
>> +             .table = sys_axi_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sys_a_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = sys_axi_parent_data,
>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap sys_a_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SYS_CLK_CTRL0,
>> +             .shift = 0,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sys_a_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sys_a_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sys_a = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SYS_CLK_CTRL0,
>> +             .bit_idx = 13,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sys_a",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sys_a_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_IGNORE_UNUSED,
> 
> As usual, a comment is expected when using CLK_IGNORE_UNUSED.
> It is very often not appropriate or justified.
> 
> Same goes for the other instances
> 
Will do.
>> +     },
>> +};
>> +
>> +static struct clk_regmap sys_b_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SYS_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 26,
>> +             .table = sys_axi_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sys_b_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = sys_axi_parent_data,
>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap sys_b_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SYS_CLK_CTRL0,
>> +             .shift = 16,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sys_b_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sys_b_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sys_b = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SYS_CLK_CTRL0,
>> +             .bit_idx = 29,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sys_b",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sys_b_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_IGNORE_UNUSED,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data sys_clk_parent_data[] = {
>> +     { .hw = &sys_a.hw },
>> +     { .hw = &sys_b.hw }
>> +};
>> +
>> +static struct clk_regmap sys_clk = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SYS_CLK_CTRL0,
>> +             .mask = 0x1,
>> +             .shift = 15,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sys_clk",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = sys_clk_parent_data,
>> +             .num_parents = ARRAY_SIZE(sys_clk_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap axi_a_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = AXI_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 10,
>> +             .table = sys_axi_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "axi_a_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = sys_axi_parent_data,
>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap axi_a_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = AXI_CLK_CTRL0,
>> +             .shift = 0,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "axi_a_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &axi_a_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap axi_a = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = AXI_CLK_CTRL0,
>> +             .bit_idx = 13,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "axi_a",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &axi_a_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_IGNORE_UNUSED,
>> +     },
>> +};
>> +
>> +static struct clk_regmap axi_b_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = AXI_CLK_CTRL0,
>> +             .mask = 0x7,
>> +             .shift = 26,
>> +             .table = sys_axi_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "axi_b_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = sys_axi_parent_data,
>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap axi_b_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = AXI_CLK_CTRL0,
>> +             .shift = 16,
>> +             .width = 10,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "axi_b_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &axi_b_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap axi_b = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = AXI_CLK_CTRL0,
>> +             .bit_idx = 29,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "axi_b",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &axi_b_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_IGNORE_UNUSED,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data axi_clk_parent_data[] = {
>> +     { .hw = &axi_a.hw },
>> +     { .hw = &axi_b.hw }
>> +};
>> +
>> +static struct clk_regmap axi_clk = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = AXI_CLK_CTRL0,
>> +             .mask = 0x1,
>> +             .shift = 15,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "axi_clk",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = axi_clk_parent_data,
>> +             .num_parents = ARRAY_SIZE(axi_clk_parent_data),
>> +     },
>> +};
>> +
>> +#define AML_CLK_GATE_SYS_CLK(_name, _reg, _bit)\
>> +     MESON_PCLK(_name, _reg, _bit, &sys_clk.hw)
>> +#define AML_CLK_GATE_AXI_CLK(_name, _reg, _bit)\
>> +     MESON_PCLK(_name, _reg, _bit, &axi_clk.hw)
>> +
>> +AML_CLK_GATE_SYS_CLK(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1);
>> +AML_CLK_GATE_SYS_CLK(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3);
>> +AML_CLK_GATE_SYS_CLK(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4);
>> +AML_CLK_GATE_SYS_CLK(sys_ctrl, SYS_CLK_EN0_REG0, 5);
>> +AML_CLK_GATE_SYS_CLK(sys_ts_pll, SYS_CLK_EN0_REG0, 6);
>> +AML_CLK_GATE_SYS_CLK(sys_dev_arb, SYS_CLK_EN0_REG0, 7);
>> +AML_CLK_GATE_SYS_CLK(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
>> +AML_CLK_GATE_SYS_CLK(sys_capu, SYS_CLK_EN0_REG0, 9);
>> +AML_CLK_GATE_SYS_CLK(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11);
>> +AML_CLK_GATE_SYS_CLK(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12);
>> +AML_CLK_GATE_SYS_CLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13);
>> +AML_CLK_GATE_SYS_CLK(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14);
>> +AML_CLK_GATE_SYS_CLK(sys_msr_clk, SYS_CLK_EN0_REG0, 15);
>> +AML_CLK_GATE_SYS_CLK(sys_rom, SYS_CLK_EN0_REG0, 16);
>> +AML_CLK_GATE_SYS_CLK(sys_uart_f, SYS_CLK_EN0_REG0, 17);
>> +AML_CLK_GATE_SYS_CLK(sys_cpu_apb, SYS_CLK_EN0_REG0, 18);
>> +AML_CLK_GATE_SYS_CLK(sys_rsa, SYS_CLK_EN0_REG0, 19);
>> +AML_CLK_GATE_SYS_CLK(sys_sar_adc, SYS_CLK_EN0_REG0, 20);
>> +AML_CLK_GATE_SYS_CLK(sys_startup, SYS_CLK_EN0_REG0, 21);
>> +AML_CLK_GATE_SYS_CLK(sys_secure, SYS_CLK_EN0_REG0, 22);
>> +AML_CLK_GATE_SYS_CLK(sys_spifc, SYS_CLK_EN0_REG0, 23);
>> +AML_CLK_GATE_SYS_CLK(sys_nna, SYS_CLK_EN0_REG0, 25);
>> +AML_CLK_GATE_SYS_CLK(sys_eth_mac, SYS_CLK_EN0_REG0, 26);
>> +AML_CLK_GATE_SYS_CLK(sys_gic, SYS_CLK_EN0_REG0, 27);
>> +AML_CLK_GATE_SYS_CLK(sys_rama, SYS_CLK_EN0_REG0, 28);
>> +AML_CLK_GATE_SYS_CLK(sys_big_nic, SYS_CLK_EN0_REG0, 29);
>> +AML_CLK_GATE_SYS_CLK(sys_ramb, SYS_CLK_EN0_REG0, 30);
>> +AML_CLK_GATE_SYS_CLK(sys_audio_pclk, SYS_CLK_EN0_REG0, 31);
>> +AML_CLK_GATE_SYS_CLK(sys_pwm_kl, SYS_CLK_EN0_REG1, 0);
>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ij, SYS_CLK_EN0_REG1, 1);
>> +AML_CLK_GATE_SYS_CLK(sys_usb, SYS_CLK_EN0_REG1, 2);
>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3);
>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4);
>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ab, SYS_CLK_EN0_REG1, 5);
>> +AML_CLK_GATE_SYS_CLK(sys_pwm_cd, SYS_CLK_EN0_REG1, 6);
>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ef, SYS_CLK_EN0_REG1, 7);
>> +AML_CLK_GATE_SYS_CLK(sys_pwm_gh, SYS_CLK_EN0_REG1, 8);
>> +AML_CLK_GATE_SYS_CLK(sys_spicc_1, SYS_CLK_EN0_REG1, 9);
>> +AML_CLK_GATE_SYS_CLK(sys_spicc_0, SYS_CLK_EN0_REG1, 10);
>> +AML_CLK_GATE_SYS_CLK(sys_uart_a, SYS_CLK_EN0_REG1, 11);
>> +AML_CLK_GATE_SYS_CLK(sys_uart_b, SYS_CLK_EN0_REG1, 12);
>> +AML_CLK_GATE_SYS_CLK(sys_uart_c, SYS_CLK_EN0_REG1, 13);
>> +AML_CLK_GATE_SYS_CLK(sys_uart_d, SYS_CLK_EN0_REG1, 14);
>> +AML_CLK_GATE_SYS_CLK(sys_uart_e, SYS_CLK_EN0_REG1, 15);
>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16);
>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17);
>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18);
>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19);
>> +AML_CLK_GATE_SYS_CLK(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20);
>> +AML_CLK_GATE_SYS_CLK(sys_rtc, SYS_CLK_EN0_REG1, 21);
>> +AML_CLK_GATE_SYS_CLK(sys_ge2d, SYS_CLK_EN0_REG1, 22);
>> +AML_CLK_GATE_SYS_CLK(sys_isp, SYS_CLK_EN0_REG1, 23);
>> +AML_CLK_GATE_SYS_CLK(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24);
>> +AML_CLK_GATE_SYS_CLK(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25);
>> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26);
>> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27);
>> +AML_CLK_GATE_SYS_CLK(sys_eth_phy, SYS_CLK_EN0_REG1, 28);
>> +AML_CLK_GATE_SYS_CLK(sys_acodec, SYS_CLK_EN0_REG1, 29);
>> +AML_CLK_GATE_SYS_CLK(sys_dwap, SYS_CLK_EN0_REG1, 30);
>> +AML_CLK_GATE_SYS_CLK(sys_dos, SYS_CLK_EN0_REG1, 31);
>> +AML_CLK_GATE_SYS_CLK(sys_cve, SYS_CLK_EN0_REG2, 0);
>> +AML_CLK_GATE_SYS_CLK(sys_vout, SYS_CLK_EN0_REG2, 1);
>> +AML_CLK_GATE_SYS_CLK(sys_vc9000e, SYS_CLK_EN0_REG2, 2);
>> +AML_CLK_GATE_SYS_CLK(sys_pwm_mn, SYS_CLK_EN0_REG2, 3);
>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4);
>> +AML_CLK_GATE_AXI_CLK(axi_sys_nic, AXI_CLK_EN0, 2);
>> +AML_CLK_GATE_AXI_CLK(axi_isp_nic, AXI_CLK_EN0, 3);
>> +AML_CLK_GATE_AXI_CLK(axi_cve_nic, AXI_CLK_EN0, 4);
>> +AML_CLK_GATE_AXI_CLK(axi_ramb, AXI_CLK_EN0, 5);
>> +AML_CLK_GATE_AXI_CLK(axi_rama, AXI_CLK_EN0, 6);
>> +AML_CLK_GATE_AXI_CLK(axi_cpu_dmc, AXI_CLK_EN0, 7);
>> +AML_CLK_GATE_AXI_CLK(axi_nic, AXI_CLK_EN0, 8);
>> +AML_CLK_GATE_AXI_CLK(axi_dma, AXI_CLK_EN0, 9);
>> +AML_CLK_GATE_AXI_CLK(axi_mux_nic, AXI_CLK_EN0, 10);
>> +AML_CLK_GATE_AXI_CLK(axi_capu, AXI_CLK_EN0, 11);
>> +AML_CLK_GATE_AXI_CLK(axi_cve, AXI_CLK_EN0, 12);
>> +AML_CLK_GATE_AXI_CLK(axi_dev1_dmc, AXI_CLK_EN0, 13);
>> +AML_CLK_GATE_AXI_CLK(axi_dev0_dmc, AXI_CLK_EN0, 14);
>> +AML_CLK_GATE_AXI_CLK(axi_dsp_dmc, AXI_CLK_EN0, 15);
>> +
>> +/*
>> + * clk_12_24m model
>> + *
>> + *          |------|     |-----| clk_12m_24m |-----|
>> + * xtal---->| gate |---->| div |------------>| pad |
>> + *          |------|     |-----|             |-----|
>> + */
>> +static const struct clk_parent_data clk_12_24m_in_parent = {
>> +     .fw_name = "xtal",
>> +};
> 
> Can't inline that ?
> 
Will do.
>> +
>> +static struct clk_regmap 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 = &clk_12_24m_in_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 *[]) {
>> +                     &clk_12_24m_in.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data fclk_25m_div_parent = {
>> +     .fw_name = "fixed_pll",
>> +};
>> +
>> +static struct clk_regmap 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 = &fclk_25m_div_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 *[]) {
>> +                     &fclk_25m_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +/* generate clock output */
> 
> That comment is not helping much ... what did you mean ?
> 
It seems superfluous, will delte it.
>> +static u32 gen_parent_table[] = { 0, 1, 5, 7 };
>> +
>> +static const struct clk_parent_data gen_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .hw = &rtc_clk.hw },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "hifi_pll" }
>> +};
>> +
>> +static struct clk_regmap gen_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = GEN_CLK_CTRL,
>> +             .mask = 0x1f,
>> +             .shift = 12,
>> +             .table = gen_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "gen_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = gen_parent_data,
>> +             .num_parents = ARRAY_SIZE(gen_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 *[]) {
>> +                     &gen_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 *[]) {
>> +                     &gen_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data saradc_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .hw = &sys_clk.hw }
>> +};
>> +
>> +static struct clk_regmap saradc_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SAR_CLK_CTRL0,
>> +             .mask = 0x1,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "saradc_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = saradc_parent_data,
>> +             .num_parents = ARRAY_SIZE(saradc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap saradc_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SAR_CLK_CTRL0,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "saradc_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &saradc_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap saradc = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SAR_CLK_CTRL0,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "saradc",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &saradc_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 pwm_parent_table[] = { 0, 2, 3 };
> 
> What's pwm parent 1, why can't it be used ?
This 1 corresponds to gp1 pll, which is currently dedicated to emmc.
> 
>> +
>> +static const struct clk_parent_data pwm_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div3" }
>> +};
>> +
>> +static struct clk_regmap pwm_a_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_AB_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 9,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_a_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_a_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_AB_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_a_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_a_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_a = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_AB_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_a",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_a_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_b_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_AB_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 25,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_b_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_b_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_AB_CTRL,
>> +             .shift = 16,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_b_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_b_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_b = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_AB_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_b",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_b_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_c_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_CD_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 9,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_c_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_c_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_CD_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_c_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_c_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_c = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_CD_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_c",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_c_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_d_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_CD_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 25,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_d_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_d_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_CD_CTRL,
>> +             .shift = 16,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_d_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_d_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_d = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_CD_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_d",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_d_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_e_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_EF_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 9,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_e_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_e_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_EF_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_e_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_e_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_e = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_EF_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_e",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_e_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_f_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_EF_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 25,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_f_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_f_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_EF_CTRL,
>> +             .shift = 16,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_f_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_f_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_f = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_EF_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_f",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_f_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_g_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_GH_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 9,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_g_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_g_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_GH_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_g_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_g_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_g = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_GH_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_g",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_g_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_h_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_GH_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 25,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_h_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_h_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_GH_CTRL,
>> +             .shift = 16,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_h_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_h_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_h = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_GH_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_h",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_h_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_i_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_IJ_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 9,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_i_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_i_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_IJ_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_i_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_i_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_i = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_IJ_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_i",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_i_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_j_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_IJ_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 25,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_j_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_j_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_IJ_CTRL,
>> +             .shift = 16,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_j_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_j_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_j = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_IJ_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_j",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_j_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_k_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_KL_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 9,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_k_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_k_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_KL_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_k_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_k_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_k = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_KL_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_k",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_k_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_l_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_KL_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 25,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_l_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_l_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_KL_CTRL,
>> +             .shift = 16,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_l_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_l_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_l = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_KL_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_l",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_l_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_m_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_MN_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 9,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_m_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_m_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_MN_CTRL,
>> +             .shift = 0,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_m_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_m_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_m = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_MN_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_m",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_m_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_n_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = PWM_CLK_MN_CTRL,
>> +             .mask = 0x3,
>> +             .shift = 25,
>> +             .table = pwm_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_n_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = pwm_parent_data,
>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_n_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = PWM_CLK_MN_CTRL,
>> +             .shift = 16,
>> +             .width = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "pwm_n_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_n_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap pwm_n = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = PWM_CLK_MN_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "pwm_n",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &pwm_n_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
> 
> Judging by the number of repeated block, a properly defined macro would
> be acceptable for the PWM block
> 
Will do.
>> +
>> +static const struct clk_parent_data spicc_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .hw = &sys_clk.hw },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div2" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "fclk_div7" }
>> +};
>> +
>> +static struct clk_regmap spicc_a_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SPICC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "spicc_a_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = spicc_parent_data,
>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_a_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SPICC_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 6,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "spicc_a_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_a_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_a = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SPICC_CLK_CTRL,
>> +             .bit_idx = 6,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_a",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_a_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_b_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SPICC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 23,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "spicc_b_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = spicc_parent_data,
>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_b_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SPICC_CLK_CTRL,
>> +             .shift = 16,
>> +             .width = 6,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "spicc_b_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_b_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap spicc_b = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SPICC_CLK_CTRL,
>> +             .bit_idx = 22,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spicc_b",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spicc_b_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data spifc_parent_data[] = {
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "fclk_div2" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "fclk_div7" }
>> +};
>> +
>> +static struct clk_regmap spifc_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SPIFC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "spifc_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = spifc_parent_data,
>> +             .num_parents = ARRAY_SIZE(spifc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap spifc_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SPIFC_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "spifc_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spifc_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap spifc = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SPIFC_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "spifc",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &spifc_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 emmc_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
> 
> What's 6 ? why can't it be used ?
> 

>> +
>> +static const struct clk_parent_data emmc_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .fw_name = "fclk_div2" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "gp0_pll" }
>> +};
>> +
>> +static struct clk_regmap sd_emmc_a_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SD_EMMC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = emmc_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sd_emmc_a_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = emmc_parent_data,
>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_a_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SD_EMMC_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sd_emmc_a_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_a_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_a = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SD_EMMC_CLK_CTRL,
>> +             .bit_idx = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_a",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_a_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_b_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = SD_EMMC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 25,
>> +             .table = emmc_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sd_emmc_b_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = emmc_parent_data,
>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_b_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = SD_EMMC_CLK_CTRL,
>> +             .shift = 16,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sd_emmc_b_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_b_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_b = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = SD_EMMC_CLK_CTRL,
>> +             .bit_idx = 23,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_b",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_b_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_c_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = NAND_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = emmc_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sd_emmc_c_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = emmc_parent_data,
>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_c_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = NAND_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "sd_emmc_c_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_c_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap sd_emmc_c = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = NAND_CLK_CTRL,
>> +             .bit_idx = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "sd_emmc_c",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &sd_emmc_c_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +/* temperature sensor */
>> +static const struct clk_parent_data ts_parent = {
>> +     .fw_name = "xtal",
>> +};
> 
> same  ...
> 
>> +
>> +static struct clk_regmap 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 = &ts_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 *[]) {
>> +                     &ts_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data eth_parent = {
>> +     .fw_name = "fclk_div2",
>> +};
>> +
>> +static struct clk_fixed_factor eth_125m_div = {
>> +     .mult = 1,
>> +     .div = 8,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "eth_125m_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_data = &eth_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 *[]) {
>> +                     &eth_125m_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 = &eth_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap 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 *[]) {
>> +                     &eth_rmii_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 mipi_dsi_meas_parent_table[] = { 0, 1, 2, 3, 5, 6, 7 };
> 
> What is 4 ? why can't it be used ?
> 
>> +
>> +static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "fclk_div2" },
>> +     { .fw_name = "fclk_div7" }
>> +};
>> +
>> +static struct clk_regmap mipi_dsi_meas_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VDIN_MEAS_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 21,
>> +             .table = mipi_dsi_meas_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mipi_dsi_meas_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = mipi_dsi_meas_parent_data,
>> +             .num_parents = ARRAY_SIZE(mipi_dsi_meas_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap mipi_dsi_meas_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VDIN_MEAS_CLK_CTRL,
>> +             .shift = 12,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mipi_dsi_meas_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mipi_dsi_meas_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mipi_dsi_meas = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = VDIN_MEAS_CLK_CTRL,
>> +             .bit_idx = 20,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "mipi_dsi_meas",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mipi_dsi_meas_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 dsi_phy_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
> 
> What about 0 ?
> 
>> +
>> +static const struct clk_parent_data dsi_phy_parent_data[] = {
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div2" },
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div7" }
>> +};
>> +
>> +static struct clk_regmap dsi_phy_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 12,
>> +             .table = dsi_phy_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "dsi_phy_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = dsi_phy_parent_data,
>> +             .num_parents = ARRAY_SIZE(dsi_phy_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap dsi_phy_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "dsi_phy_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dsi_phy_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap dsi_phy = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dsi_phy",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dsi_phy_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 vout_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
> 
> same
> 
>> +
>> +static const struct clk_parent_data vout_parent_data[] = {
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div7" }
>> +};
>> +
>> +static struct clk_regmap vout_mclk_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VOUTENC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = vout_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vout_mclk_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = vout_parent_data,
>> +             .num_parents = ARRAY_SIZE(vout_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap vout_mclk_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VOUTENC_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vout_mclk_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vout_mclk_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap vout_mclk = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "vout_mclk",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vout_mclk_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap vout_enc_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VOUTENC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 25,
>> +             .table = vout_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vout_enc_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = vout_parent_data,
>> +             .num_parents = ARRAY_SIZE(vout_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap vout_enc_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VOUTENC_CLK_CTRL,
>> +             .shift = 16,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vout_enc_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vout_enc_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap vout_enc = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = VOUTENC_CLK_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "vout_enc",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vout_enc_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data hcodec_pre_parent_data[] = {
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "fclk_div7" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "xtal" }
>> +};
>> +
>> +static struct clk_regmap hcodec_0_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VDEC_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "hcodec_0_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = hcodec_pre_parent_data,
>> +             .num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap hcodec_0_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VDEC_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "hcodec_0_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &hcodec_0_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap hcodec_0 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = VDEC_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "hcodec_0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &hcodec_0_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap hcodec_1_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VDEC3_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "hcodec_1_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = hcodec_pre_parent_data,
>> +             .num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap hcodec_1_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VDEC3_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "hcodec_1_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &hcodec_1_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap hcodec_1 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = VDEC3_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "hcodec_1",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &hcodec_1_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data hcodec_parent_data[] = {
>> +     { .hw = &hcodec_0.hw },
>> +     { .hw = &hcodec_1.hw }
>> +};
>> +
>> +
> 
> remove extra new lines
> 
Will do.
>> +static struct clk_regmap hcodec = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VDEC3_CLK_CTRL,
>> +             .mask = 0x1,
>> +             .shift = 15,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "hcodec",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = hcodec_parent_data,
>> +             .num_parents = ARRAY_SIZE(hcodec_parent_data),
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data vc9000e_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "fclk_div7" },
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "gp0_pll" }
>> +};
>> +
>> +static struct clk_regmap vc9000e_aclk_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VC9000E_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vc9000e_aclk_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = vc9000e_parent_data,
>> +             .num_parents = ARRAY_SIZE(vc9000e_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap vc9000e_aclk_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VC9000E_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vc9000e_aclk_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vc9000e_aclk_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap vc9000e_aclk = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = VC9000E_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "vc9000e_aclk",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vc9000e_aclk_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap vc9000e_core_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VC9000E_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 25,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vc9000e_core_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = vc9000e_parent_data,
>> +             .num_parents = ARRAY_SIZE(vc9000e_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap vc9000e_core_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VC9000E_CLK_CTRL,
>> +             .shift = 16,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vc9000e_core_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vc9000e_core_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap vc9000e_core = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = VC9000E_CLK_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "vc9000e_core",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vc9000e_core_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 csi_phy_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
> 
> Same here and all following instance
> 
This 1 corresponds to gp1 pll, which is currently dedicated to emmc.
>> +
>> +static const struct clk_parent_data csi_phy_parent_data[] = {
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "xtal" }
>> +};
>> +
>> +static struct clk_regmap csi_phy0_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = ISP0_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 25,
>> +             .table = csi_phy_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "csi_phy0_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = csi_phy_parent_data,
>> +             .num_parents = ARRAY_SIZE(csi_phy_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap csi_phy0_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ISP0_CLK_CTRL,
>> +             .shift = 16,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "csi_phy0_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &csi_phy0_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap csi_phy0 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ISP0_CLK_CTRL,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "csi_phy0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &csi_phy0_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 dewarpa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>> +
>> +static const struct clk_parent_data dewarpa_parent_data[] = {
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "fclk_div7" }
>> +};
>> +
>> +static struct clk_regmap dewarpa_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = DEWARPA_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = dewarpa_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "dewarpa_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = dewarpa_parent_data,
>> +             .num_parents = ARRAY_SIZE(dewarpa_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap dewarpa_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = DEWARPA_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "dewarpa_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dewarpa_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap dewarpa = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = DEWARPA_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "dewarpa",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &dewarpa_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 isp_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>> +
>> +static const struct clk_parent_data isp_parent_data[] = {
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "xtal" }
>> +};
>> +
>> +static struct clk_regmap isp0_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = ISP0_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = isp_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "isp0_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = isp_parent_data,
>> +             .num_parents = ARRAY_SIZE(isp_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap isp0_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ISP0_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "isp0_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &isp0_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap isp0 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ISP0_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "isp0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &isp0_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 nna_core_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>> +
>> +static const struct clk_parent_data nna_core_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "fclk_div2" },
>> +     { .fw_name = "hifi_pll" }
>> +};
>> +
>> +static struct clk_regmap nna_core_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = NNA_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = nna_core_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "nna_core_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = nna_core_parent_data,
>> +             .num_parents = ARRAY_SIZE(nna_core_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap nna_core_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = NNA_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "nna_core_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &nna_core_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap nna_core = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = NNA_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "nna_core",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &nna_core_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct clk_parent_data ge2d_parent_data[] = {
>> +     { .fw_name = "xtal" },
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .hw = &rtc_clk.hw }
>> +};
>> +
>> +static struct clk_regmap ge2d_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = GE2D_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "ge2d_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = ge2d_parent_data,
>> +             .num_parents = ARRAY_SIZE(ge2d_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap ge2d_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = GE2D_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "ge2d_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &ge2d_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap ge2d = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = GE2D_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "ge2d",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &ge2d_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static u32 c3_vapb_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>> +
>> +static const struct clk_parent_data vapb_parent_data[] = {
>> +     { .fw_name = "fclk_div2p5" },
>> +     { .fw_name = "fclk_div3" },
>> +     { .fw_name = "fclk_div4" },
>> +     { .fw_name = "fclk_div5" },
>> +     { .fw_name = "gp0_pll" },
>> +     { .fw_name = "hifi_pll" },
>> +     { .fw_name = "xtal" }
>> +};
>> +
>> +static struct clk_regmap vapb_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = VAPB_CLK_CTRL,
>> +             .mask = 0x7,
>> +             .shift = 9,
>> +             .table = c3_vapb_parent_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vapb_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = vapb_parent_data,
>> +             .num_parents = ARRAY_SIZE(vapb_parent_data),
>> +     },
>> +};
>> +
>> +static struct clk_regmap vapb_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = VAPB_CLK_CTRL,
>> +             .shift = 0,
>> +             .width = 7,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "vapb_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vapb_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap vapb = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = VAPB_CLK_CTRL,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "vapb",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &vapb_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_hw *c3_periphs_hw_clks[] = {
>> +     [CLKID_PLL_IN]                  = &pll_in.hw,
>> +     [CLKID_MCLK_PLL_IN]             = &mclk_pll_in.hw,
>> +     [CLKID_RTC_XTAL_CLKIN]          = &rtc_xtal_clkin.hw,
>> +     [CLKID_RTC_32K_DIV]             = &rtc_32k_div.hw,
>> +     [CLKID_RTC_32K_MUX]             = &rtc_32k_mux.hw,
>> +     [CLKID_RTC_32K]                 = &rtc_32k.hw,
>> +     [CLKID_RTC_CLK]                 = &rtc_clk.hw,
>> +     [CLKID_SYS_A_SEL]               = &sys_a_sel.hw,
>> +     [CLKID_SYS_A_DIV]               = &sys_a_div.hw,
>> +     [CLKID_SYS_A]                   = &sys_a.hw,
>> +     [CLKID_SYS_B_SEL]               = &sys_b_sel.hw,
>> +     [CLKID_SYS_B_DIV]               = &sys_b_div.hw,
>> +     [CLKID_SYS_B]                   = &sys_b.hw,
>> +     [CLKID_SYS_CLK]                 = &sys_clk.hw,
>> +     [CLKID_AXI_A_SEL]               = &axi_a_sel.hw,
>> +     [CLKID_AXI_A_DIV]               = &axi_a_div.hw,
>> +     [CLKID_AXI_A]                   = &axi_a.hw,
>> +     [CLKID_AXI_B_SEL]               = &axi_b_sel.hw,
>> +     [CLKID_AXI_B_DIV]               = &axi_b_div.hw,
>> +     [CLKID_AXI_B]                   = &axi_b.hw,
>> +     [CLKID_AXI_CLK]                 = &axi_clk.hw,
>> +     [CLKID_SYS_RESET_CTRL]          = &sys_reset_ctrl.hw,
>> +     [CLKID_SYS_PAD_CTRL]            = &sys_pwr_ctrl.hw,
>> +     [CLKID_SYS_CTRL]                = &sys_ctrl.hw,
>> +     [CLKID_SYS_TS_PLL]              = &sys_ts_pll.hw,
>> +     [CLKID_SYS_DEV_ARB]             = &sys_dev_arb.hw,
>> +     [CLKID_SYS_MMC_PCLK]            = &sys_mmc_pclk.hw,
>> +     [CLKID_SYS_CAPU]                = &sys_capu.hw,
>> +     [CLKID_SYS_CPU_CTRL]            = &sys_cpu_ctrl.hw,
>> +     [CLKID_SYS_JTAG_CTRL]           = &sys_jtag_ctrl.hw,
>> +     [CLKID_SYS_IR_CTRL]             = &sys_ir_ctrl.hw,
>> +     [CLKID_SYS_IRQ_CTRL]            = &sys_irq_ctrl.hw,
>> +     [CLKID_SYS_MSR_CLK]             = &sys_msr_clk.hw,
>> +     [CLKID_SYS_ROM]                 = &sys_rom.hw,
>> +     [CLKID_SYS_UART_F]              = &sys_uart_f.hw,
>> +     [CLKID_SYS_CPU_ARB]             = &sys_cpu_apb.hw,
>> +     [CLKID_SYS_RSA]                 = &sys_rsa.hw,
>> +     [CLKID_SYS_SAR_ADC]             = &sys_sar_adc.hw,
>> +     [CLKID_SYS_STARTUP]             = &sys_startup.hw,
>> +     [CLKID_SYS_SECURE]              = &sys_secure.hw,
>> +     [CLKID_SYS_SPIFC]               = &sys_spifc.hw,
>> +     [CLKID_SYS_NNA]                 = &sys_nna.hw,
>> +     [CLKID_SYS_ETH_MAC]             = &sys_eth_mac.hw,
>> +     [CLKID_SYS_GIC]                 = &sys_gic.hw,
>> +     [CLKID_SYS_RAMA]                = &sys_rama.hw,
>> +     [CLKID_SYS_BIG_NIC]             = &sys_big_nic.hw,
>> +     [CLKID_SYS_RAMB]                = &sys_ramb.hw,
>> +     [CLKID_SYS_AUDIO_PCLK]          = &sys_audio_pclk.hw,
>> +     [CLKID_SYS_PWM_KL]              = &sys_pwm_kl.hw,
>> +     [CLKID_SYS_PWM_IJ]              = &sys_pwm_ij.hw,
>> +     [CLKID_SYS_USB]                 = &sys_usb.hw,
>> +     [CLKID_SYS_SD_EMMC_A]           = &sys_sd_emmc_a.hw,
>> +     [CLKID_SYS_SD_EMMC_C]           = &sys_sd_emmc_c.hw,
>> +     [CLKID_SYS_PWM_AB]              = &sys_pwm_ab.hw,
>> +     [CLKID_SYS_PWM_CD]              = &sys_pwm_cd.hw,
>> +     [CLKID_SYS_PWM_EF]              = &sys_pwm_ef.hw,
>> +     [CLKID_SYS_PWM_GH]              = &sys_pwm_gh.hw,
>> +     [CLKID_SYS_SPICC_1]             = &sys_spicc_1.hw,
>> +     [CLKID_SYS_SPICC_0]             = &sys_spicc_0.hw,
>> +     [CLKID_SYS_UART_A]              = &sys_uart_a.hw,
>> +     [CLKID_SYS_UART_B]              = &sys_uart_b.hw,
>> +     [CLKID_SYS_UART_C]              = &sys_uart_c.hw,
>> +     [CLKID_SYS_UART_D]              = &sys_uart_d.hw,
>> +     [CLKID_SYS_UART_E]              = &sys_uart_e.hw,
>> +     [CLKID_SYS_I2C_M_A]             = &sys_i2c_m_a.hw,
>> +     [CLKID_SYS_I2C_M_B]             = &sys_i2c_m_b.hw,
>> +     [CLKID_SYS_I2C_M_C]             = &sys_i2c_m_c.hw,
>> +     [CLKID_SYS_I2C_M_D]             = &sys_i2c_m_d.hw,
>> +     [CLKID_SYS_I2S_S_A]             = &sys_i2c_s_a.hw,
>> +     [CLKID_SYS_RTC]                 = &sys_rtc.hw,
>> +     [CLKID_SYS_GE2D]                = &sys_ge2d.hw,
>> +     [CLKID_SYS_ISP]                 = &sys_isp.hw,
>> +     [CLKID_SYS_GPV_ISP_NIC]         = &sys_gpv_isp_nic.hw,
>> +     [CLKID_SYS_GPV_CVE_NIC]         = &sys_gpv_cve_nic.hw,
>> +     [CLKID_SYS_MIPI_DSI_HOST]       = &sys_mipi_dsi_host.hw,
>> +     [CLKID_SYS_MIPI_DSI_PHY]        = &sys_mipi_dsi_phy.hw,
>> +     [CLKID_SYS_ETH_PHY]             = &sys_eth_phy.hw,
>> +     [CLKID_SYS_ACODEC]              = &sys_acodec.hw,
>> +     [CLKID_SYS_DWAP]                = &sys_dwap.hw,
>> +     [CLKID_SYS_DOS]                 = &sys_dos.hw,
>> +     [CLKID_SYS_CVE]                 = &sys_cve.hw,
>> +     [CLKID_SYS_VOUT]                = &sys_vout.hw,
>> +     [CLKID_SYS_VC9000E]             = &sys_vc9000e.hw,
>> +     [CLKID_SYS_PWM_MN]              = &sys_pwm_mn.hw,
>> +     [CLKID_SYS_SD_EMMC_B]           = &sys_sd_emmc_b.hw,
>> +     [CLKID_AXI_SYS_NIC]             = &axi_sys_nic.hw,
>> +     [CLKID_AXI_ISP_NIC]             = &axi_isp_nic.hw,
>> +     [CLKID_AXI_CVE_NIC]             = &axi_cve_nic.hw,
>> +     [CLKID_AXI_RAMB]                = &axi_ramb.hw,
>> +     [CLKID_AXI_RAMA]                = &axi_rama.hw,
>> +     [CLKID_AXI_CPU_DMC]             = &axi_cpu_dmc.hw,
>> +     [CLKID_AXI_NIC]                 = &axi_nic.hw,
>> +     [CLKID_AXI_DMA]                 = &axi_dma.hw,
>> +     [CLKID_AXI_MUX_NIC]             = &axi_mux_nic.hw,
>> +     [CLKID_AXI_CAPU]                = &axi_capu.hw,
>> +     [CLKID_AXI_CVE]                 = &axi_cve.hw,
>> +     [CLKID_AXI_DEV1_DMC]            = &axi_dev1_dmc.hw,
>> +     [CLKID_AXI_DEV0_DMC]            = &axi_dev0_dmc.hw,
>> +     [CLKID_AXI_DSP_DMC]             = &axi_dsp_dmc.hw,
>> +     [CLKID_12_24M_IN]               = &clk_12_24m_in.hw,
>> +     [CLKID_12M_24M]                 = &clk_12_24m.hw,
>> +     [CLKID_FCLK_25M_DIV]            = &fclk_25m_div.hw,
>> +     [CLKID_FCLK_25M]                = &fclk_25m.hw,
>> +     [CLKID_GEN_SEL]                 = &gen_sel.hw,
>> +     [CLKID_GEN_DIV]                 = &gen_div.hw,
>> +     [CLKID_GEN]                     = &gen.hw,
>> +     [CLKID_SARADC_SEL]              = &saradc_sel.hw,
>> +     [CLKID_SARADC_DIV]              = &saradc_div.hw,
>> +     [CLKID_SARADC]                  = &saradc.hw,
>> +     [CLKID_PWM_A_SEL]               = &pwm_a_sel.hw,
>> +     [CLKID_PWM_A_DIV]               = &pwm_a_div.hw,
>> +     [CLKID_PWM_A]                   = &pwm_a.hw,
>> +     [CLKID_PWM_B_SEL]               = &pwm_b_sel.hw,
>> +     [CLKID_PWM_B_DIV]               = &pwm_b_div.hw,
>> +     [CLKID_PWM_B]                   = &pwm_b.hw,
>> +     [CLKID_PWM_C_SEL]               = &pwm_c_sel.hw,
>> +     [CLKID_PWM_C_DIV]               = &pwm_c_div.hw,
>> +     [CLKID_PWM_C]                   = &pwm_c.hw,
>> +     [CLKID_PWM_D_SEL]               = &pwm_d_sel.hw,
>> +     [CLKID_PWM_D_DIV]               = &pwm_d_div.hw,
>> +     [CLKID_PWM_D]                   = &pwm_d.hw,
>> +     [CLKID_PWM_E_SEL]               = &pwm_e_sel.hw,
>> +     [CLKID_PWM_E_DIV]               = &pwm_e_div.hw,
>> +     [CLKID_PWM_E]                   = &pwm_e.hw,
>> +     [CLKID_PWM_F_SEL]               = &pwm_f_sel.hw,
>> +     [CLKID_PWM_F_DIV]               = &pwm_f_div.hw,
>> +     [CLKID_PWM_F]                   = &pwm_f.hw,
>> +     [CLKID_PWM_G_SEL]               = &pwm_g_sel.hw,
>> +     [CLKID_PWM_G_DIV]               = &pwm_g_div.hw,
>> +     [CLKID_PWM_G]                   = &pwm_g.hw,
>> +     [CLKID_PWM_H_SEL]               = &pwm_h_sel.hw,
>> +     [CLKID_PWM_H_DIV]               = &pwm_h_div.hw,
>> +     [CLKID_PWM_H]                   = &pwm_h.hw,
>> +     [CLKID_PWM_I_SEL]               = &pwm_i_sel.hw,
>> +     [CLKID_PWM_I_DIV]               = &pwm_i_div.hw,
>> +     [CLKID_PWM_I]                   = &pwm_i.hw,
>> +     [CLKID_PWM_J_SEL]               = &pwm_j_sel.hw,
>> +     [CLKID_PWM_J_DIV]               = &pwm_j_div.hw,
>> +     [CLKID_PWM_J]                   = &pwm_j.hw,
>> +     [CLKID_PWM_K_SEL]               = &pwm_k_sel.hw,
>> +     [CLKID_PWM_K_DIV]               = &pwm_k_div.hw,
>> +     [CLKID_PWM_K]                   = &pwm_k.hw,
>> +     [CLKID_PWM_L_SEL]               = &pwm_l_sel.hw,
>> +     [CLKID_PWM_L_DIV]               = &pwm_l_div.hw,
>> +     [CLKID_PWM_L]                   = &pwm_l.hw,
>> +     [CLKID_PWM_M_SEL]               = &pwm_m_sel.hw,
>> +     [CLKID_PWM_M_DIV]               = &pwm_m_div.hw,
>> +     [CLKID_PWM_M]                   = &pwm_m.hw,
>> +     [CLKID_PWM_N_SEL]               = &pwm_n_sel.hw,
>> +     [CLKID_PWM_N_DIV]               = &pwm_n_div.hw,
>> +     [CLKID_PWM_N]                   = &pwm_n.hw,
>> +     [CLKID_SPICC_A_SEL]             = &spicc_a_sel.hw,
>> +     [CLKID_SPICC_A_DIV]             = &spicc_a_div.hw,
>> +     [CLKID_SPICC_A]                 = &spicc_a.hw,
>> +     [CLKID_SPICC_B_SEL]             = &spicc_b_sel.hw,
>> +     [CLKID_SPICC_B_DIV]             = &spicc_b_div.hw,
>> +     [CLKID_SPICC_B]                 = &spicc_b.hw,
>> +     [CLKID_SPIFC_SEL]               = &spifc_sel.hw,
>> +     [CLKID_SPIFC_DIV]               = &spifc_div.hw,
>> +     [CLKID_SPIFC]                   = &spifc.hw,
>> +     [CLKID_SD_EMMC_A_SEL]           = &sd_emmc_a_sel.hw,
>> +     [CLKID_SD_EMMC_A_DIV]           = &sd_emmc_a_div.hw,
>> +     [CLKID_SD_EMMC_A]               = &sd_emmc_a.hw,
>> +     [CLKID_SD_EMMC_B_SEL]           = &sd_emmc_b_sel.hw,
>> +     [CLKID_SD_EMMC_B_DIV]           = &sd_emmc_b_div.hw,
>> +     [CLKID_SD_EMMC_B]               = &sd_emmc_b.hw,
>> +     [CLKID_SD_EMMC_C_SEL]           = &sd_emmc_c_sel.hw,
>> +     [CLKID_SD_EMMC_C_DIV]           = &sd_emmc_c_div.hw,
>> +     [CLKID_SD_EMMC_C]               = &sd_emmc_c.hw,
>> +     [CLKID_TS_DIV]                  = &ts_div.hw,
>> +     [CLKID_TS]                      = &ts.hw,
>> +     [CLKID_ETH_125M_DIV]            = &eth_125m_div.hw,
>> +     [CLKID_ETH_125M]                = &eth_125m.hw,
>> +     [CLKID_ETH_RMII_DIV]            = &eth_rmii_div.hw,
>> +     [CLKID_ETH_RMII]                = &eth_rmii.hw,
>> +     [CLKID_MIPI_DSI_MEAS_SEL]       = &mipi_dsi_meas_sel.hw,
>> +     [CLKID_MIPI_DSI_MEAS_DIV]       = &mipi_dsi_meas_div.hw,
>> +     [CLKID_MIPI_DSI_MEAS]           = &mipi_dsi_meas.hw,
>> +     [CLKID_DSI_PHY_SEL]             = &dsi_phy_sel.hw,
>> +     [CLKID_DSI_PHY_DIV]             = &dsi_phy_div.hw,
>> +     [CLKID_DSI_PHY]                 = &dsi_phy.hw,
>> +     [CLKID_VOUT_MCLK_SEL]           = &vout_mclk_sel.hw,
>> +     [CLKID_VOUT_MCLK_DIV]           = &vout_mclk_div.hw,
>> +     [CLKID_VOUT_MCLK]               = &vout_mclk.hw,
>> +     [CLKID_VOUT_ENC_SEL]            = &vout_enc_sel.hw,
>> +     [CLKID_VOUT_ENC_DIV]            = &vout_enc_div.hw,
>> +     [CLKID_VOUT_ENC]                = &vout_enc.hw,
>> +     [CLKID_HCODEC_0_SEL]            = &hcodec_0_sel.hw,
>> +     [CLKID_HCODEC_0_DIV]            = &hcodec_0_div.hw,
>> +     [CLKID_HCODEC_0]                = &hcodec_0.hw,
>> +     [CLKID_HCODEC_1_SEL]            = &hcodec_1_sel.hw,
>> +     [CLKID_HCODEC_1_DIV]            = &hcodec_1_div.hw,
>> +     [CLKID_HCODEC_1]                = &hcodec_1.hw,
>> +     [CLKID_HCODEC]                  = &hcodec.hw,
>> +     [CLKID_VC9000E_ACLK_SEL]        = &vc9000e_aclk_sel.hw,
>> +     [CLKID_VC9000E_ACLK_DIV]        = &vc9000e_aclk_div.hw,
>> +     [CLKID_VC9000E_ACLK]            = &vc9000e_aclk.hw,
>> +     [CLKID_VC9000E_CORE_SEL]        = &vc9000e_core_sel.hw,
>> +     [CLKID_VC9000E_CORE_DIV]        = &vc9000e_core_div.hw,
>> +     [CLKID_VC9000E_CORE]            = &vc9000e_core.hw,
>> +     [CLKID_CSI_PHY0_SEL]            = &csi_phy0_sel.hw,
>> +     [CLKID_CSI_PHY0_DIV]            = &csi_phy0_div.hw,
>> +     [CLKID_CSI_PHY0]                = &csi_phy0.hw,
>> +     [CLKID_DEWARPA_SEL]             = &dewarpa_sel.hw,
>> +     [CLKID_DEWARPA_DIV]             = &dewarpa_div.hw,
>> +     [CLKID_DEWARPA]                 = &dewarpa.hw,
>> +     [CLKID_ISP0_SEL]                = &isp0_sel.hw,
>> +     [CLKID_ISP0_DIV]                = &isp0_div.hw,
>> +     [CLKID_ISP0]                    = &isp0.hw,
>> +     [CLKID_NNA_CORE_SEL]            = &nna_core_sel.hw,
>> +     [CLKID_NNA_CORE_DIV]            = &nna_core_div.hw,
>> +     [CLKID_NNA_CORE]                = &nna_core.hw,
>> +     [CLKID_GE2D_SEL]                = &ge2d_sel.hw,
>> +     [CLKID_GE2D_DIV]                = &ge2d_div.hw,
>> +     [CLKID_GE2D]                    = &ge2d.hw,
>> +     [CLKID_VAPB_SEL]                = &vapb_sel.hw,
>> +     [CLKID_VAPB_DIV]                = &vapb_div.hw,
>> +     [CLKID_VAPB]                    = &vapb.hw,
>> +};
>> +
>> +/* Convenience table to populate regmap in .probe */
>> +static struct clk_regmap *const c3_periphs_clk_regmaps[] = {
>> +     &pll_in,
>> +     &mclk_pll_in,
>> +     &rtc_xtal_clkin,
>> +     &rtc_32k_div,
>> +     &rtc_32k_mux,
>> +     &rtc_32k,
>> +     &rtc_clk,
>> +     &sys_a_sel,
>> +     &sys_a_div,
>> +     &sys_a,
>> +     &sys_b_sel,
>> +     &sys_b_div,
>> +     &sys_b,
>> +     &sys_clk,
>> +     &axi_a_sel,
>> +     &axi_a_div,
>> +     &axi_a,
>> +     &axi_b_sel,
>> +     &axi_b_div,
>> +     &axi_b,
>> +     &axi_clk,
>> +     &sys_reset_ctrl,
>> +     &sys_pwr_ctrl,
>> +     &sys_pad_ctrl,
>> +     &sys_ctrl,
>> +     &sys_ts_pll,
>> +     &sys_dev_arb,
>> +     &sys_mmc_pclk,
>> +     &sys_capu,
>> +     &sys_cpu_ctrl,
>> +     &sys_jtag_ctrl,
>> +     &sys_ir_ctrl,
>> +     &sys_irq_ctrl,
>> +     &sys_msr_clk,
>> +     &sys_rom,
>> +     &sys_uart_f,
>> +     &sys_cpu_apb,
>> +     &sys_rsa,
>> +     &sys_sar_adc,
>> +     &sys_startup,
>> +     &sys_secure,
>> +     &sys_spifc,
>> +     &sys_nna,
>> +     &sys_eth_mac,
>> +     &sys_gic,
>> +     &sys_rama,
>> +     &sys_big_nic,
>> +     &sys_ramb,
>> +     &sys_audio_pclk,
>> +     &sys_pwm_kl,
>> +     &sys_pwm_ij,
>> +     &sys_usb,
>> +     &sys_sd_emmc_a,
>> +     &sys_sd_emmc_c,
>> +     &sys_pwm_ab,
>> +     &sys_pwm_cd,
>> +     &sys_pwm_ef,
>> +     &sys_pwm_gh,
>> +     &sys_spicc_1,
>> +     &sys_spicc_0,
>> +     &sys_uart_a,
>> +     &sys_uart_b,
>> +     &sys_uart_c,
>> +     &sys_uart_d,
>> +     &sys_uart_e,
>> +     &sys_i2c_m_a,
>> +     &sys_i2c_m_b,
>> +     &sys_i2c_m_c,
>> +     &sys_i2c_m_d,
>> +     &sys_i2c_s_a,
>> +     &sys_rtc,
>> +     &sys_ge2d,
>> +     &sys_isp,
>> +     &sys_gpv_isp_nic,
>> +     &sys_gpv_cve_nic,
>> +     &sys_mipi_dsi_host,
>> +     &sys_mipi_dsi_phy,
>> +     &sys_eth_phy,
>> +     &sys_acodec,
>> +     &sys_dwap,
>> +     &sys_dos,
>> +     &sys_cve,
>> +     &sys_vout,
>> +     &sys_vc9000e,
>> +     &sys_pwm_mn,
>> +     &sys_sd_emmc_b,
>> +     &axi_sys_nic,
>> +     &axi_isp_nic,
>> +     &axi_cve_nic,
>> +     &axi_ramb,
>> +     &axi_rama,
>> +     &axi_cpu_dmc,
>> +     &axi_nic,
>> +     &axi_dma,
>> +     &axi_mux_nic,
>> +     &axi_capu,
>> +     &axi_cve,
>> +     &axi_dev1_dmc,
>> +     &axi_dev0_dmc,
>> +     &axi_dsp_dmc,
>> +     &clk_12_24m_in,
>> +     &clk_12_24m,
>> +     &fclk_25m_div,
>> +     &fclk_25m,
>> +     &gen_sel,
>> +     &gen_div,
>> +     &gen,
>> +     &saradc_sel,
>> +     &saradc_div,
>> +     &saradc,
>> +     &pwm_a_sel,
>> +     &pwm_a_div,
>> +     &pwm_a,
>> +     &pwm_b_sel,
>> +     &pwm_b_div,
>> +     &pwm_b,
>> +     &pwm_c_sel,
>> +     &pwm_c_div,
>> +     &pwm_c,
>> +     &pwm_d_sel,
>> +     &pwm_d_div,
>> +     &pwm_d,
>> +     &pwm_e_sel,
>> +     &pwm_e_div,
>> +     &pwm_e,
>> +     &pwm_f_sel,
>> +     &pwm_f_div,
>> +     &pwm_f,
>> +     &pwm_g_sel,
>> +     &pwm_g_div,
>> +     &pwm_g,
>> +     &pwm_h_sel,
>> +     &pwm_h_div,
>> +     &pwm_h,
>> +     &pwm_i_sel,
>> +     &pwm_i_div,
>> +     &pwm_i,
>> +     &pwm_j_sel,
>> +     &pwm_j_div,
>> +     &pwm_j,
>> +     &pwm_k_sel,
>> +     &pwm_k_div,
>> +     &pwm_k,
>> +     &pwm_l_sel,
>> +     &pwm_l_div,
>> +     &pwm_l,
>> +     &pwm_m_sel,
>> +     &pwm_m_div,
>> +     &pwm_m,
>> +     &pwm_n_sel,
>> +     &pwm_n_div,
>> +     &pwm_n,
>> +     &spicc_a_sel,
>> +     &spicc_a_div,
>> +     &spicc_a,
>> +     &spicc_b_sel,
>> +     &spicc_b_div,
>> +     &spicc_b,
>> +     &spifc_sel,
>> +     &spifc_div,
>> +     &spifc,
>> +     &sd_emmc_a_sel,
>> +     &sd_emmc_a_div,
>> +     &sd_emmc_a,
>> +     &sd_emmc_b_sel,
>> +     &sd_emmc_b_div,
>> +     &sd_emmc_b,
>> +     &sd_emmc_c_sel,
>> +     &sd_emmc_c_div,
>> +     &sd_emmc_c,
>> +     &ts_div,
>> +     &ts,
>> +     &eth_125m,
>> +     &eth_rmii_div,
>> +     &eth_rmii,
>> +     &mipi_dsi_meas_sel,
>> +     &mipi_dsi_meas_div,
>> +     &mipi_dsi_meas,
>> +     &dsi_phy_sel,
>> +     &dsi_phy_div,
>> +     &dsi_phy,
>> +     &vout_mclk_sel,
>> +     &vout_mclk_div,
>> +     &vout_mclk,
>> +     &vout_enc_sel,
>> +     &vout_enc_div,
>> +     &vout_enc,
>> +     &hcodec_0_sel,
>> +     &hcodec_0_div,
>> +     &hcodec_0,
>> +     &hcodec_1_sel,
>> +     &hcodec_1_div,
>> +     &hcodec_1,
>> +     &hcodec,
>> +     &vc9000e_aclk_sel,
>> +     &vc9000e_aclk_div,
>> +     &vc9000e_aclk,
>> +     &vc9000e_core_sel,
>> +     &vc9000e_core_div,
>> +     &vc9000e_core,
>> +     &csi_phy0_sel,
>> +     &csi_phy0_div,
>> +     &csi_phy0,
>> +     &dewarpa_sel,
>> +     &dewarpa_div,
>> +     &dewarpa,
>> +     &isp0_sel,
>> +     &isp0_div,
>> +     &isp0,
>> +     &nna_core_sel,
>> +     &nna_core_div,
>> +     &nna_core,
>> +     &ge2d_sel,
>> +     &ge2d_div,
>> +     &ge2d,
>> +     &vapb_sel,
>> +     &vapb_div,
>> +     &vapb,
>> +};
>> +
>> +static struct regmap_config clkc_regmap_config = {
>> +     .reg_bits       = 32,
>> +     .val_bits       = 32,
>> +     .reg_stride     = 4,
>> +};
>> +
>> +static struct meson_clk_hw_data c3_periphs_clks = {
>> +     .hws = c3_periphs_hw_clks,
>> +     .num = ARRAY_SIZE(c3_periphs_hw_clks),
>> +};
>> +
>> +static int aml_c3_peripherals_probe(struct platform_device *pdev)
>> +{
>> +     struct device *dev = &pdev->dev;
>> +     struct regmap *regmap;
>> +     void __iomem *base;
>> +     int clkid, ret, i;
>> +
>> +     base = devm_platform_ioremap_resource(pdev, 0);
>> +     if (IS_ERR(base))
>> +             return PTR_ERR(base);
>> +
>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>> +     if (IS_ERR(regmap))
>> +             return PTR_ERR(regmap);
>> +
>> +     /* Populate regmap for the regmap backed clocks */
>> +     for (i = 0; i < ARRAY_SIZE(c3_periphs_clk_regmaps); i++)
>> +             c3_periphs_clk_regmaps[i]->map = regmap;
>> +
>> +     for (clkid = 0; clkid < c3_periphs_clks.num; clkid++) {
>> +             /* array might be sparse */
>> +             if (!c3_periphs_clks.hws[clkid])
>> +                     continue;
>> +
>> +             ret = devm_clk_hw_register(dev, c3_periphs_clks.hws[clkid]);
>> +             if (ret) {
>> +                     dev_err(dev, "Clock registration failed\n");
>> +                     return ret;
>> +             }
>> +     }
>> +
>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>> +                                        &c3_periphs_clks);
>> +}
>> +
>> +static const struct of_device_id c3_peripherals_clkc_match_table[] = {
>> +     {
>> +             .compatible = "amlogic,c3-peripherals-clkc",
>> +     },
>> +     {}
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, c3_peripherals_clkc_match_table);
>> +
>> +static struct platform_driver c3_peripherals_driver = {
>> +     .probe          = aml_c3_peripherals_probe,
>> +     .driver         = {
>> +             .name   = "c3-peripherals-clkc",
>> +             .of_match_table = c3_peripherals_clkc_match_table,
>> +     },
>> +};
>> +
>> +module_platform_driver(c3_peripherals_driver);
>> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/clk/meson/c3-peripherals.h b/drivers/clk/meson/c3-peripherals.h
>> new file mode 100644
>> index 000000000000..ddcc23e25669
>> --- /dev/null
>> +++ b/drivers/clk/meson/c3-peripherals.h
>> @@ -0,0 +1,48 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (c) 2023 Amlogic, inc.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>> + */
>> +
>> +#ifndef __AML_C3_PERIPHERALS_H__
>> +#define __AML_C3_PERIPHERALS_H__
>> +
>> +#define OSCIN_CTRL                           0x0004
>> +#define RTC_BY_OSCIN_CTRL0                   0x0008
>> +#define RTC_BY_OSCIN_CTRL1                   0x000c
>> +#define RTC_CTRL                             0x0010
>> +#define SYS_CLK_CTRL0                                0x0040
>> +#define SYS_CLK_EN0_REG0                     0x0044
>> +#define SYS_CLK_EN0_REG1                     0x0048
>> +#define SYS_CLK_EN0_REG2                     0x004c
>> +#define AXI_CLK_CTRL0                                0x006c
>> +#define CLK12_24_CTRL                                0x00a8
>> +#define AXI_CLK_EN0                          0x00ac
>> +#define VDIN_MEAS_CLK_CTRL                   0x00f8
>> +#define VAPB_CLK_CTRL                                0x00fc
>> +#define MIPIDSI_PHY_CLK_CTRL                 0x0104
>> +#define GE2D_CLK_CTRL                                0x010c
>> +#define ISP0_CLK_CTRL                                0x0110
>> +#define DEWARPA_CLK_CTRL                     0x0114
>> +#define VOUTENC_CLK_CTRL                     0x0118
>> +#define VDEC_CLK_CTRL                                0x0140
>> +#define VDEC3_CLK_CTRL                               0x0148
>> +#define TS_CLK_CTRL                          0x0158
>> +#define ETH_CLK_CTRL                         0x0164
>> +#define NAND_CLK_CTRL                                0x0168
>> +#define SD_EMMC_CLK_CTRL                     0x016c
>> +#define SPICC_CLK_CTRL                               0x0174
>> +#define GEN_CLK_CTRL                         0x0178
>> +#define SAR_CLK_CTRL0                                0x017c
>> +#define PWM_CLK_AB_CTRL                              0x0180
>> +#define PWM_CLK_CD_CTRL                              0x0184
>> +#define PWM_CLK_EF_CTRL                              0x0188
>> +#define PWM_CLK_GH_CTRL                              0x018c
>> +#define PWM_CLK_IJ_CTRL                              0x0190
>> +#define PWM_CLK_KL_CTRL                              0x0194
>> +#define PWM_CLK_MN_CTRL                              0x0198
>> +#define VC9000E_CLK_CTRL                     0x019c
>> +#define SPIFC_CLK_CTRL                               0x01a0
>> +#define NNA_CLK_CTRL                         0x0220
> 
> Nitpick - the extra zero is not needed
> Since this is used only by c3 periph clkc - do you really need an header
> or can it be defined in the related .c file ?
> 
> (I know this is a pattern we have been using so far, but it is not
> really justified. No reason to continue with it)
> 
>> +
>> +#endif  /* __AML_C3_PERIPHERALS_H__ */
> 

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

* Re: [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock
  2023-10-13  7:49   ` Jerome Brunet
@ 2023-10-17  6:15     ` Xianwei Zhao
  2023-10-17 13:06       ` Jerome Brunet
  0 siblings, 1 reply; 27+ messages in thread
From: Xianwei Zhao @ 2023-10-17  6:15 UTC (permalink / raw)
  To: Jerome Brunet, linux-arm-kernel, linux-amlogic, linux-clk,
	devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu

Hi Jerome,


On 2023/10/13 15:49, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:
> 
>> Add the C3 PLL clock controller driver for the Amlogic C3 SoC family.
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>> ---
>> V1 -> V2: Delete macro definition.
>> ---
>>   drivers/clk/meson/Kconfig  |  12 +
>>   drivers/clk/meson/Makefile |   1 +
>>   drivers/clk/meson/c3-pll.c | 808 +++++++++++++++++++++++++++++++++++++
>>   drivers/clk/meson/c3-pll.h |  35 ++
>>   4 files changed, 856 insertions(+)
>>   create mode 100644 drivers/clk/meson/c3-pll.c
>>   create mode 100644 drivers/clk/meson/c3-pll.h
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index c5303e4c1604..76be4bbd2afb 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -128,6 +128,18 @@ config COMMON_CLK_A1_PERIPHERALS
>>          device, A1 SoC Family. Say Y if you want A1 Peripherals clock
>>          controller to work.
>>
>> +config COMMON_CLK_C3_PLL
>> +     tristate "Amlogic C3 PLL clock controller"
>> +     default y
>> +     select COMMON_CLK_MESON_REGMAP
>> +     select COMMON_CLK_MESON_PLL
>> +     select COMMON_CLK_MESON_CLKC_UTILS
>> +     help
>> +       Support for the PLL clock controller on Amlogic C302X and C308L devices,
>> +       AKA c3. Amlogic C302X and C308L devices include AW402, AW409 and AW419.
>> +       Say Y if you want the board to work, because PLLs are the parent of most
>> +       peripherals.
>> +
>>   config COMMON_CLK_G12A
>>        tristate "G12 and SM1 SoC clock controllers support"
>>        depends on ARM64
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index 9ee4b954c896..4420af628b31 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_C3_PLL) += c3-pll.o
>>   obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>>   obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>>   obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
>> diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c
>> new file mode 100644
>> index 000000000000..97619bc7ab79
>> --- /dev/null
>> +++ b/drivers/clk/meson/c3-pll.c
>> @@ -0,0 +1,808 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Amlogic C3 PLL Controller Driver
>> + *
>> + * Copyright (c) 2023 Amlogic, inc.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/clk.h>
>> +#include "clk-regmap.h"
>> +#include "clk-pll.h"
>> +#include "c3-pll.h"
>> +#include "meson-clkc-utils.h"
>> +#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
>> +
>> +static const struct clk_parent_data pll_dco_parent = {
>> +     .fw_name = "pll_in",
>> +};
>> +
>> +static const struct clk_parent_data mclk_pll_dco_parent = {
>> +     .fw_name = "mclk_pll_in",
>> +};
> 
> I'm assuming this section relates to Documentation section 6.6.3.5 MPLL
> because all the fixed clock looks very familiar.
> 
> Because of the naming of another clock below, I'm not quite sure. Please clarify
> 
MPLL is not included in C3 SoC. Document was not updated to reflect this 
change.
Mclk_Pll is  designed for sensor in C3 Soc.
>> +
>> +static struct clk_regmap fixed_pll_dco = {
>> +     .data = &(struct meson_clk_pll_data){
>> +             .en = {
>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .m = {
>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 8,
>> +             },
>> +             .n = {
>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>> +                     .shift   = 16,
>> +                     .width   = 5,
>> +             },
>> +             .l = {
>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>> +                     .shift   = 31,
>> +                     .width   = 1,
>> +             },
>> +             .rst = {
>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fixed_pll_dco",
>> +             .ops = &meson_clk_pll_ro_ops,
>> +             .parent_data = &pll_dco_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fixed_pll = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL0,
>> +             .shift = 12,
>> +             .width = 3,
>> +             .flags = CLK_DIVIDER_POWER_OF_TWO,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fixed_pll",
>> +             .ops = &clk_regmap_divider_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll_dco.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
> 
> Need a comment about why this is using RO ops
>
Will do.

>> +
>> +static struct clk_fixed_factor fclk_div40_div = {
>> +     .mult = 1,
>> +     .div = 40,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fclk_div40_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_div40 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>> +             .bit_idx = 0,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_div40",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_div40_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
> 
> Don't see div40 in the diagram, where does it come from ?
> The div40 is  an alias of  fixpll_clk50m in sec 6.6.5.3 about FIXPLL.
>> +
>> +static struct clk_fixed_factor fclk_div2_div = {
>> +     .mult = 1,
>> +     .div = 2,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fclk_div2_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_div2 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>> +             .bit_idx = 24,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_div2",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_div2_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_fixed_factor fclk_div2p5_div = {
>> +     .mult = 2,
>> +     .div = 5,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fclk_div2p5_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
> 
> This one is wrong if I follow the doc.
> It is supposed to be fixed 8 divider taking it's source directly from
> the DCO, skipping the OD post divider ... assuming the doc is up to date.
> 
No, C3 SoC div2p5 is not skipping the OD post divider.
>> +
>> +static struct clk_regmap fclk_div2p5 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>> +             .bit_idx = 4,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_div2p5",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_div2p5_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_fixed_factor fclk_div3_div = {
>> +     .mult = 1,
>> +     .div = 3,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fclk_div3_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_div3 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>> +             .bit_idx = 20,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_div3",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_div3_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_fixed_factor fclk_div4_div = {
>> +     .mult = 1,
>> +     .div = 4,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fclk_div4_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_div4 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>> +             .bit_idx = 21,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_div4",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_div4_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_fixed_factor fclk_div5_div = {
>> +     .mult = 1,
>> +     .div = 5,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fclk_div5_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_div5 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>> +             .bit_idx = 22,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_div5",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_div5_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_fixed_factor fclk_div7_div = {
>> +     .mult = 1,
>> +     .div = 7,
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "fclk_div7_div",
>> +             .ops = &clk_fixed_factor_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fixed_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap fclk_div7 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>> +             .bit_idx = 23,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "fclk_div7",
>> +             .ops = &clk_regmap_gate_ro_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &fclk_div7_div.hw
>> +             },
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence c3_gp0_init_regs[] = {
>> +     { .reg = ANACTRL_GP0PLL_CTRL1,  .def = 0x0 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL2,  .def = 0x0 },
> 
> This should re-init GP0 rate on boot which is not desirable in case the
> bootloader had already set a rate (for splash screen for example)
> 
> Sugguest you drop these
If I drop these ,set rate will be failed.
There are two differences between C3 SoC PLL and the previous SoC PLL.
It recommends reconfiguring PLL according to time sequence each time 
when C3 PLL set rate. When previous SoC set rate, it set frequency 
related parameters and  enable PLL after directly reset PLL about 
previous SoC.
When setting C3 PLL, you need to reset a pll lock rst bit, otherwise the 
PLL lock bit will not refresh.
> 
>> +     { .reg = ANACTRL_GP0PLL_CTRL3,  .def = 0x48681c00 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL4,  .def = 0x88770290 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL5,  .def = 0x3927200a },
>> +     { .reg = ANACTRL_GP0PLL_CTRL6,  .def = 0x56540000, .delay_us = 10 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0x080304fa },
>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0x380304fa, .delay_us = 10 },
>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0X180304fa }
>> +};
>> +
>> +static const struct pll_params_table c3_gp0_pll_params_table[] = {
>> +     PLL_PARAMS(150, 1), /* DCO = 3600M */
>> +     PLL_PARAMS(130, 1), /* DCO = 3120M */
>> +     PLL_PARAMS(192, 1), /* DCO = 4608M */
>> +     PLL_PARAMS(125, 1), /* DCO = 3000M */
>> +     { /* sentinel */  }
>> +};
> 
> Why can't C3 use mult_range for GP0, like the other SoC ?
> Doc says DCO can do 3 to 6GHz
> 
The mult_range method is time-consuming and not suitable for scenarios 
requiring high frequency cutting performance.
We generally only use a few commonly used frequencies.
>> +
>> +/* The maximum frequency divider supports is 32, not 128(2^7) */
>> +static const struct clk_div_table c3_gp0_pll_od_table[] = {
>> +     { 0,  1 },
>> +     { 1,  2 },
>> +     { 2,  4 },
>> +     { 3,  8 },
>> +     { 4, 16 },
>> +     { 5, 32 },
>> +     { /* sentinel */ }
>> +};
> 
> Please put that table next to the related divider
> Same for other instances
> 
Will do.
>> +
>> +static struct clk_regmap gp0_pll_dco = {
>> +     .data = &(struct meson_clk_pll_data){
>> +             .en = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .m = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 9,
>> +             },
>> +             .frac = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL1,
>> +                     .shift   = 0,
>> +                     .width   = 19,
>> +             },
>> +             .n = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 10,
>> +                     .width   = 5,
>> +             },
>> +             .l = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 31,
>> +                     .width   = 1,
>> +             },
>> +             .rst = {
>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .table = c3_gp0_pll_params_table,
>> +             .init_regs = c3_gp0_init_regs,
>> +             .init_count = ARRAY_SIZE(c3_gp0_init_regs),
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "gp0_pll_dco",
>> +             .ops = &meson_clk_pll_ops,
>> +             .parent_data = &pll_dco_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap gp0_pll = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ANACTRL_GP0PLL_CTRL0,
>> +             .shift = 16,
>> +             .width = 3,
>> +             .table = c3_gp0_pll_od_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "gp0_pll",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &gp0_pll_dco.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static const struct reg_sequence c3_hifi_init_regs[] = {
>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x08010496 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x38010496 },
> 
> Same here, this an hidden hard coded rate init, with enable on top.
> Please drop this
> 
> If you need a specific rate after the init, use assigned-rate in DT
> 
>> +     { .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x0000ce40 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000, .delay_us = 50 },
>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x18010496, .delay_us = 20 },
>> +};
>> +
>> +static const struct pll_params_table c3_hifi_pll_params_table[] = {
>> +     PLL_PARAMS(150, 1), /* DCO = 3600M */
>> +     PLL_PARAMS(130, 1), /* DCO = 3120M */
>> +     PLL_PARAMS(192, 1), /* DCO = 4608M */
>> +     PLL_PARAMS(125, 1), /* DCO = 3000M */
>> +     { /* sentinel */  }
>> +};
> 
> Again, why can't HiFi use mult range ?
>
The mult_range method is time-consuming and not suitable for scenarios 
requiring high frequency cutting performance.
>> +
>> +static struct clk_regmap hifi_pll_dco = {
>> +     .data = &(struct meson_clk_pll_data){
>> +             .en = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .m = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 8,
>> +             },
>> +             .frac = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL1,
>> +                     .shift   = 0,
>> +                     .width   = 19,
>> +             },
>> +             .n = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 10,
>> +                     .width   = 5,
>> +             },
>> +             .l = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 31,
>> +                     .width   = 1,
>> +             },
>> +             .rst = {
>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .table = c3_hifi_pll_params_table,
>> +             .init_regs = c3_hifi_init_regs,
>> +             .init_count = ARRAY_SIZE(c3_hifi_init_regs),
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "hifi_pll_dco",
>> +             .ops = &meson_clk_pll_ops,
>> +             .parent_data = &pll_dco_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap hifi_pll = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ANACTRL_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 *[]) {
>> +                     &hifi_pll_dco.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
> 
> I cannot make out what all the mclk section below relates to in
> documentation clock. Could you please clarify ?
> 
>> +static const struct reg_sequence c3_mclk_init_regs[] = {
>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x20011063 },
>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x30011063 },
> 
> Again, hidden rate set on init ...
> 
>> +     { .reg = ANACTRL_MPLL_CTRL1,    .def = 0x1420500f },
>> +     { .reg = ANACTRL_MPLL_CTRL2,    .def = 0x00023041 },
>> +     { .reg = ANACTRL_MPLL_CTRL3,    .def = 0x18180000 },
>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x10011063 },
>> +     { .reg = ANACTRL_MPLL_CTRL2,    .def = 0x00023001 }
>> +};
>> +
>> +static const struct pll_params_table c3_mclk_pll_params_table[] = {
>> +     PLL_PARAMS(99, 1), /* VCO = 2376M */
>> +     { /* sentinel */  }
>> +};
>> +
>> +static const struct clk_div_table c3_mpll_od_table[] = {
>> +     { 0,  1 },
>> +     { 1,  2 },
>> +     { 2,  4 },
>> +     { 3,  8 },
>> +     { 4, 16 },
>> +     { /* sentinel */ }
>> +};
>> +
>> +static struct clk_regmap mclk_pll_dco = {
>> +     .data = &(struct meson_clk_pll_data){
>> +             .en = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>> +                     .shift   = 28,
>> +                     .width   = 1,
>> +             },
>> +             .m = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>> +                     .shift   = 0,
>> +                     .width   = 9,
>> +             },
>> +             .n = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>> +                     .shift   = 10,
>> +                     .width   = 5,
>> +             },
>> +             .l = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>> +                     .shift   = 31,
>> +                     .width   = 1,
>> +             },
>> +             .rst = {
>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>> +                     .shift   = 29,
>> +                     .width   = 1,
>> +             },
>> +             .table = c3_mclk_pll_params_table,
>> +             .init_regs = c3_mclk_init_regs,
>> +             .init_count = ARRAY_SIZE(c3_mclk_init_regs),
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mclk_pll_dco",
>> +             .ops = &meson_clk_pll_ops,
>> +             .parent_data = &mclk_pll_dco_parent,
>> +             .num_parents = 1,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk_pll = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ANACTRL_MPLL_CTRL0,
>> +             .shift = 12,
>> +             .width = 3,
>> +             .table = c3_mpll_od_table,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mclk_pll",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk_pll_dco.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk_pll_clk = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .shift = 16,
>> +             .width = 5,
>> +             .flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mclk_pll_clk",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk_pll.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
> 
> 
> "mclk_pll" then "mclk_pll_clk" ... that is confusing
> 
Maybe mclk_pll rename mclk_pll_od.>> +
>> +static const struct clk_parent_data mclk_parent[] = {
>> +     { .hw = &mclk_pll_clk.hw },
>> +     { .fw_name = "mclk_pll_in" },
>> +     { .hw = &fclk_div40.hw }
>> +};
>> +
>> +static struct clk_regmap mclk0_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .mask = 0x3,
>> +             .shift = 4,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mclk0_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = mclk_parent,
>> +             .num_parents = ARRAY_SIZE(mclk_parent),
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk0_sel_out = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .bit_idx = 1,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "mclk0_sel_out",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk0_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk0_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .shift = 2,
>> +             .width = 1,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mclk0_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk0_sel_out.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk0 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .bit_idx = 0,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "mclk0",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk0_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk1_sel = {
>> +     .data = &(struct clk_regmap_mux_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .mask = 0x3,
>> +             .shift = 12,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mclk1_sel",
>> +             .ops = &clk_regmap_mux_ops,
>> +             .parent_data = mclk_parent,
>> +             .num_parents = ARRAY_SIZE(mclk_parent),
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk1_sel_out = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .bit_idx = 9,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "mclk1_sel_out",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk1_sel.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk1_div = {
>> +     .data = &(struct clk_regmap_div_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .shift = 10,
>> +             .width = 1,
>> +     },
>> +     .hw.init = &(struct clk_init_data){
>> +             .name = "mclk1_div",
>> +             .ops = &clk_regmap_divider_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk1_sel_out.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_regmap mclk1 = {
>> +     .data = &(struct clk_regmap_gate_data){
>> +             .offset = ANACTRL_MPLL_CTRL4,
>> +             .bit_idx = 8,
>> +     },
>> +     .hw.init = &(struct clk_init_data) {
>> +             .name = "mclk1",
>> +             .ops = &clk_regmap_gate_ops,
>> +             .parent_hws = (const struct clk_hw *[]) {
>> +                     &mclk1_div.hw
>> +             },
>> +             .num_parents = 1,
>> +             .flags = CLK_SET_RATE_PARENT,
>> +     },
>> +};
>> +
>> +static struct clk_hw *c3_pll_hw_clks[] = {
>> +     [CLKID_FIXED_PLL_DCO]   = &fixed_pll_dco.hw,
>> +     [CLKID_FIXED_PLL]       = &fixed_pll.hw,
>> +     [CLKID_FCLK_DIV40_DIV]  = &fclk_div40_div.hw,
>> +     [CLKID_FCLK_DIV40]      = &fclk_div40.hw,
>> +     [CLKID_FCLK_DIV2_DIV]   = &fclk_div2_div.hw,
>> +     [CLKID_FCLK_DIV2]       = &fclk_div2.hw,
>> +     [CLKID_FCLK_DIV2P5_DIV] = &fclk_div2p5_div.hw,
>> +     [CLKID_FCLK_DIV2P5]     = &fclk_div2p5.hw,
>> +     [CLKID_FCLK_DIV3_DIV]   = &fclk_div3_div.hw,
>> +     [CLKID_FCLK_DIV3]       = &fclk_div3.hw,
>> +     [CLKID_FCLK_DIV4_DIV]   = &fclk_div4_div.hw,
>> +     [CLKID_FCLK_DIV4]       = &fclk_div4.hw,
>> +     [CLKID_FCLK_DIV5_DIV]   = &fclk_div5_div.hw,
>> +     [CLKID_FCLK_DIV5]       = &fclk_div5.hw,
>> +     [CLKID_FCLK_DIV7_DIV]   = &fclk_div7_div.hw,
>> +     [CLKID_FCLK_DIV7]       = &fclk_div7.hw,
>> +     [CLKID_GP0_PLL_DCO]     = &gp0_pll_dco.hw,
>> +     [CLKID_GP0_PLL]         = &gp0_pll.hw,
>> +     [CLKID_HIFI_PLL_DCO]    = &hifi_pll_dco.hw,
>> +     [CLKID_HIFI_PLL]        = &hifi_pll.hw,
>> +     [CLKID_MCLK_PLL_DCO]    = &mclk_pll_dco.hw,
>> +     [CLKID_MCLK_PLL]        = &mclk_pll.hw,
>> +     [CLKID_MCLK_PLL_CLK]    = &mclk_pll_clk.hw,
>> +     [CLKID_MCLK0_SEL]       = &mclk0_sel.hw,
>> +     [CLKID_MCLK0_SEL_OUT]   = &mclk0_sel_out.hw,
>> +     [CLKID_MCLK0_DIV]       = &mclk0_div.hw,
>> +     [CLKID_MCLK0]           = &mclk0.hw,
>> +     [CLKID_MCLK1_SEL]       = &mclk1_sel.hw,
>> +     [CLKID_MCLK1_SEL_OUT]   = &mclk1_sel_out.hw,
>> +     [CLKID_MCLK1_DIV]       = &mclk1_div.hw,
>> +     [CLKID_MCLK1]           = &mclk1.hw
>> +};
>> +
>> +/* Convenience table to populate regmap in .probe */
>> +static struct clk_regmap *const c3_pll_clk_regmaps[] = {
>> +     &fixed_pll_dco,
>> +     &fixed_pll,
>> +     &fclk_div40,
>> +     &fclk_div2,
>> +     &fclk_div2p5,
>> +     &fclk_div3,
>> +     &fclk_div4,
>> +     &fclk_div5,
>> +     &fclk_div7,
>> +     &gp0_pll_dco,
>> +     &gp0_pll,
>> +     &hifi_pll_dco,
>> +     &hifi_pll,
>> +     &mclk_pll_dco,
>> +     &mclk_pll,
>> +     &mclk_pll_clk,
>> +     &mclk0_sel,
>> +     &mclk0_sel_out,
>> +     &mclk0_div,
>> +     &mclk0,
>> +     &mclk1_sel,
>> +     &mclk1_sel_out,
>> +     &mclk1_div,
>> +     &mclk1,
>> +};
>> +
>> +static struct regmap_config clkc_regmap_config = {
>> +     .reg_bits       = 32,
>> +     .val_bits       = 32,
>> +     .reg_stride     = 4,
>> +};
>> +
>> +static struct meson_clk_hw_data c3_pll_clks = {
>> +     .hws = c3_pll_hw_clks,
>> +     .num = ARRAY_SIZE(c3_pll_hw_clks),
>> +};
>> +
>> +static int aml_c3_pll_probe(struct platform_device *pdev)
>> +{
>> +     struct device *dev = &pdev->dev;
>> +     struct regmap *regmap;
>> +     void __iomem *base;
>> +     int clkid, ret, i;
>> +
>> +     base = devm_platform_ioremap_resource(pdev, 0);
>> +     if (IS_ERR(base))
>> +             return PTR_ERR(base);
>> +
>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>> +     if (IS_ERR(regmap))
>> +             return PTR_ERR(regmap);
>> +
>> +     /* Populate regmap for the regmap backed clocks */
>> +     for (i = 0; i < ARRAY_SIZE(c3_pll_clk_regmaps); i++)
>> +             c3_pll_clk_regmaps[i]->map = regmap;
>> +
>> +     for (clkid = 0; clkid < c3_pll_clks.num; clkid++) {
>> +             /* array might be sparse */
>> +             if (!c3_pll_clks.hws[clkid])
>> +                     continue;
>> +
>> +             ret = devm_clk_hw_register(dev, c3_pll_clks.hws[clkid]);
>> +             if (ret) {
>> +                     dev_err(dev, "Clock registration failed\n");
>> +                     return ret;
>> +             }
>> +     }
>> +
>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>> +                                        &c3_pll_clks);
>> +}
>> +
>> +static const struct of_device_id c3_pll_clkc_match_table[] = {
>> +     {
>> +             .compatible = "amlogic,c3-pll-clkc",
>> +     },
>> +     {}
>> +};
>> +MODULE_DEVICE_TABLE(of, c3_pll_clkc_match_table);
>> +
>> +static struct platform_driver c3_pll_driver = {
>> +     .probe          = aml_c3_pll_probe,
>> +     .driver         = {
>> +             .name   = "c3-pll-clkc",
>> +             .of_match_table = c3_pll_clkc_match_table,
>> +     },
>> +};
>> +
>> +module_platform_driver(c3_pll_driver);
>> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/clk/meson/c3-pll.h b/drivers/clk/meson/c3-pll.h
>> new file mode 100644
>> index 000000000000..92a08196a46f
>> --- /dev/null
>> +++ b/drivers/clk/meson/c3-pll.h
>> @@ -0,0 +1,35 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>> +/*
>> + * Copyright (c) 2023 Amlogic, inc.
>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>> + */
>> +
>> +#ifndef __AML_C3_PLL_H__
>> +#define __AML_C3_PLL_H__
>> +
>> +#define ANACTRL_FIXPLL_CTRL0                 0x0040
>> +#define ANACTRL_FIXPLL_CTRL4                 0x0050
>> +#define ANACTRL_GP0PLL_CTRL0                 0x0080
>> +#define ANACTRL_GP0PLL_CTRL1                 0x0084
>> +#define ANACTRL_GP0PLL_CTRL2                 0x0088
>> +#define ANACTRL_GP0PLL_CTRL3                 0x008c
>> +#define ANACTRL_GP0PLL_CTRL4                 0x0090
>> +#define ANACTRL_GP0PLL_CTRL5                 0x0094
>> +#define ANACTRL_GP0PLL_CTRL6                 0x0098
>> +#define ANACTRL_GP0PLL_STS                   0x009c
>> +#define ANACTRL_HIFIPLL_CTRL0                        0x0100
>> +#define ANACTRL_HIFIPLL_CTRL1                        0x0104
>> +#define ANACTRL_HIFIPLL_CTRL2                        0x0108
>> +#define ANACTRL_HIFIPLL_CTRL3                        0x010c
>> +#define ANACTRL_HIFIPLL_CTRL4                        0x0110
>> +#define ANACTRL_HIFIPLL_CTRL5                        0x0114
>> +#define ANACTRL_HIFIPLL_CTRL6                        0x0118
>> +#define ANACTRL_HIFIPLL_STS                  0x011c
>> +#define ANACTRL_MPLL_CTRL0                   0x0180
>> +#define ANACTRL_MPLL_CTRL1                   0x0184
>> +#define ANACTRL_MPLL_CTRL2                   0x0188
>> +#define ANACTRL_MPLL_CTRL3                   0x018c
>> +#define ANACTRL_MPLL_CTRL4                   0x0190
>> +#define ANACTRL_MPLL_STS                     0x01a4
>> +
>> +#endif  /* __AML_C3_PLL_H__ */
> 

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

* Re: [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock
  2023-10-17  6:15     ` Xianwei Zhao
@ 2023-10-17 13:06       ` Jerome Brunet
  2023-10-17 14:39         ` Chuan Liu
  0 siblings, 1 reply; 27+ messages in thread
From: Jerome Brunet @ 2023-10-17 13:06 UTC (permalink / raw)
  To: Xianwei Zhao, linux-arm-kernel, linux-amlogic, linux-clk,
	devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu


On Tue 17 Oct 2023 at 14:15, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:

> Hi Jerome,
>
>
> On 2023/10/13 15:49, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>> On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com>
>> wrote:
>> 
>>> Add the C3 PLL clock controller driver for the Amlogic C3 SoC family.
>>>
>>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>>> ---
>>> V1 -> V2: Delete macro definition.
>>> ---
>>>   drivers/clk/meson/Kconfig  |  12 +
>>>   drivers/clk/meson/Makefile |   1 +
>>>   drivers/clk/meson/c3-pll.c | 808 +++++++++++++++++++++++++++++++++++++
>>>   drivers/clk/meson/c3-pll.h |  35 ++
>>>   4 files changed, 856 insertions(+)
>>>   create mode 100644 drivers/clk/meson/c3-pll.c
>>>   create mode 100644 drivers/clk/meson/c3-pll.h
>>>
>>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>>> index c5303e4c1604..76be4bbd2afb 100644
>>> --- a/drivers/clk/meson/Kconfig
>>> +++ b/drivers/clk/meson/Kconfig
>>> @@ -128,6 +128,18 @@ config COMMON_CLK_A1_PERIPHERALS
>>>          device, A1 SoC Family. Say Y if you want A1 Peripherals clock
>>>          controller to work.
>>>
>>> +config COMMON_CLK_C3_PLL
>>> +     tristate "Amlogic C3 PLL clock controller"
>>> +     default y
>>> +     select COMMON_CLK_MESON_REGMAP
>>> +     select COMMON_CLK_MESON_PLL
>>> +     select COMMON_CLK_MESON_CLKC_UTILS
>>> +     help
>>> +       Support for the PLL clock controller on Amlogic C302X and C308L devices,
>>> +       AKA c3. Amlogic C302X and C308L devices include AW402, AW409 and AW419.
>>> +       Say Y if you want the board to work, because PLLs are the parent of most
>>> +       peripherals.
>>> +
>>>   config COMMON_CLK_G12A
>>>        tristate "G12 and SM1 SoC clock controllers support"
>>>        depends on ARM64
>>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>>> index 9ee4b954c896..4420af628b31 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_C3_PLL) += c3-pll.o
>>>   obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>>>   obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>>>   obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
>>> diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c
>>> new file mode 100644
>>> index 000000000000..97619bc7ab79
>>> --- /dev/null
>>> +++ b/drivers/clk/meson/c3-pll.c
>>> @@ -0,0 +1,808 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Amlogic C3 PLL Controller Driver
>>> + *
>>> + * Copyright (c) 2023 Amlogic, inc.
>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>> + */
>>> +
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/clk.h>
>>> +#include "clk-regmap.h"
>>> +#include "clk-pll.h"
>>> +#include "c3-pll.h"
>>> +#include "meson-clkc-utils.h"
>>> +#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
>>> +
>>> +static const struct clk_parent_data pll_dco_parent = {
>>> +     .fw_name = "pll_in",
>>> +};
>>> +
>>> +static const struct clk_parent_data mclk_pll_dco_parent = {
>>> +     .fw_name = "mclk_pll_in",
>>> +};
>> I'm assuming this section relates to Documentation section 6.6.3.5 MPLL
>> because all the fixed clock looks very familiar.
>> Because of the naming of another clock below, I'm not quite sure. Please
>> clarify
>> 
> MPLL is not included in C3 SoC. Document was not updated to reflect this
> change.
> Mclk_Pll is  designed for sensor in C3 Soc.
>>> +
>>> +static struct clk_regmap fixed_pll_dco = {
>>> +     .data = &(struct meson_clk_pll_data){
>>> +             .en = {
>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>> +                     .shift   = 28,
>>> +                     .width   = 1,
>>> +             },
>>> +             .m = {
>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>> +                     .shift   = 0,
>>> +                     .width   = 8,
>>> +             },
>>> +             .n = {
>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>> +                     .shift   = 16,
>>> +                     .width   = 5,
>>> +             },
>>> +             .l = {
>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>> +                     .shift   = 31,
>>> +                     .width   = 1,
>>> +             },
>>> +             .rst = {
>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>> +                     .shift   = 29,
>>> +                     .width   = 1,
>>> +             },
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fixed_pll_dco",
>>> +             .ops = &meson_clk_pll_ro_ops,
>>> +             .parent_data = &pll_dco_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap fixed_pll = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL0,
>>> +             .shift = 12,
>>> +             .width = 3,
>>> +             .flags = CLK_DIVIDER_POWER_OF_TWO,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fixed_pll",
>>> +             .ops = &clk_regmap_divider_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll_dco.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>> Need a comment about why this is using RO ops
>>
> Will do.
>
>>> +
>>> +static struct clk_fixed_factor fclk_div40_div = {
>>> +     .mult = 1,
>>> +     .div = 40,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fclk_div40_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap fclk_div40 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>> +             .bit_idx = 0,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "fclk_div40",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fclk_div40_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>> Don't see div40 in the diagram, where does it come from ?
>> The div40 is  an alias of  fixpll_clk50m in sec 6.6.5.3 about FIXPLL.

Then maybe clk50m something is better name for it

>>> +
>>> +static struct clk_fixed_factor fclk_div2_div = {
>>> +     .mult = 1,
>>> +     .div = 2,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fclk_div2_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap fclk_div2 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "fclk_div2",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fclk_div2_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_fixed_factor fclk_div2p5_div = {
>>> +     .mult = 2,
>>> +     .div = 5,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fclk_div2p5_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>> This one is wrong if I follow the doc.
>> It is supposed to be fixed 8 divider taking it's source directly from
>> the DCO, skipping the OD post divider ... assuming the doc is up to date.
>> 
> No, C3 SoC div2p5 is not skipping the OD post divider.

I a bit surprised there would be a frequency multiplier considering the
complexity of it, when skiping a divider is possible HW wise. Are you
sure ?

>>> +
>>> +static struct clk_regmap fclk_div2p5 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>> +             .bit_idx = 4,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "fclk_div2p5",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fclk_div2p5_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_fixed_factor fclk_div3_div = {
>>> +     .mult = 1,
>>> +     .div = 3,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fclk_div3_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap fclk_div3 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>> +             .bit_idx = 20,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "fclk_div3",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fclk_div3_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_fixed_factor fclk_div4_div = {
>>> +     .mult = 1,
>>> +     .div = 4,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fclk_div4_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap fclk_div4 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>> +             .bit_idx = 21,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "fclk_div4",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fclk_div4_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_fixed_factor fclk_div5_div = {
>>> +     .mult = 1,
>>> +     .div = 5,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fclk_div5_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap fclk_div5 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>> +             .bit_idx = 22,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "fclk_div5",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fclk_div5_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_fixed_factor fclk_div7_div = {
>>> +     .mult = 1,
>>> +     .div = 7,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "fclk_div7_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fixed_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap fclk_div7 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>> +             .bit_idx = 23,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "fclk_div7",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &fclk_div7_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static const struct reg_sequence c3_gp0_init_regs[] = {
>>> +     { .reg = ANACTRL_GP0PLL_CTRL1,  .def = 0x0 },

This would change frac

>>> +     { .reg = ANACTRL_GP0PLL_CTRL2,  .def = 0x0 },

This might be OK

>> This should re-init GP0 rate on boot which is not desirable in case the
>> bootloader had already set a rate (for splash screen for example)
>> Sugguest you drop these
> If I drop these ,set rate will be failed.
> There are two differences between C3 SoC PLL and the previous SoC PLL.
> It recommends reconfiguring PLL according to time sequence each time when
> C3 PLL set rate. When previous SoC set rate, it set frequency related
> parameters and  enable PLL after directly reset PLL about previous SoC.
> When setting C3 PLL, you need to reset a pll lock rst bit, otherwise the
> PLL lock bit will not refresh.

1. The amlogic off tree driver might using this for every set_rate() but
upstream does not. this is only used for init.
2. We have a rst parameter explicitly for this. This bit is poked. It is
part of the enable sequence.

>> 
>>> +     { .reg = ANACTRL_GP0PLL_CTRL3,  .def = 0x48681c00 },
>>> +     { .reg = ANACTRL_GP0PLL_CTRL4,  .def = 0x88770290 },
>>> +     { .reg = ANACTRL_GP0PLL_CTRL5,  .def = 0x3927200a },
>>> +     { .reg = ANACTRL_GP0PLL_CTRL6,  .def = 0x56540000, .delay_us = 10 },

---

>>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0x080304fa },
>>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0x380304fa, .delay_us = 10 },
>>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0X180304fa }

This definitely is not.

For all I can tell, in addition to an hard coded rate,
This disable 'en' and 'rst', put them back to 1 - wait 10us then disable
rst again.

On set_rate() here what the current driver would do with this (assuming
the clock was enabled)

- disable: rst 0 -> 1 ; en 1 -> 0;
- set_rate : write m, n, and frac
- enable: en 0 -> 1; rst 1 -> 0;

If you think the current sequence used by clk-pll.c is not approriate,
feel free to submit a patch.

>>> +};
>>> +
>>> +static const struct pll_params_table c3_gp0_pll_params_table[] = {
>>> +     PLL_PARAMS(150, 1), /* DCO = 3600M */
>>> +     PLL_PARAMS(130, 1), /* DCO = 3120M */
>>> +     PLL_PARAMS(192, 1), /* DCO = 4608M */
>>> +     PLL_PARAMS(125, 1), /* DCO = 3000M */
>>> +     { /* sentinel */  }
>>> +};
>> Why can't C3 use mult_range for GP0, like the other SoC ?
>> Doc says DCO can do 3 to 6GHz
>> 
> The mult_range method is time-consuming and not suitable for scenarios
> requiring high frequency cutting performance.

Do you have numbers backing this up ?

I might be wrong but I don't think going through the mult_range
calculation is even a topic when you consider the time it takes to
relock the PLL or the delay added in the sequence.

> We generally only use a few commonly used frequencies.

You do yes. A driver is about enabling the HW, not just what a set of
people are doing with it.

>>> +
>>> +/* The maximum frequency divider supports is 32, not 128(2^7) */
>>> +static const struct clk_div_table c3_gp0_pll_od_table[] = {
>>> +     { 0,  1 },
>>> +     { 1,  2 },
>>> +     { 2,  4 },
>>> +     { 3,  8 },
>>> +     { 4, 16 },
>>> +     { 5, 32 },
>>> +     { /* sentinel */ }
>>> +};
>> Please put that table next to the related divider
>> Same for other instances
>> 
> Will do.
>>> +
>>> +static struct clk_regmap gp0_pll_dco = {
>>> +     .data = &(struct meson_clk_pll_data){
>>> +             .en = {
>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>> +                     .shift   = 28,
>>> +                     .width   = 1,
>>> +             },
>>> +             .m = {
>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>> +                     .shift   = 0,
>>> +                     .width   = 9,
>>> +             },
>>> +             .frac = {
>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL1,
>>> +                     .shift   = 0,
>>> +                     .width   = 19,
>>> +             },
>>> +             .n = {
>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>> +                     .shift   = 10,
>>> +                     .width   = 5,
>>> +             },
>>> +             .l = {
>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>> +                     .shift   = 31,
>>> +                     .width   = 1,
>>> +             },
>>> +             .rst = {
>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>> +                     .shift   = 29,
>>> +                     .width   = 1,
>>> +             },
>>> +             .table = c3_gp0_pll_params_table,
>>> +             .init_regs = c3_gp0_init_regs,
>>> +             .init_count = ARRAY_SIZE(c3_gp0_init_regs),
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "gp0_pll_dco",
>>> +             .ops = &meson_clk_pll_ops,
>>> +             .parent_data = &pll_dco_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap gp0_pll = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ANACTRL_GP0PLL_CTRL0,
>>> +             .shift = 16,
>>> +             .width = 3,
>>> +             .table = c3_gp0_pll_od_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "gp0_pll",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &gp0_pll_dco.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct reg_sequence c3_hifi_init_regs[] = {
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x08010496 },
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x38010496 },
>> Same here, this an hidden hard coded rate init, with enable on top.
>> Please drop this
>> If you need a specific rate after the init, use assigned-rate in DT
>> 
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x0000ce40 },
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 },
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 },
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000, .delay_us = 50 },
>>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x18010496, .delay_us = 20 },
>>> +};
>>> +
>>> +static const struct pll_params_table c3_hifi_pll_params_table[] = {
>>> +     PLL_PARAMS(150, 1), /* DCO = 3600M */
>>> +     PLL_PARAMS(130, 1), /* DCO = 3120M */
>>> +     PLL_PARAMS(192, 1), /* DCO = 4608M */
>>> +     PLL_PARAMS(125, 1), /* DCO = 3000M */
>>> +     { /* sentinel */  }
>>> +};
>> Again, why can't HiFi use mult range ?
>>
> The mult_range method is time-consuming and not suitable for scenarios
> requiring high frequency cutting performance.

Again, I'd be curious how this can be a problem when considering the
time it takes to reloc the PLL.

How often do you relock a PLL for HiFi use cases ?

>>> +
>>> +static struct clk_regmap hifi_pll_dco = {
>>> +     .data = &(struct meson_clk_pll_data){
>>> +             .en = {
>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>> +                     .shift   = 28,
>>> +                     .width   = 1,
>>> +             },
>>> +             .m = {
>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>> +                     .shift   = 0,
>>> +                     .width   = 8,
>>> +             },
>>> +             .frac = {
>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL1,
>>> +                     .shift   = 0,
>>> +                     .width   = 19,
>>> +             },
>>> +             .n = {
>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>> +                     .shift   = 10,
>>> +                     .width   = 5,
>>> +             },
>>> +             .l = {
>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>> +                     .shift   = 31,
>>> +                     .width   = 1,
>>> +             },
>>> +             .rst = {
>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>> +                     .shift   = 29,
>>> +                     .width   = 1,
>>> +             },
>>> +             .table = c3_hifi_pll_params_table,
>>> +             .init_regs = c3_hifi_init_regs,
>>> +             .init_count = ARRAY_SIZE(c3_hifi_init_regs),
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "hifi_pll_dco",
>>> +             .ops = &meson_clk_pll_ops,
>>> +             .parent_data = &pll_dco_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap hifi_pll = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ANACTRL_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 *[]) {
>>> +                     &hifi_pll_dco.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>> I cannot make out what all the mclk section below relates to in
>> documentation clock. Could you please clarify ?
>> 
>>> +static const struct reg_sequence c3_mclk_init_regs[] = {
>>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x20011063 },
>>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x30011063 },
>> Again, hidden rate set on init ...
>> 
>>> +     { .reg = ANACTRL_MPLL_CTRL1,    .def = 0x1420500f },
>>> +     { .reg = ANACTRL_MPLL_CTRL2,    .def = 0x00023041 },
>>> +     { .reg = ANACTRL_MPLL_CTRL3,    .def = 0x18180000 },
>>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x10011063 },
>>> +     { .reg = ANACTRL_MPLL_CTRL2,    .def = 0x00023001 }
>>> +};
>>> +
>>> +static const struct pll_params_table c3_mclk_pll_params_table[] = {
>>> +     PLL_PARAMS(99, 1), /* VCO = 2376M */
>>> +     { /* sentinel */  }
>>> +};
>>> +
>>> +static const struct clk_div_table c3_mpll_od_table[] = {
>>> +     { 0,  1 },
>>> +     { 1,  2 },
>>> +     { 2,  4 },
>>> +     { 3,  8 },
>>> +     { 4, 16 },
>>> +     { /* sentinel */ }
>>> +};
>>> +
>>> +static struct clk_regmap mclk_pll_dco = {
>>> +     .data = &(struct meson_clk_pll_data){
>>> +             .en = {
>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>> +                     .shift   = 28,
>>> +                     .width   = 1,
>>> +             },
>>> +             .m = {
>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>> +                     .shift   = 0,
>>> +                     .width   = 9,
>>> +             },
>>> +             .n = {
>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>> +                     .shift   = 10,
>>> +                     .width   = 5,
>>> +             },
>>> +             .l = {
>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>> +                     .shift   = 31,
>>> +                     .width   = 1,
>>> +             },
>>> +             .rst = {
>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>> +                     .shift   = 29,
>>> +                     .width   = 1,
>>> +             },
>>> +             .table = c3_mclk_pll_params_table,
>>> +             .init_regs = c3_mclk_init_regs,
>>> +             .init_count = ARRAY_SIZE(c3_mclk_init_regs),
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mclk_pll_dco",
>>> +             .ops = &meson_clk_pll_ops,
>>> +             .parent_data = &mclk_pll_dco_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk_pll = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ANACTRL_MPLL_CTRL0,
>>> +             .shift = 12,
>>> +             .width = 3,
>>> +             .table = c3_mpll_od_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mclk_pll",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk_pll_dco.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk_pll_clk = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .shift = 16,
>>> +             .width = 5,
>>> +             .flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mclk_pll_clk",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk_pll.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>> "mclk_pll" then "mclk_pll_clk" ... that is confusing
>> 
> Maybe mclk_pll rename mclk_pll_od.>> +
>>> +static const struct clk_parent_data mclk_parent[] = {
>>> +     { .hw = &mclk_pll_clk.hw },
>>> +     { .fw_name = "mclk_pll_in" },
>>> +     { .hw = &fclk_div40.hw }
>>> +};
>>> +
>>> +static struct clk_regmap mclk0_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .mask = 0x3,
>>> +             .shift = 4,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mclk0_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = mclk_parent,
>>> +             .num_parents = ARRAY_SIZE(mclk_parent),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk0_sel_out = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .bit_idx = 1,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "mclk0_sel_out",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk0_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk0_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .shift = 2,
>>> +             .width = 1,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mclk0_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk0_sel_out.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk0 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .bit_idx = 0,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "mclk0",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk0_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk1_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .mask = 0x3,
>>> +             .shift = 12,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mclk1_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = mclk_parent,
>>> +             .num_parents = ARRAY_SIZE(mclk_parent),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk1_sel_out = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .bit_idx = 9,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "mclk1_sel_out",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk1_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk1_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .shift = 10,
>>> +             .width = 1,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mclk1_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk1_sel_out.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk1 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "mclk1",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mclk1_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_hw *c3_pll_hw_clks[] = {
>>> +     [CLKID_FIXED_PLL_DCO]   = &fixed_pll_dco.hw,
>>> +     [CLKID_FIXED_PLL]       = &fixed_pll.hw,
>>> +     [CLKID_FCLK_DIV40_DIV]  = &fclk_div40_div.hw,
>>> +     [CLKID_FCLK_DIV40]      = &fclk_div40.hw,
>>> +     [CLKID_FCLK_DIV2_DIV]   = &fclk_div2_div.hw,
>>> +     [CLKID_FCLK_DIV2]       = &fclk_div2.hw,
>>> +     [CLKID_FCLK_DIV2P5_DIV] = &fclk_div2p5_div.hw,
>>> +     [CLKID_FCLK_DIV2P5]     = &fclk_div2p5.hw,
>>> +     [CLKID_FCLK_DIV3_DIV]   = &fclk_div3_div.hw,
>>> +     [CLKID_FCLK_DIV3]       = &fclk_div3.hw,
>>> +     [CLKID_FCLK_DIV4_DIV]   = &fclk_div4_div.hw,
>>> +     [CLKID_FCLK_DIV4]       = &fclk_div4.hw,
>>> +     [CLKID_FCLK_DIV5_DIV]   = &fclk_div5_div.hw,
>>> +     [CLKID_FCLK_DIV5]       = &fclk_div5.hw,
>>> +     [CLKID_FCLK_DIV7_DIV]   = &fclk_div7_div.hw,
>>> +     [CLKID_FCLK_DIV7]       = &fclk_div7.hw,
>>> +     [CLKID_GP0_PLL_DCO]     = &gp0_pll_dco.hw,
>>> +     [CLKID_GP0_PLL]         = &gp0_pll.hw,
>>> +     [CLKID_HIFI_PLL_DCO]    = &hifi_pll_dco.hw,
>>> +     [CLKID_HIFI_PLL]        = &hifi_pll.hw,
>>> +     [CLKID_MCLK_PLL_DCO]    = &mclk_pll_dco.hw,
>>> +     [CLKID_MCLK_PLL]        = &mclk_pll.hw,
>>> +     [CLKID_MCLK_PLL_CLK]    = &mclk_pll_clk.hw,
>>> +     [CLKID_MCLK0_SEL]       = &mclk0_sel.hw,
>>> +     [CLKID_MCLK0_SEL_OUT]   = &mclk0_sel_out.hw,
>>> +     [CLKID_MCLK0_DIV]       = &mclk0_div.hw,
>>> +     [CLKID_MCLK0]           = &mclk0.hw,
>>> +     [CLKID_MCLK1_SEL]       = &mclk1_sel.hw,
>>> +     [CLKID_MCLK1_SEL_OUT]   = &mclk1_sel_out.hw,
>>> +     [CLKID_MCLK1_DIV]       = &mclk1_div.hw,
>>> +     [CLKID_MCLK1]           = &mclk1.hw
>>> +};
>>> +
>>> +/* Convenience table to populate regmap in .probe */
>>> +static struct clk_regmap *const c3_pll_clk_regmaps[] = {
>>> +     &fixed_pll_dco,
>>> +     &fixed_pll,
>>> +     &fclk_div40,
>>> +     &fclk_div2,
>>> +     &fclk_div2p5,
>>> +     &fclk_div3,
>>> +     &fclk_div4,
>>> +     &fclk_div5,
>>> +     &fclk_div7,
>>> +     &gp0_pll_dco,
>>> +     &gp0_pll,
>>> +     &hifi_pll_dco,
>>> +     &hifi_pll,
>>> +     &mclk_pll_dco,
>>> +     &mclk_pll,
>>> +     &mclk_pll_clk,
>>> +     &mclk0_sel,
>>> +     &mclk0_sel_out,
>>> +     &mclk0_div,
>>> +     &mclk0,
>>> +     &mclk1_sel,
>>> +     &mclk1_sel_out,
>>> +     &mclk1_div,
>>> +     &mclk1,
>>> +};
>>> +
>>> +static struct regmap_config clkc_regmap_config = {
>>> +     .reg_bits       = 32,
>>> +     .val_bits       = 32,
>>> +     .reg_stride     = 4,
>>> +};
>>> +
>>> +static struct meson_clk_hw_data c3_pll_clks = {
>>> +     .hws = c3_pll_hw_clks,
>>> +     .num = ARRAY_SIZE(c3_pll_hw_clks),
>>> +};
>>> +
>>> +static int aml_c3_pll_probe(struct platform_device *pdev)
>>> +{
>>> +     struct device *dev = &pdev->dev;
>>> +     struct regmap *regmap;
>>> +     void __iomem *base;
>>> +     int clkid, ret, i;
>>> +
>>> +     base = devm_platform_ioremap_resource(pdev, 0);
>>> +     if (IS_ERR(base))
>>> +             return PTR_ERR(base);
>>> +
>>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>>> +     if (IS_ERR(regmap))
>>> +             return PTR_ERR(regmap);
>>> +
>>> +     /* Populate regmap for the regmap backed clocks */
>>> +     for (i = 0; i < ARRAY_SIZE(c3_pll_clk_regmaps); i++)
>>> +             c3_pll_clk_regmaps[i]->map = regmap;
>>> +
>>> +     for (clkid = 0; clkid < c3_pll_clks.num; clkid++) {
>>> +             /* array might be sparse */
>>> +             if (!c3_pll_clks.hws[clkid])
>>> +                     continue;
>>> +
>>> +             ret = devm_clk_hw_register(dev, c3_pll_clks.hws[clkid]);
>>> +             if (ret) {
>>> +                     dev_err(dev, "Clock registration failed\n");
>>> +                     return ret;
>>> +             }
>>> +     }
>>> +
>>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>>> +                                        &c3_pll_clks);
>>> +}
>>> +
>>> +static const struct of_device_id c3_pll_clkc_match_table[] = {
>>> +     {
>>> +             .compatible = "amlogic,c3-pll-clkc",
>>> +     },
>>> +     {}
>>> +};
>>> +MODULE_DEVICE_TABLE(of, c3_pll_clkc_match_table);
>>> +
>>> +static struct platform_driver c3_pll_driver = {
>>> +     .probe          = aml_c3_pll_probe,
>>> +     .driver         = {
>>> +             .name   = "c3-pll-clkc",
>>> +             .of_match_table = c3_pll_clkc_match_table,
>>> +     },
>>> +};
>>> +
>>> +module_platform_driver(c3_pll_driver);
>>> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
>>> +MODULE_LICENSE("GPL");
>>> diff --git a/drivers/clk/meson/c3-pll.h b/drivers/clk/meson/c3-pll.h
>>> new file mode 100644
>>> index 000000000000..92a08196a46f
>>> --- /dev/null
>>> +++ b/drivers/clk/meson/c3-pll.h
>>> @@ -0,0 +1,35 @@
>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>>> +/*
>>> + * Copyright (c) 2023 Amlogic, inc.
>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>> + */
>>> +
>>> +#ifndef __AML_C3_PLL_H__
>>> +#define __AML_C3_PLL_H__
>>> +
>>> +#define ANACTRL_FIXPLL_CTRL0                 0x0040
>>> +#define ANACTRL_FIXPLL_CTRL4                 0x0050
>>> +#define ANACTRL_GP0PLL_CTRL0                 0x0080
>>> +#define ANACTRL_GP0PLL_CTRL1                 0x0084
>>> +#define ANACTRL_GP0PLL_CTRL2                 0x0088
>>> +#define ANACTRL_GP0PLL_CTRL3                 0x008c
>>> +#define ANACTRL_GP0PLL_CTRL4                 0x0090
>>> +#define ANACTRL_GP0PLL_CTRL5                 0x0094
>>> +#define ANACTRL_GP0PLL_CTRL6                 0x0098
>>> +#define ANACTRL_GP0PLL_STS                   0x009c
>>> +#define ANACTRL_HIFIPLL_CTRL0                        0x0100
>>> +#define ANACTRL_HIFIPLL_CTRL1                        0x0104
>>> +#define ANACTRL_HIFIPLL_CTRL2                        0x0108
>>> +#define ANACTRL_HIFIPLL_CTRL3                        0x010c
>>> +#define ANACTRL_HIFIPLL_CTRL4                        0x0110
>>> +#define ANACTRL_HIFIPLL_CTRL5                        0x0114
>>> +#define ANACTRL_HIFIPLL_CTRL6                        0x0118
>>> +#define ANACTRL_HIFIPLL_STS                  0x011c
>>> +#define ANACTRL_MPLL_CTRL0                   0x0180
>>> +#define ANACTRL_MPLL_CTRL1                   0x0184
>>> +#define ANACTRL_MPLL_CTRL2                   0x0188
>>> +#define ANACTRL_MPLL_CTRL3                   0x018c
>>> +#define ANACTRL_MPLL_CTRL4                   0x0190
>>> +#define ANACTRL_MPLL_STS                     0x01a4
>>> +
>>> +#endif  /* __AML_C3_PLL_H__ */
>> 


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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-17  3:25     ` Xianwei Zhao
@ 2023-10-17 13:28       ` Jerome Brunet
  2023-10-17 14:59         ` Chuan Liu
  0 siblings, 1 reply; 27+ messages in thread
From: Jerome Brunet @ 2023-10-17 13:28 UTC (permalink / raw)
  To: Xianwei Zhao, linux-arm-kernel, linux-amlogic, linux-clk,
	devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl, Chuan Liu


On Tue 17 Oct 2023 at 11:25, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:

> Hi Jerome,
>      Thank you for your reply.
>
> On 2023/10/13 16:46, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>> On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com>
>> wrote:
>> 
>>> Add the C3 peripherals clock controller driver in the C3 SoC family.
>>>
>>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>>> ---
>>> V1 -> V2: Delete macro definition.
>>> ---
>>>   drivers/clk/meson/Kconfig          |   13 +
>>>   drivers/clk/meson/Makefile         |    1 +
>>>   drivers/clk/meson/c3-peripherals.c | 3096 ++++++++++++++++++++++++++++
>>>   drivers/clk/meson/c3-peripherals.h |   48 +
>>>   4 files changed, 3158 insertions(+)
>>>   create mode 100644 drivers/clk/meson/c3-peripherals.c
>>>   create mode 100644 drivers/clk/meson/c3-peripherals.h
>>>
>>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>>> index 76be4bbd2afb..c8d59d28c8ff 100644
>>> --- a/drivers/clk/meson/Kconfig
>>> +++ b/drivers/clk/meson/Kconfig
>>> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
>>>          Say Y if you want the board to work, because PLLs are the parent of most
>>>          peripherals.
>>>
>>> +config COMMON_CLK_C3_PERIPHERALS
>>> +     tristate "Amlogic C3 peripherals clock controller"
>>> +     default y
>>> +     select COMMON_CLK_MESON_REGMAP
>>> +     select COMMON_CLK_MESON_DUALDIV
>>> +     select COMMON_CLK_MESON_CLKC_UTILS
>>> +     select COMMON_CLK_C3_PLL
>>> +     help
>>> +       Support for the Peripherals clock controller on Amlogic C302X and
>>> +       C308L devices, AKA c3. Amlogic C302X and C308L devices include
>>> +       AW402, AW409 and AW419. Say Y if you want the peripherals clock
>>> +       to work.
>>> +
>>>   config COMMON_CLK_G12A
>>>        tristate "G12 and SM1 SoC clock controllers support"
>>>        depends on ARM64
>>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>>> index 4420af628b31..20ad9482c892 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_C3_PLL) += c3-pll.o
>>> +obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>>>   obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>>>   obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>>>   obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
>>> diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c
>>> new file mode 100644
>>> index 000000000000..2931cb20299a
>>> --- /dev/null
>>> +++ b/drivers/clk/meson/c3-peripherals.c
>>> @@ -0,0 +1,3096 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Amlogic C3 Peripherals Clock Controller Driver
>>> + *
>>> + * Copyright (c) 2023 Amlogic, inc.
>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>> + */
>>> +
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/clk.h>
>>> +#include "clk-regmap.h"
>>> +#include "clk-dualdiv.h"
>>> +#include "c3-peripherals.h"
>>> +#include "meson-clkc-utils.h"
>>> +#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
>>> +
>>> +static struct clk_regmap pll_in = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = OSCIN_CTRL,
>>> +             .bit_idx = 4,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pll_in",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_data = &(const struct clk_parent_data) {
>>> +                     .fw_name = "xtal",
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mclk_pll_in = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = OSCIN_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "mclk_pll_in",
>>> +             .ops = &clk_regmap_gate_ro_ops,
>>> +             .parent_data = &(const struct clk_parent_data) {
>>> +                     .fw_name = "xtal",
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data rtc_xtal_clkin_parent = {
>>> +     .fw_name = "xtal",
>>> +};
>>> +
>>> +static struct clk_regmap rtc_xtal_clkin = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = RTC_BY_OSCIN_CTRL0,
>>> +             .bit_idx = 31,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "rtc_xtal_clkin",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_data = &rtc_xtal_clkin_parent,
>> Why can't you inline
>> 
> Will do
>>                  .parent_data = &(const struct clk_parent_data) {
>>                          .fw_name = "xtal",
>>                  },
>> like for the other clock ... please be consistent
>> 
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = {
>>> +     { 733, 732, 8, 11, 1 },
>>> +     { /* sentinel */ }
>>> +};
>>> +
>>> +static struct clk_regmap rtc_32k_div = {
>>> +     .data = &(struct meson_clk_dualdiv_data){
>>> +             .n1 = {
>>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>>> +                     .shift   = 0,
>>> +                     .width   = 12,
>>> +             },
>>> +             .n2 = {
>>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>>> +                     .shift   = 12,
>>> +                     .width   = 12,
>>> +             },
>>> +             .m1 = {
>>> +                     .reg_off = RTC_BY_OSCIN_CTRL1,
>>> +                     .shift   = 0,
>>> +                     .width   = 12,
>>> +             },
>>> +             .m2 = {
>>> +                     .reg_off = RTC_BY_OSCIN_CTRL1,
>>> +                     .shift   = 12,
>>> +                     .width   = 12,
>>> +             },
>>> +             .dual = {
>>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>>> +                     .shift   = 28,
>>> +                     .width   = 1,
>>> +             },
>>> +             .table = rtc_32k_div_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "rtc_32k_div",
>>> +             .ops = &meson_clk_dualdiv_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &rtc_xtal_clkin.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data rtc_32k_mux_parent_data[] = {
>>> +     { .hw = &rtc_32k_div.hw },
>>> +     { .hw = &rtc_xtal_clkin.hw }
>>> +};
>>> +
>>> +static struct clk_regmap rtc_32k_mux = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = RTC_BY_OSCIN_CTRL1,
>>> +             .mask = 0x1,
>>> +             .shift = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "rtc_32k_mux",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = rtc_32k_mux_parent_data,
>>> +             .num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data),
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap rtc_32k = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = RTC_BY_OSCIN_CTRL0,
>>> +             .bit_idx = 30,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "rtc_32k",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &rtc_32k_mux.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data rtc_clk_mux_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .hw = &rtc_32k.hw }
>>> +};
>>> +
>>> +static struct clk_regmap 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 = rtc_clk_mux_parent_data,
>>> +             .num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data),
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +/*
>>> + * Some clocks have multiple clock sources, and the parent clock and index are
>>> + * discontinuous, Some channels corresponding to the clock index are not
>>> + * actually connected inside the chip, or the clock source is invalid.
>>> + */
>>> +
>>> +static u32 sys_axi_parent_table[] = { 0, 2, 3, 4, 7 };
>>> +
>>> +static const struct clk_parent_data sys_axi_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .hw = &rtc_clk.hw }
>>> +};
>>> +
>>> +static struct clk_regmap sys_a_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SYS_CLK_CTRL0,
>>> +             .mask = 0x7,
>>> +             .shift = 10,
>>> +             .table = sys_axi_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sys_a_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = sys_axi_parent_data,
>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sys_a_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SYS_CLK_CTRL0,
>>> +             .shift = 0,
>>> +             .width = 10,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sys_a_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sys_a_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sys_a = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SYS_CLK_CTRL0,
>>> +             .bit_idx = 13,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "sys_a",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sys_a_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_IGNORE_UNUSED,
>> As usual, a comment is expected when using CLK_IGNORE_UNUSED.
>> It is very often not appropriate or justified.
>> Same goes for the other instances
>> 
> Will do.
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sys_b_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SYS_CLK_CTRL0,
>>> +             .mask = 0x7,
>>> +             .shift = 26,
>>> +             .table = sys_axi_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sys_b_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = sys_axi_parent_data,
>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sys_b_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SYS_CLK_CTRL0,
>>> +             .shift = 16,
>>> +             .width = 10,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sys_b_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sys_b_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sys_b = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SYS_CLK_CTRL0,
>>> +             .bit_idx = 29,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "sys_b",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sys_b_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_IGNORE_UNUSED,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data sys_clk_parent_data[] = {
>>> +     { .hw = &sys_a.hw },
>>> +     { .hw = &sys_b.hw }
>>> +};
>>> +
>>> +static struct clk_regmap sys_clk = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SYS_CLK_CTRL0,
>>> +             .mask = 0x1,
>>> +             .shift = 15,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sys_clk",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = sys_clk_parent_data,
>>> +             .num_parents = ARRAY_SIZE(sys_clk_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap axi_a_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = AXI_CLK_CTRL0,
>>> +             .mask = 0x7,
>>> +             .shift = 10,
>>> +             .table = sys_axi_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "axi_a_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = sys_axi_parent_data,
>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap axi_a_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = AXI_CLK_CTRL0,
>>> +             .shift = 0,
>>> +             .width = 10,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "axi_a_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &axi_a_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap axi_a = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = AXI_CLK_CTRL0,
>>> +             .bit_idx = 13,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "axi_a",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &axi_a_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_IGNORE_UNUSED,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap axi_b_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = AXI_CLK_CTRL0,
>>> +             .mask = 0x7,
>>> +             .shift = 26,
>>> +             .table = sys_axi_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "axi_b_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = sys_axi_parent_data,
>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap axi_b_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = AXI_CLK_CTRL0,
>>> +             .shift = 16,
>>> +             .width = 10,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "axi_b_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &axi_b_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap axi_b = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = AXI_CLK_CTRL0,
>>> +             .bit_idx = 29,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "axi_b",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &axi_b_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_IGNORE_UNUSED,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data axi_clk_parent_data[] = {
>>> +     { .hw = &axi_a.hw },
>>> +     { .hw = &axi_b.hw }
>>> +};
>>> +
>>> +static struct clk_regmap axi_clk = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = AXI_CLK_CTRL0,
>>> +             .mask = 0x1,
>>> +             .shift = 15,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "axi_clk",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = axi_clk_parent_data,
>>> +             .num_parents = ARRAY_SIZE(axi_clk_parent_data),
>>> +     },
>>> +};
>>> +
>>> +#define AML_CLK_GATE_SYS_CLK(_name, _reg, _bit)\
>>> +     MESON_PCLK(_name, _reg, _bit, &sys_clk.hw)
>>> +#define AML_CLK_GATE_AXI_CLK(_name, _reg, _bit)\
>>> +     MESON_PCLK(_name, _reg, _bit, &axi_clk.hw)
>>> +
>>> +AML_CLK_GATE_SYS_CLK(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3);
>>> +AML_CLK_GATE_SYS_CLK(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4);
>>> +AML_CLK_GATE_SYS_CLK(sys_ctrl, SYS_CLK_EN0_REG0, 5);
>>> +AML_CLK_GATE_SYS_CLK(sys_ts_pll, SYS_CLK_EN0_REG0, 6);
>>> +AML_CLK_GATE_SYS_CLK(sys_dev_arb, SYS_CLK_EN0_REG0, 7);
>>> +AML_CLK_GATE_SYS_CLK(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
>>> +AML_CLK_GATE_SYS_CLK(sys_capu, SYS_CLK_EN0_REG0, 9);
>>> +AML_CLK_GATE_SYS_CLK(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11);
>>> +AML_CLK_GATE_SYS_CLK(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12);
>>> +AML_CLK_GATE_SYS_CLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13);
>>> +AML_CLK_GATE_SYS_CLK(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14);
>>> +AML_CLK_GATE_SYS_CLK(sys_msr_clk, SYS_CLK_EN0_REG0, 15);
>>> +AML_CLK_GATE_SYS_CLK(sys_rom, SYS_CLK_EN0_REG0, 16);
>>> +AML_CLK_GATE_SYS_CLK(sys_uart_f, SYS_CLK_EN0_REG0, 17);
>>> +AML_CLK_GATE_SYS_CLK(sys_cpu_apb, SYS_CLK_EN0_REG0, 18);
>>> +AML_CLK_GATE_SYS_CLK(sys_rsa, SYS_CLK_EN0_REG0, 19);
>>> +AML_CLK_GATE_SYS_CLK(sys_sar_adc, SYS_CLK_EN0_REG0, 20);
>>> +AML_CLK_GATE_SYS_CLK(sys_startup, SYS_CLK_EN0_REG0, 21);
>>> +AML_CLK_GATE_SYS_CLK(sys_secure, SYS_CLK_EN0_REG0, 22);
>>> +AML_CLK_GATE_SYS_CLK(sys_spifc, SYS_CLK_EN0_REG0, 23);
>>> +AML_CLK_GATE_SYS_CLK(sys_nna, SYS_CLK_EN0_REG0, 25);
>>> +AML_CLK_GATE_SYS_CLK(sys_eth_mac, SYS_CLK_EN0_REG0, 26);
>>> +AML_CLK_GATE_SYS_CLK(sys_gic, SYS_CLK_EN0_REG0, 27);
>>> +AML_CLK_GATE_SYS_CLK(sys_rama, SYS_CLK_EN0_REG0, 28);
>>> +AML_CLK_GATE_SYS_CLK(sys_big_nic, SYS_CLK_EN0_REG0, 29);
>>> +AML_CLK_GATE_SYS_CLK(sys_ramb, SYS_CLK_EN0_REG0, 30);
>>> +AML_CLK_GATE_SYS_CLK(sys_audio_pclk, SYS_CLK_EN0_REG0, 31);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_kl, SYS_CLK_EN0_REG1, 0);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ij, SYS_CLK_EN0_REG1, 1);
>>> +AML_CLK_GATE_SYS_CLK(sys_usb, SYS_CLK_EN0_REG1, 2);
>>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3);
>>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ab, SYS_CLK_EN0_REG1, 5);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_cd, SYS_CLK_EN0_REG1, 6);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ef, SYS_CLK_EN0_REG1, 7);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_gh, SYS_CLK_EN0_REG1, 8);
>>> +AML_CLK_GATE_SYS_CLK(sys_spicc_1, SYS_CLK_EN0_REG1, 9);
>>> +AML_CLK_GATE_SYS_CLK(sys_spicc_0, SYS_CLK_EN0_REG1, 10);
>>> +AML_CLK_GATE_SYS_CLK(sys_uart_a, SYS_CLK_EN0_REG1, 11);
>>> +AML_CLK_GATE_SYS_CLK(sys_uart_b, SYS_CLK_EN0_REG1, 12);
>>> +AML_CLK_GATE_SYS_CLK(sys_uart_c, SYS_CLK_EN0_REG1, 13);
>>> +AML_CLK_GATE_SYS_CLK(sys_uart_d, SYS_CLK_EN0_REG1, 14);
>>> +AML_CLK_GATE_SYS_CLK(sys_uart_e, SYS_CLK_EN0_REG1, 15);
>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16);
>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17);
>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18);
>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19);
>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20);
>>> +AML_CLK_GATE_SYS_CLK(sys_rtc, SYS_CLK_EN0_REG1, 21);
>>> +AML_CLK_GATE_SYS_CLK(sys_ge2d, SYS_CLK_EN0_REG1, 22);
>>> +AML_CLK_GATE_SYS_CLK(sys_isp, SYS_CLK_EN0_REG1, 23);
>>> +AML_CLK_GATE_SYS_CLK(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24);
>>> +AML_CLK_GATE_SYS_CLK(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25);
>>> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26);
>>> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27);
>>> +AML_CLK_GATE_SYS_CLK(sys_eth_phy, SYS_CLK_EN0_REG1, 28);
>>> +AML_CLK_GATE_SYS_CLK(sys_acodec, SYS_CLK_EN0_REG1, 29);
>>> +AML_CLK_GATE_SYS_CLK(sys_dwap, SYS_CLK_EN0_REG1, 30);
>>> +AML_CLK_GATE_SYS_CLK(sys_dos, SYS_CLK_EN0_REG1, 31);
>>> +AML_CLK_GATE_SYS_CLK(sys_cve, SYS_CLK_EN0_REG2, 0);
>>> +AML_CLK_GATE_SYS_CLK(sys_vout, SYS_CLK_EN0_REG2, 1);
>>> +AML_CLK_GATE_SYS_CLK(sys_vc9000e, SYS_CLK_EN0_REG2, 2);
>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_mn, SYS_CLK_EN0_REG2, 3);
>>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4);
>>> +AML_CLK_GATE_AXI_CLK(axi_sys_nic, AXI_CLK_EN0, 2);
>>> +AML_CLK_GATE_AXI_CLK(axi_isp_nic, AXI_CLK_EN0, 3);
>>> +AML_CLK_GATE_AXI_CLK(axi_cve_nic, AXI_CLK_EN0, 4);
>>> +AML_CLK_GATE_AXI_CLK(axi_ramb, AXI_CLK_EN0, 5);
>>> +AML_CLK_GATE_AXI_CLK(axi_rama, AXI_CLK_EN0, 6);
>>> +AML_CLK_GATE_AXI_CLK(axi_cpu_dmc, AXI_CLK_EN0, 7);
>>> +AML_CLK_GATE_AXI_CLK(axi_nic, AXI_CLK_EN0, 8);
>>> +AML_CLK_GATE_AXI_CLK(axi_dma, AXI_CLK_EN0, 9);
>>> +AML_CLK_GATE_AXI_CLK(axi_mux_nic, AXI_CLK_EN0, 10);
>>> +AML_CLK_GATE_AXI_CLK(axi_capu, AXI_CLK_EN0, 11);
>>> +AML_CLK_GATE_AXI_CLK(axi_cve, AXI_CLK_EN0, 12);
>>> +AML_CLK_GATE_AXI_CLK(axi_dev1_dmc, AXI_CLK_EN0, 13);
>>> +AML_CLK_GATE_AXI_CLK(axi_dev0_dmc, AXI_CLK_EN0, 14);
>>> +AML_CLK_GATE_AXI_CLK(axi_dsp_dmc, AXI_CLK_EN0, 15);
>>> +
>>> +/*
>>> + * clk_12_24m model
>>> + *
>>> + *          |------|     |-----| clk_12m_24m |-----|
>>> + * xtal---->| gate |---->| div |------------>| pad |
>>> + *          |------|     |-----|             |-----|
>>> + */
>>> +static const struct clk_parent_data clk_12_24m_in_parent = {
>>> +     .fw_name = "xtal",
>>> +};
>> Can't inline that ?
>> 
> Will do.
>>> +
>>> +static struct clk_regmap 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 = &clk_12_24m_in_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 *[]) {
>>> +                     &clk_12_24m_in.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_pa]rent_data fclk_25m_div_parent = {
>>> +     .fw_name = "fixed_pll",
>>> +};
>>> +
>>> +static struct clk_regmap 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 = &fclk_25m_div_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 *[]) {
>>> +                     &fclk_25m_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +/* generate clock output */
>> That comment is not helping much ... what did you mean ?
>> 
> It seems superfluous, will delte it.
>>> +static u32 gen_parent_table[] = { 0, 1, 5, 7 };
>>> +
>>> +static const struct clk_parent_data gen_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .hw = &rtc_clk.hw },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "hifi_pll" }
>>> +};
>>> +
>>> +static struct clk_regmap gen_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = GEN_CLK_CTRL,
>>> +             .mask = 0x1f,
>>> +             .shift = 12,
>>> +             .table = gen_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "gen_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = gen_parent_data,
>>> +             .num_parents = ARRAY_SIZE(gen_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 *[]) {
>>> +                     &gen_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 *[]) {
>>> +                     &gen_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data saradc_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .hw = &sys_clk.hw }
>>> +};
>>> +
>>> +static struct clk_regmap saradc_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SAR_CLK_CTRL0,
>>> +             .mask = 0x1,
>>> +             .shift = 9,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "saradc_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = saradc_parent_data,
>>> +             .num_parents = ARRAY_SIZE(saradc_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap saradc_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SAR_CLK_CTRL0,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "saradc_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &saradc_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap saradc = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SAR_CLK_CTRL0,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "saradc",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &saradc_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 pwm_parent_table[] = { 0, 2, 3 };
>> What's pwm parent 1, why can't it be used ?
> This 1 corresponds to gp1 pll, which is currently dedicated to emmc.

Given that gp1 does not exist in your PLL controller, it is going to be
hard to dedicate it to eMMC ;)

>> 
>>> +
>>> +static const struct clk_parent_data pwm_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div3" }
>>> +};
>>> +
>>> +static struct clk_regmap pwm_a_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_AB_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 9,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_a_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_a_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_AB_CTRL,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_a_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_a_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_a = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_AB_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_a",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_a_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_b_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_AB_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 25,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_b_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_b_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_AB_CTRL,
>>> +             .shift = 16,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_b_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_b_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_b = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_AB_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_b",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_b_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_c_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_CD_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 9,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_c_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_c_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_CD_CTRL,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_c_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_c_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_c = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_CD_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_c",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_c_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_d_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_CD_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 25,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_d_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_d_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_CD_CTRL,
>>> +             .shift = 16,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_d_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_d_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_d = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_CD_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_d",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_d_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_e_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_EF_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 9,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_e_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_e_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_EF_CTRL,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_e_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_e_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_e = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_EF_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_e",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_e_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_f_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_EF_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 25,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_f_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_f_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_EF_CTRL,
>>> +             .shift = 16,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_f_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_f_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_f = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_EF_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_f",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_f_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_g_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_GH_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 9,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_g_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_g_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_GH_CTRL,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_g_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_g_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_g = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_GH_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_g",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_g_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_h_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_GH_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 25,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_h_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_h_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_GH_CTRL,
>>> +             .shift = 16,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_h_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_h_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_h = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_GH_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_h",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_h_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_i_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_IJ_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 9,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_i_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_i_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_IJ_CTRL,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_i_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_i_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_i = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_IJ_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_i",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_i_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_j_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_IJ_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 25,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_j_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_j_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_IJ_CTRL,
>>> +             .shift = 16,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_j_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_j_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_j = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_IJ_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_j",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_j_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_k_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_KL_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 9,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_k_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_k_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_KL_CTRL,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_k_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_k_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_k = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_KL_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_k",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_k_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_l_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_KL_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 25,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_l_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_l_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_KL_CTRL,
>>> +             .shift = 16,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_l_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_l_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_l = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_KL_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_l",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_l_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_m_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_MN_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 9,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_m_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_m_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_MN_CTRL,
>>> +             .shift = 0,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_m_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_m_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_m = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_MN_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_m",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_m_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_n_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = PWM_CLK_MN_CTRL,
>>> +             .mask = 0x3,
>>> +             .shift = 25,
>>> +             .table = pwm_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_n_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = pwm_parent_data,
>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_n_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = PWM_CLK_MN_CTRL,
>>> +             .shift = 16,
>>> +             .width = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "pwm_n_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_n_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap pwm_n = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = PWM_CLK_MN_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "pwm_n",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &pwm_n_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>> Judging by the number of repeated block, a properly defined macro would
>> be acceptable for the PWM block
>> 
> Will do.
>>> +
>>> +static const struct clk_parent_data spicc_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .hw = &sys_clk.hw },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div2" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "fclk_div7" }
>>> +};
>>> +
>>> +static struct clk_regmap spicc_a_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SPICC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "spicc_a_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = spicc_parent_data,
>>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap spicc_a_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SPICC_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 6,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "spicc_a_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &spicc_a_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap spicc_a = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SPICC_CLK_CTRL,
>>> +             .bit_idx = 6,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "spicc_a",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &spicc_a_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap spicc_b_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SPICC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 23,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "spicc_b_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = spicc_parent_data,
>>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap spicc_b_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SPICC_CLK_CTRL,
>>> +             .shift = 16,
>>> +             .width = 6,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "spicc_b_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &spicc_b_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap spicc_b = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SPICC_CLK_CTRL,
>>> +             .bit_idx = 22,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "spicc_b",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &spicc_b_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data spifc_parent_data[] = {
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "fclk_div2" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "fclk_div7" }
>>> +};
>>> +
>>> +static struct clk_regmap spifc_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SPIFC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "spifc_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = spifc_parent_data,
>>> +             .num_parents = ARRAY_SIZE(spifc_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap spifc_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SPIFC_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "spifc_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &spifc_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap spifc = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SPIFC_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "spifc",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &spifc_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 emmc_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>> What's 6 ? why can't it be used ?
>> 
>

No answer ?

>>> +
>>> +static const struct clk_parent_data emmc_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .fw_name = "fclk_div2" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "gp0_pll" }
>>> +};

Not seeing gp1 there ? why would you need to dedicate an GP pll for MMC
? Maybe I missing something but it seems to me the usual MMC rate are
acheivable with the fclks, especially 2p5.

>>> +
>>> +static struct clk_regmap sd_emmc_a_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SD_EMMC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +             .table = emmc_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sd_emmc_a_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = emmc_parent_data,
>>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_a_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SD_EMMC_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sd_emmc_a_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sd_emmc_a_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_a = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SD_EMMC_CLK_CTRL,
>>> +             .bit_idx = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "sd_emmc_a",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sd_emmc_a_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_b_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = SD_EMMC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 25,
>>> +             .table = emmc_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sd_emmc_b_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = emmc_parent_data,
>>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_b_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = SD_EMMC_CLK_CTRL,
>>> +             .shift = 16,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sd_emmc_b_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sd_emmc_b_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_b = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = SD_EMMC_CLK_CTRL,
>>> +             .bit_idx = 23,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "sd_emmc_b",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sd_emmc_b_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_c_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = NAND_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +             .table = emmc_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sd_emmc_c_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = emmc_parent_data,
>>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_c_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = NAND_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "sd_emmc_c_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sd_emmc_c_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap sd_emmc_c = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = NAND_CLK_CTRL,
>>> +             .bit_idx = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "sd_emmc_c",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &sd_emmc_c_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +/* temperature sensor */
>>> +static const struct clk_parent_data ts_parent = {
>>> +     .fw_name = "xtal",
>>> +};
>> same  ...
>> 
>>> +
>>> +static struct clk_regmap 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 = &ts_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 *[]) {
>>> +                     &ts_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data eth_parent = {
>>> +     .fw_name = "fclk_div2",
>>> +};
>>> +
>>> +static struct clk_fixed_factor eth_125m_div = {
>>> +     .mult = 1,
>>> +     .div = 8,
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "eth_125m_div",
>>> +             .ops = &clk_fixed_factor_ops,
>>> +             .parent_data = &eth_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 *[]) {
>>> +                     &eth_125m_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 = &eth_parent,
>>> +             .num_parents = 1,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap 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 *[]) {
>>> +                     &eth_rmii_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 mipi_dsi_meas_parent_table[] = { 0, 1, 2, 3, 5, 6, 7 };
>> What is 4 ? why can't it be used ?
>> 
>>> +
>>> +static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "fclk_div2" },
>>> +     { .fw_name = "fclk_div7" }
>>> +};
>>> +
>>> +static struct clk_regmap mipi_dsi_meas_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VDIN_MEAS_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 21,
>>> +             .table = mipi_dsi_meas_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mipi_dsi_meas_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = mipi_dsi_meas_parent_data,
>>> +             .num_parents = ARRAY_SIZE(mipi_dsi_meas_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mipi_dsi_meas_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VDIN_MEAS_CLK_CTRL,
>>> +             .shift = 12,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "mipi_dsi_meas_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mipi_dsi_meas_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap mipi_dsi_meas = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = VDIN_MEAS_CLK_CTRL,
>>> +             .bit_idx = 20,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "mipi_dsi_meas",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &mipi_dsi_meas_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 dsi_phy_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
>> What about 0 ?
>> 
>>> +
>>> +static const struct clk_parent_data dsi_phy_parent_data[] = {
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div2" },
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div7" }
>>> +};
>>> +
>>> +static struct clk_regmap dsi_phy_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 12,
>>> +             .table = dsi_phy_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "dsi_phy_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = dsi_phy_parent_data,
>>> +             .num_parents = ARRAY_SIZE(dsi_phy_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap dsi_phy_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "dsi_phy_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &dsi_phy_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap dsi_phy = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "dsi_phy",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &dsi_phy_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 vout_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
>> same
>> 
>>> +
>>> +static const struct clk_parent_data vout_parent_data[] = {
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div7" }
>>> +};
>>> +
>>> +static struct clk_regmap vout_mclk_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VOUTENC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +             .table = vout_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vout_mclk_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = vout_parent_data,
>>> +             .num_parents = ARRAY_SIZE(vout_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vout_mclk_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VOUTENC_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vout_mclk_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vout_mclk_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vout_mclk = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "vout_mclk",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vout_mclk_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vout_enc_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VOUTENC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 25,
>>> +             .table = vout_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vout_enc_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = vout_parent_data,
>>> +             .num_parents = ARRAY_SIZE(vout_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vout_enc_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VOUTENC_CLK_CTRL,
>>> +             .shift = 16,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vout_enc_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vout_enc_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vout_enc = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = VOUTENC_CLK_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "vout_enc",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vout_enc_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data hcodec_pre_parent_data[] = {
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "fclk_div7" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "xtal" }
>>> +};
>>> +
>>> +static struct clk_regmap hcodec_0_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VDEC_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "hcodec_0_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = hcodec_pre_parent_data,
>>> +             .num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap hcodec_0_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VDEC_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "hcodec_0_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &hcodec_0_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap hcodec_0 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = VDEC_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "hcodec_0",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &hcodec_0_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap hcodec_1_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VDEC3_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "hcodec_1_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = hcodec_pre_parent_data,
>>> +             .num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap hcodec_1_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VDEC3_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "hcodec_1_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &hcodec_1_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap hcodec_1 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = VDEC3_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "hcodec_1",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &hcodec_1_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data hcodec_parent_data[] = {
>>> +     { .hw = &hcodec_0.hw },
>>> +     { .hw = &hcodec_1.hw }
>>> +};
>>> +
>>> +
>> remove extra new lines
>> 
> Will do.
>>> +static struct clk_regmap hcodec = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VDEC3_CLK_CTRL,
>>> +             .mask = 0x1,
>>> +             .shift = 15,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "hcodec",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = hcodec_parent_data,
>>> +             .num_parents = ARRAY_SIZE(hcodec_parent_data),
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data vc9000e_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "fclk_div7" },
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "gp0_pll" }
>>> +};
>>> +
>>> +static struct clk_regmap vc9000e_aclk_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VC9000E_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vc9000e_aclk_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = vc9000e_parent_data,
>>> +             .num_parents = ARRAY_SIZE(vc9000e_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vc9000e_aclk_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VC9000E_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vc9000e_aclk_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vc9000e_aclk_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vc9000e_aclk = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = VC9000E_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "vc9000e_aclk",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vc9000e_aclk_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vc9000e_core_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VC9000E_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 25,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vc9000e_core_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = vc9000e_parent_data,
>>> +             .num_parents = ARRAY_SIZE(vc9000e_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vc9000e_core_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VC9000E_CLK_CTRL,
>>> +             .shift = 16,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vc9000e_core_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vc9000e_core_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vc9000e_core = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = VC9000E_CLK_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "vc9000e_core",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vc9000e_core_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 csi_phy_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>> Same here and all following instance
>> 
> This 1 corresponds to gp1 pll, which is currently dedicated to emmc.

No it is not. Again mainline drivers are slightly different from AML
fork you might be used to. No PLL is dedicated to the mmc driver.
Unless you can make a strong case for it, I don't think it will happen
in the near future.

>>> +
>>> +static const struct clk_parent_data csi_phy_parent_data[] = {
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "xtal" }
>>> +};
>>> +
>>> +static struct clk_regmap csi_phy0_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = ISP0_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 25,
>>> +             .table = csi_phy_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "csi_phy0_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = csi_phy_parent_data,
>>> +             .num_parents = ARRAY_SIZE(csi_phy_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap csi_phy0_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ISP0_CLK_CTRL,
>>> +             .shift = 16,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "csi_phy0_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &csi_phy0_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap csi_phy0 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ISP0_CLK_CTRL,
>>> +             .bit_idx = 24,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "csi_phy0",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &csi_phy0_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 dewarpa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>> +
>>> +static const struct clk_parent_data dewarpa_parent_data[] = {
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "fclk_div7" }
>>> +};
>>> +
>>> +static struct clk_regmap dewarpa_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = DEWARPA_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +             .table = dewarpa_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "dewarpa_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = dewarpa_parent_data,
>>> +             .num_parents = ARRAY_SIZE(dewarpa_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap dewarpa_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = DEWARPA_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "dewarpa_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &dewarpa_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap dewarpa = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = DEWARPA_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "dewarpa",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &dewarpa_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 isp_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>> +
>>> +static const struct clk_parent_data isp_parent_data[] = {
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "xtal" }
>>> +};
>>> +
>>> +static struct clk_regmap isp0_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = ISP0_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +             .table = isp_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "isp0_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = isp_parent_data,
>>> +             .num_parents = ARRAY_SIZE(isp_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap isp0_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = ISP0_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "isp0_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &isp0_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap isp0 = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = ISP0_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "isp0",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &isp0_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 nna_core_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>> +
>>> +static const struct clk_parent_data nna_core_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "fclk_div2" },
>>> +     { .fw_name = "hifi_pll" }
>>> +};
>>> +
>>> +static struct clk_regmap nna_core_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = NNA_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +             .table = nna_core_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "nna_core_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = nna_core_parent_data,
>>> +             .num_parents = ARRAY_SIZE(nna_core_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap nna_core_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = NNA_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "nna_core_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &nna_core_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap nna_core = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = NNA_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "nna_core",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &nna_core_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static const struct clk_parent_data ge2d_parent_data[] = {
>>> +     { .fw_name = "xtal" },
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .hw = &rtc_clk.hw }
>>> +};
>>> +
>>> +static struct clk_regmap ge2d_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = GE2D_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "ge2d_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = ge2d_parent_data,
>>> +             .num_parents = ARRAY_SIZE(ge2d_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap ge2d_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = GE2D_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "ge2d_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &ge2d_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap ge2d = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = GE2D_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "ge2d",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &ge2d_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static u32 c3_vapb_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>> +
>>> +static const struct clk_parent_data vapb_parent_data[] = {
>>> +     { .fw_name = "fclk_div2p5" },
>>> +     { .fw_name = "fclk_div3" },
>>> +     { .fw_name = "fclk_div4" },
>>> +     { .fw_name = "fclk_div5" },
>>> +     { .fw_name = "gp0_pll" },
>>> +     { .fw_name = "hifi_pll" },
>>> +     { .fw_name = "xtal" }
>>> +};
>>> +
>>> +static struct clk_regmap vapb_sel = {
>>> +     .data = &(struct clk_regmap_mux_data){
>>> +             .offset = VAPB_CLK_CTRL,
>>> +             .mask = 0x7,
>>> +             .shift = 9,
>>> +             .table = c3_vapb_parent_table,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vapb_sel",
>>> +             .ops = &clk_regmap_mux_ops,
>>> +             .parent_data = vapb_parent_data,
>>> +             .num_parents = ARRAY_SIZE(vapb_parent_data),
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vapb_div = {
>>> +     .data = &(struct clk_regmap_div_data){
>>> +             .offset = VAPB_CLK_CTRL,
>>> +             .shift = 0,
>>> +             .width = 7,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data){
>>> +             .name = "vapb_div",
>>> +             .ops = &clk_regmap_divider_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vapb_sel.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_regmap vapb = {
>>> +     .data = &(struct clk_regmap_gate_data){
>>> +             .offset = VAPB_CLK_CTRL,
>>> +             .bit_idx = 8,
>>> +     },
>>> +     .hw.init = &(struct clk_init_data) {
>>> +             .name = "vapb",
>>> +             .ops = &clk_regmap_gate_ops,
>>> +             .parent_hws = (const struct clk_hw *[]) {
>>> +                     &vapb_div.hw
>>> +             },
>>> +             .num_parents = 1,
>>> +             .flags = CLK_SET_RATE_PARENT,
>>> +     },
>>> +};
>>> +
>>> +static struct clk_hw *c3_periphs_hw_clks[] = {
>>> +     [CLKID_PLL_IN]                  = &pll_in.hw,
>>> +     [CLKID_MCLK_PLL_IN]             = &mclk_pll_in.hw,
>>> +     [CLKID_RTC_XTAL_CLKIN]          = &rtc_xtal_clkin.hw,
>>> +     [CLKID_RTC_32K_DIV]             = &rtc_32k_div.hw,
>>> +     [CLKID_RTC_32K_MUX]             = &rtc_32k_mux.hw,
>>> +     [CLKID_RTC_32K]                 = &rtc_32k.hw,
>>> +     [CLKID_RTC_CLK]                 = &rtc_clk.hw,
>>> +     [CLKID_SYS_A_SEL]               = &sys_a_sel.hw,
>>> +     [CLKID_SYS_A_DIV]               = &sys_a_div.hw,
>>> +     [CLKID_SYS_A]                   = &sys_a.hw,
>>> +     [CLKID_SYS_B_SEL]               = &sys_b_sel.hw,
>>> +     [CLKID_SYS_B_DIV]               = &sys_b_div.hw,
>>> +     [CLKID_SYS_B]                   = &sys_b.hw,
>>> +     [CLKID_SYS_CLK]                 = &sys_clk.hw,
>>> +     [CLKID_AXI_A_SEL]               = &axi_a_sel.hw,
>>> +     [CLKID_AXI_A_DIV]               = &axi_a_div.hw,
>>> +     [CLKID_AXI_A]                   = &axi_a.hw,
>>> +     [CLKID_AXI_B_SEL]               = &axi_b_sel.hw,
>>> +     [CLKID_AXI_B_DIV]               = &axi_b_div.hw,
>>> +     [CLKID_AXI_B]                   = &axi_b.hw,
>>> +     [CLKID_AXI_CLK]                 = &axi_clk.hw,
>>> +     [CLKID_SYS_RESET_CTRL]          = &sys_reset_ctrl.hw,
>>> +     [CLKID_SYS_PAD_CTRL]            = &sys_pwr_ctrl.hw,
>>> +     [CLKID_SYS_CTRL]                = &sys_ctrl.hw,
>>> +     [CLKID_SYS_TS_PLL]              = &sys_ts_pll.hw,
>>> +     [CLKID_SYS_DEV_ARB]             = &sys_dev_arb.hw,
>>> +     [CLKID_SYS_MMC_PCLK]            = &sys_mmc_pclk.hw,
>>> +     [CLKID_SYS_CAPU]                = &sys_capu.hw,
>>> +     [CLKID_SYS_CPU_CTRL]            = &sys_cpu_ctrl.hw,
>>> +     [CLKID_SYS_JTAG_CTRL]           = &sys_jtag_ctrl.hw,
>>> +     [CLKID_SYS_IR_CTRL]             = &sys_ir_ctrl.hw,
>>> +     [CLKID_SYS_IRQ_CTRL]            = &sys_irq_ctrl.hw,
>>> +     [CLKID_SYS_MSR_CLK]             = &sys_msr_clk.hw,
>>> +     [CLKID_SYS_ROM]                 = &sys_rom.hw,
>>> +     [CLKID_SYS_UART_F]              = &sys_uart_f.hw,
>>> +     [CLKID_SYS_CPU_ARB]             = &sys_cpu_apb.hw,
>>> +     [CLKID_SYS_RSA]                 = &sys_rsa.hw,
>>> +     [CLKID_SYS_SAR_ADC]             = &sys_sar_adc.hw,
>>> +     [CLKID_SYS_STARTUP]             = &sys_startup.hw,
>>> +     [CLKID_SYS_SECURE]              = &sys_secure.hw,
>>> +     [CLKID_SYS_SPIFC]               = &sys_spifc.hw,
>>> +     [CLKID_SYS_NNA]                 = &sys_nna.hw,
>>> +     [CLKID_SYS_ETH_MAC]             = &sys_eth_mac.hw,
>>> +     [CLKID_SYS_GIC]                 = &sys_gic.hw,
>>> +     [CLKID_SYS_RAMA]                = &sys_rama.hw,
>>> +     [CLKID_SYS_BIG_NIC]             = &sys_big_nic.hw,
>>> +     [CLKID_SYS_RAMB]                = &sys_ramb.hw,
>>> +     [CLKID_SYS_AUDIO_PCLK]          = &sys_audio_pclk.hw,
>>> +     [CLKID_SYS_PWM_KL]              = &sys_pwm_kl.hw,
>>> +     [CLKID_SYS_PWM_IJ]              = &sys_pwm_ij.hw,
>>> +     [CLKID_SYS_USB]                 = &sys_usb.hw,
>>> +     [CLKID_SYS_SD_EMMC_A]           = &sys_sd_emmc_a.hw,
>>> +     [CLKID_SYS_SD_EMMC_C]           = &sys_sd_emmc_c.hw,
>>> +     [CLKID_SYS_PWM_AB]              = &sys_pwm_ab.hw,
>>> +     [CLKID_SYS_PWM_CD]              = &sys_pwm_cd.hw,
>>> +     [CLKID_SYS_PWM_EF]              = &sys_pwm_ef.hw,
>>> +     [CLKID_SYS_PWM_GH]              = &sys_pwm_gh.hw,
>>> +     [CLKID_SYS_SPICC_1]             = &sys_spicc_1.hw,
>>> +     [CLKID_SYS_SPICC_0]             = &sys_spicc_0.hw,
>>> +     [CLKID_SYS_UART_A]              = &sys_uart_a.hw,
>>> +     [CLKID_SYS_UART_B]              = &sys_uart_b.hw,
>>> +     [CLKID_SYS_UART_C]              = &sys_uart_c.hw,
>>> +     [CLKID_SYS_UART_D]              = &sys_uart_d.hw,
>>> +     [CLKID_SYS_UART_E]              = &sys_uart_e.hw,
>>> +     [CLKID_SYS_I2C_M_A]             = &sys_i2c_m_a.hw,
>>> +     [CLKID_SYS_I2C_M_B]             = &sys_i2c_m_b.hw,
>>> +     [CLKID_SYS_I2C_M_C]             = &sys_i2c_m_c.hw,
>>> +     [CLKID_SYS_I2C_M_D]             = &sys_i2c_m_d.hw,
>>> +     [CLKID_SYS_I2S_S_A]             = &sys_i2c_s_a.hw,
>>> +     [CLKID_SYS_RTC]                 = &sys_rtc.hw,
>>> +     [CLKID_SYS_GE2D]                = &sys_ge2d.hw,
>>> +     [CLKID_SYS_ISP]                 = &sys_isp.hw,
>>> +     [CLKID_SYS_GPV_ISP_NIC]         = &sys_gpv_isp_nic.hw,
>>> +     [CLKID_SYS_GPV_CVE_NIC]         = &sys_gpv_cve_nic.hw,
>>> +     [CLKID_SYS_MIPI_DSI_HOST]       = &sys_mipi_dsi_host.hw,
>>> +     [CLKID_SYS_MIPI_DSI_PHY]        = &sys_mipi_dsi_phy.hw,
>>> +     [CLKID_SYS_ETH_PHY]             = &sys_eth_phy.hw,
>>> +     [CLKID_SYS_ACODEC]              = &sys_acodec.hw,
>>> +     [CLKID_SYS_DWAP]                = &sys_dwap.hw,
>>> +     [CLKID_SYS_DOS]                 = &sys_dos.hw,
>>> +     [CLKID_SYS_CVE]                 = &sys_cve.hw,
>>> +     [CLKID_SYS_VOUT]                = &sys_vout.hw,
>>> +     [CLKID_SYS_VC9000E]             = &sys_vc9000e.hw,
>>> +     [CLKID_SYS_PWM_MN]              = &sys_pwm_mn.hw,
>>> +     [CLKID_SYS_SD_EMMC_B]           = &sys_sd_emmc_b.hw,
>>> +     [CLKID_AXI_SYS_NIC]             = &axi_sys_nic.hw,
>>> +     [CLKID_AXI_ISP_NIC]             = &axi_isp_nic.hw,
>>> +     [CLKID_AXI_CVE_NIC]             = &axi_cve_nic.hw,
>>> +     [CLKID_AXI_RAMB]                = &axi_ramb.hw,
>>> +     [CLKID_AXI_RAMA]                = &axi_rama.hw,
>>> +     [CLKID_AXI_CPU_DMC]             = &axi_cpu_dmc.hw,
>>> +     [CLKID_AXI_NIC]                 = &axi_nic.hw,
>>> +     [CLKID_AXI_DMA]                 = &axi_dma.hw,
>>> +     [CLKID_AXI_MUX_NIC]             = &axi_mux_nic.hw,
>>> +     [CLKID_AXI_CAPU]                = &axi_capu.hw,
>>> +     [CLKID_AXI_CVE]                 = &axi_cve.hw,
>>> +     [CLKID_AXI_DEV1_DMC]            = &axi_dev1_dmc.hw,
>>> +     [CLKID_AXI_DEV0_DMC]            = &axi_dev0_dmc.hw,
>>> +     [CLKID_AXI_DSP_DMC]             = &axi_dsp_dmc.hw,
>>> +     [CLKID_12_24M_IN]               = &clk_12_24m_in.hw,
>>> +     [CLKID_12M_24M]                 = &clk_12_24m.hw,
>>> +     [CLKID_FCLK_25M_DIV]            = &fclk_25m_div.hw,
>>> +     [CLKID_FCLK_25M]                = &fclk_25m.hw,
>>> +     [CLKID_GEN_SEL]                 = &gen_sel.hw,
>>> +     [CLKID_GEN_DIV]                 = &gen_div.hw,
>>> +     [CLKID_GEN]                     = &gen.hw,
>>> +     [CLKID_SARADC_SEL]              = &saradc_sel.hw,
>>> +     [CLKID_SARADC_DIV]              = &saradc_div.hw,
>>> +     [CLKID_SARADC]                  = &saradc.hw,
>>> +     [CLKID_PWM_A_SEL]               = &pwm_a_sel.hw,
>>> +     [CLKID_PWM_A_DIV]               = &pwm_a_div.hw,
>>> +     [CLKID_PWM_A]                   = &pwm_a.hw,
>>> +     [CLKID_PWM_B_SEL]               = &pwm_b_sel.hw,
>>> +     [CLKID_PWM_B_DIV]               = &pwm_b_div.hw,
>>> +     [CLKID_PWM_B]                   = &pwm_b.hw,
>>> +     [CLKID_PWM_C_SEL]               = &pwm_c_sel.hw,
>>> +     [CLKID_PWM_C_DIV]               = &pwm_c_div.hw,
>>> +     [CLKID_PWM_C]                   = &pwm_c.hw,
>>> +     [CLKID_PWM_D_SEL]               = &pwm_d_sel.hw,
>>> +     [CLKID_PWM_D_DIV]               = &pwm_d_div.hw,
>>> +     [CLKID_PWM_D]                   = &pwm_d.hw,
>>> +     [CLKID_PWM_E_SEL]               = &pwm_e_sel.hw,
>>> +     [CLKID_PWM_E_DIV]               = &pwm_e_div.hw,
>>> +     [CLKID_PWM_E]                   = &pwm_e.hw,
>>> +     [CLKID_PWM_F_SEL]               = &pwm_f_sel.hw,
>>> +     [CLKID_PWM_F_DIV]               = &pwm_f_div.hw,
>>> +     [CLKID_PWM_F]                   = &pwm_f.hw,
>>> +     [CLKID_PWM_G_SEL]               = &pwm_g_sel.hw,
>>> +     [CLKID_PWM_G_DIV]               = &pwm_g_div.hw,
>>> +     [CLKID_PWM_G]                   = &pwm_g.hw,
>>> +     [CLKID_PWM_H_SEL]               = &pwm_h_sel.hw,
>>> +     [CLKID_PWM_H_DIV]               = &pwm_h_div.hw,
>>> +     [CLKID_PWM_H]                   = &pwm_h.hw,
>>> +     [CLKID_PWM_I_SEL]               = &pwm_i_sel.hw,
>>> +     [CLKID_PWM_I_DIV]               = &pwm_i_div.hw,
>>> +     [CLKID_PWM_I]                   = &pwm_i.hw,
>>> +     [CLKID_PWM_J_SEL]               = &pwm_j_sel.hw,
>>> +     [CLKID_PWM_J_DIV]               = &pwm_j_div.hw,
>>> +     [CLKID_PWM_J]                   = &pwm_j.hw,
>>> +     [CLKID_PWM_K_SEL]               = &pwm_k_sel.hw,
>>> +     [CLKID_PWM_K_DIV]               = &pwm_k_div.hw,
>>> +     [CLKID_PWM_K]                   = &pwm_k.hw,
>>> +     [CLKID_PWM_L_SEL]               = &pwm_l_sel.hw,
>>> +     [CLKID_PWM_L_DIV]               = &pwm_l_div.hw,
>>> +     [CLKID_PWM_L]                   = &pwm_l.hw,
>>> +     [CLKID_PWM_M_SEL]               = &pwm_m_sel.hw,
>>> +     [CLKID_PWM_M_DIV]               = &pwm_m_div.hw,
>>> +     [CLKID_PWM_M]                   = &pwm_m.hw,
>>> +     [CLKID_PWM_N_SEL]               = &pwm_n_sel.hw,
>>> +     [CLKID_PWM_N_DIV]               = &pwm_n_div.hw,
>>> +     [CLKID_PWM_N]                   = &pwm_n.hw,
>>> +     [CLKID_SPICC_A_SEL]             = &spicc_a_sel.hw,
>>> +     [CLKID_SPICC_A_DIV]             = &spicc_a_div.hw,
>>> +     [CLKID_SPICC_A]                 = &spicc_a.hw,
>>> +     [CLKID_SPICC_B_SEL]             = &spicc_b_sel.hw,
>>> +     [CLKID_SPICC_B_DIV]             = &spicc_b_div.hw,
>>> +     [CLKID_SPICC_B]                 = &spicc_b.hw,
>>> +     [CLKID_SPIFC_SEL]               = &spifc_sel.hw,
>>> +     [CLKID_SPIFC_DIV]               = &spifc_div.hw,
>>> +     [CLKID_SPIFC]                   = &spifc.hw,
>>> +     [CLKID_SD_EMMC_A_SEL]           = &sd_emmc_a_sel.hw,
>>> +     [CLKID_SD_EMMC_A_DIV]           = &sd_emmc_a_div.hw,
>>> +     [CLKID_SD_EMMC_A]               = &sd_emmc_a.hw,
>>> +     [CLKID_SD_EMMC_B_SEL]           = &sd_emmc_b_sel.hw,
>>> +     [CLKID_SD_EMMC_B_DIV]           = &sd_emmc_b_div.hw,
>>> +     [CLKID_SD_EMMC_B]               = &sd_emmc_b.hw,
>>> +     [CLKID_SD_EMMC_C_SEL]           = &sd_emmc_c_sel.hw,
>>> +     [CLKID_SD_EMMC_C_DIV]           = &sd_emmc_c_div.hw,
>>> +     [CLKID_SD_EMMC_C]               = &sd_emmc_c.hw,
>>> +     [CLKID_TS_DIV]                  = &ts_div.hw,
>>> +     [CLKID_TS]                      = &ts.hw,
>>> +     [CLKID_ETH_125M_DIV]            = &eth_125m_div.hw,
>>> +     [CLKID_ETH_125M]                = &eth_125m.hw,
>>> +     [CLKID_ETH_RMII_DIV]            = &eth_rmii_div.hw,
>>> +     [CLKID_ETH_RMII]                = &eth_rmii.hw,
>>> +     [CLKID_MIPI_DSI_MEAS_SEL]       = &mipi_dsi_meas_sel.hw,
>>> +     [CLKID_MIPI_DSI_MEAS_DIV]       = &mipi_dsi_meas_div.hw,
>>> +     [CLKID_MIPI_DSI_MEAS]           = &mipi_dsi_meas.hw,
>>> +     [CLKID_DSI_PHY_SEL]             = &dsi_phy_sel.hw,
>>> +     [CLKID_DSI_PHY_DIV]             = &dsi_phy_div.hw,
>>> +     [CLKID_DSI_PHY]                 = &dsi_phy.hw,
>>> +     [CLKID_VOUT_MCLK_SEL]           = &vout_mclk_sel.hw,
>>> +     [CLKID_VOUT_MCLK_DIV]           = &vout_mclk_div.hw,
>>> +     [CLKID_VOUT_MCLK]               = &vout_mclk.hw,
>>> +     [CLKID_VOUT_ENC_SEL]            = &vout_enc_sel.hw,
>>> +     [CLKID_VOUT_ENC_DIV]            = &vout_enc_div.hw,
>>> +     [CLKID_VOUT_ENC]                = &vout_enc.hw,
>>> +     [CLKID_HCODEC_0_SEL]            = &hcodec_0_sel.hw,
>>> +     [CLKID_HCODEC_0_DIV]            = &hcodec_0_div.hw,
>>> +     [CLKID_HCODEC_0]                = &hcodec_0.hw,
>>> +     [CLKID_HCODEC_1_SEL]            = &hcodec_1_sel.hw,
>>> +     [CLKID_HCODEC_1_DIV]            = &hcodec_1_div.hw,
>>> +     [CLKID_HCODEC_1]                = &hcodec_1.hw,
>>> +     [CLKID_HCODEC]                  = &hcodec.hw,
>>> +     [CLKID_VC9000E_ACLK_SEL]        = &vc9000e_aclk_sel.hw,
>>> +     [CLKID_VC9000E_ACLK_DIV]        = &vc9000e_aclk_div.hw,
>>> +     [CLKID_VC9000E_ACLK]            = &vc9000e_aclk.hw,
>>> +     [CLKID_VC9000E_CORE_SEL]        = &vc9000e_core_sel.hw,
>>> +     [CLKID_VC9000E_CORE_DIV]        = &vc9000e_core_div.hw,
>>> +     [CLKID_VC9000E_CORE]            = &vc9000e_core.hw,
>>> +     [CLKID_CSI_PHY0_SEL]            = &csi_phy0_sel.hw,
>>> +     [CLKID_CSI_PHY0_DIV]            = &csi_phy0_div.hw,
>>> +     [CLKID_CSI_PHY0]                = &csi_phy0.hw,
>>> +     [CLKID_DEWARPA_SEL]             = &dewarpa_sel.hw,
>>> +     [CLKID_DEWARPA_DIV]             = &dewarpa_div.hw,
>>> +     [CLKID_DEWARPA]                 = &dewarpa.hw,
>>> +     [CLKID_ISP0_SEL]                = &isp0_sel.hw,
>>> +     [CLKID_ISP0_DIV]                = &isp0_div.hw,
>>> +     [CLKID_ISP0]                    = &isp0.hw,
>>> +     [CLKID_NNA_CORE_SEL]            = &nna_core_sel.hw,
>>> +     [CLKID_NNA_CORE_DIV]            = &nna_core_div.hw,
>>> +     [CLKID_NNA_CORE]                = &nna_core.hw,
>>> +     [CLKID_GE2D_SEL]                = &ge2d_sel.hw,
>>> +     [CLKID_GE2D_DIV]                = &ge2d_div.hw,
>>> +     [CLKID_GE2D]                    = &ge2d.hw,
>>> +     [CLKID_VAPB_SEL]                = &vapb_sel.hw,
>>> +     [CLKID_VAPB_DIV]                = &vapb_div.hw,
>>> +     [CLKID_VAPB]                    = &vapb.hw,
>>> +};
>>> +
>>> +/* Convenience table to populate regmap in .probe */
>>> +static struct clk_regmap *const c3_periphs_clk_regmaps[] = {
>>> +     &pll_in,
>>> +     &mclk_pll_in,
>>> +     &rtc_xtal_clkin,
>>> +     &rtc_32k_div,
>>> +     &rtc_32k_mux,
>>> +     &rtc_32k,
>>> +     &rtc_clk,
>>> +     &sys_a_sel,
>>> +     &sys_a_div,
>>> +     &sys_a,
>>> +     &sys_b_sel,
>>> +     &sys_b_div,
>>> +     &sys_b,
>>> +     &sys_clk,
>>> +     &axi_a_sel,
>>> +     &axi_a_div,
>>> +     &axi_a,
>>> +     &axi_b_sel,
>>> +     &axi_b_div,
>>> +     &axi_b,
>>> +     &axi_clk,
>>> +     &sys_reset_ctrl,
>>> +     &sys_pwr_ctrl,
>>> +     &sys_pad_ctrl,
>>> +     &sys_ctrl,
>>> +     &sys_ts_pll,
>>> +     &sys_dev_arb,
>>> +     &sys_mmc_pclk,
>>> +     &sys_capu,
>>> +     &sys_cpu_ctrl,
>>> +     &sys_jtag_ctrl,
>>> +     &sys_ir_ctrl,
>>> +     &sys_irq_ctrl,
>>> +     &sys_msr_clk,
>>> +     &sys_rom,
>>> +     &sys_uart_f,
>>> +     &sys_cpu_apb,
>>> +     &sys_rsa,
>>> +     &sys_sar_adc,
>>> +     &sys_startup,
>>> +     &sys_secure,
>>> +     &sys_spifc,
>>> +     &sys_nna,
>>> +     &sys_eth_mac,
>>> +     &sys_gic,
>>> +     &sys_rama,
>>> +     &sys_big_nic,
>>> +     &sys_ramb,
>>> +     &sys_audio_pclk,
>>> +     &sys_pwm_kl,
>>> +     &sys_pwm_ij,
>>> +     &sys_usb,
>>> +     &sys_sd_emmc_a,
>>> +     &sys_sd_emmc_c,
>>> +     &sys_pwm_ab,
>>> +     &sys_pwm_cd,
>>> +     &sys_pwm_ef,
>>> +     &sys_pwm_gh,
>>> +     &sys_spicc_1,
>>> +     &sys_spicc_0,
>>> +     &sys_uart_a,
>>> +     &sys_uart_b,
>>> +     &sys_uart_c,
>>> +     &sys_uart_d,
>>> +     &sys_uart_e,
>>> +     &sys_i2c_m_a,
>>> +     &sys_i2c_m_b,
>>> +     &sys_i2c_m_c,
>>> +     &sys_i2c_m_d,
>>> +     &sys_i2c_s_a,
>>> +     &sys_rtc,
>>> +     &sys_ge2d,
>>> +     &sys_isp,
>>> +     &sys_gpv_isp_nic,
>>> +     &sys_gpv_cve_nic,
>>> +     &sys_mipi_dsi_host,
>>> +     &sys_mipi_dsi_phy,
>>> +     &sys_eth_phy,
>>> +     &sys_acodec,
>>> +     &sys_dwap,
>>> +     &sys_dos,
>>> +     &sys_cve,
>>> +     &sys_vout,
>>> +     &sys_vc9000e,
>>> +     &sys_pwm_mn,
>>> +     &sys_sd_emmc_b,
>>> +     &axi_sys_nic,
>>> +     &axi_isp_nic,
>>> +     &axi_cve_nic,
>>> +     &axi_ramb,
>>> +     &axi_rama,
>>> +     &axi_cpu_dmc,
>>> +     &axi_nic,
>>> +     &axi_dma,
>>> +     &axi_mux_nic,
>>> +     &axi_capu,
>>> +     &axi_cve,
>>> +     &axi_dev1_dmc,
>>> +     &axi_dev0_dmc,
>>> +     &axi_dsp_dmc,
>>> +     &clk_12_24m_in,
>>> +     &clk_12_24m,
>>> +     &fclk_25m_div,
>>> +     &fclk_25m,
>>> +     &gen_sel,
>>> +     &gen_div,
>>> +     &gen,
>>> +     &saradc_sel,
>>> +     &saradc_div,
>>> +     &saradc,
>>> +     &pwm_a_sel,
>>> +     &pwm_a_div,
>>> +     &pwm_a,
>>> +     &pwm_b_sel,
>>> +     &pwm_b_div,
>>> +     &pwm_b,
>>> +     &pwm_c_sel,
>>> +     &pwm_c_div,
>>> +     &pwm_c,
>>> +     &pwm_d_sel,
>>> +     &pwm_d_div,
>>> +     &pwm_d,
>>> +     &pwm_e_sel,
>>> +     &pwm_e_div,
>>> +     &pwm_e,
>>> +     &pwm_f_sel,
>>> +     &pwm_f_div,
>>> +     &pwm_f,
>>> +     &pwm_g_sel,
>>> +     &pwm_g_div,
>>> +     &pwm_g,
>>> +     &pwm_h_sel,
>>> +     &pwm_h_div,
>>> +     &pwm_h,
>>> +     &pwm_i_sel,
>>> +     &pwm_i_div,
>>> +     &pwm_i,
>>> +     &pwm_j_sel,
>>> +     &pwm_j_div,
>>> +     &pwm_j,
>>> +     &pwm_k_sel,
>>> +     &pwm_k_div,
>>> +     &pwm_k,
>>> +     &pwm_l_sel,
>>> +     &pwm_l_div,
>>> +     &pwm_l,
>>> +     &pwm_m_sel,
>>> +     &pwm_m_div,
>>> +     &pwm_m,
>>> +     &pwm_n_sel,
>>> +     &pwm_n_div,
>>> +     &pwm_n,
>>> +     &spicc_a_sel,
>>> +     &spicc_a_div,
>>> +     &spicc_a,
>>> +     &spicc_b_sel,
>>> +     &spicc_b_div,
>>> +     &spicc_b,
>>> +     &spifc_sel,
>>> +     &spifc_div,
>>> +     &spifc,
>>> +     &sd_emmc_a_sel,
>>> +     &sd_emmc_a_div,
>>> +     &sd_emmc_a,
>>> +     &sd_emmc_b_sel,
>>> +     &sd_emmc_b_div,
>>> +     &sd_emmc_b,
>>> +     &sd_emmc_c_sel,
>>> +     &sd_emmc_c_div,
>>> +     &sd_emmc_c,
>>> +     &ts_div,
>>> +     &ts,
>>> +     &eth_125m,
>>> +     &eth_rmii_div,
>>> +     &eth_rmii,
>>> +     &mipi_dsi_meas_sel,
>>> +     &mipi_dsi_meas_div,
>>> +     &mipi_dsi_meas,
>>> +     &dsi_phy_sel,
>>> +     &dsi_phy_div,
>>> +     &dsi_phy,
>>> +     &vout_mclk_sel,
>>> +     &vout_mclk_div,
>>> +     &vout_mclk,
>>> +     &vout_enc_sel,
>>> +     &vout_enc_div,
>>> +     &vout_enc,
>>> +     &hcodec_0_sel,
>>> +     &hcodec_0_div,
>>> +     &hcodec_0,
>>> +     &hcodec_1_sel,
>>> +     &hcodec_1_div,
>>> +     &hcodec_1,
>>> +     &hcodec,
>>> +     &vc9000e_aclk_sel,
>>> +     &vc9000e_aclk_div,
>>> +     &vc9000e_aclk,
>>> +     &vc9000e_core_sel,
>>> +     &vc9000e_core_div,
>>> +     &vc9000e_core,
>>> +     &csi_phy0_sel,
>>> +     &csi_phy0_div,
>>> +     &csi_phy0,
>>> +     &dewarpa_sel,
>>> +     &dewarpa_div,
>>> +     &dewarpa,
>>> +     &isp0_sel,
>>> +     &isp0_div,
>>> +     &isp0,
>>> +     &nna_core_sel,
>>> +     &nna_core_div,
>>> +     &nna_core,
>>> +     &ge2d_sel,
>>> +     &ge2d_div,
>>> +     &ge2d,
>>> +     &vapb_sel,
>>> +     &vapb_div,
>>> +     &vapb,
>>> +};
>>> +
>>> +static struct regmap_config clkc_regmap_config = {
>>> +     .reg_bits       = 32,
>>> +     .val_bits       = 32,
>>> +     .reg_stride     = 4,
>>> +};
>>> +
>>> +static struct meson_clk_hw_data c3_periphs_clks = {
>>> +     .hws = c3_periphs_hw_clks,
>>> +     .num = ARRAY_SIZE(c3_periphs_hw_clks),
>>> +};
>>> +
>>> +static int aml_c3_peripherals_probe(struct platform_device *pdev)
>>> +{
>>> +     struct device *dev = &pdev->dev;
>>> +     struct regmap *regmap;
>>> +     void __iomem *base;
>>> +     int clkid, ret, i;
>>> +
>>> +     base = devm_platform_ioremap_resource(pdev, 0);
>>> +     if (IS_ERR(base))
>>> +             return PTR_ERR(base);
>>> +
>>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>>> +     if (IS_ERR(regmap))
>>> +             return PTR_ERR(regmap);
>>> +
>>> +     /* Populate regmap for the regmap backed clocks */
>>> +     for (i = 0; i < ARRAY_SIZE(c3_periphs_clk_regmaps); i++)
>>> +             c3_periphs_clk_regmaps[i]->map = regmap;
>>> +
>>> +     for (clkid = 0; clkid < c3_periphs_clks.num; clkid++) {
>>> +             /* array might be sparse */
>>> +             if (!c3_periphs_clks.hws[clkid])
>>> +                     continue;
>>> +
>>> +             ret = devm_clk_hw_register(dev, c3_periphs_clks.hws[clkid]);
>>> +             if (ret) {
>>> +                     dev_err(dev, "Clock registration failed\n");
>>> +                     return ret;
>>> +             }
>>> +     }
>>> +
>>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>>> +                                        &c3_periphs_clks);
>>> +}
>>> +
>>> +static const struct of_device_id c3_peripherals_clkc_match_table[] = {
>>> +     {
>>> +             .compatible = "amlogic,c3-peripherals-clkc",
>>> +     },
>>> +     {}
>>> +};
>>> +
>>> +MODULE_DEVICE_TABLE(of, c3_peripherals_clkc_match_table);
>>> +
>>> +static struct platform_driver c3_peripherals_driver = {
>>> +     .probe          = aml_c3_peripherals_probe,
>>> +     .driver         = {
>>> +             .name   = "c3-peripherals-clkc",
>>> +             .of_match_table = c3_peripherals_clkc_match_table,
>>> +     },
>>> +};
>>> +
>>> +module_platform_driver(c3_peripherals_driver);
>>> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
>>> +MODULE_LICENSE("GPL");
>>> diff --git a/drivers/clk/meson/c3-peripherals.h b/drivers/clk/meson/c3-peripherals.h
>>> new file mode 100644
>>> index 000000000000..ddcc23e25669
>>> --- /dev/null
>>> +++ b/drivers/clk/meson/c3-peripherals.h
>>> @@ -0,0 +1,48 @@
>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>>> +/*
>>> + * Copyright (c) 2023 Amlogic, inc.
>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>> + */
>>> +
>>> +#ifndef __AML_C3_PERIPHERALS_H__
>>> +#define __AML_C3_PERIPHERALS_H__
>>> +
>>> +#define OSCIN_CTRL                           0x0004
>>> +#define RTC_BY_OSCIN_CTRL0                   0x0008
>>> +#define RTC_BY_OSCIN_CTRL1                   0x000c
>>> +#define RTC_CTRL                             0x0010
>>> +#define SYS_CLK_CTRL0                                0x0040
>>> +#define SYS_CLK_EN0_REG0                     0x0044
>>> +#define SYS_CLK_EN0_REG1                     0x0048
>>> +#define SYS_CLK_EN0_REG2                     0x004c
>>> +#define AXI_CLK_CTRL0                                0x006c
>>> +#define CLK12_24_CTRL                                0x00a8
>>> +#define AXI_CLK_EN0                          0x00ac
>>> +#define VDIN_MEAS_CLK_CTRL                   0x00f8
>>> +#define VAPB_CLK_CTRL                                0x00fc
>>> +#define MIPIDSI_PHY_CLK_CTRL                 0x0104
>>> +#define GE2D_CLK_CTRL                                0x010c
>>> +#define ISP0_CLK_CTRL                                0x0110
>>> +#define DEWARPA_CLK_CTRL                     0x0114
>>> +#define VOUTENC_CLK_CTRL                     0x0118
>>> +#define VDEC_CLK_CTRL                                0x0140
>>> +#define VDEC3_CLK_CTRL                               0x0148
>>> +#define TS_CLK_CTRL                          0x0158
>>> +#define ETH_CLK_CTRL                         0x0164
>>> +#define NAND_CLK_CTRL                                0x0168
>>> +#define SD_EMMC_CLK_CTRL                     0x016c
>>> +#define SPICC_CLK_CTRL                               0x0174
>>> +#define GEN_CLK_CTRL                         0x0178
>>> +#define SAR_CLK_CTRL0                                0x017c
>>> +#define PWM_CLK_AB_CTRL                              0x0180
>>> +#define PWM_CLK_CD_CTRL                              0x0184
>>> +#define PWM_CLK_EF_CTRL                              0x0188
>>> +#define PWM_CLK_GH_CTRL                              0x018c
>>> +#define PWM_CLK_IJ_CTRL                              0x0190
>>> +#define PWM_CLK_KL_CTRL                              0x0194
>>> +#define PWM_CLK_MN_CTRL                              0x0198
>>> +#define VC9000E_CLK_CTRL                     0x019c
>>> +#define SPIFC_CLK_CTRL                               0x01a0
>>> +#define NNA_CLK_CTRL                         0x0220
>> Nitpick - the extra zero is not needed
>> Since this is used only by c3 periph clkc - do you really need an header
>> or can it be defined in the related .c file ?
>> (I know this is a pattern we have been using so far, but it is not
>> really justified. No reason to continue with it)
>> 
>>> +
>>> +#endif  /* __AML_C3_PERIPHERALS_H__ */
>> 


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

* Re: [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock
  2023-10-17 13:06       ` Jerome Brunet
@ 2023-10-17 14:39         ` Chuan Liu
  2023-10-17 14:42           ` Jerome Brunet
  0 siblings, 1 reply; 27+ messages in thread
From: Chuan Liu @ 2023-10-17 14:39 UTC (permalink / raw)
  To: Jerome Brunet, Xianwei Zhao, linux-arm-kernel, linux-amlogic,
	linux-clk, devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl

Hi Jerome

     Thank you for your reply.

在 2023/10/17 21:06, Jerome Brunet 写道:
> [????????? jbrunet@baylibre.com ????????? https://aka.ms/LearnAboutSenderIdentification,????????????]
>
> [ EXTERNAL EMAIL ]
>
> On Tue 17 Oct 2023 at 14:15, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:
>
>> Hi Jerome,
>>
>>
>> On 2023/10/13 15:49, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>> On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com>
>>> wrote:
>>>
>>>> Add the C3 PLL clock controller driver for the Amlogic C3 SoC family.
>>>>
>>>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>>>> ---
>>>> V1 -> V2: Delete macro definition.
>>>> ---
>>>>    drivers/clk/meson/Kconfig  |  12 +
>>>>    drivers/clk/meson/Makefile |   1 +
>>>>    drivers/clk/meson/c3-pll.c | 808 +++++++++++++++++++++++++++++++++++++
>>>>    drivers/clk/meson/c3-pll.h |  35 ++
>>>>    4 files changed, 856 insertions(+)
>>>>    create mode 100644 drivers/clk/meson/c3-pll.c
>>>>    create mode 100644 drivers/clk/meson/c3-pll.h
>>>>
>>>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>>>> index c5303e4c1604..76be4bbd2afb 100644
>>>> --- a/drivers/clk/meson/Kconfig
>>>> +++ b/drivers/clk/meson/Kconfig
>>>> @@ -128,6 +128,18 @@ config COMMON_CLK_A1_PERIPHERALS
>>>>           device, A1 SoC Family. Say Y if you want A1 Peripherals clock
>>>>           controller to work.
>>>>
>>>> +config COMMON_CLK_C3_PLL
>>>> +     tristate "Amlogic C3 PLL clock controller"
>>>> +     default y
>>>> +     select COMMON_CLK_MESON_REGMAP
>>>> +     select COMMON_CLK_MESON_PLL
>>>> +     select COMMON_CLK_MESON_CLKC_UTILS
>>>> +     help
>>>> +       Support for the PLL clock controller on Amlogic C302X and C308L devices,
>>>> +       AKA c3. Amlogic C302X and C308L devices include AW402, AW409 and AW419.
>>>> +       Say Y if you want the board to work, because PLLs are the parent of most
>>>> +       peripherals.
>>>> +
>>>>    config COMMON_CLK_G12A
>>>>         tristate "G12 and SM1 SoC clock controllers support"
>>>>         depends on ARM64
>>>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>>>> index 9ee4b954c896..4420af628b31 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_C3_PLL) += c3-pll.o
>>>>    obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>>>>    obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>>>>    obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
>>>> diff --git a/drivers/clk/meson/c3-pll.c b/drivers/clk/meson/c3-pll.c
>>>> new file mode 100644
>>>> index 000000000000..97619bc7ab79
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/c3-pll.c
>>>> @@ -0,0 +1,808 @@
>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>> +/*
>>>> + * Amlogic C3 PLL Controller Driver
>>>> + *
>>>> + * Copyright (c) 2023 Amlogic, inc.
>>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>>> + */
>>>> +
>>>> +#include <linux/clk-provider.h>
>>>> +#include <linux/of_device.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/clk.h>
>>>> +#include "clk-regmap.h"
>>>> +#include "clk-pll.h"
>>>> +#include "c3-pll.h"
>>>> +#include "meson-clkc-utils.h"
>>>> +#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
>>>> +
>>>> +static const struct clk_parent_data pll_dco_parent = {
>>>> +     .fw_name = "pll_in",
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data mclk_pll_dco_parent = {
>>>> +     .fw_name = "mclk_pll_in",
>>>> +};
>>> I'm assuming this section relates to Documentation section 6.6.3.5 MPLL
>>> because all the fixed clock looks very familiar.
>>> Because of the naming of another clock below, I'm not quite sure. Please
>>> clarify
>>>
>> MPLL is not included in C3 SoC. Document was not updated to reflect this
>> change.
>> Mclk_Pll is  designed for sensor in C3 Soc.
>>>> +
>>>> +static struct clk_regmap fixed_pll_dco = {
>>>> +     .data = &(struct meson_clk_pll_data){
>>>> +             .en = {
>>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>>> +                     .shift   = 28,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .m = {
>>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 8,
>>>> +             },
>>>> +             .n = {
>>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>>> +                     .shift   = 16,
>>>> +                     .width   = 5,
>>>> +             },
>>>> +             .l = {
>>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>>> +                     .shift   = 31,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .rst = {
>>>> +                     .reg_off = ANACTRL_FIXPLL_CTRL0,
>>>> +                     .shift   = 29,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fixed_pll_dco",
>>>> +             .ops = &meson_clk_pll_ro_ops,
>>>> +             .parent_data = &pll_dco_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap fixed_pll = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL0,
>>>> +             .shift = 12,
>>>> +             .width = 3,
>>>> +             .flags = CLK_DIVIDER_POWER_OF_TWO,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fixed_pll",
>>>> +             .ops = &clk_regmap_divider_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll_dco.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>> Need a comment about why this is using RO ops
>>>
>> Will do.
>>
>>>> +
>>>> +static struct clk_fixed_factor fclk_div40_div = {
>>>> +     .mult = 1,
>>>> +     .div = 40,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fclk_div40_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap fclk_div40 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>> +             .bit_idx = 0,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "fclk_div40",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fclk_div40_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>> Don't see div40 in the diagram, where does it come from ?
>>> The div40 is  an alias of  fixpll_clk50m in sec 6.6.5.3 about FIXPLL.
> Then maybe clk50m something is better name for it
OK,Will be fixed in the next version
>
>>>> +
>>>> +static struct clk_fixed_factor fclk_div2_div = {
>>>> +     .mult = 1,
>>>> +     .div = 2,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fclk_div2_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap fclk_div2 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "fclk_div2",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fclk_div2_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_fixed_factor fclk_div2p5_div = {
>>>> +     .mult = 2,
>>>> +     .div = 5,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fclk_div2p5_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>> This one is wrong if I follow the doc.
>>> It is supposed to be fixed 8 divider taking it's source directly from
>>> the DCO, skipping the OD post divider ... assuming the doc is up to date.
>>>
>> No, C3 SoC div2p5 is not skipping the OD post divider.
> I a bit surprised there would be a frequency multiplier considering the
> complexity of it, when skiping a divider is possible HW wise. Are you
> sure ?
This part confirms with our chip design engineer that fclk_div2p5 here 
is actually a clock output by a divider with decimal (divider factor is 
2.5). The divider factor in clk-divider.c is int, so this description is 
used in the software. Or what do you suggest would be a better way to 
describe this type of divider with decimals?
>>>> +
>>>> +static struct clk_regmap fclk_div2p5 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>> +             .bit_idx = 4,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "fclk_div2p5",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fclk_div2p5_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_fixed_factor fclk_div3_div = {
>>>> +     .mult = 1,
>>>> +     .div = 3,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fclk_div3_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap fclk_div3 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>> +             .bit_idx = 20,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "fclk_div3",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fclk_div3_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_fixed_factor fclk_div4_div = {
>>>> +     .mult = 1,
>>>> +     .div = 4,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fclk_div4_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap fclk_div4 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>> +             .bit_idx = 21,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "fclk_div4",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fclk_div4_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_fixed_factor fclk_div5_div = {
>>>> +     .mult = 1,
>>>> +     .div = 5,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fclk_div5_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap fclk_div5 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>> +             .bit_idx = 22,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "fclk_div5",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fclk_div5_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_fixed_factor fclk_div7_div = {
>>>> +     .mult = 1,
>>>> +     .div = 7,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "fclk_div7_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fixed_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap fclk_div7 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>> +             .bit_idx = 23,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "fclk_div7",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &fclk_div7_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct reg_sequence c3_gp0_init_regs[] = {
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL1,  .def = 0x0 },
> This would change frac
>
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL2,  .def = 0x0 },
> This might be OK
>
>>> This should re-init GP0 rate on boot which is not desirable in case the
>>> bootloader had already set a rate (for splash screen for example)
>>> Sugguest you drop these
>> If I drop these ,set rate will be failed.
>> There are two differences between C3 SoC PLL and the previous SoC PLL.
>> It recommends reconfiguring PLL according to time sequence each time when
>> C3 PLL set rate. When previous SoC set rate, it set frequency related
>> parameters and  enable PLL after directly reset PLL about previous SoC.
>> When setting C3 PLL, you need to reset a pll lock rst bit, otherwise the
>> PLL lock bit will not refresh.
> 1. The amlogic off tree driver might using this for every set_rate() but
> upstream does not. this is only used for init.
> 2. We have a rst parameter explicitly for this. This bit is poked. It is
> part of the enable sequence.
>
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL3,  .def = 0x48681c00 },
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL4,  .def = 0x88770290 },
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL5,  .def = 0x3927200a },
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL6,  .def = 0x56540000, .delay_us = 10 },
> ---
>
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0x080304fa },
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0x380304fa, .delay_us = 10 },
>>>> +     { .reg = ANACTRL_GP0PLL_CTRL0,  .def = 0X180304fa }
> This definitely is not.
>
> For all I can tell, in addition to an hard coded rate,
> This disable 'en' and 'rst', put them back to 1 - wait 10us then disable
> rst again.
>
> On set_rate() here what the current driver would do with this (assuming
> the clock was enabled)
>
> - disable: rst 0 -> 1 ; en 1 -> 0;
> - set_rate : write m, n, and frac
> - enable: en 0 -> 1; rst 1 -> 0;
>
> If you think the current sequence used by clk-pll.c is not approriate,
> feel free to submit a patch.
Here's the background:
PLL design engineers suggest that it is best to reconfigure the 
corresponding registers each time the pll frequency is set to prevent 
extreme cases where pll lock may fail. At present, 
meson_clk_pll_set_rate() can also be configured properly before using 
the adaptation. The next version of this part will be adapted to the 
previous ops, and the clk-pll.c related patch will be submitted when 
there are problems in the future.
>>>> +};
>>>> +
>>>> +static const struct pll_params_table c3_gp0_pll_params_table[] = {
>>>> +     PLL_PARAMS(150, 1), /* DCO = 3600M */
>>>> +     PLL_PARAMS(130, 1), /* DCO = 3120M */
>>>> +     PLL_PARAMS(192, 1), /* DCO = 4608M */
>>>> +     PLL_PARAMS(125, 1), /* DCO = 3000M */
>>>> +     { /* sentinel */  }
>>>> +};
>>> Why can't C3 use mult_range for GP0, like the other SoC ?
>>> Doc says DCO can do 3 to 6GHz
>>>
>> The mult_range method is time-consuming and not suitable for scenarios
>> requiring high frequency cutting performance.
> Do you have numbers backing this up ?
>
> I might be wrong but I don't think going through the mult_range
> calculation is even a topic when you consider the time it takes to
> relock the PLL or the delay added in the sequence.
>
>> We generally only use a few commonly used frequencies.
> You do yes. A driver is about enabling the HW, not just what a set of
> people are doing with it.
Compared with set_rate() of table, muli_range takes longer time. In 
scenarios where the number of frequency points is small and performance 
requirements are strict, we use the table definition (for example, when 
sys_pll serves as the CPU clock source, the frequency needs to be 
dynamically switched quickly). muli_range can support more frequencies 
to adapt to a wider range of scenarios, considering that the next 
version will be adapted to muli_range
>>>> +
>>>> +/* The maximum frequency divider supports is 32, not 128(2^7) */
>>>> +static const struct clk_div_table c3_gp0_pll_od_table[] = {
>>>> +     { 0,  1 },
>>>> +     { 1,  2 },
>>>> +     { 2,  4 },
>>>> +     { 3,  8 },
>>>> +     { 4, 16 },
>>>> +     { 5, 32 },
>>>> +     { /* sentinel */ }
>>>> +};
>>> Please put that table next to the related divider
>>> Same for other instances
>>>
>> Will do.
>>>> +
>>>> +static struct clk_regmap gp0_pll_dco = {
>>>> +     .data = &(struct meson_clk_pll_data){
>>>> +             .en = {
>>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>>> +                     .shift   = 28,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .m = {
>>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 9,
>>>> +             },
>>>> +             .frac = {
>>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL1,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 19,
>>>> +             },
>>>> +             .n = {
>>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>>> +                     .shift   = 10,
>>>> +                     .width   = 5,
>>>> +             },
>>>> +             .l = {
>>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>>> +                     .shift   = 31,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .rst = {
>>>> +                     .reg_off = ANACTRL_GP0PLL_CTRL0,
>>>> +                     .shift   = 29,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .table = c3_gp0_pll_params_table,
>>>> +             .init_regs = c3_gp0_init_regs,
>>>> +             .init_count = ARRAY_SIZE(c3_gp0_init_regs),
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "gp0_pll_dco",
>>>> +             .ops = &meson_clk_pll_ops,
>>>> +             .parent_data = &pll_dco_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap gp0_pll = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ANACTRL_GP0PLL_CTRL0,
>>>> +             .shift = 16,
>>>> +             .width = 3,
>>>> +             .table = c3_gp0_pll_od_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "gp0_pll",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &gp0_pll_dco.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct reg_sequence c3_hifi_init_regs[] = {
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x08010496 },
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x38010496 },
>>> Same here, this an hidden hard coded rate init, with enable on top.
>>> Please drop this
>>> If you need a specific rate after the init, use assigned-rate in DT
>>>
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x0000ce40 },
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 },
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 },
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000, .delay_us = 50 },
>>>> +     { .reg = ANACTRL_HIFIPLL_CTRL0, .def = 0x18010496, .delay_us = 20 },
>>>> +};
>>>> +
>>>> +static const struct pll_params_table c3_hifi_pll_params_table[] = {
>>>> +     PLL_PARAMS(150, 1), /* DCO = 3600M */
>>>> +     PLL_PARAMS(130, 1), /* DCO = 3120M */
>>>> +     PLL_PARAMS(192, 1), /* DCO = 4608M */
>>>> +     PLL_PARAMS(125, 1), /* DCO = 3000M */
>>>> +     { /* sentinel */  }
>>>> +};
>>> Again, why can't HiFi use mult range ?
>>>
>> The mult_range method is time-consuming and not suitable for scenarios
>> requiring high frequency cutting performance.
> Again, I'd be curious how this can be a problem when considering the
> time it takes to reloc the PLL.
>
> How often do you relock a PLL for HiFi use cases ?
The next version will change to mult_range
>>>> +
>>>> +static struct clk_regmap hifi_pll_dco = {
>>>> +     .data = &(struct meson_clk_pll_data){
>>>> +             .en = {
>>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>>> +                     .shift   = 28,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .m = {
>>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 8,
>>>> +             },
>>>> +             .frac = {
>>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL1,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 19,
>>>> +             },
>>>> +             .n = {
>>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>>> +                     .shift   = 10,
>>>> +                     .width   = 5,
>>>> +             },
>>>> +             .l = {
>>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>>> +                     .shift   = 31,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .rst = {
>>>> +                     .reg_off = ANACTRL_HIFIPLL_CTRL0,
>>>> +                     .shift   = 29,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .table = c3_hifi_pll_params_table,
>>>> +             .init_regs = c3_hifi_init_regs,
>>>> +             .init_count = ARRAY_SIZE(c3_hifi_init_regs),
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "hifi_pll_dco",
>>>> +             .ops = &meson_clk_pll_ops,
>>>> +             .parent_data = &pll_dco_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap hifi_pll = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ANACTRL_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 *[]) {
>>>> +                     &hifi_pll_dco.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>> I cannot make out what all the mclk section below relates to in
>>> documentation clock. Could you please clarify ?
>>>
>>>> +static const struct reg_sequence c3_mclk_init_regs[] = {
>>>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x20011063 },
>>>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x30011063 },
>>> Again, hidden rate set on init ...
>>>
>>>> +     { .reg = ANACTRL_MPLL_CTRL1,    .def = 0x1420500f },
>>>> +     { .reg = ANACTRL_MPLL_CTRL2,    .def = 0x00023041 },
>>>> +     { .reg = ANACTRL_MPLL_CTRL3,    .def = 0x18180000 },
>>>> +     { .reg = ANACTRL_MPLL_CTRL0,    .def = 0x10011063 },
>>>> +     { .reg = ANACTRL_MPLL_CTRL2,    .def = 0x00023001 }
>>>> +};
>>>> +
>>>> +static const struct pll_params_table c3_mclk_pll_params_table[] = {
>>>> +     PLL_PARAMS(99, 1), /* VCO = 2376M */
>>>> +     { /* sentinel */  }
>>>> +};
>>>> +
>>>> +static const struct clk_div_table c3_mpll_od_table[] = {
>>>> +     { 0,  1 },
>>>> +     { 1,  2 },
>>>> +     { 2,  4 },
>>>> +     { 3,  8 },
>>>> +     { 4, 16 },
>>>> +     { /* sentinel */ }
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk_pll_dco = {
>>>> +     .data = &(struct meson_clk_pll_data){
>>>> +             .en = {
>>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>>> +                     .shift   = 28,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .m = {
>>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 9,
>>>> +             },
>>>> +             .n = {
>>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>>> +                     .shift   = 10,
>>>> +                     .width   = 5,
>>>> +             },
>>>> +             .l = {
>>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>>> +                     .shift   = 31,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .rst = {
>>>> +                     .reg_off = ANACTRL_MPLL_CTRL0,
>>>> +                     .shift   = 29,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .table = c3_mclk_pll_params_table,
>>>> +             .init_regs = c3_mclk_init_regs,
>>>> +             .init_count = ARRAY_SIZE(c3_mclk_init_regs),
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mclk_pll_dco",
>>>> +             .ops = &meson_clk_pll_ops,
>>>> +             .parent_data = &mclk_pll_dco_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk_pll = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL0,
>>>> +             .shift = 12,
>>>> +             .width = 3,
>>>> +             .table = c3_mpll_od_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mclk_pll",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk_pll_dco.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk_pll_clk = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .shift = 16,
>>>> +             .width = 5,
>>>> +             .flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mclk_pll_clk",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk_pll.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>> "mclk_pll" then "mclk_pll_clk" ... that is confusing
>>>
>> Maybe mclk_pll rename mclk_pll_od.>> +
>>>> +static const struct clk_parent_data mclk_parent[] = {
>>>> +     { .hw = &mclk_pll_clk.hw },
>>>> +     { .fw_name = "mclk_pll_in" },
>>>> +     { .hw = &fclk_div40.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk0_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .mask = 0x3,
>>>> +             .shift = 4,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mclk0_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = mclk_parent,
>>>> +             .num_parents = ARRAY_SIZE(mclk_parent),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk0_sel_out = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .bit_idx = 1,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "mclk0_sel_out",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk0_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk0_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .shift = 2,
>>>> +             .width = 1,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mclk0_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk0_sel_out.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk0 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .bit_idx = 0,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "mclk0",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk0_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk1_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .mask = 0x3,
>>>> +             .shift = 12,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mclk1_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = mclk_parent,
>>>> +             .num_parents = ARRAY_SIZE(mclk_parent),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk1_sel_out = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .bit_idx = 9,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "mclk1_sel_out",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk1_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk1_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .shift = 10,
>>>> +             .width = 1,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mclk1_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk1_sel_out.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk1 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ANACTRL_MPLL_CTRL4,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "mclk1",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mclk1_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_hw *c3_pll_hw_clks[] = {
>>>> +     [CLKID_FIXED_PLL_DCO]   = &fixed_pll_dco.hw,
>>>> +     [CLKID_FIXED_PLL]       = &fixed_pll.hw,
>>>> +     [CLKID_FCLK_DIV40_DIV]  = &fclk_div40_div.hw,
>>>> +     [CLKID_FCLK_DIV40]      = &fclk_div40.hw,
>>>> +     [CLKID_FCLK_DIV2_DIV]   = &fclk_div2_div.hw,
>>>> +     [CLKID_FCLK_DIV2]       = &fclk_div2.hw,
>>>> +     [CLKID_FCLK_DIV2P5_DIV] = &fclk_div2p5_div.hw,
>>>> +     [CLKID_FCLK_DIV2P5]     = &fclk_div2p5.hw,
>>>> +     [CLKID_FCLK_DIV3_DIV]   = &fclk_div3_div.hw,
>>>> +     [CLKID_FCLK_DIV3]       = &fclk_div3.hw,
>>>> +     [CLKID_FCLK_DIV4_DIV]   = &fclk_div4_div.hw,
>>>> +     [CLKID_FCLK_DIV4]       = &fclk_div4.hw,
>>>> +     [CLKID_FCLK_DIV5_DIV]   = &fclk_div5_div.hw,
>>>> +     [CLKID_FCLK_DIV5]       = &fclk_div5.hw,
>>>> +     [CLKID_FCLK_DIV7_DIV]   = &fclk_div7_div.hw,
>>>> +     [CLKID_FCLK_DIV7]       = &fclk_div7.hw,
>>>> +     [CLKID_GP0_PLL_DCO]     = &gp0_pll_dco.hw,
>>>> +     [CLKID_GP0_PLL]         = &gp0_pll.hw,
>>>> +     [CLKID_HIFI_PLL_DCO]    = &hifi_pll_dco.hw,
>>>> +     [CLKID_HIFI_PLL]        = &hifi_pll.hw,
>>>> +     [CLKID_MCLK_PLL_DCO]    = &mclk_pll_dco.hw,
>>>> +     [CLKID_MCLK_PLL]        = &mclk_pll.hw,
>>>> +     [CLKID_MCLK_PLL_CLK]    = &mclk_pll_clk.hw,
>>>> +     [CLKID_MCLK0_SEL]       = &mclk0_sel.hw,
>>>> +     [CLKID_MCLK0_SEL_OUT]   = &mclk0_sel_out.hw,
>>>> +     [CLKID_MCLK0_DIV]       = &mclk0_div.hw,
>>>> +     [CLKID_MCLK0]           = &mclk0.hw,
>>>> +     [CLKID_MCLK1_SEL]       = &mclk1_sel.hw,
>>>> +     [CLKID_MCLK1_SEL_OUT]   = &mclk1_sel_out.hw,
>>>> +     [CLKID_MCLK1_DIV]       = &mclk1_div.hw,
>>>> +     [CLKID_MCLK1]           = &mclk1.hw
>>>> +};
>>>> +
>>>> +/* Convenience table to populate regmap in .probe */
>>>> +static struct clk_regmap *const c3_pll_clk_regmaps[] = {
>>>> +     &fixed_pll_dco,
>>>> +     &fixed_pll,
>>>> +     &fclk_div40,
>>>> +     &fclk_div2,
>>>> +     &fclk_div2p5,
>>>> +     &fclk_div3,
>>>> +     &fclk_div4,
>>>> +     &fclk_div5,
>>>> +     &fclk_div7,
>>>> +     &gp0_pll_dco,
>>>> +     &gp0_pll,
>>>> +     &hifi_pll_dco,
>>>> +     &hifi_pll,
>>>> +     &mclk_pll_dco,
>>>> +     &mclk_pll,
>>>> +     &mclk_pll_clk,
>>>> +     &mclk0_sel,
>>>> +     &mclk0_sel_out,
>>>> +     &mclk0_div,
>>>> +     &mclk0,
>>>> +     &mclk1_sel,
>>>> +     &mclk1_sel_out,
>>>> +     &mclk1_div,
>>>> +     &mclk1,
>>>> +};
>>>> +
>>>> +static struct regmap_config clkc_regmap_config = {
>>>> +     .reg_bits       = 32,
>>>> +     .val_bits       = 32,
>>>> +     .reg_stride     = 4,
>>>> +};
>>>> +
>>>> +static struct meson_clk_hw_data c3_pll_clks = {
>>>> +     .hws = c3_pll_hw_clks,
>>>> +     .num = ARRAY_SIZE(c3_pll_hw_clks),
>>>> +};
>>>> +
>>>> +static int aml_c3_pll_probe(struct platform_device *pdev)
>>>> +{
>>>> +     struct device *dev = &pdev->dev;
>>>> +     struct regmap *regmap;
>>>> +     void __iomem *base;
>>>> +     int clkid, ret, i;
>>>> +
>>>> +     base = devm_platform_ioremap_resource(pdev, 0);
>>>> +     if (IS_ERR(base))
>>>> +             return PTR_ERR(base);
>>>> +
>>>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>>>> +     if (IS_ERR(regmap))
>>>> +             return PTR_ERR(regmap);
>>>> +
>>>> +     /* Populate regmap for the regmap backed clocks */
>>>> +     for (i = 0; i < ARRAY_SIZE(c3_pll_clk_regmaps); i++)
>>>> +             c3_pll_clk_regmaps[i]->map = regmap;
>>>> +
>>>> +     for (clkid = 0; clkid < c3_pll_clks.num; clkid++) {
>>>> +             /* array might be sparse */
>>>> +             if (!c3_pll_clks.hws[clkid])
>>>> +                     continue;
>>>> +
>>>> +             ret = devm_clk_hw_register(dev, c3_pll_clks.hws[clkid]);
>>>> +             if (ret) {
>>>> +                     dev_err(dev, "Clock registration failed\n");
>>>> +                     return ret;
>>>> +             }
>>>> +     }
>>>> +
>>>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>>>> +                                        &c3_pll_clks);
>>>> +}
>>>> +
>>>> +static const struct of_device_id c3_pll_clkc_match_table[] = {
>>>> +     {
>>>> +             .compatible = "amlogic,c3-pll-clkc",
>>>> +     },
>>>> +     {}
>>>> +};
>>>> +MODULE_DEVICE_TABLE(of, c3_pll_clkc_match_table);
>>>> +
>>>> +static struct platform_driver c3_pll_driver = {
>>>> +     .probe          = aml_c3_pll_probe,
>>>> +     .driver         = {
>>>> +             .name   = "c3-pll-clkc",
>>>> +             .of_match_table = c3_pll_clkc_match_table,
>>>> +     },
>>>> +};
>>>> +
>>>> +module_platform_driver(c3_pll_driver);
>>>> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
>>>> +MODULE_LICENSE("GPL");
>>>> diff --git a/drivers/clk/meson/c3-pll.h b/drivers/clk/meson/c3-pll.h
>>>> new file mode 100644
>>>> index 000000000000..92a08196a46f
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/c3-pll.h
>>>> @@ -0,0 +1,35 @@
>>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>>>> +/*
>>>> + * Copyright (c) 2023 Amlogic, inc.
>>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>>> + */
>>>> +
>>>> +#ifndef __AML_C3_PLL_H__
>>>> +#define __AML_C3_PLL_H__
>>>> +
>>>> +#define ANACTRL_FIXPLL_CTRL0                 0x0040
>>>> +#define ANACTRL_FIXPLL_CTRL4                 0x0050
>>>> +#define ANACTRL_GP0PLL_CTRL0                 0x0080
>>>> +#define ANACTRL_GP0PLL_CTRL1                 0x0084
>>>> +#define ANACTRL_GP0PLL_CTRL2                 0x0088
>>>> +#define ANACTRL_GP0PLL_CTRL3                 0x008c
>>>> +#define ANACTRL_GP0PLL_CTRL4                 0x0090
>>>> +#define ANACTRL_GP0PLL_CTRL5                 0x0094
>>>> +#define ANACTRL_GP0PLL_CTRL6                 0x0098
>>>> +#define ANACTRL_GP0PLL_STS                   0x009c
>>>> +#define ANACTRL_HIFIPLL_CTRL0                        0x0100
>>>> +#define ANACTRL_HIFIPLL_CTRL1                        0x0104
>>>> +#define ANACTRL_HIFIPLL_CTRL2                        0x0108
>>>> +#define ANACTRL_HIFIPLL_CTRL3                        0x010c
>>>> +#define ANACTRL_HIFIPLL_CTRL4                        0x0110
>>>> +#define ANACTRL_HIFIPLL_CTRL5                        0x0114
>>>> +#define ANACTRL_HIFIPLL_CTRL6                        0x0118
>>>> +#define ANACTRL_HIFIPLL_STS                  0x011c
>>>> +#define ANACTRL_MPLL_CTRL0                   0x0180
>>>> +#define ANACTRL_MPLL_CTRL1                   0x0184
>>>> +#define ANACTRL_MPLL_CTRL2                   0x0188
>>>> +#define ANACTRL_MPLL_CTRL3                   0x018c
>>>> +#define ANACTRL_MPLL_CTRL4                   0x0190
>>>> +#define ANACTRL_MPLL_STS                     0x01a4
>>>> +
>>>> +#endif  /* __AML_C3_PLL_H__ */

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

* Re: [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock
  2023-10-17 14:39         ` Chuan Liu
@ 2023-10-17 14:42           ` Jerome Brunet
  0 siblings, 0 replies; 27+ messages in thread
From: Jerome Brunet @ 2023-10-17 14:42 UTC (permalink / raw)
  To: Chuan Liu, Xianwei Zhao, linux-arm-kernel, linux-amlogic,
	linux-clk, devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl


On Tue 17 Oct 2023 at 22:39, Chuan Liu <chuan.liu@amlogic.com> wrote:


>>>>> +
>>>>> +static struct clk_fixed_factor fclk_div2p5_div = {
>>>>> +     .mult = 2,
>>>>> +     .div = 5,
>>>>> +     .hw.init = &(struct clk_init_data){
>>>>> +             .name = "fclk_div2p5_div",
>>>>> +             .ops = &clk_fixed_factor_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &fixed_pll.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +     },
>>>>> +};
>>>> This one is wrong if I follow the doc.
>>>> It is supposed to be fixed 8 divider taking it's source directly from
>>>> the DCO, skipping the OD post divider ... assuming the doc is up to date.
>>>>
>>> No, C3 SoC div2p5 is not skipping the OD post divider.
>> I a bit surprised there would be a frequency multiplier considering the
>> complexity of it, when skiping a divider is possible HW wise. Are you
>> sure ?
> This part confirms with our chip design engineer that fclk_div2p5 here is
> actually a clock output by a divider with decimal (divider factor is
> 2.5). The divider factor in clk-divider.c is int, so this description is
> used in the software. Or what do you suggest would be a better way to
> describe this type of divider with decimals?

It's alright. keep it that way then.
Consider fixing the doc maybe.

>>>>> +
>>>>> +static struct clk_regmap fclk_div2p5 = {
>>>>> +     .data = &(struct clk_regmap_gate_data){
>>>>> +             .offset = ANACTRL_FIXPLL_CTRL4,
>>>>> +             .bit_idx = 4,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data) {
>>>>> +             .name = "fclk_div2p5",
>>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &fclk_div2p5_div.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +     },
>>>>> +};
>>>>> +

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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-17 13:28       ` Jerome Brunet
@ 2023-10-17 14:59         ` Chuan Liu
  2023-10-17 15:21           ` Jerome Brunet
  0 siblings, 1 reply; 27+ messages in thread
From: Chuan Liu @ 2023-10-17 14:59 UTC (permalink / raw)
  To: Jerome Brunet, Xianwei Zhao, linux-arm-kernel, linux-amlogic,
	linux-clk, devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl


在 2023/10/17 21:28, Jerome Brunet 写道:
> [ EXTERNAL EMAIL ]
>
> On Tue 17 Oct 2023 at 11:25, Xianwei Zhao <xianwei.zhao@amlogic.com> wrote:
>
>> Hi Jerome,
>>       Thank you for your reply.
>>
>> On 2023/10/13 16:46, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>> On Tue 10 Oct 2023 at 14:29, Xianwei Zhao <xianwei.zhao@amlogic.com>
>>> wrote:
>>>
>>>> Add the C3 peripherals clock controller driver in the C3 SoC family.
>>>>
>>>> Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
>>>> ---
>>>> V1 -> V2: Delete macro definition.
>>>> ---
>>>>    drivers/clk/meson/Kconfig          |   13 +
>>>>    drivers/clk/meson/Makefile         |    1 +
>>>>    drivers/clk/meson/c3-peripherals.c | 3096 ++++++++++++++++++++++++++++
>>>>    drivers/clk/meson/c3-peripherals.h |   48 +
>>>>    4 files changed, 3158 insertions(+)
>>>>    create mode 100644 drivers/clk/meson/c3-peripherals.c
>>>>    create mode 100644 drivers/clk/meson/c3-peripherals.h
>>>>
>>>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>>>> index 76be4bbd2afb..c8d59d28c8ff 100644
>>>> --- a/drivers/clk/meson/Kconfig
>>>> +++ b/drivers/clk/meson/Kconfig
>>>> @@ -140,6 +140,19 @@ config COMMON_CLK_C3_PLL
>>>>           Say Y if you want the board to work, because PLLs are the parent of most
>>>>           peripherals.
>>>>
>>>> +config COMMON_CLK_C3_PERIPHERALS
>>>> +     tristate "Amlogic C3 peripherals clock controller"
>>>> +     default y
>>>> +     select COMMON_CLK_MESON_REGMAP
>>>> +     select COMMON_CLK_MESON_DUALDIV
>>>> +     select COMMON_CLK_MESON_CLKC_UTILS
>>>> +     select COMMON_CLK_C3_PLL
>>>> +     help
>>>> +       Support for the Peripherals clock controller on Amlogic C302X and
>>>> +       C308L devices, AKA c3. Amlogic C302X and C308L devices include
>>>> +       AW402, AW409 and AW419. Say Y if you want the peripherals clock
>>>> +       to work.
>>>> +
>>>>    config COMMON_CLK_G12A
>>>>         tristate "G12 and SM1 SoC clock controllers support"
>>>>         depends on ARM64
>>>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>>>> index 4420af628b31..20ad9482c892 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_C3_PLL) += c3-pll.o
>>>> +obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>>>>    obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
>>>>    obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
>>>>    obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
>>>> diff --git a/drivers/clk/meson/c3-peripherals.c b/drivers/clk/meson/c3-peripherals.c
>>>> new file mode 100644
>>>> index 000000000000..2931cb20299a
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/c3-peripherals.c
>>>> @@ -0,0 +1,3096 @@
>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>> +/*
>>>> + * Amlogic C3 Peripherals Clock Controller Driver
>>>> + *
>>>> + * Copyright (c) 2023 Amlogic, inc.
>>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>>> + */
>>>> +
>>>> +#include <linux/clk-provider.h>
>>>> +#include <linux/of_device.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/clk.h>
>>>> +#include "clk-regmap.h"
>>>> +#include "clk-dualdiv.h"
>>>> +#include "c3-peripherals.h"
>>>> +#include "meson-clkc-utils.h"
>>>> +#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
>>>> +
>>>> +static struct clk_regmap pll_in = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = OSCIN_CTRL,
>>>> +             .bit_idx = 4,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pll_in",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_data = &(const struct clk_parent_data) {
>>>> +                     .fw_name = "xtal",
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mclk_pll_in = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = OSCIN_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "mclk_pll_in",
>>>> +             .ops = &clk_regmap_gate_ro_ops,
>>>> +             .parent_data = &(const struct clk_parent_data) {
>>>> +                     .fw_name = "xtal",
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data rtc_xtal_clkin_parent = {
>>>> +     .fw_name = "xtal",
>>>> +};
>>>> +
>>>> +static struct clk_regmap rtc_xtal_clkin = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = RTC_BY_OSCIN_CTRL0,
>>>> +             .bit_idx = 31,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "rtc_xtal_clkin",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_data = &rtc_xtal_clkin_parent,
>>> Why can't you inline
>>>
>> Will do
>>>                   .parent_data = &(const struct clk_parent_data) {
>>>                           .fw_name = "xtal",
>>>                   },
>>> like for the other clock ... please be consistent
>>>
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct meson_clk_dualdiv_param rtc_32k_div_table[] = {
>>>> +     { 733, 732, 8, 11, 1 },
>>>> +     { /* sentinel */ }
>>>> +};
>>>> +
>>>> +static struct clk_regmap rtc_32k_div = {
>>>> +     .data = &(struct meson_clk_dualdiv_data){
>>>> +             .n1 = {
>>>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 12,
>>>> +             },
>>>> +             .n2 = {
>>>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>>>> +                     .shift   = 12,
>>>> +                     .width   = 12,
>>>> +             },
>>>> +             .m1 = {
>>>> +                     .reg_off = RTC_BY_OSCIN_CTRL1,
>>>> +                     .shift   = 0,
>>>> +                     .width   = 12,
>>>> +             },
>>>> +             .m2 = {
>>>> +                     .reg_off = RTC_BY_OSCIN_CTRL1,
>>>> +                     .shift   = 12,
>>>> +                     .width   = 12,
>>>> +             },
>>>> +             .dual = {
>>>> +                     .reg_off = RTC_BY_OSCIN_CTRL0,
>>>> +                     .shift   = 28,
>>>> +                     .width   = 1,
>>>> +             },
>>>> +             .table = rtc_32k_div_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "rtc_32k_div",
>>>> +             .ops = &meson_clk_dualdiv_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &rtc_xtal_clkin.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data rtc_32k_mux_parent_data[] = {
>>>> +     { .hw = &rtc_32k_div.hw },
>>>> +     { .hw = &rtc_xtal_clkin.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap rtc_32k_mux = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = RTC_BY_OSCIN_CTRL1,
>>>> +             .mask = 0x1,
>>>> +             .shift = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "rtc_32k_mux",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = rtc_32k_mux_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(rtc_32k_mux_parent_data),
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap rtc_32k = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = RTC_BY_OSCIN_CTRL0,
>>>> +             .bit_idx = 30,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "rtc_32k",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &rtc_32k_mux.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data rtc_clk_mux_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .hw = &rtc_32k.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 = rtc_clk_mux_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(rtc_clk_mux_parent_data),
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +/*
>>>> + * Some clocks have multiple clock sources, and the parent clock and index are
>>>> + * discontinuous, Some channels corresponding to the clock index are not
>>>> + * actually connected inside the chip, or the clock source is invalid.
>>>> + */
>>>> +
>>>> +static u32 sys_axi_parent_table[] = { 0, 2, 3, 4, 7 };
>>>> +
>>>> +static const struct clk_parent_data sys_axi_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .hw = &rtc_clk.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap sys_a_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SYS_CLK_CTRL0,
>>>> +             .mask = 0x7,
>>>> +             .shift = 10,
>>>> +             .table = sys_axi_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sys_a_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = sys_axi_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sys_a_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SYS_CLK_CTRL0,
>>>> +             .shift = 0,
>>>> +             .width = 10,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sys_a_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sys_a_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sys_a = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SYS_CLK_CTRL0,
>>>> +             .bit_idx = 13,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "sys_a",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sys_a_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_IGNORE_UNUSED,
>>> As usual, a comment is expected when using CLK_IGNORE_UNUSED.
>>> It is very often not appropriate or justified.
>>> Same goes for the other instances
>>>
>> Will do.
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sys_b_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SYS_CLK_CTRL0,
>>>> +             .mask = 0x7,
>>>> +             .shift = 26,
>>>> +             .table = sys_axi_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sys_b_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = sys_axi_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sys_b_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SYS_CLK_CTRL0,
>>>> +             .shift = 16,
>>>> +             .width = 10,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sys_b_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sys_b_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sys_b = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SYS_CLK_CTRL0,
>>>> +             .bit_idx = 29,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "sys_b",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sys_b_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_IGNORE_UNUSED,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data sys_clk_parent_data[] = {
>>>> +     { .hw = &sys_a.hw },
>>>> +     { .hw = &sys_b.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap sys_clk = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SYS_CLK_CTRL0,
>>>> +             .mask = 0x1,
>>>> +             .shift = 15,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sys_clk",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = sys_clk_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(sys_clk_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap axi_a_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = AXI_CLK_CTRL0,
>>>> +             .mask = 0x7,
>>>> +             .shift = 10,
>>>> +             .table = sys_axi_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "axi_a_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = sys_axi_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap axi_a_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = AXI_CLK_CTRL0,
>>>> +             .shift = 0,
>>>> +             .width = 10,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "axi_a_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &axi_a_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap axi_a = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = AXI_CLK_CTRL0,
>>>> +             .bit_idx = 13,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "axi_a",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &axi_a_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_IGNORE_UNUSED,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap axi_b_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = AXI_CLK_CTRL0,
>>>> +             .mask = 0x7,
>>>> +             .shift = 26,
>>>> +             .table = sys_axi_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "axi_b_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = sys_axi_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(sys_axi_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap axi_b_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = AXI_CLK_CTRL0,
>>>> +             .shift = 16,
>>>> +             .width = 10,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "axi_b_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &axi_b_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap axi_b = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = AXI_CLK_CTRL0,
>>>> +             .bit_idx = 29,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "axi_b",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &axi_b_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_IGNORE_UNUSED,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data axi_clk_parent_data[] = {
>>>> +     { .hw = &axi_a.hw },
>>>> +     { .hw = &axi_b.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap axi_clk = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = AXI_CLK_CTRL0,
>>>> +             .mask = 0x1,
>>>> +             .shift = 15,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "axi_clk",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = axi_clk_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(axi_clk_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +#define AML_CLK_GATE_SYS_CLK(_name, _reg, _bit)\
>>>> +     MESON_PCLK(_name, _reg, _bit, &sys_clk.hw)
>>>> +#define AML_CLK_GATE_AXI_CLK(_name, _reg, _bit)\
>>>> +     MESON_PCLK(_name, _reg, _bit, &axi_clk.hw)
>>>> +
>>>> +AML_CLK_GATE_SYS_CLK(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4);
>>>> +AML_CLK_GATE_SYS_CLK(sys_ctrl, SYS_CLK_EN0_REG0, 5);
>>>> +AML_CLK_GATE_SYS_CLK(sys_ts_pll, SYS_CLK_EN0_REG0, 6);
>>>> +AML_CLK_GATE_SYS_CLK(sys_dev_arb, SYS_CLK_EN0_REG0, 7);
>>>> +AML_CLK_GATE_SYS_CLK(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
>>>> +AML_CLK_GATE_SYS_CLK(sys_capu, SYS_CLK_EN0_REG0, 9);
>>>> +AML_CLK_GATE_SYS_CLK(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11);
>>>> +AML_CLK_GATE_SYS_CLK(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12);
>>>> +AML_CLK_GATE_SYS_CLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13);
>>>> +AML_CLK_GATE_SYS_CLK(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14);
>>>> +AML_CLK_GATE_SYS_CLK(sys_msr_clk, SYS_CLK_EN0_REG0, 15);
>>>> +AML_CLK_GATE_SYS_CLK(sys_rom, SYS_CLK_EN0_REG0, 16);
>>>> +AML_CLK_GATE_SYS_CLK(sys_uart_f, SYS_CLK_EN0_REG0, 17);
>>>> +AML_CLK_GATE_SYS_CLK(sys_cpu_apb, SYS_CLK_EN0_REG0, 18);
>>>> +AML_CLK_GATE_SYS_CLK(sys_rsa, SYS_CLK_EN0_REG0, 19);
>>>> +AML_CLK_GATE_SYS_CLK(sys_sar_adc, SYS_CLK_EN0_REG0, 20);
>>>> +AML_CLK_GATE_SYS_CLK(sys_startup, SYS_CLK_EN0_REG0, 21);
>>>> +AML_CLK_GATE_SYS_CLK(sys_secure, SYS_CLK_EN0_REG0, 22);
>>>> +AML_CLK_GATE_SYS_CLK(sys_spifc, SYS_CLK_EN0_REG0, 23);
>>>> +AML_CLK_GATE_SYS_CLK(sys_nna, SYS_CLK_EN0_REG0, 25);
>>>> +AML_CLK_GATE_SYS_CLK(sys_eth_mac, SYS_CLK_EN0_REG0, 26);
>>>> +AML_CLK_GATE_SYS_CLK(sys_gic, SYS_CLK_EN0_REG0, 27);
>>>> +AML_CLK_GATE_SYS_CLK(sys_rama, SYS_CLK_EN0_REG0, 28);
>>>> +AML_CLK_GATE_SYS_CLK(sys_big_nic, SYS_CLK_EN0_REG0, 29);
>>>> +AML_CLK_GATE_SYS_CLK(sys_ramb, SYS_CLK_EN0_REG0, 30);
>>>> +AML_CLK_GATE_SYS_CLK(sys_audio_pclk, SYS_CLK_EN0_REG0, 31);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_kl, SYS_CLK_EN0_REG1, 0);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ij, SYS_CLK_EN0_REG1, 1);
>>>> +AML_CLK_GATE_SYS_CLK(sys_usb, SYS_CLK_EN0_REG1, 2);
>>>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3);
>>>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ab, SYS_CLK_EN0_REG1, 5);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_cd, SYS_CLK_EN0_REG1, 6);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_ef, SYS_CLK_EN0_REG1, 7);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_gh, SYS_CLK_EN0_REG1, 8);
>>>> +AML_CLK_GATE_SYS_CLK(sys_spicc_1, SYS_CLK_EN0_REG1, 9);
>>>> +AML_CLK_GATE_SYS_CLK(sys_spicc_0, SYS_CLK_EN0_REG1, 10);
>>>> +AML_CLK_GATE_SYS_CLK(sys_uart_a, SYS_CLK_EN0_REG1, 11);
>>>> +AML_CLK_GATE_SYS_CLK(sys_uart_b, SYS_CLK_EN0_REG1, 12);
>>>> +AML_CLK_GATE_SYS_CLK(sys_uart_c, SYS_CLK_EN0_REG1, 13);
>>>> +AML_CLK_GATE_SYS_CLK(sys_uart_d, SYS_CLK_EN0_REG1, 14);
>>>> +AML_CLK_GATE_SYS_CLK(sys_uart_e, SYS_CLK_EN0_REG1, 15);
>>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16);
>>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17);
>>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18);
>>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19);
>>>> +AML_CLK_GATE_SYS_CLK(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20);
>>>> +AML_CLK_GATE_SYS_CLK(sys_rtc, SYS_CLK_EN0_REG1, 21);
>>>> +AML_CLK_GATE_SYS_CLK(sys_ge2d, SYS_CLK_EN0_REG1, 22);
>>>> +AML_CLK_GATE_SYS_CLK(sys_isp, SYS_CLK_EN0_REG1, 23);
>>>> +AML_CLK_GATE_SYS_CLK(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24);
>>>> +AML_CLK_GATE_SYS_CLK(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25);
>>>> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26);
>>>> +AML_CLK_GATE_SYS_CLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27);
>>>> +AML_CLK_GATE_SYS_CLK(sys_eth_phy, SYS_CLK_EN0_REG1, 28);
>>>> +AML_CLK_GATE_SYS_CLK(sys_acodec, SYS_CLK_EN0_REG1, 29);
>>>> +AML_CLK_GATE_SYS_CLK(sys_dwap, SYS_CLK_EN0_REG1, 30);
>>>> +AML_CLK_GATE_SYS_CLK(sys_dos, SYS_CLK_EN0_REG1, 31);
>>>> +AML_CLK_GATE_SYS_CLK(sys_cve, SYS_CLK_EN0_REG2, 0);
>>>> +AML_CLK_GATE_SYS_CLK(sys_vout, SYS_CLK_EN0_REG2, 1);
>>>> +AML_CLK_GATE_SYS_CLK(sys_vc9000e, SYS_CLK_EN0_REG2, 2);
>>>> +AML_CLK_GATE_SYS_CLK(sys_pwm_mn, SYS_CLK_EN0_REG2, 3);
>>>> +AML_CLK_GATE_SYS_CLK(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4);
>>>> +AML_CLK_GATE_AXI_CLK(axi_sys_nic, AXI_CLK_EN0, 2);
>>>> +AML_CLK_GATE_AXI_CLK(axi_isp_nic, AXI_CLK_EN0, 3);
>>>> +AML_CLK_GATE_AXI_CLK(axi_cve_nic, AXI_CLK_EN0, 4);
>>>> +AML_CLK_GATE_AXI_CLK(axi_ramb, AXI_CLK_EN0, 5);
>>>> +AML_CLK_GATE_AXI_CLK(axi_rama, AXI_CLK_EN0, 6);
>>>> +AML_CLK_GATE_AXI_CLK(axi_cpu_dmc, AXI_CLK_EN0, 7);
>>>> +AML_CLK_GATE_AXI_CLK(axi_nic, AXI_CLK_EN0, 8);
>>>> +AML_CLK_GATE_AXI_CLK(axi_dma, AXI_CLK_EN0, 9);
>>>> +AML_CLK_GATE_AXI_CLK(axi_mux_nic, AXI_CLK_EN0, 10);
>>>> +AML_CLK_GATE_AXI_CLK(axi_capu, AXI_CLK_EN0, 11);
>>>> +AML_CLK_GATE_AXI_CLK(axi_cve, AXI_CLK_EN0, 12);
>>>> +AML_CLK_GATE_AXI_CLK(axi_dev1_dmc, AXI_CLK_EN0, 13);
>>>> +AML_CLK_GATE_AXI_CLK(axi_dev0_dmc, AXI_CLK_EN0, 14);
>>>> +AML_CLK_GATE_AXI_CLK(axi_dsp_dmc, AXI_CLK_EN0, 15);
>>>> +
>>>> +/*
>>>> + * clk_12_24m model
>>>> + *
>>>> + *          |------|     |-----| clk_12m_24m |-----|
>>>> + * xtal---->| gate |---->| div |------------>| pad |
>>>> + *          |------|     |-----|             |-----|
>>>> + */
>>>> +static const struct clk_parent_data clk_12_24m_in_parent = {
>>>> +     .fw_name = "xtal",
>>>> +};
>>> Can't inline that ?
>>>
>> Will do.
>>>> +
>>>> +static struct clk_regmap 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 = &clk_12_24m_in_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 *[]) {
>>>> +                     &clk_12_24m_in.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_pa]rent_data fclk_25m_div_parent = {
>>>> +     .fw_name = "fixed_pll",
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 = &fclk_25m_div_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 *[]) {
>>>> +                     &fclk_25m_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +/* generate clock output */
>>> That comment is not helping much ... what did you mean ?
>>>
>> It seems superfluous, will delte it.
>>>> +static u32 gen_parent_table[] = { 0, 1, 5, 7 };
>>>> +
>>>> +static const struct clk_parent_data gen_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .hw = &rtc_clk.hw },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "hifi_pll" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap gen_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = GEN_CLK_CTRL,
>>>> +             .mask = 0x1f,
>>>> +             .shift = 12,
>>>> +             .table = gen_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "gen_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = gen_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(gen_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 *[]) {
>>>> +                     &gen_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 *[]) {
>>>> +                     &gen_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data saradc_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .hw = &sys_clk.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap saradc_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SAR_CLK_CTRL0,
>>>> +             .mask = 0x1,
>>>> +             .shift = 9,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "saradc_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = saradc_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(saradc_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap saradc_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SAR_CLK_CTRL0,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "saradc_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &saradc_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap saradc = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SAR_CLK_CTRL0,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "saradc",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &saradc_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 pwm_parent_table[] = { 0, 2, 3 };
>>> What's pwm parent 1, why can't it be used ?
>> This 1 corresponds to gp1 pll, which is currently dedicated to emmc.
> Given that gp1 does not exist in your PLL controller, it is going to be
> hard to dedicate it to eMMC ;)
Because the register corresponding to gp1_pll has permission 
restrictions, the corresponding register is read-only in the kernel (can 
read and write in the bl31 environment), here first mask the source to 
solve the permission problem before opening
>
>>>> +
>>>> +static const struct clk_parent_data pwm_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div3" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_a_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 9,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_a_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_a_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_a_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_a_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_a = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_a",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_a_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_b_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 25,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_b_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_b_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_b_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_b_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_b = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_b",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_b_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_c_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_CD_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 9,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_c_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_c_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_CD_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_c_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_c_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_c = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_CD_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_c",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_c_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_d_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_CD_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 25,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_d_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_d_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_CD_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_d_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_d_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_d = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_CD_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_d",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_d_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_e_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_EF_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 9,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_e_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_e_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_EF_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_e_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_e_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_e = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_EF_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_e",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_e_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_f_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_EF_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 25,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_f_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_f_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_EF_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_f_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_f_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_f = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_EF_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_f",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_f_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_g_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_GH_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 9,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_g_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_g_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_GH_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_g_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_g_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_g = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_GH_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_g",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_g_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_h_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_GH_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 25,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_h_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_h_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_GH_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_h_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_h_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_h = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_GH_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_h",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_h_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_i_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_IJ_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 9,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_i_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_i_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_IJ_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_i_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_i_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_i = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_IJ_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_i",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_i_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_j_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_IJ_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 25,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_j_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_j_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_IJ_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_j_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_j_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_j = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_IJ_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_j",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_j_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_k_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_KL_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 9,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_k_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_k_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_KL_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_k_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_k_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_k = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_KL_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_k",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_k_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_l_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_KL_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 25,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_l_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_l_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_KL_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_l_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_l_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_l = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_KL_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_l",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_l_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_m_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_MN_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 9,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_m_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_m_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_MN_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_m_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_m_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_m = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_MN_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_m",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_m_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_n_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = PWM_CLK_MN_CTRL,
>>>> +             .mask = 0x3,
>>>> +             .shift = 25,
>>>> +             .table = pwm_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_n_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = pwm_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_n_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = PWM_CLK_MN_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "pwm_n_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_n_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap pwm_n = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = PWM_CLK_MN_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "pwm_n",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &pwm_n_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>> Judging by the number of repeated block, a properly defined macro would
>>> be acceptable for the PWM block
>>>
>> Will do.
>>>> +
>>>> +static const struct clk_parent_data spicc_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .hw = &sys_clk.hw },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div2" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "fclk_div7" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap spicc_a_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SPICC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "spicc_a_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = spicc_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap spicc_a_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SPICC_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 6,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "spicc_a_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &spicc_a_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap spicc_a = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SPICC_CLK_CTRL,
>>>> +             .bit_idx = 6,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "spicc_a",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &spicc_a_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap spicc_b_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SPICC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 23,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "spicc_b_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = spicc_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(spicc_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap spicc_b_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SPICC_CLK_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 6,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "spicc_b_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &spicc_b_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap spicc_b = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SPICC_CLK_CTRL,
>>>> +             .bit_idx = 22,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "spicc_b",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &spicc_b_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data spifc_parent_data[] = {
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "fclk_div2" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "fclk_div7" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap spifc_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SPIFC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "spifc_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = spifc_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(spifc_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap spifc_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SPIFC_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "spifc_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &spifc_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap spifc = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SPIFC_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "spifc",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &spifc_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 emmc_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>> What's 6 ? why can't it be used ?
>>>
> No answer ?
6 - gp1_pll,The permission reason is that the patch is submitted to open 
after the solution is resolved
>
>>>> +
>>>> +static const struct clk_parent_data emmc_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .fw_name = "fclk_div2" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "gp0_pll" }
>>>> +};
> Not seeing gp1 there ? why would you need to dedicate an GP pll for MMC
> ? Maybe I missing something but it seems to me the usual MMC rate are
> acheivable with the fclks, especially 2p5.
Permission reason
>
>>>> +
>>>> +static struct clk_regmap sd_emmc_a_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +             .table = emmc_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sd_emmc_a_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = emmc_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_a_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sd_emmc_a_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sd_emmc_a_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_a = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>> +             .bit_idx = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "sd_emmc_a",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sd_emmc_a_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_b_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 25,
>>>> +             .table = emmc_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sd_emmc_b_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = emmc_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_b_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sd_emmc_b_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sd_emmc_b_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_b = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>> +             .bit_idx = 23,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "sd_emmc_b",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sd_emmc_b_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_c_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = NAND_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +             .table = emmc_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sd_emmc_c_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = emmc_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_c_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = NAND_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "sd_emmc_c_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sd_emmc_c_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap sd_emmc_c = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = NAND_CLK_CTRL,
>>>> +             .bit_idx = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "sd_emmc_c",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &sd_emmc_c_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +/* temperature sensor */
>>>> +static const struct clk_parent_data ts_parent = {
>>>> +     .fw_name = "xtal",
>>>> +};
>>> same  ...
>>>
>>>> +
>>>> +static struct clk_regmap 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 = &ts_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 *[]) {
>>>> +                     &ts_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data eth_parent = {
>>>> +     .fw_name = "fclk_div2",
>>>> +};
>>>> +
>>>> +static struct clk_fixed_factor eth_125m_div = {
>>>> +     .mult = 1,
>>>> +     .div = 8,
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "eth_125m_div",
>>>> +             .ops = &clk_fixed_factor_ops,
>>>> +             .parent_data = &eth_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 *[]) {
>>>> +                     &eth_125m_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 = &eth_parent,
>>>> +             .num_parents = 1,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap 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 *[]) {
>>>> +                     &eth_rmii_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 mipi_dsi_meas_parent_table[] = { 0, 1, 2, 3, 5, 6, 7 };
>>> What is 4 ? why can't it be used ?
>>>
>>>> +
>>>> +static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "fclk_div2" },
>>>> +     { .fw_name = "fclk_div7" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap mipi_dsi_meas_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VDIN_MEAS_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 21,
>>>> +             .table = mipi_dsi_meas_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mipi_dsi_meas_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = mipi_dsi_meas_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(mipi_dsi_meas_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mipi_dsi_meas_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VDIN_MEAS_CLK_CTRL,
>>>> +             .shift = 12,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "mipi_dsi_meas_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mipi_dsi_meas_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap mipi_dsi_meas = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = VDIN_MEAS_CLK_CTRL,
>>>> +             .bit_idx = 20,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "mipi_dsi_meas",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &mipi_dsi_meas_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 dsi_phy_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
>>> What about 0 ?
>>>
>>>> +
>>>> +static const struct clk_parent_data dsi_phy_parent_data[] = {
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div2" },
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div7" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap dsi_phy_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 12,
>>>> +             .table = dsi_phy_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "dsi_phy_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = dsi_phy_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(dsi_phy_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap dsi_phy_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "dsi_phy_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &dsi_phy_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap dsi_phy = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "dsi_phy",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &dsi_phy_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 vout_parent_table[] = { 1, 2, 3, 4, 5, 6, 7 };
>>> same
>>>
>>>> +
>>>> +static const struct clk_parent_data vout_parent_data[] = {
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div7" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap vout_mclk_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VOUTENC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +             .table = vout_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vout_mclk_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = vout_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(vout_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vout_mclk_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VOUTENC_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vout_mclk_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vout_mclk_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vout_mclk = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = MIPIDSI_PHY_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "vout_mclk",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vout_mclk_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vout_enc_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VOUTENC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 25,
>>>> +             .table = vout_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vout_enc_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = vout_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(vout_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vout_enc_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VOUTENC_CLK_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vout_enc_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vout_enc_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vout_enc = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = VOUTENC_CLK_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "vout_enc",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vout_enc_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data hcodec_pre_parent_data[] = {
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "fclk_div7" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "xtal" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap hcodec_0_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VDEC_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "hcodec_0_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = hcodec_pre_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap hcodec_0_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VDEC_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "hcodec_0_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &hcodec_0_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap hcodec_0 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = VDEC_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "hcodec_0",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &hcodec_0_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap hcodec_1_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VDEC3_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "hcodec_1_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = hcodec_pre_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(hcodec_pre_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap hcodec_1_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VDEC3_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "hcodec_1_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &hcodec_1_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap hcodec_1 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = VDEC3_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "hcodec_1",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &hcodec_1_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data hcodec_parent_data[] = {
>>>> +     { .hw = &hcodec_0.hw },
>>>> +     { .hw = &hcodec_1.hw }
>>>> +};
>>>> +
>>>> +
>>> remove extra new lines
>>>
>> Will do.
>>>> +static struct clk_regmap hcodec = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VDEC3_CLK_CTRL,
>>>> +             .mask = 0x1,
>>>> +             .shift = 15,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "hcodec",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = hcodec_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(hcodec_parent_data),
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data vc9000e_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "fclk_div7" },
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "gp0_pll" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap vc9000e_aclk_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VC9000E_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vc9000e_aclk_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = vc9000e_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(vc9000e_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vc9000e_aclk_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VC9000E_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vc9000e_aclk_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vc9000e_aclk_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vc9000e_aclk = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = VC9000E_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "vc9000e_aclk",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vc9000e_aclk_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vc9000e_core_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VC9000E_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 25,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vc9000e_core_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = vc9000e_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(vc9000e_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vc9000e_core_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VC9000E_CLK_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vc9000e_core_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vc9000e_core_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vc9000e_core = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = VC9000E_CLK_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "vc9000e_core",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vc9000e_core_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 csi_phy_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>> Same here and all following instance
>>>
>> This 1 corresponds to gp1 pll, which is currently dedicated to emmc.
> No it is not. Again mainline drivers are slightly different from AML
> fork you might be used to. No PLL is dedicated to the mmc driver.
> Unless you can make a strong case for it, I don't think it will happen
> in the near future.
For performance considerations, emmc needs to use a higher frequency 
clock source (currently our emmc driver has been adapted to 1152M), so 
we internally allocate gp1_pll to emmc.As mentioned above, the gp1_pll 
register permission problem is masked here first🙂
>>>> +
>>>> +static const struct clk_parent_data csi_phy_parent_data[] = {
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "xtal" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap csi_phy0_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = ISP0_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 25,
>>>> +             .table = csi_phy_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "csi_phy0_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = csi_phy_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(csi_phy_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap csi_phy0_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ISP0_CLK_CTRL,
>>>> +             .shift = 16,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "csi_phy0_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &csi_phy0_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap csi_phy0 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ISP0_CLK_CTRL,
>>>> +             .bit_idx = 24,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "csi_phy0",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &csi_phy0_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 dewarpa_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>>> +
>>>> +static const struct clk_parent_data dewarpa_parent_data[] = {
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "fclk_div7" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap dewarpa_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = DEWARPA_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +             .table = dewarpa_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "dewarpa_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = dewarpa_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(dewarpa_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap dewarpa_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = DEWARPA_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "dewarpa_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &dewarpa_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap dewarpa = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = DEWARPA_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "dewarpa",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &dewarpa_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 isp_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>>> +
>>>> +static const struct clk_parent_data isp_parent_data[] = {
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "xtal" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap isp0_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = ISP0_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +             .table = isp_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "isp0_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = isp_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(isp_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap isp0_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = ISP0_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "isp0_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &isp0_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap isp0 = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = ISP0_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "isp0",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &isp0_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 nna_core_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>>> +
>>>> +static const struct clk_parent_data nna_core_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "fclk_div2" },
>>>> +     { .fw_name = "hifi_pll" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap nna_core_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = NNA_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +             .table = nna_core_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "nna_core_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = nna_core_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(nna_core_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap nna_core_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = NNA_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "nna_core_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &nna_core_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap nna_core = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = NNA_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "nna_core",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &nna_core_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static const struct clk_parent_data ge2d_parent_data[] = {
>>>> +     { .fw_name = "xtal" },
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .hw = &rtc_clk.hw }
>>>> +};
>>>> +
>>>> +static struct clk_regmap ge2d_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = GE2D_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "ge2d_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = ge2d_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(ge2d_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap ge2d_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = GE2D_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "ge2d_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &ge2d_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap ge2d = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = GE2D_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "ge2d",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &ge2d_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static u32 c3_vapb_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>>> +
>>>> +static const struct clk_parent_data vapb_parent_data[] = {
>>>> +     { .fw_name = "fclk_div2p5" },
>>>> +     { .fw_name = "fclk_div3" },
>>>> +     { .fw_name = "fclk_div4" },
>>>> +     { .fw_name = "fclk_div5" },
>>>> +     { .fw_name = "gp0_pll" },
>>>> +     { .fw_name = "hifi_pll" },
>>>> +     { .fw_name = "xtal" }
>>>> +};
>>>> +
>>>> +static struct clk_regmap vapb_sel = {
>>>> +     .data = &(struct clk_regmap_mux_data){
>>>> +             .offset = VAPB_CLK_CTRL,
>>>> +             .mask = 0x7,
>>>> +             .shift = 9,
>>>> +             .table = c3_vapb_parent_table,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vapb_sel",
>>>> +             .ops = &clk_regmap_mux_ops,
>>>> +             .parent_data = vapb_parent_data,
>>>> +             .num_parents = ARRAY_SIZE(vapb_parent_data),
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vapb_div = {
>>>> +     .data = &(struct clk_regmap_div_data){
>>>> +             .offset = VAPB_CLK_CTRL,
>>>> +             .shift = 0,
>>>> +             .width = 7,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data){
>>>> +             .name = "vapb_div",
>>>> +             .ops = &clk_regmap_divider_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vapb_sel.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_regmap vapb = {
>>>> +     .data = &(struct clk_regmap_gate_data){
>>>> +             .offset = VAPB_CLK_CTRL,
>>>> +             .bit_idx = 8,
>>>> +     },
>>>> +     .hw.init = &(struct clk_init_data) {
>>>> +             .name = "vapb",
>>>> +             .ops = &clk_regmap_gate_ops,
>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>> +                     &vapb_div.hw
>>>> +             },
>>>> +             .num_parents = 1,
>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>> +     },
>>>> +};
>>>> +
>>>> +static struct clk_hw *c3_periphs_hw_clks[] = {
>>>> +     [CLKID_PLL_IN]                  = &pll_in.hw,
>>>> +     [CLKID_MCLK_PLL_IN]             = &mclk_pll_in.hw,
>>>> +     [CLKID_RTC_XTAL_CLKIN]          = &rtc_xtal_clkin.hw,
>>>> +     [CLKID_RTC_32K_DIV]             = &rtc_32k_div.hw,
>>>> +     [CLKID_RTC_32K_MUX]             = &rtc_32k_mux.hw,
>>>> +     [CLKID_RTC_32K]                 = &rtc_32k.hw,
>>>> +     [CLKID_RTC_CLK]                 = &rtc_clk.hw,
>>>> +     [CLKID_SYS_A_SEL]               = &sys_a_sel.hw,
>>>> +     [CLKID_SYS_A_DIV]               = &sys_a_div.hw,
>>>> +     [CLKID_SYS_A]                   = &sys_a.hw,
>>>> +     [CLKID_SYS_B_SEL]               = &sys_b_sel.hw,
>>>> +     [CLKID_SYS_B_DIV]               = &sys_b_div.hw,
>>>> +     [CLKID_SYS_B]                   = &sys_b.hw,
>>>> +     [CLKID_SYS_CLK]                 = &sys_clk.hw,
>>>> +     [CLKID_AXI_A_SEL]               = &axi_a_sel.hw,
>>>> +     [CLKID_AXI_A_DIV]               = &axi_a_div.hw,
>>>> +     [CLKID_AXI_A]                   = &axi_a.hw,
>>>> +     [CLKID_AXI_B_SEL]               = &axi_b_sel.hw,
>>>> +     [CLKID_AXI_B_DIV]               = &axi_b_div.hw,
>>>> +     [CLKID_AXI_B]                   = &axi_b.hw,
>>>> +     [CLKID_AXI_CLK]                 = &axi_clk.hw,
>>>> +     [CLKID_SYS_RESET_CTRL]          = &sys_reset_ctrl.hw,
>>>> +     [CLKID_SYS_PAD_CTRL]            = &sys_pwr_ctrl.hw,
>>>> +     [CLKID_SYS_CTRL]                = &sys_ctrl.hw,
>>>> +     [CLKID_SYS_TS_PLL]              = &sys_ts_pll.hw,
>>>> +     [CLKID_SYS_DEV_ARB]             = &sys_dev_arb.hw,
>>>> +     [CLKID_SYS_MMC_PCLK]            = &sys_mmc_pclk.hw,
>>>> +     [CLKID_SYS_CAPU]                = &sys_capu.hw,
>>>> +     [CLKID_SYS_CPU_CTRL]            = &sys_cpu_ctrl.hw,
>>>> +     [CLKID_SYS_JTAG_CTRL]           = &sys_jtag_ctrl.hw,
>>>> +     [CLKID_SYS_IR_CTRL]             = &sys_ir_ctrl.hw,
>>>> +     [CLKID_SYS_IRQ_CTRL]            = &sys_irq_ctrl.hw,
>>>> +     [CLKID_SYS_MSR_CLK]             = &sys_msr_clk.hw,
>>>> +     [CLKID_SYS_ROM]                 = &sys_rom.hw,
>>>> +     [CLKID_SYS_UART_F]              = &sys_uart_f.hw,
>>>> +     [CLKID_SYS_CPU_ARB]             = &sys_cpu_apb.hw,
>>>> +     [CLKID_SYS_RSA]                 = &sys_rsa.hw,
>>>> +     [CLKID_SYS_SAR_ADC]             = &sys_sar_adc.hw,
>>>> +     [CLKID_SYS_STARTUP]             = &sys_startup.hw,
>>>> +     [CLKID_SYS_SECURE]              = &sys_secure.hw,
>>>> +     [CLKID_SYS_SPIFC]               = &sys_spifc.hw,
>>>> +     [CLKID_SYS_NNA]                 = &sys_nna.hw,
>>>> +     [CLKID_SYS_ETH_MAC]             = &sys_eth_mac.hw,
>>>> +     [CLKID_SYS_GIC]                 = &sys_gic.hw,
>>>> +     [CLKID_SYS_RAMA]                = &sys_rama.hw,
>>>> +     [CLKID_SYS_BIG_NIC]             = &sys_big_nic.hw,
>>>> +     [CLKID_SYS_RAMB]                = &sys_ramb.hw,
>>>> +     [CLKID_SYS_AUDIO_PCLK]          = &sys_audio_pclk.hw,
>>>> +     [CLKID_SYS_PWM_KL]              = &sys_pwm_kl.hw,
>>>> +     [CLKID_SYS_PWM_IJ]              = &sys_pwm_ij.hw,
>>>> +     [CLKID_SYS_USB]                 = &sys_usb.hw,
>>>> +     [CLKID_SYS_SD_EMMC_A]           = &sys_sd_emmc_a.hw,
>>>> +     [CLKID_SYS_SD_EMMC_C]           = &sys_sd_emmc_c.hw,
>>>> +     [CLKID_SYS_PWM_AB]              = &sys_pwm_ab.hw,
>>>> +     [CLKID_SYS_PWM_CD]              = &sys_pwm_cd.hw,
>>>> +     [CLKID_SYS_PWM_EF]              = &sys_pwm_ef.hw,
>>>> +     [CLKID_SYS_PWM_GH]              = &sys_pwm_gh.hw,
>>>> +     [CLKID_SYS_SPICC_1]             = &sys_spicc_1.hw,
>>>> +     [CLKID_SYS_SPICC_0]             = &sys_spicc_0.hw,
>>>> +     [CLKID_SYS_UART_A]              = &sys_uart_a.hw,
>>>> +     [CLKID_SYS_UART_B]              = &sys_uart_b.hw,
>>>> +     [CLKID_SYS_UART_C]              = &sys_uart_c.hw,
>>>> +     [CLKID_SYS_UART_D]              = &sys_uart_d.hw,
>>>> +     [CLKID_SYS_UART_E]              = &sys_uart_e.hw,
>>>> +     [CLKID_SYS_I2C_M_A]             = &sys_i2c_m_a.hw,
>>>> +     [CLKID_SYS_I2C_M_B]             = &sys_i2c_m_b.hw,
>>>> +     [CLKID_SYS_I2C_M_C]             = &sys_i2c_m_c.hw,
>>>> +     [CLKID_SYS_I2C_M_D]             = &sys_i2c_m_d.hw,
>>>> +     [CLKID_SYS_I2S_S_A]             = &sys_i2c_s_a.hw,
>>>> +     [CLKID_SYS_RTC]                 = &sys_rtc.hw,
>>>> +     [CLKID_SYS_GE2D]                = &sys_ge2d.hw,
>>>> +     [CLKID_SYS_ISP]                 = &sys_isp.hw,
>>>> +     [CLKID_SYS_GPV_ISP_NIC]         = &sys_gpv_isp_nic.hw,
>>>> +     [CLKID_SYS_GPV_CVE_NIC]         = &sys_gpv_cve_nic.hw,
>>>> +     [CLKID_SYS_MIPI_DSI_HOST]       = &sys_mipi_dsi_host.hw,
>>>> +     [CLKID_SYS_MIPI_DSI_PHY]        = &sys_mipi_dsi_phy.hw,
>>>> +     [CLKID_SYS_ETH_PHY]             = &sys_eth_phy.hw,
>>>> +     [CLKID_SYS_ACODEC]              = &sys_acodec.hw,
>>>> +     [CLKID_SYS_DWAP]                = &sys_dwap.hw,
>>>> +     [CLKID_SYS_DOS]                 = &sys_dos.hw,
>>>> +     [CLKID_SYS_CVE]                 = &sys_cve.hw,
>>>> +     [CLKID_SYS_VOUT]                = &sys_vout.hw,
>>>> +     [CLKID_SYS_VC9000E]             = &sys_vc9000e.hw,
>>>> +     [CLKID_SYS_PWM_MN]              = &sys_pwm_mn.hw,
>>>> +     [CLKID_SYS_SD_EMMC_B]           = &sys_sd_emmc_b.hw,
>>>> +     [CLKID_AXI_SYS_NIC]             = &axi_sys_nic.hw,
>>>> +     [CLKID_AXI_ISP_NIC]             = &axi_isp_nic.hw,
>>>> +     [CLKID_AXI_CVE_NIC]             = &axi_cve_nic.hw,
>>>> +     [CLKID_AXI_RAMB]                = &axi_ramb.hw,
>>>> +     [CLKID_AXI_RAMA]                = &axi_rama.hw,
>>>> +     [CLKID_AXI_CPU_DMC]             = &axi_cpu_dmc.hw,
>>>> +     [CLKID_AXI_NIC]                 = &axi_nic.hw,
>>>> +     [CLKID_AXI_DMA]                 = &axi_dma.hw,
>>>> +     [CLKID_AXI_MUX_NIC]             = &axi_mux_nic.hw,
>>>> +     [CLKID_AXI_CAPU]                = &axi_capu.hw,
>>>> +     [CLKID_AXI_CVE]                 = &axi_cve.hw,
>>>> +     [CLKID_AXI_DEV1_DMC]            = &axi_dev1_dmc.hw,
>>>> +     [CLKID_AXI_DEV0_DMC]            = &axi_dev0_dmc.hw,
>>>> +     [CLKID_AXI_DSP_DMC]             = &axi_dsp_dmc.hw,
>>>> +     [CLKID_12_24M_IN]               = &clk_12_24m_in.hw,
>>>> +     [CLKID_12M_24M]                 = &clk_12_24m.hw,
>>>> +     [CLKID_FCLK_25M_DIV]            = &fclk_25m_div.hw,
>>>> +     [CLKID_FCLK_25M]                = &fclk_25m.hw,
>>>> +     [CLKID_GEN_SEL]                 = &gen_sel.hw,
>>>> +     [CLKID_GEN_DIV]                 = &gen_div.hw,
>>>> +     [CLKID_GEN]                     = &gen.hw,
>>>> +     [CLKID_SARADC_SEL]              = &saradc_sel.hw,
>>>> +     [CLKID_SARADC_DIV]              = &saradc_div.hw,
>>>> +     [CLKID_SARADC]                  = &saradc.hw,
>>>> +     [CLKID_PWM_A_SEL]               = &pwm_a_sel.hw,
>>>> +     [CLKID_PWM_A_DIV]               = &pwm_a_div.hw,
>>>> +     [CLKID_PWM_A]                   = &pwm_a.hw,
>>>> +     [CLKID_PWM_B_SEL]               = &pwm_b_sel.hw,
>>>> +     [CLKID_PWM_B_DIV]               = &pwm_b_div.hw,
>>>> +     [CLKID_PWM_B]                   = &pwm_b.hw,
>>>> +     [CLKID_PWM_C_SEL]               = &pwm_c_sel.hw,
>>>> +     [CLKID_PWM_C_DIV]               = &pwm_c_div.hw,
>>>> +     [CLKID_PWM_C]                   = &pwm_c.hw,
>>>> +     [CLKID_PWM_D_SEL]               = &pwm_d_sel.hw,
>>>> +     [CLKID_PWM_D_DIV]               = &pwm_d_div.hw,
>>>> +     [CLKID_PWM_D]                   = &pwm_d.hw,
>>>> +     [CLKID_PWM_E_SEL]               = &pwm_e_sel.hw,
>>>> +     [CLKID_PWM_E_DIV]               = &pwm_e_div.hw,
>>>> +     [CLKID_PWM_E]                   = &pwm_e.hw,
>>>> +     [CLKID_PWM_F_SEL]               = &pwm_f_sel.hw,
>>>> +     [CLKID_PWM_F_DIV]               = &pwm_f_div.hw,
>>>> +     [CLKID_PWM_F]                   = &pwm_f.hw,
>>>> +     [CLKID_PWM_G_SEL]               = &pwm_g_sel.hw,
>>>> +     [CLKID_PWM_G_DIV]               = &pwm_g_div.hw,
>>>> +     [CLKID_PWM_G]                   = &pwm_g.hw,
>>>> +     [CLKID_PWM_H_SEL]               = &pwm_h_sel.hw,
>>>> +     [CLKID_PWM_H_DIV]               = &pwm_h_div.hw,
>>>> +     [CLKID_PWM_H]                   = &pwm_h.hw,
>>>> +     [CLKID_PWM_I_SEL]               = &pwm_i_sel.hw,
>>>> +     [CLKID_PWM_I_DIV]               = &pwm_i_div.hw,
>>>> +     [CLKID_PWM_I]                   = &pwm_i.hw,
>>>> +     [CLKID_PWM_J_SEL]               = &pwm_j_sel.hw,
>>>> +     [CLKID_PWM_J_DIV]               = &pwm_j_div.hw,
>>>> +     [CLKID_PWM_J]                   = &pwm_j.hw,
>>>> +     [CLKID_PWM_K_SEL]               = &pwm_k_sel.hw,
>>>> +     [CLKID_PWM_K_DIV]               = &pwm_k_div.hw,
>>>> +     [CLKID_PWM_K]                   = &pwm_k.hw,
>>>> +     [CLKID_PWM_L_SEL]               = &pwm_l_sel.hw,
>>>> +     [CLKID_PWM_L_DIV]               = &pwm_l_div.hw,
>>>> +     [CLKID_PWM_L]                   = &pwm_l.hw,
>>>> +     [CLKID_PWM_M_SEL]               = &pwm_m_sel.hw,
>>>> +     [CLKID_PWM_M_DIV]               = &pwm_m_div.hw,
>>>> +     [CLKID_PWM_M]                   = &pwm_m.hw,
>>>> +     [CLKID_PWM_N_SEL]               = &pwm_n_sel.hw,
>>>> +     [CLKID_PWM_N_DIV]               = &pwm_n_div.hw,
>>>> +     [CLKID_PWM_N]                   = &pwm_n.hw,
>>>> +     [CLKID_SPICC_A_SEL]             = &spicc_a_sel.hw,
>>>> +     [CLKID_SPICC_A_DIV]             = &spicc_a_div.hw,
>>>> +     [CLKID_SPICC_A]                 = &spicc_a.hw,
>>>> +     [CLKID_SPICC_B_SEL]             = &spicc_b_sel.hw,
>>>> +     [CLKID_SPICC_B_DIV]             = &spicc_b_div.hw,
>>>> +     [CLKID_SPICC_B]                 = &spicc_b.hw,
>>>> +     [CLKID_SPIFC_SEL]               = &spifc_sel.hw,
>>>> +     [CLKID_SPIFC_DIV]               = &spifc_div.hw,
>>>> +     [CLKID_SPIFC]                   = &spifc.hw,
>>>> +     [CLKID_SD_EMMC_A_SEL]           = &sd_emmc_a_sel.hw,
>>>> +     [CLKID_SD_EMMC_A_DIV]           = &sd_emmc_a_div.hw,
>>>> +     [CLKID_SD_EMMC_A]               = &sd_emmc_a.hw,
>>>> +     [CLKID_SD_EMMC_B_SEL]           = &sd_emmc_b_sel.hw,
>>>> +     [CLKID_SD_EMMC_B_DIV]           = &sd_emmc_b_div.hw,
>>>> +     [CLKID_SD_EMMC_B]               = &sd_emmc_b.hw,
>>>> +     [CLKID_SD_EMMC_C_SEL]           = &sd_emmc_c_sel.hw,
>>>> +     [CLKID_SD_EMMC_C_DIV]           = &sd_emmc_c_div.hw,
>>>> +     [CLKID_SD_EMMC_C]               = &sd_emmc_c.hw,
>>>> +     [CLKID_TS_DIV]                  = &ts_div.hw,
>>>> +     [CLKID_TS]                      = &ts.hw,
>>>> +     [CLKID_ETH_125M_DIV]            = &eth_125m_div.hw,
>>>> +     [CLKID_ETH_125M]                = &eth_125m.hw,
>>>> +     [CLKID_ETH_RMII_DIV]            = &eth_rmii_div.hw,
>>>> +     [CLKID_ETH_RMII]                = &eth_rmii.hw,
>>>> +     [CLKID_MIPI_DSI_MEAS_SEL]       = &mipi_dsi_meas_sel.hw,
>>>> +     [CLKID_MIPI_DSI_MEAS_DIV]       = &mipi_dsi_meas_div.hw,
>>>> +     [CLKID_MIPI_DSI_MEAS]           = &mipi_dsi_meas.hw,
>>>> +     [CLKID_DSI_PHY_SEL]             = &dsi_phy_sel.hw,
>>>> +     [CLKID_DSI_PHY_DIV]             = &dsi_phy_div.hw,
>>>> +     [CLKID_DSI_PHY]                 = &dsi_phy.hw,
>>>> +     [CLKID_VOUT_MCLK_SEL]           = &vout_mclk_sel.hw,
>>>> +     [CLKID_VOUT_MCLK_DIV]           = &vout_mclk_div.hw,
>>>> +     [CLKID_VOUT_MCLK]               = &vout_mclk.hw,
>>>> +     [CLKID_VOUT_ENC_SEL]            = &vout_enc_sel.hw,
>>>> +     [CLKID_VOUT_ENC_DIV]            = &vout_enc_div.hw,
>>>> +     [CLKID_VOUT_ENC]                = &vout_enc.hw,
>>>> +     [CLKID_HCODEC_0_SEL]            = &hcodec_0_sel.hw,
>>>> +     [CLKID_HCODEC_0_DIV]            = &hcodec_0_div.hw,
>>>> +     [CLKID_HCODEC_0]                = &hcodec_0.hw,
>>>> +     [CLKID_HCODEC_1_SEL]            = &hcodec_1_sel.hw,
>>>> +     [CLKID_HCODEC_1_DIV]            = &hcodec_1_div.hw,
>>>> +     [CLKID_HCODEC_1]                = &hcodec_1.hw,
>>>> +     [CLKID_HCODEC]                  = &hcodec.hw,
>>>> +     [CLKID_VC9000E_ACLK_SEL]        = &vc9000e_aclk_sel.hw,
>>>> +     [CLKID_VC9000E_ACLK_DIV]        = &vc9000e_aclk_div.hw,
>>>> +     [CLKID_VC9000E_ACLK]            = &vc9000e_aclk.hw,
>>>> +     [CLKID_VC9000E_CORE_SEL]        = &vc9000e_core_sel.hw,
>>>> +     [CLKID_VC9000E_CORE_DIV]        = &vc9000e_core_div.hw,
>>>> +     [CLKID_VC9000E_CORE]            = &vc9000e_core.hw,
>>>> +     [CLKID_CSI_PHY0_SEL]            = &csi_phy0_sel.hw,
>>>> +     [CLKID_CSI_PHY0_DIV]            = &csi_phy0_div.hw,
>>>> +     [CLKID_CSI_PHY0]                = &csi_phy0.hw,
>>>> +     [CLKID_DEWARPA_SEL]             = &dewarpa_sel.hw,
>>>> +     [CLKID_DEWARPA_DIV]             = &dewarpa_div.hw,
>>>> +     [CLKID_DEWARPA]                 = &dewarpa.hw,
>>>> +     [CLKID_ISP0_SEL]                = &isp0_sel.hw,
>>>> +     [CLKID_ISP0_DIV]                = &isp0_div.hw,
>>>> +     [CLKID_ISP0]                    = &isp0.hw,
>>>> +     [CLKID_NNA_CORE_SEL]            = &nna_core_sel.hw,
>>>> +     [CLKID_NNA_CORE_DIV]            = &nna_core_div.hw,
>>>> +     [CLKID_NNA_CORE]                = &nna_core.hw,
>>>> +     [CLKID_GE2D_SEL]                = &ge2d_sel.hw,
>>>> +     [CLKID_GE2D_DIV]                = &ge2d_div.hw,
>>>> +     [CLKID_GE2D]                    = &ge2d.hw,
>>>> +     [CLKID_VAPB_SEL]                = &vapb_sel.hw,
>>>> +     [CLKID_VAPB_DIV]                = &vapb_div.hw,
>>>> +     [CLKID_VAPB]                    = &vapb.hw,
>>>> +};
>>>> +
>>>> +/* Convenience table to populate regmap in .probe */
>>>> +static struct clk_regmap *const c3_periphs_clk_regmaps[] = {
>>>> +     &pll_in,
>>>> +     &mclk_pll_in,
>>>> +     &rtc_xtal_clkin,
>>>> +     &rtc_32k_div,
>>>> +     &rtc_32k_mux,
>>>> +     &rtc_32k,
>>>> +     &rtc_clk,
>>>> +     &sys_a_sel,
>>>> +     &sys_a_div,
>>>> +     &sys_a,
>>>> +     &sys_b_sel,
>>>> +     &sys_b_div,
>>>> +     &sys_b,
>>>> +     &sys_clk,
>>>> +     &axi_a_sel,
>>>> +     &axi_a_div,
>>>> +     &axi_a,
>>>> +     &axi_b_sel,
>>>> +     &axi_b_div,
>>>> +     &axi_b,
>>>> +     &axi_clk,
>>>> +     &sys_reset_ctrl,
>>>> +     &sys_pwr_ctrl,
>>>> +     &sys_pad_ctrl,
>>>> +     &sys_ctrl,
>>>> +     &sys_ts_pll,
>>>> +     &sys_dev_arb,
>>>> +     &sys_mmc_pclk,
>>>> +     &sys_capu,
>>>> +     &sys_cpu_ctrl,
>>>> +     &sys_jtag_ctrl,
>>>> +     &sys_ir_ctrl,
>>>> +     &sys_irq_ctrl,
>>>> +     &sys_msr_clk,
>>>> +     &sys_rom,
>>>> +     &sys_uart_f,
>>>> +     &sys_cpu_apb,
>>>> +     &sys_rsa,
>>>> +     &sys_sar_adc,
>>>> +     &sys_startup,
>>>> +     &sys_secure,
>>>> +     &sys_spifc,
>>>> +     &sys_nna,
>>>> +     &sys_eth_mac,
>>>> +     &sys_gic,
>>>> +     &sys_rama,
>>>> +     &sys_big_nic,
>>>> +     &sys_ramb,
>>>> +     &sys_audio_pclk,
>>>> +     &sys_pwm_kl,
>>>> +     &sys_pwm_ij,
>>>> +     &sys_usb,
>>>> +     &sys_sd_emmc_a,
>>>> +     &sys_sd_emmc_c,
>>>> +     &sys_pwm_ab,
>>>> +     &sys_pwm_cd,
>>>> +     &sys_pwm_ef,
>>>> +     &sys_pwm_gh,
>>>> +     &sys_spicc_1,
>>>> +     &sys_spicc_0,
>>>> +     &sys_uart_a,
>>>> +     &sys_uart_b,
>>>> +     &sys_uart_c,
>>>> +     &sys_uart_d,
>>>> +     &sys_uart_e,
>>>> +     &sys_i2c_m_a,
>>>> +     &sys_i2c_m_b,
>>>> +     &sys_i2c_m_c,
>>>> +     &sys_i2c_m_d,
>>>> +     &sys_i2c_s_a,
>>>> +     &sys_rtc,
>>>> +     &sys_ge2d,
>>>> +     &sys_isp,
>>>> +     &sys_gpv_isp_nic,
>>>> +     &sys_gpv_cve_nic,
>>>> +     &sys_mipi_dsi_host,
>>>> +     &sys_mipi_dsi_phy,
>>>> +     &sys_eth_phy,
>>>> +     &sys_acodec,
>>>> +     &sys_dwap,
>>>> +     &sys_dos,
>>>> +     &sys_cve,
>>>> +     &sys_vout,
>>>> +     &sys_vc9000e,
>>>> +     &sys_pwm_mn,
>>>> +     &sys_sd_emmc_b,
>>>> +     &axi_sys_nic,
>>>> +     &axi_isp_nic,
>>>> +     &axi_cve_nic,
>>>> +     &axi_ramb,
>>>> +     &axi_rama,
>>>> +     &axi_cpu_dmc,
>>>> +     &axi_nic,
>>>> +     &axi_dma,
>>>> +     &axi_mux_nic,
>>>> +     &axi_capu,
>>>> +     &axi_cve,
>>>> +     &axi_dev1_dmc,
>>>> +     &axi_dev0_dmc,
>>>> +     &axi_dsp_dmc,
>>>> +     &clk_12_24m_in,
>>>> +     &clk_12_24m,
>>>> +     &fclk_25m_div,
>>>> +     &fclk_25m,
>>>> +     &gen_sel,
>>>> +     &gen_div,
>>>> +     &gen,
>>>> +     &saradc_sel,
>>>> +     &saradc_div,
>>>> +     &saradc,
>>>> +     &pwm_a_sel,
>>>> +     &pwm_a_div,
>>>> +     &pwm_a,
>>>> +     &pwm_b_sel,
>>>> +     &pwm_b_div,
>>>> +     &pwm_b,
>>>> +     &pwm_c_sel,
>>>> +     &pwm_c_div,
>>>> +     &pwm_c,
>>>> +     &pwm_d_sel,
>>>> +     &pwm_d_div,
>>>> +     &pwm_d,
>>>> +     &pwm_e_sel,
>>>> +     &pwm_e_div,
>>>> +     &pwm_e,
>>>> +     &pwm_f_sel,
>>>> +     &pwm_f_div,
>>>> +     &pwm_f,
>>>> +     &pwm_g_sel,
>>>> +     &pwm_g_div,
>>>> +     &pwm_g,
>>>> +     &pwm_h_sel,
>>>> +     &pwm_h_div,
>>>> +     &pwm_h,
>>>> +     &pwm_i_sel,
>>>> +     &pwm_i_div,
>>>> +     &pwm_i,
>>>> +     &pwm_j_sel,
>>>> +     &pwm_j_div,
>>>> +     &pwm_j,
>>>> +     &pwm_k_sel,
>>>> +     &pwm_k_div,
>>>> +     &pwm_k,
>>>> +     &pwm_l_sel,
>>>> +     &pwm_l_div,
>>>> +     &pwm_l,
>>>> +     &pwm_m_sel,
>>>> +     &pwm_m_div,
>>>> +     &pwm_m,
>>>> +     &pwm_n_sel,
>>>> +     &pwm_n_div,
>>>> +     &pwm_n,
>>>> +     &spicc_a_sel,
>>>> +     &spicc_a_div,
>>>> +     &spicc_a,
>>>> +     &spicc_b_sel,
>>>> +     &spicc_b_div,
>>>> +     &spicc_b,
>>>> +     &spifc_sel,
>>>> +     &spifc_div,
>>>> +     &spifc,
>>>> +     &sd_emmc_a_sel,
>>>> +     &sd_emmc_a_div,
>>>> +     &sd_emmc_a,
>>>> +     &sd_emmc_b_sel,
>>>> +     &sd_emmc_b_div,
>>>> +     &sd_emmc_b,
>>>> +     &sd_emmc_c_sel,
>>>> +     &sd_emmc_c_div,
>>>> +     &sd_emmc_c,
>>>> +     &ts_div,
>>>> +     &ts,
>>>> +     &eth_125m,
>>>> +     &eth_rmii_div,
>>>> +     &eth_rmii,
>>>> +     &mipi_dsi_meas_sel,
>>>> +     &mipi_dsi_meas_div,
>>>> +     &mipi_dsi_meas,
>>>> +     &dsi_phy_sel,
>>>> +     &dsi_phy_div,
>>>> +     &dsi_phy,
>>>> +     &vout_mclk_sel,
>>>> +     &vout_mclk_div,
>>>> +     &vout_mclk,
>>>> +     &vout_enc_sel,
>>>> +     &vout_enc_div,
>>>> +     &vout_enc,
>>>> +     &hcodec_0_sel,
>>>> +     &hcodec_0_div,
>>>> +     &hcodec_0,
>>>> +     &hcodec_1_sel,
>>>> +     &hcodec_1_div,
>>>> +     &hcodec_1,
>>>> +     &hcodec,
>>>> +     &vc9000e_aclk_sel,
>>>> +     &vc9000e_aclk_div,
>>>> +     &vc9000e_aclk,
>>>> +     &vc9000e_core_sel,
>>>> +     &vc9000e_core_div,
>>>> +     &vc9000e_core,
>>>> +     &csi_phy0_sel,
>>>> +     &csi_phy0_div,
>>>> +     &csi_phy0,
>>>> +     &dewarpa_sel,
>>>> +     &dewarpa_div,
>>>> +     &dewarpa,
>>>> +     &isp0_sel,
>>>> +     &isp0_div,
>>>> +     &isp0,
>>>> +     &nna_core_sel,
>>>> +     &nna_core_div,
>>>> +     &nna_core,
>>>> +     &ge2d_sel,
>>>> +     &ge2d_div,
>>>> +     &ge2d,
>>>> +     &vapb_sel,
>>>> +     &vapb_div,
>>>> +     &vapb,
>>>> +};
>>>> +
>>>> +static struct regmap_config clkc_regmap_config = {
>>>> +     .reg_bits       = 32,
>>>> +     .val_bits       = 32,
>>>> +     .reg_stride     = 4,
>>>> +};
>>>> +
>>>> +static struct meson_clk_hw_data c3_periphs_clks = {
>>>> +     .hws = c3_periphs_hw_clks,
>>>> +     .num = ARRAY_SIZE(c3_periphs_hw_clks),
>>>> +};
>>>> +
>>>> +static int aml_c3_peripherals_probe(struct platform_device *pdev)
>>>> +{
>>>> +     struct device *dev = &pdev->dev;
>>>> +     struct regmap *regmap;
>>>> +     void __iomem *base;
>>>> +     int clkid, ret, i;
>>>> +
>>>> +     base = devm_platform_ioremap_resource(pdev, 0);
>>>> +     if (IS_ERR(base))
>>>> +             return PTR_ERR(base);
>>>> +
>>>> +     regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
>>>> +     if (IS_ERR(regmap))
>>>> +             return PTR_ERR(regmap);
>>>> +
>>>> +     /* Populate regmap for the regmap backed clocks */
>>>> +     for (i = 0; i < ARRAY_SIZE(c3_periphs_clk_regmaps); i++)
>>>> +             c3_periphs_clk_regmaps[i]->map = regmap;
>>>> +
>>>> +     for (clkid = 0; clkid < c3_periphs_clks.num; clkid++) {
>>>> +             /* array might be sparse */
>>>> +             if (!c3_periphs_clks.hws[clkid])
>>>> +                     continue;
>>>> +
>>>> +             ret = devm_clk_hw_register(dev, c3_periphs_clks.hws[clkid]);
>>>> +             if (ret) {
>>>> +                     dev_err(dev, "Clock registration failed\n");
>>>> +                     return ret;
>>>> +             }
>>>> +     }
>>>> +
>>>> +     return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
>>>> +                                        &c3_periphs_clks);
>>>> +}
>>>> +
>>>> +static const struct of_device_id c3_peripherals_clkc_match_table[] = {
>>>> +     {
>>>> +             .compatible = "amlogic,c3-peripherals-clkc",
>>>> +     },
>>>> +     {}
>>>> +};
>>>> +
>>>> +MODULE_DEVICE_TABLE(of, c3_peripherals_clkc_match_table);
>>>> +
>>>> +static struct platform_driver c3_peripherals_driver = {
>>>> +     .probe          = aml_c3_peripherals_probe,
>>>> +     .driver         = {
>>>> +             .name   = "c3-peripherals-clkc",
>>>> +             .of_match_table = c3_peripherals_clkc_match_table,
>>>> +     },
>>>> +};
>>>> +
>>>> +module_platform_driver(c3_peripherals_driver);
>>>> +MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
>>>> +MODULE_LICENSE("GPL");
>>>> diff --git a/drivers/clk/meson/c3-peripherals.h b/drivers/clk/meson/c3-peripherals.h
>>>> new file mode 100644
>>>> index 000000000000..ddcc23e25669
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/c3-peripherals.h
>>>> @@ -0,0 +1,48 @@
>>>> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
>>>> +/*
>>>> + * Copyright (c) 2023 Amlogic, inc.
>>>> + * Author: Chuan Liu <chuan.liu@amlogic.com>
>>>> + */
>>>> +
>>>> +#ifndef __AML_C3_PERIPHERALS_H__
>>>> +#define __AML_C3_PERIPHERALS_H__
>>>> +
>>>> +#define OSCIN_CTRL                           0x0004
>>>> +#define RTC_BY_OSCIN_CTRL0                   0x0008
>>>> +#define RTC_BY_OSCIN_CTRL1                   0x000c
>>>> +#define RTC_CTRL                             0x0010
>>>> +#define SYS_CLK_CTRL0                                0x0040
>>>> +#define SYS_CLK_EN0_REG0                     0x0044
>>>> +#define SYS_CLK_EN0_REG1                     0x0048
>>>> +#define SYS_CLK_EN0_REG2                     0x004c
>>>> +#define AXI_CLK_CTRL0                                0x006c
>>>> +#define CLK12_24_CTRL                                0x00a8
>>>> +#define AXI_CLK_EN0                          0x00ac
>>>> +#define VDIN_MEAS_CLK_CTRL                   0x00f8
>>>> +#define VAPB_CLK_CTRL                                0x00fc
>>>> +#define MIPIDSI_PHY_CLK_CTRL                 0x0104
>>>> +#define GE2D_CLK_CTRL                                0x010c
>>>> +#define ISP0_CLK_CTRL                                0x0110
>>>> +#define DEWARPA_CLK_CTRL                     0x0114
>>>> +#define VOUTENC_CLK_CTRL                     0x0118
>>>> +#define VDEC_CLK_CTRL                                0x0140
>>>> +#define VDEC3_CLK_CTRL                               0x0148
>>>> +#define TS_CLK_CTRL                          0x0158
>>>> +#define ETH_CLK_CTRL                         0x0164
>>>> +#define NAND_CLK_CTRL                                0x0168
>>>> +#define SD_EMMC_CLK_CTRL                     0x016c
>>>> +#define SPICC_CLK_CTRL                               0x0174
>>>> +#define GEN_CLK_CTRL                         0x0178
>>>> +#define SAR_CLK_CTRL0                                0x017c
>>>> +#define PWM_CLK_AB_CTRL                              0x0180
>>>> +#define PWM_CLK_CD_CTRL                              0x0184
>>>> +#define PWM_CLK_EF_CTRL                              0x0188
>>>> +#define PWM_CLK_GH_CTRL                              0x018c
>>>> +#define PWM_CLK_IJ_CTRL                              0x0190
>>>> +#define PWM_CLK_KL_CTRL                              0x0194
>>>> +#define PWM_CLK_MN_CTRL                              0x0198
>>>> +#define VC9000E_CLK_CTRL                     0x019c
>>>> +#define SPIFC_CLK_CTRL                               0x01a0
>>>> +#define NNA_CLK_CTRL                         0x0220
>>> Nitpick - the extra zero is not needed
>>> Since this is used only by c3 periph clkc - do you really need an header
>>> or can it be defined in the related .c file ?
>>> (I know this is a pattern we have been using so far, but it is not
>>> really justified. No reason to continue with it)
>>>
>>>> +
>>>> +#endif  /* __AML_C3_PERIPHERALS_H__ */

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

* Re: [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver
  2023-10-17 14:59         ` Chuan Liu
@ 2023-10-17 15:21           ` Jerome Brunet
  0 siblings, 0 replies; 27+ messages in thread
From: Jerome Brunet @ 2023-10-17 15:21 UTC (permalink / raw)
  To: Chuan Liu, Xianwei Zhao, linux-arm-kernel, linux-amlogic,
	linux-clk, devicetree, linux-kernel
  Cc: Neil Armstrong, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Kevin Hilman, Martin Blumenstingl


On Tue 17 Oct 2023 at 22:59, Chuan Liu <chuan.liu@amlogic.com> wrote:

>>>>> +
>>>>> +static struct clk_regmap saradc = {
>>>>> +     .data = &(struct clk_regmap_gate_data){
>>>>> +             .offset = SAR_CLK_CTRL0,
>>>>> +             .bit_idx = 8,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data) {
>>>>> +             .name = "saradc",
>>>>> +             .ops = &clk_regmap_gate_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &saradc_div.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>>> +     },
>>>>> +};
>>>>> +
>>>>> +static u32 pwm_parent_table[] = { 0, 2, 3 };
>>>> What's pwm parent 1, why can't it be used ?
>>> This 1 corresponds to gp1 pll, which is currently dedicated to emmc.
>> Given that gp1 does not exist in your PLL controller, it is going to be
>> hard to dedicate it to eMMC ;)
> Because the register corresponding to gp1_pll has permission restrictions,
> the corresponding register is read-only in the kernel (can read and write
> in the bl31 environment), here first mask the source to solve the
> permission problem before opening

The PWM sel clock does not have CLK_SET_RATE_PARENT so it is not going to
request rate change for any parent clock, it will just what is available.

Your reason does not apply here.

Also, if gp1 registers are read-only from the kernel, you can still
expose it with RO ops, possibly with CLK_GET_RATE_NOCACHE if the bl31
may change at runtime.

>>
>>>>> +
>>>>> +static const struct clk_parent_data pwm_parent_data[] = {
>>>>> +     { .fw_name = "xtal" },
>>>>> +     { .fw_name = "fclk_div4" },
>>>>> +     { .fw_name = "fclk_div3" }
>>>>> +};
>>>>> +
>>>>> +static struct clk_regmap pwm_a_sel = {
>>>>> +     .data = &(struct clk_regmap_mux_data){
>>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>>> +             .mask = 0x3,
>>>>> +             .shift = 9,
>>>>> +             .table = pwm_parent_table,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data){
>>>>> +             .name = "pwm_a_sel",
>>>>> +             .ops = &clk_regmap_mux_ops,
>>>>> +             .parent_data = pwm_parent_data,
>>>>> +             .num_parents = ARRAY_SIZE(pwm_parent_data),
>>>>> +     },
>>>>> +};
>>>>> +
>>>>> +static struct clk_regmap pwm_a_div = {
>>>>> +     .data = &(struct clk_regmap_div_data){
>>>>> +             .offset = PWM_CLK_AB_CTRL,
>>>>> +             .shift = 0,
>>>>> +             .width = 8,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data){
>>>>> +             .name = "pwm_a_div",
>>>>> +             .ops = &clk_regmap_divider_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &pwm_a_sel.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>>> +     },
>>>>> +};

[...]

>>>>> +
>>>>> +static struct clk_regmap spifc = {
>>>>> +     .data = &(struct clk_regmap_gate_data){
>>>>> +             .offset = SPIFC_CLK_CTRL,
>>>>> +             .bit_idx = 8,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data) {
>>>>> +             .name = "spifc",
>>>>> +             .ops = &clk_regmap_gate_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &spifc_div.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>>> +     },
>>>>> +};
>>>>> +
>>>>> +static u32 emmc_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>>> What's 6 ? why can't it be used ?
>>>>
>> No answer ?
> 6 - gp1_pll,The permission reason is that the patch is submitted to open
> after the solution is resolved
>>
>>>>> +
>>>>> +static const struct clk_parent_data emmc_parent_data[] = {
>>>>> +     { .fw_name = "xtal" },
>>>>> +     { .fw_name = "fclk_div2" },
>>>>> +     { .fw_name = "fclk_div3" },
>>>>> +     { .fw_name = "hifi_pll" },
>>>>> +     { .fw_name = "fclk_div2p5" },
>>>>> +     { .fw_name = "fclk_div4" },
>>>>> +     { .fw_name = "gp0_pll" }
>>>>> +};
>> Not seeing gp1 there ? why would you need to dedicate an GP pll for MMC
>> ? Maybe I missing something but it seems to me the usual MMC rate are
>> acheivable with the fclks, especially 2p5.
> Permission reason

use RO ops.

>>
>>>>> +
>>>>> +static struct clk_regmap sd_emmc_a_sel = {
>>>>> +     .data = &(struct clk_regmap_mux_data){
>>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>>> +             .mask = 0x7,
>>>>> +             .shift = 9,
>>>>> +             .table = emmc_parent_table,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data){
>>>>> +             .name = "sd_emmc_a_sel",
>>>>> +             .ops = &clk_regmap_mux_ops,
>>>>> +             .parent_data = emmc_parent_data,
>>>>> +             .num_parents = ARRAY_SIZE(emmc_parent_data),
>>>>> +     },
>>>>> +};
>>>>> +
>>>>> +static struct clk_regmap sd_emmc_a_div = {
>>>>> +     .data = &(struct clk_regmap_div_data){
>>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>>> +             .shift = 0,
>>>>> +             .width = 7,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data){
>>>>> +             .name = "sd_emmc_a_div",
>>>>> +             .ops = &clk_regmap_divider_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &sd_emmc_a_sel.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>>> +     },
>>>>> +};
>>>>> +
>>>>> +static struct clk_regmap sd_emmc_a = {
>>>>> +     .data = &(struct clk_regmap_gate_data){
>>>>> +             .offset = SD_EMMC_CLK_CTRL,
>>>>> +             .bit_idx = 7,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data) {
>>>>> +             .name = "sd_emmc_a",
>>>>> +             .ops = &clk_regmap_gate_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &sd_emmc_a_div.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>>> +     },
>>>>> +};

[...]

>>>>> +static u32 csi_phy_parent_table[] = { 0, 1, 2, 3, 4, 5, 7 };
>>>> Same here and all following instance
>>>>
>>> This 1 corresponds to gp1 pll, which is currently dedicated to emmc.
>> No it is not. Again mainline drivers are slightly different from AML
>> fork you might be used to. No PLL is dedicated to the mmc driver.
>> Unless you can make a strong case for it, I don't think it will happen
>> in the near future.
> For performance considerations, emmc needs to use a higher frequency clock
> source (currently our emmc driver has been adapted to 1152M), so we
> internally allocate gp1_pll to emmc.As mentioned above, the gp1_pll
> register permission problem is masked here first🙂

Your GP1 is controlled by the SCP FW and RO for the kernel. That's all from
the clock controller POV.

No reason to remove it here and elsewhere AFAICT

>>>>> +
>>>>> +static const struct clk_parent_data csi_phy_parent_data[] = {
>>>>> +     { .fw_name = "fclk_div2p5" },
>>>>> +     { .fw_name = "fclk_div3" },
>>>>> +     { .fw_name = "fclk_div4" },
>>>>> +     { .fw_name = "fclk_div5" },
>>>>> +     { .fw_name = "gp0_pll" },
>>>>> +     { .fw_name = "hifi_pll" },
>>>>> +     { .fw_name = "xtal" }
>>>>> +};
>>>>> +
>>>>> +static struct clk_regmap csi_phy0_sel = {
>>>>> +     .data = &(struct clk_regmap_mux_data){
>>>>> +             .offset = ISP0_CLK_CTRL,
>>>>> +             .mask = 0x7,
>>>>> +             .shift = 25,
>>>>> +             .table = csi_phy_parent_table,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data){
>>>>> +             .name = "csi_phy0_sel",
>>>>> +             .ops = &clk_regmap_mux_ops,
>>>>> +             .parent_data = csi_phy_parent_data,
>>>>> +             .num_parents = ARRAY_SIZE(csi_phy_parent_data),
>>>>> +     },
>>>>> +};
>>>>> +
>>>>> +static struct clk_regmap csi_phy0_div = {
>>>>> +     .data = &(struct clk_regmap_div_data){
>>>>> +             .offset = ISP0_CLK_CTRL,
>>>>> +             .shift = 16,
>>>>> +             .width = 7,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data){
>>>>> +             .name = "csi_phy0_div",
>>>>> +             .ops = &clk_regmap_divider_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &csi_phy0_sel.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>>> +     },
>>>>> +};
>>>>> +
>>>>> +static struct clk_regmap csi_phy0 = {
>>>>> +     .data = &(struct clk_regmap_gate_data){
>>>>> +             .offset = ISP0_CLK_CTRL,
>>>>> +             .bit_idx = 24,
>>>>> +     },
>>>>> +     .hw.init = &(struct clk_init_data) {
>>>>> +             .name = "csi_phy0",
>>>>> +             .ops = &clk_regmap_gate_ops,
>>>>> +             .parent_hws = (const struct clk_hw *[]) {
>>>>> +                     &csi_phy0_div.hw
>>>>> +             },
>>>>> +             .num_parents = 1,
>>>>> +             .flags = CLK_SET_RATE_PARENT,
>>>>> +     },
>>>>> +};

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

end of thread, other threads:[~2023-10-17 15:36 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-10  6:29 [PATCH V2 0/4] Add C3 SoC PLLs and Peripheral clock Xianwei Zhao
2023-10-10  6:29 ` [PATCH V2 1/4] dt-bindings: clock: add Amlogic C3 PLL clock controller bindings Xianwei Zhao
2023-10-10  7:22   ` Rob Herring
2023-10-10 13:21   ` Rob Herring
2023-10-11  2:50     ` Xianwei Zhao
2023-10-13  7:35       ` Jerome Brunet
2023-10-16  6:41         ` Xianwei Zhao
2023-10-10  6:29 ` [PATCH V2 2/4] dt-bindings: clock: add Amlogic C3 peripherals " Xianwei Zhao
2023-10-10  7:22   ` Rob Herring
2023-10-10 13:25   ` Rob Herring
2023-10-11  2:54     ` Xianwei Zhao
2023-10-10  6:29 ` [PATCH V2 3/4] clk: meson: c3: add support for the C3 SoC PLL clock Xianwei Zhao
2023-10-13  7:49   ` Jerome Brunet
2023-10-17  6:15     ` Xianwei Zhao
2023-10-17 13:06       ` Jerome Brunet
2023-10-17 14:39         ` Chuan Liu
2023-10-17 14:42           ` Jerome Brunet
2023-10-10  6:29 ` [PATCH V2 4/4] clk: meson: c3: add c3 clock peripherals controller driver Xianwei Zhao
2023-10-12 23:51   ` Stephen Boyd
2023-10-13  7:38     ` Jerome Brunet
2023-10-13 22:01       ` Stephen Boyd
2023-10-16  6:49         ` Xianwei Zhao
2023-10-13  8:46   ` Jerome Brunet
2023-10-17  3:25     ` Xianwei Zhao
2023-10-17 13:28       ` Jerome Brunet
2023-10-17 14:59         ` Chuan Liu
2023-10-17 15:21           ` Jerome Brunet

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).