Changes since V7 [1]:
- Remove included head file not used.
- Link to v7: https://lore.kernel.org/all/[email protected]
Changes since V6 [12]:
- Add pad src for rtc clock.
- Add SCMI clock controller support, move some clock node in SCMI,such as GP1 PLL DDR USB etc.
- Fix some spelling mistake.
- Use lower case for bindings and update some input clocks desc.
- Update some clock comments.
- Delete prefix "AML_" for macro definition.
- Addd some clock annotation and some clock flag CRITICAL.
- Add maximum for regmap_config.
- Delete some unused register definition and unused clock inputs.
- Drop patch subject redundant "bindings". Suggested by Krzysztof.
- Not reference header file "clk.h" and replace comment. Suggested by Jerome.
- Modify description about board in Kconfig file help item. Suggested by Jerome.
- Link to v6: https://lore.kernel.org/all/[email protected]
Changes since V5 [3]:
- Fix some typo and modify formart for MARCO. Suggested by Jerome.
- Add pad clock for peripheral input clock in bindings.
- Add some description for explaining why ddr_dpll_pt_clk and cts_msr_clk are out of tree.
Changes since V4 [10]:
- Change some fw_name of clocks. Suggested by Jerome.
- Delete minItem of clocks.
- Add CLk_GET_RATE_NOCACHE flags for gp1_pll
- Fix some format. and fix width as 8 for mclk_pll_dco.
- exchange gate and divder for fclk_50m clock.
- add CLK_SET_RATE_PARENT for axi_a_divder & axi_b_divder.
- add CLK_IS_CRITICAL for axi_clk
- Optimized macro define for pwm clk.
- add cts_oscin_clk mux between 24M and 32k
- add some missing gate clock, such as ddr_pll.
Changes since V3 [7]:
- Modify Kconfig desc and PLL yaml clk desc.
- Fix some format.Suggested by Yixun and Jerome.
- Add flag CLK_GET_RATE_NOCACHE for sys_clk.
- Optimized macro define for pwm clk.
- Use flag CLK_IS_CRITICAL for axi_clk.
- Add some description for some clocks.
- Use FCLK_50M instead of FCLK_DIV40.
Changes since V2 [4]:
- Modify some format, include clk name & inline, and so on.
- Define marco for pwm clock.
- Add GP1_PLL clock.
- Modify yaml use raw instead of macro.
Changes since V1 [2]:
- Fix errors when check binding by using "make dt_binding_check".
- Delete macro definition.
Xianwei Zhao (5):
dt-bindings: clock: add Amlogic C3 PLL clock controller
dt-bindings: clock: add Amlogic C3 SCMI clock controller support
dt-bindings: clock: add Amlogic C3 peripherals clock controller
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 | 120 +
.../bindings/clock/amlogic,c3-pll-clkc.yaml | 59 +
drivers/clk/meson/Kconfig | 29 +
drivers/clk/meson/Makefile | 2 +
drivers/clk/meson/c3-peripherals.c | 2365 +++++++++++++++++
drivers/clk/meson/c3-pll.c | 746 ++++++
.../clock/amlogic,c3-peripherals-clkc.h | 212 ++
.../dt-bindings/clock/amlogic,c3-pll-clkc.h | 40 +
.../dt-bindings/clock/amlogic,c3-scmi-clkc.h | 27 +
9 files changed, 3600 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-pll.c
create mode 100644 include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h
create mode 100644 include/dt-bindings/clock/amlogic,c3-scmi-clkc.h
base-commit: ba535bce57e71463a86f8b33a0ea88c26e3a6418
--
2.39.2
Add the SCMI clock controller dt-bindings for Amlogic C3 SoC family
Acked-by: Rob Herring (Arm) <[email protected]>
Co-developed-by: Chuan Liu <[email protected]>
Signed-off-by: Chuan Liu <[email protected]>
Signed-off-by: Xianwei Zhao <[email protected]>
---
.../dt-bindings/clock/amlogic,c3-scmi-clkc.h | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 include/dt-bindings/clock/amlogic,c3-scmi-clkc.h
diff --git a/include/dt-bindings/clock/amlogic,c3-scmi-clkc.h b/include/dt-bindings/clock/amlogic,c3-scmi-clkc.h
new file mode 100644
index 000000000000..663c9b349275
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,c3-scmi-clkc.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
+ * Author: Chuan Liu <[email protected]>
+ */
+
+#ifndef __AMLOGIC_C3_SCMI_CLKC_H
+#define __AMLOGIC_C3_SCMI_CLKC_H
+
+#define CLKID_DDR_PLL_OSC 0
+#define CLKID_DDR_PHY 1
+#define CLKID_TOP_PLL_OSC 2
+#define CLKID_USB_PLL_OSC 3
+#define CLKID_MIPIISP_VOUT 4
+#define CLKID_MCLK_PLL_OSC 5
+#define CLKID_USB_CTRL 6
+#define CLKID_ETH_PLL_OSC 7
+#define CLKID_OSC 8
+#define CLKID_SYS_CLK 9
+#define CLKID_AXI_CLK 10
+#define CLKID_CPU_CLK 11
+#define CLKID_FIXED_PLL_OSC 12
+#define CLKID_GP1_PLL_OSC 13
+#define CLKID_SYS_PLL_DIV16 14
+#define CLKID_CPU_CLK_DIV16 15
+
+#endif /* __AMLOGIC_C3_SCMI_CLKC_H */
--
2.39.2
Add the peripherals clock controller dt-bindings for Amlogic C3 SoC family
Reviewed-by: Rob Herring (Arm) <[email protected]>
Co-developed-by: Chuan Liu <[email protected]>
Signed-off-by: Chuan Liu <[email protected]>
Signed-off-by: Xianwei Zhao <[email protected]>
---
.../clock/amlogic,c3-peripherals-clkc.yaml | 120 ++++++++++
.../clock/amlogic,c3-peripherals-clkc.h | 212 ++++++++++++++++++
2 files changed, 332 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..98e30b8c0529
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,c3-peripherals-clkc.yaml
@@ -0,0 +1,120 @@
+# 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 C3 series Peripheral Clock Controller
+
+maintainers:
+ - Neil Armstrong <[email protected]>
+ - Jerome Brunet <[email protected]>
+ - Xianwei Zhao <[email protected]>
+ - Chuan Liu <[email protected]>
+
+properties:
+ compatible:
+ const: amlogic,c3-peripherals-clkc
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 16
+ items:
+ - description: input oscillator (usually at 24MHz)
+ - description: input oscillators multiplexer
+ - description: input fix pll
+ - description: input fclk div 2
+ - description: input fclk div 2p5
+ - description: input fclk div 3
+ - description: input fclk div 4
+ - description: input fclk div 5
+ - description: input fclk div 7
+ - description: input gp0 pll
+ - description: input gp1 pll
+ - description: input hifi pll
+ - description: input sys clk
+ - description: input axi clk
+ - description: input sys pll div 16
+ - description: input cpu clk div 16
+ - description: input pad clock for rtc clk (optional)
+
+ clock-names:
+ minItems: 16
+ items:
+ - const: xtal_24m
+ - const: oscin
+ - const: fix
+ - const: fdiv2
+ - const: fdiv2p5
+ - const: fdiv3
+ - const: fdiv4
+ - const: fdiv5
+ - const: fdiv7
+ - const: gp0
+ - const: gp1
+ - const: hifi
+ - const: sysclk
+ - const: axiclk
+ - const: sysplldiv16
+ - const: cpudiv16
+ - const: pad_osc
+
+ "#clock-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ apb {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clock-controller@0 {
+ compatible = "amlogic,c3-peripherals-clkc";
+ reg = <0x0 0x0 0x0 0x49c>;
+ #clock-cells = <1>;
+ clocks = <&xtal_24m>,
+ <&scmi_clk 8>,
+ <&scmi_clk 12>,
+ <&clkc_pll 3>,
+ <&clkc_pll 5>,
+ <&clkc_pll 7>,
+ <&clkc_pll 9>,
+ <&clkc_pll 11>,
+ <&clkc_pll 13>,
+ <&clkc_pll 15>,
+ <&scmi_clk 13>,
+ <&clkc_pll 17>,
+ <&scmi_clk 9>,
+ <&scmi_clk 10>,
+ <&scmi_clk 14>,
+ <&scmi_clk 15>;
+ clock-names = "xtal_24m",
+ "oscin",
+ "fix",
+ "fdiv2",
+ "fdiv2p5",
+ "fdiv3",
+ "fdiv4",
+ "fdiv5",
+ "fdiv7",
+ "gp0",
+ "gp1",
+ "hifi",
+ "sysclk",
+ "axiclk",
+ "sysplldiv16",
+ "cpudiv16";
+ };
+ };
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..d115c741c255
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2023 Amlogic, Inc. All rights reserved.
+ * Author: Chuan Liu <[email protected]>
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
+#define _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H
+
+#define CLKID_RTC_XTAL_CLKIN 0
+#define CLKID_RTC_32K_DIV 1
+#define CLKID_RTC_32K_MUX 2
+#define CLKID_RTC_32K 3
+#define CLKID_RTC_CLK 4
+#define CLKID_SYS_RESET_CTRL 5
+#define CLKID_SYS_PWR_CTRL 6
+#define CLKID_SYS_PAD_CTRL 7
+#define CLKID_SYS_CTRL 8
+#define CLKID_SYS_TS_PLL 9
+#define CLKID_SYS_DEV_ARB 10
+#define CLKID_SYS_MMC_PCLK 11
+#define CLKID_SYS_CPU_CTRL 12
+#define CLKID_SYS_JTAG_CTRL 13
+#define CLKID_SYS_IR_CTRL 14
+#define CLKID_SYS_IRQ_CTRL 15
+#define CLKID_SYS_MSR_CLK 16
+#define CLKID_SYS_ROM 17
+#define CLKID_SYS_UART_F 18
+#define CLKID_SYS_CPU_ARB 19
+#define CLKID_SYS_RSA 20
+#define CLKID_SYS_SAR_ADC 21
+#define CLKID_SYS_STARTUP 22
+#define CLKID_SYS_SECURE 23
+#define CLKID_SYS_SPIFC 24
+#define CLKID_SYS_NNA 25
+#define CLKID_SYS_ETH_MAC 26
+#define CLKID_SYS_GIC 27
+#define CLKID_SYS_RAMA 28
+#define CLKID_SYS_BIG_NIC 29
+#define CLKID_SYS_RAMB 30
+#define CLKID_SYS_AUDIO_PCLK 31
+#define CLKID_SYS_PWM_KL 32
+#define CLKID_SYS_PWM_IJ 33
+#define CLKID_SYS_USB 34
+#define CLKID_SYS_SD_EMMC_A 35
+#define CLKID_SYS_SD_EMMC_C 36
+#define CLKID_SYS_PWM_AB 37
+#define CLKID_SYS_PWM_CD 38
+#define CLKID_SYS_PWM_EF 39
+#define CLKID_SYS_PWM_GH 40
+#define CLKID_SYS_SPICC_1 41
+#define CLKID_SYS_SPICC_0 42
+#define CLKID_SYS_UART_A 43
+#define CLKID_SYS_UART_B 44
+#define CLKID_SYS_UART_C 45
+#define CLKID_SYS_UART_D 46
+#define CLKID_SYS_UART_E 47
+#define CLKID_SYS_I2C_M_A 48
+#define CLKID_SYS_I2C_M_B 49
+#define CLKID_SYS_I2C_M_C 50
+#define CLKID_SYS_I2C_M_D 51
+#define CLKID_SYS_I2S_S_A 52
+#define CLKID_SYS_RTC 53
+#define CLKID_SYS_GE2D 54
+#define CLKID_SYS_ISP 55
+#define CLKID_SYS_GPV_ISP_NIC 56
+#define CLKID_SYS_GPV_CVE_NIC 57
+#define CLKID_SYS_MIPI_DSI_HOST 58
+#define CLKID_SYS_MIPI_DSI_PHY 59
+#define CLKID_SYS_ETH_PHY 60
+#define CLKID_SYS_ACODEC 61
+#define CLKID_SYS_DWAP 62
+#define CLKID_SYS_DOS 63
+#define CLKID_SYS_CVE 64
+#define CLKID_SYS_VOUT 65
+#define CLKID_SYS_VC9000E 66
+#define CLKID_SYS_PWM_MN 67
+#define CLKID_SYS_SD_EMMC_B 68
+#define CLKID_AXI_SYS_NIC 69
+#define CLKID_AXI_ISP_NIC 70
+#define CLKID_AXI_CVE_NIC 71
+#define CLKID_AXI_RAMB 72
+#define CLKID_AXI_RAMA 73
+#define CLKID_AXI_CPU_DMC 74
+#define CLKID_AXI_NIC 75
+#define CLKID_AXI_DMA 76
+#define CLKID_AXI_MUX_NIC 77
+#define CLKID_AXI_CVE 78
+#define CLKID_AXI_DEV1_DMC 79
+#define CLKID_AXI_DEV0_DMC 80
+#define CLKID_AXI_DSP_DMC 81
+#define CLKID_12_24M_IN 82
+#define CLKID_12M_24M 83
+#define CLKID_FCLK_25M_DIV 84
+#define CLKID_FCLK_25M 85
+#define CLKID_GEN_SEL 86
+#define CLKID_GEN_DIV 87
+#define CLKID_GEN 88
+#define CLKID_SARADC_SEL 89
+#define CLKID_SARADC_DIV 90
+#define CLKID_SARADC 91
+#define CLKID_PWM_A_SEL 92
+#define CLKID_PWM_A_DIV 93
+#define CLKID_PWM_A 94
+#define CLKID_PWM_B_SEL 95
+#define CLKID_PWM_B_DIV 96
+#define CLKID_PWM_B 97
+#define CLKID_PWM_C_SEL 98
+#define CLKID_PWM_C_DIV 99
+#define CLKID_PWM_C 100
+#define CLKID_PWM_D_SEL 101
+#define CLKID_PWM_D_DIV 102
+#define CLKID_PWM_D 103
+#define CLKID_PWM_E_SEL 104
+#define CLKID_PWM_E_DIV 105
+#define CLKID_PWM_E 106
+#define CLKID_PWM_F_SEL 107
+#define CLKID_PWM_F_DIV 108
+#define CLKID_PWM_F 109
+#define CLKID_PWM_G_SEL 110
+#define CLKID_PWM_G_DIV 111
+#define CLKID_PWM_G 112
+#define CLKID_PWM_H_SEL 113
+#define CLKID_PWM_H_DIV 114
+#define CLKID_PWM_H 115
+#define CLKID_PWM_I_SEL 116
+#define CLKID_PWM_I_DIV 117
+#define CLKID_PWM_I 118
+#define CLKID_PWM_J_SEL 119
+#define CLKID_PWM_J_DIV 120
+#define CLKID_PWM_J 121
+#define CLKID_PWM_K_SEL 122
+#define CLKID_PWM_K_DIV 123
+#define CLKID_PWM_K 124
+#define CLKID_PWM_L_SEL 125
+#define CLKID_PWM_L_DIV 126
+#define CLKID_PWM_L 127
+#define CLKID_PWM_M_SEL 128
+#define CLKID_PWM_M_DIV 129
+#define CLKID_PWM_M 130
+#define CLKID_PWM_N_SEL 131
+#define CLKID_PWM_N_DIV 132
+#define CLKID_PWM_N 133
+#define CLKID_SPICC_A_SEL 134
+#define CLKID_SPICC_A_DIV 135
+#define CLKID_SPICC_A 136
+#define CLKID_SPICC_B_SEL 137
+#define CLKID_SPICC_B_DIV 138
+#define CLKID_SPICC_B 139
+#define CLKID_SPIFC_SEL 140
+#define CLKID_SPIFC_DIV 141
+#define CLKID_SPIFC 142
+#define CLKID_SD_EMMC_A_SEL 143
+#define CLKID_SD_EMMC_A_DIV 144
+#define CLKID_SD_EMMC_A 145
+#define CLKID_SD_EMMC_B_SEL 146
+#define CLKID_SD_EMMC_B_DIV 147
+#define CLKID_SD_EMMC_B 148
+#define CLKID_SD_EMMC_C_SEL 149
+#define CLKID_SD_EMMC_C_DIV 150
+#define CLKID_SD_EMMC_C 151
+#define CLKID_TS_DIV 152
+#define CLKID_TS 153
+#define CLKID_ETH_125M_DIV 154
+#define CLKID_ETH_125M 155
+#define CLKID_ETH_RMII_DIV 156
+#define CLKID_ETH_RMII 157
+#define CLKID_MIPI_DSI_MEAS_SEL 158
+#define CLKID_MIPI_DSI_MEAS_DIV 159
+#define CLKID_MIPI_DSI_MEAS 160
+#define CLKID_DSI_PHY_SEL 161
+#define CLKID_DSI_PHY_DIV 162
+#define CLKID_DSI_PHY 163
+#define CLKID_VOUT_MCLK_SEL 164
+#define CLKID_VOUT_MCLK_DIV 165
+#define CLKID_VOUT_MCLK 166
+#define CLKID_VOUT_ENC_SEL 167
+#define CLKID_VOUT_ENC_DIV 168
+#define CLKID_VOUT_ENC 169
+#define CLKID_HCODEC_0_SEL 170
+#define CLKID_HCODEC_0_DIV 171
+#define CLKID_HCODEC_0 172
+#define CLKID_HCODEC_1_SEL 173
+#define CLKID_HCODEC_1_DIV 174
+#define CLKID_HCODEC_1 175
+#define CLKID_HCODEC 176
+#define CLKID_VC9000E_ACLK_SEL 177
+#define CLKID_VC9000E_ACLK_DIV 178
+#define CLKID_VC9000E_ACLK 179
+#define CLKID_VC9000E_CORE_SEL 180
+#define CLKID_VC9000E_CORE_DIV 181
+#define CLKID_VC9000E_CORE 182
+#define CLKID_CSI_PHY0_SEL 183
+#define CLKID_CSI_PHY0_DIV 184
+#define CLKID_CSI_PHY0 185
+#define CLKID_DEWARPA_SEL 186
+#define CLKID_DEWARPA_DIV 187
+#define CLKID_DEWARPA 188
+#define CLKID_ISP0_SEL 189
+#define CLKID_ISP0_DIV 190
+#define CLKID_ISP0 191
+#define CLKID_NNA_CORE_SEL 192
+#define CLKID_NNA_CORE_DIV 193
+#define CLKID_NNA_CORE 194
+#define CLKID_GE2D_SEL 195
+#define CLKID_GE2D_DIV 196
+#define CLKID_GE2D 197
+#define CLKID_VAPB_SEL 198
+#define CLKID_VAPB_DIV 199
+#define CLKID_VAPB 200
+
+#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_C3_PERIPHERALS_CLKC_H */
--
2.39.2
Add the C3 PLL clock controller driver for the Amlogic C3 SoC family.
Co-developed-by: Chuan Liu <[email protected]>
Signed-off-by: Chuan Liu <[email protected]>
Signed-off-by: Xianwei Zhao <[email protected]>
---
drivers/clk/meson/Kconfig | 14 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/c3-pll.c | 746 +++++++++++++++++++++++++++++++++++++
3 files changed, 761 insertions(+)
create mode 100644 drivers/clk/meson/c3-pll.c
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 29ffd14d267b..9f975a980581 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -128,6 +128,20 @@ 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"
+ depends on ARM64
+ depends on ARM_SCMI_PROTOCOL
+ depends on COMMON_CLK_SCMI
+ 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. 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..74e11add165c
--- /dev/null
+++ b/drivers/clk/meson/c3-pll.c
@@ -0,0 +1,746 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Amlogic C3 PLL Controller Driver
+ *
+ * Copyright (c) 2023 Amlogic, inc.
+ * Author: Chuan Liu <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "meson-clkc-utils.h"
+#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
+
+#define ANACTRL_FIXPLL_CTRL4 0x50
+#define ANACTRL_GP0PLL_CTRL0 0x80
+#define ANACTRL_GP0PLL_CTRL1 0x84
+#define ANACTRL_GP0PLL_CTRL2 0x88
+#define ANACTRL_GP0PLL_CTRL3 0x8c
+#define ANACTRL_GP0PLL_CTRL4 0x90
+#define ANACTRL_GP0PLL_CTRL5 0x94
+#define ANACTRL_GP0PLL_CTRL6 0x98
+#define ANACTRL_HIFIPLL_CTRL0 0x100
+#define ANACTRL_HIFIPLL_CTRL1 0x104
+#define ANACTRL_HIFIPLL_CTRL2 0x108
+#define ANACTRL_HIFIPLL_CTRL3 0x10c
+#define ANACTRL_HIFIPLL_CTRL4 0x110
+#define ANACTRL_HIFIPLL_CTRL5 0x114
+#define ANACTRL_HIFIPLL_CTRL6 0x118
+#define ANACTRL_MPLL_CTRL0 0x180
+#define ANACTRL_MPLL_CTRL1 0x184
+#define ANACTRL_MPLL_CTRL2 0x188
+#define ANACTRL_MPLL_CTRL3 0x18c
+#define ANACTRL_MPLL_CTRL4 0x190
+
+static struct clk_regmap fclk_50m_en = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ANACTRL_FIXPLL_CTRL4,
+ .bit_idx = 0,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "fclk_50m_en",
+ .ops = &clk_regmap_gate_ro_ops,
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "fix"
+ },
+ .num_parents = 1,
+ },
+};
+
+static struct clk_fixed_factor fclk_50m = {
+ .mult = 1,
+ .div = 40,
+ .hw.init = &(struct clk_init_data) {
+ .name = "fclk_50m",
+ .ops = &clk_fixed_factor_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &fclk_50m_en.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_data = &(const struct clk_parent_data) {
+ .fw_name = "fix"
+ },
+ .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_data = &(const struct clk_parent_data) {
+ .fw_name = "fix"
+ },
+ .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_data = &(const struct clk_parent_data) {
+ .fw_name = "fix"
+ },
+ .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_data = &(const struct clk_parent_data) {
+ .fw_name = "fix"
+ },
+ .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_data = &(const struct clk_parent_data) {
+ .fw_name = "fix"
+ },
+ .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_data = &(const struct clk_parent_data) {
+ .fw_name = "fix"
+ },
+ .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_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 },
+};
+
+static const struct pll_mult_range c3_gp0_pll_mult_range = {
+ .min = 125,
+ .max = 250,
+};
+
+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,
+ },
+ .range = &c3_gp0_pll_mult_range,
+ .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 = &(const struct clk_parent_data) {
+ .fw_name = "top",
+ },
+ .num_parents = 1,
+ },
+};
+
+/* 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 = {
+ .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_CTRL2, .def = 0x0 },
+ { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 },
+ { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
+ { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
+ { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000 },
+};
+
+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,
+ },
+ .range = &c3_gp0_pll_mult_range,
+ .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 = &(const struct clk_parent_data) {
+ .fw_name = "top",
+ },
+ .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_CTRL1, .def = 0x1420500f },
+ { .reg = ANACTRL_MPLL_CTRL2, .def = 0x00023041 },
+ { .reg = ANACTRL_MPLL_CTRL3, .def = 0x18180000 },
+ { .reg = ANACTRL_MPLL_CTRL2, .def = 0x00023001 }
+};
+
+static const struct pll_mult_range c3_mclk_pll_mult_range = {
+ .min = 67,
+ .max = 133,
+};
+
+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 = 8,
+ },
+ .n = {
+ .reg_off = ANACTRL_MPLL_CTRL0,
+ .shift = 16,
+ .width = 5,
+ },
+ .l = {
+ .reg_off = ANACTRL_MPLL_CTRL0,
+ .shift = 31,
+ .width = 1,
+ },
+ .rst = {
+ .reg_off = ANACTRL_MPLL_CTRL0,
+ .shift = 29,
+ .width = 1,
+ },
+ .range = &c3_mclk_pll_mult_range,
+ .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 = &(const struct clk_parent_data) {
+ .fw_name = "mclk",
+ },
+ .num_parents = 1,
+ },
+};
+
+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_od = {
+ .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_od",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &mclk_pll_dco.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+/* both value 0 and 1 gives divide the input rate by one */
+static struct clk_regmap mclk_pll = {
+ .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",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &mclk_pll_od.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data mclk_parent[] = {
+ { .hw = &mclk_pll.hw },
+ { .fw_name = "mclk" },
+ { .hw = &fclk_50m.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_div_en = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ANACTRL_MPLL_CTRL4,
+ .bit_idx = 1,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "mclk0_div_en",
+ .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_div_en.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_div_en = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ANACTRL_MPLL_CTRL4,
+ .bit_idx = 9,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "mclk1_div_en",
+ .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_div_en.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_FCLK_50M_EN] = &fclk_50m_en.hw,
+ [CLKID_FCLK_50M] = &fclk_50m.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_OD] = &mclk_pll_od.hw,
+ [CLKID_MCLK_PLL] = &mclk_pll.hw,
+ [CLKID_MCLK0_SEL] = &mclk0_sel.hw,
+ [CLKID_MCLK0_SEL_EN] = &mclk0_div_en.hw,
+ [CLKID_MCLK0_DIV] = &mclk0_div.hw,
+ [CLKID_MCLK0] = &mclk0.hw,
+ [CLKID_MCLK1_SEL] = &mclk1_sel.hw,
+ [CLKID_MCLK1_SEL_EN] = &mclk1_div_en.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[] = {
+ &fclk_50m_en,
+ &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_od,
+ &mclk_pll,
+ &mclk0_sel,
+ &mclk0_div_en,
+ &mclk0_div,
+ &mclk0,
+ &mclk1_sel,
+ &mclk1_div_en,
+ &mclk1_div,
+ &mclk1,
+};
+
+static struct regmap_config clkc_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = ANACTRL_MPLL_CTRL4,
+};
+
+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 <[email protected]>");
+MODULE_LICENSE("GPL");
--
2.39.2
Add the C3 peripherals clock controller driver in the C3 SoC family.
Co-developed-by: Chuan Liu <[email protected]>
Signed-off-by: Chuan Liu <[email protected]>
Signed-off-by: Xianwei Zhao <[email protected]>
---
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/c3-peripherals.c | 2365 ++++++++++++++++++++++++++++
3 files changed, 2381 insertions(+)
create mode 100644 drivers/clk/meson/c3-peripherals.c
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 9f975a980581..0b85d584910e 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -142,6 +142,21 @@ config COMMON_CLK_C3_PLL
AKA C3. 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"
+ depends on ARM64
+ depends on ARM_SCMI_PROTOCOL
+ depends on COMMON_CLK_SCMI
+ depends on COMMON_CLK_C3_PLL
+ default y
+ select COMMON_CLK_MESON_REGMAP
+ select COMMON_CLK_MESON_DUALDIV
+ select COMMON_CLK_MESON_CLKC_UTILS
+ help
+ Support for the Peripherals clock controller on Amlogic C302X and
+ C308L devices, AKA C3. 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..b786d8ff9be0
--- /dev/null
+++ b/drivers/clk/meson/c3-peripherals.c
@@ -0,0 +1,2365 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Amlogic C3 Peripherals Clock Controller Driver
+ *
+ * Copyright (c) 2023 Amlogic, inc.
+ * Author: Chuan Liu <[email protected]>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
+
+#define RTC_BY_OSCIN_CTRL0 0x8
+#define RTC_BY_OSCIN_CTRL1 0xc
+#define RTC_CTRL 0x10
+#define SYS_CLK_EN0_REG0 0x44
+#define SYS_CLK_EN0_REG1 0x48
+#define SYS_CLK_EN0_REG2 0x4c
+#define CLK12_24_CTRL 0xa8
+#define AXI_CLK_EN0 0xac
+#define VDIN_MEAS_CLK_CTRL 0xf8
+#define VAPB_CLK_CTRL 0xfc
+#define MIPIDSI_PHY_CLK_CTRL 0x104
+#define GE2D_CLK_CTRL 0x10c
+#define ISP0_CLK_CTRL 0x110
+#define DEWARPA_CLK_CTRL 0x114
+#define VOUTENC_CLK_CTRL 0x118
+#define VDEC_CLK_CTRL 0x140
+#define VDEC3_CLK_CTRL 0x148
+#define TS_CLK_CTRL 0x158
+#define ETH_CLK_CTRL 0x164
+#define NAND_CLK_CTRL 0x168
+#define SD_EMMC_CLK_CTRL 0x16c
+#define SPICC_CLK_CTRL 0x174
+#define GEN_CLK_CTRL 0x178
+#define SAR_CLK_CTRL0 0x17c
+#define PWM_CLK_AB_CTRL 0x180
+#define PWM_CLK_CD_CTRL 0x184
+#define PWM_CLK_EF_CTRL 0x188
+#define PWM_CLK_GH_CTRL 0x18c
+#define PWM_CLK_IJ_CTRL 0x190
+#define PWM_CLK_KL_CTRL 0x194
+#define PWM_CLK_MN_CTRL 0x198
+#define VC9000E_CLK_CTRL 0x19c
+#define SPIFC_CLK_CTRL 0x1a0
+#define NNA_CLK_CTRL 0x220
+
+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 = &(const struct clk_parent_data) {
+ .fw_name = "oscin",
+ },
+ .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 = "oscin" },
+ { .hw = &rtc_32k.hw },
+ { .fw_name = "pad_osc" }
+};
+
+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,
+ },
+};
+
+#define C3_CLK_GATE(_name, _reg, _bit, _fw_name, _ops, _flags) \
+struct clk_regmap _name = { \
+ .data = &(struct clk_regmap_gate_data){ \
+ .offset = (_reg), \
+ .bit_idx = (_bit), \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = #_name, \
+ .ops = _ops, \
+ .parent_data = &(const struct clk_parent_data) { \
+ .fw_name = #_fw_name, \
+ }, \
+ .num_parents = 1, \
+ .flags = (_flags), \
+ }, \
+}
+
+#define C3_SYS_GATE(_name, _reg, _bit, _flags) \
+ C3_CLK_GATE(_name, _reg, _bit, sysclk, \
+ &clk_regmap_gate_ops, _flags)
+
+#define C3_SYS_GATE_RO(_name, _reg, _bit) \
+ C3_CLK_GATE(_name, _reg, _bit, sysclk, \
+ &clk_regmap_gate_ro_ops, 0)
+
+static C3_SYS_GATE(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1, 0);
+static C3_SYS_GATE(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3, 0);
+static C3_SYS_GATE(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4, 0);
+static C3_SYS_GATE(sys_ctrl, SYS_CLK_EN0_REG0, 5, 0);
+static C3_SYS_GATE(sys_ts_pll, SYS_CLK_EN0_REG0, 6, 0);
+
+/*
+ * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that
+ * access the AXI bus.
+ */
+static C3_SYS_GATE(sys_dev_arb, SYS_CLK_EN0_REG0, 7, 0);
+
+/*
+ * FIXME: sys_mmc_pclk provides the clock for the DDR PHY, DDR will only be
+ * initialized in bl2, and this clock should not be touched in linux.
+ */
+static C3_SYS_GATE_RO(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
+
+/*
+ * NOTE: sys_cpu_ctrl provides the clock for CPU controller. After clock is
+ * disabled, cpu_clk and other key CPU-related configurations cannot take effect.
+ */
+static C3_SYS_GATE(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11, CLK_IS_CRITICAL);
+static C3_SYS_GATE(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12, 0);
+static C3_SYS_GATE(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13, 0);
+
+/*
+ * NOTE: sys_irq_ctrl provides the clock for IRQ controller. The IRQ controller
+ * collects and distributes the interrupt signal to the GIC, PWR_CTRL, and
+ * AOCPU. If the clock is disabled, interrupt-related functions will occurs an
+ * exception.
+ */
+static C3_SYS_GATE(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14, CLK_IS_CRITICAL);
+static C3_SYS_GATE(sys_msr_clk, SYS_CLK_EN0_REG0, 15, 0);
+static C3_SYS_GATE(sys_rom, SYS_CLK_EN0_REG0, 16, 0);
+static C3_SYS_GATE(sys_uart_f, SYS_CLK_EN0_REG0, 17, 0);
+static C3_SYS_GATE(sys_cpu_apb, SYS_CLK_EN0_REG0, 18, 0);
+static C3_SYS_GATE(sys_rsa, SYS_CLK_EN0_REG0, 19, 0);
+static C3_SYS_GATE(sys_sar_adc, SYS_CLK_EN0_REG0, 20, 0);
+static C3_SYS_GATE(sys_startup, SYS_CLK_EN0_REG0, 21, 0);
+static C3_SYS_GATE(sys_secure, SYS_CLK_EN0_REG0, 22, 0);
+static C3_SYS_GATE(sys_spifc, SYS_CLK_EN0_REG0, 23, 0);
+static C3_SYS_GATE(sys_nna, SYS_CLK_EN0_REG0, 25, 0);
+static C3_SYS_GATE(sys_eth_mac, SYS_CLK_EN0_REG0, 26, 0);
+
+/*
+ * FIXME: sys_gic provides the clock for GIC(Generic Interrupt Controller).
+ * After clock is disabled, The GIC cannot work properly. At present, the driver
+ * used by our GIC is the public driver in kernel, and there is no management
+ * clock in the driver.
+ */
+static C3_SYS_GATE(sys_gic, SYS_CLK_EN0_REG0, 27, CLK_IS_CRITICAL);
+static C3_SYS_GATE(sys_rama, SYS_CLK_EN0_REG0, 28, 0);
+
+/*
+ * NOTE: sys_big_nic provides the clock to the control bus of the NIC(Network
+ * Interface Controller) between multiple devices(CPU, DDR, RAM, ROM, GIC,
+ * SPIFC, CAPU, JTAG, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC) in the
+ * system. After clock is disabled, The NIC cannot work.
+ */
+static C3_SYS_GATE(sys_big_nic, SYS_CLK_EN0_REG0, 29, CLK_IS_CRITICAL);
+static C3_SYS_GATE(sys_ramb, SYS_CLK_EN0_REG0, 30, 0);
+static C3_SYS_GATE(sys_audio_pclk, SYS_CLK_EN0_REG0, 31, 0);
+static C3_SYS_GATE(sys_pwm_kl, SYS_CLK_EN0_REG1, 0, 0);
+static C3_SYS_GATE(sys_pwm_ij, SYS_CLK_EN0_REG1, 1, 0);
+static C3_SYS_GATE(sys_usb, SYS_CLK_EN0_REG1, 2, 0);
+static C3_SYS_GATE(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3, 0);
+static C3_SYS_GATE(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4, 0);
+static C3_SYS_GATE(sys_pwm_ab, SYS_CLK_EN0_REG1, 5, 0);
+static C3_SYS_GATE(sys_pwm_cd, SYS_CLK_EN0_REG1, 6, 0);
+static C3_SYS_GATE(sys_pwm_ef, SYS_CLK_EN0_REG1, 7, 0);
+static C3_SYS_GATE(sys_pwm_gh, SYS_CLK_EN0_REG1, 8, 0);
+static C3_SYS_GATE(sys_spicc_1, SYS_CLK_EN0_REG1, 9, 0);
+static C3_SYS_GATE(sys_spicc_0, SYS_CLK_EN0_REG1, 10, 0);
+static C3_SYS_GATE(sys_uart_a, SYS_CLK_EN0_REG1, 11, 0);
+static C3_SYS_GATE(sys_uart_b, SYS_CLK_EN0_REG1, 12, 0);
+static C3_SYS_GATE(sys_uart_c, SYS_CLK_EN0_REG1, 13, 0);
+static C3_SYS_GATE(sys_uart_d, SYS_CLK_EN0_REG1, 14, 0);
+static C3_SYS_GATE(sys_uart_e, SYS_CLK_EN0_REG1, 15, 0);
+static C3_SYS_GATE(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16, 0);
+static C3_SYS_GATE(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17, 0);
+static C3_SYS_GATE(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18, 0);
+static C3_SYS_GATE(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19, 0);
+static C3_SYS_GATE(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20, 0);
+static C3_SYS_GATE(sys_rtc, SYS_CLK_EN0_REG1, 21, 0);
+static C3_SYS_GATE(sys_ge2d, SYS_CLK_EN0_REG1, 22, 0);
+static C3_SYS_GATE(sys_isp, SYS_CLK_EN0_REG1, 23, 0);
+static C3_SYS_GATE(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24, 0);
+static C3_SYS_GATE(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25, 0);
+static C3_SYS_GATE(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26, 0);
+static C3_SYS_GATE(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27, 0);
+static C3_SYS_GATE(sys_eth_phy, SYS_CLK_EN0_REG1, 28, 0);
+static C3_SYS_GATE(sys_acodec, SYS_CLK_EN0_REG1, 29, 0);
+static C3_SYS_GATE(sys_dwap, SYS_CLK_EN0_REG1, 30, 0);
+static C3_SYS_GATE(sys_dos, SYS_CLK_EN0_REG1, 31, 0);
+static C3_SYS_GATE(sys_cve, SYS_CLK_EN0_REG2, 0, 0);
+static C3_SYS_GATE(sys_vout, SYS_CLK_EN0_REG2, 1, 0);
+static C3_SYS_GATE(sys_vc9000e, SYS_CLK_EN0_REG2, 2, 0);
+static C3_SYS_GATE(sys_pwm_mn, SYS_CLK_EN0_REG2, 3, 0);
+static C3_SYS_GATE(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4, 0);
+
+#define C3_AXI_GATE(_name, _reg, _bit, _flags) \
+ C3_CLK_GATE(_name, _reg, _bit, axiclk, \
+ &clk_regmap_gate_ops, _flags)
+
+/*
+ * NOTE: axi_sys_nic provides the clock to the AXI bus of the system NIC. After
+ * clock is disabled, The NIC cannot work.
+ */
+static C3_AXI_GATE(axi_sys_nic, AXI_CLK_EN0, 2, CLK_IS_CRITICAL);
+static C3_AXI_GATE(axi_isp_nic, AXI_CLK_EN0, 3, 0);
+static C3_AXI_GATE(axi_cve_nic, AXI_CLK_EN0, 4, 0);
+static C3_AXI_GATE(axi_ramb, AXI_CLK_EN0, 5, 0);
+static C3_AXI_GATE(axi_rama, AXI_CLK_EN0, 6, 0);
+
+/*
+ * NOTE: axi_cpu_dmc provides the clock to the AXI bus where the CPU accesses
+ * the DDR. After clock is disabled, The CPU will not have access to the DDR.
+ */
+static C3_AXI_GATE(axi_cpu_dmc, AXI_CLK_EN0, 7, CLK_IS_CRITICAL);
+static C3_AXI_GATE(axi_nic, AXI_CLK_EN0, 8, 0);
+static C3_AXI_GATE(axi_dma, AXI_CLK_EN0, 9, 0);
+
+/*
+ * NOTE: axi_mux_nic provides the clock to the NIC's AXI bus for NN(Neural
+ * Network) and other devices(CPU, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC)
+ * to access RAM space.
+ */
+static C3_AXI_GATE(axi_mux_nic, AXI_CLK_EN0, 10, 0);
+static C3_AXI_GATE(axi_cve, AXI_CLK_EN0, 12, 0);
+
+/*
+ * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO,
+ * sec_top, USB, Audio, ETH, SPICC) to access the AXI bus of the DDR.
+ */
+static C3_AXI_GATE(axi_dev1_dmc, AXI_CLK_EN0, 13, 0);
+static C3_AXI_GATE(axi_dev0_dmc, AXI_CLK_EN0, 14, 0);
+static C3_AXI_GATE(axi_dsp_dmc, AXI_CLK_EN0, 15, 0);
+
+/*
+ * clk_12_24m model
+ *
+ * |------| |-----| clk_12m_24m |-----|
+ * xtal---->| gate |---->| div |------------>| pad |
+ * |------| |-----| |-----|
+ */
+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 = &(const struct clk_parent_data) {
+ .fw_name = "xtal_24m",
+ },
+ .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,
+ },
+};
+
+/* Fix me: set value 0 will div by 2 like value 1 */
+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 = &(const struct clk_parent_data) {
+ .fw_name = "fix",
+ },
+ .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,
+ },
+};
+
+/*
+ * Channel 3(ddr_dpll_pt_clk) is manged by the DDR module; channel 12(cts_msr_clk)
+ * is manged by clock measures module. Their hardware are out of clock tree.
+ * Channel 4 8 9 10 11 13 14 15 16 18 are not connected.
+ */
+static u32 gen_parent_table[] = { 0, 1, 2, 5, 6, 7, 17, 19, 20, 21, 22, 23, 24};
+
+static const struct clk_parent_data gen_parent_data[] = {
+ { .fw_name = "oscin" },
+ { .hw = &rtc_clk.hw },
+ { .fw_name = "sysplldiv16" },
+ { .fw_name = "gp0" },
+ { .fw_name = "gp1" },
+ { .fw_name = "hifi" },
+ { .fw_name = "cpudiv16" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" }
+};
+
+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 = "oscin" },
+ { .fw_name = "sysclk" }
+};
+
+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 const struct clk_parent_data pwm_parent_data[] = {
+ { .fw_name = "oscin" },
+ { .fw_name = "gp1" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv3" }
+};
+
+#define AML_PWM_CLK_MUX(_name, _reg, _shift) { \
+ .data = &(struct clk_regmap_mux_data) { \
+ .offset = _reg, \
+ .mask = 0x3, \
+ .shift = _shift, \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = #_name "_sel", \
+ .ops = &clk_regmap_mux_ops, \
+ .parent_data = pwm_parent_data, \
+ .num_parents = ARRAY_SIZE(pwm_parent_data), \
+ }, \
+}
+
+#define AML_PWM_CLK_DIV(_name, _reg, _shift) { \
+ .data = &(struct clk_regmap_div_data) { \
+ .offset = _reg, \
+ .shift = _shift, \
+ .width = 8, \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = #_name "_div", \
+ .ops = &clk_regmap_divider_ops, \
+ .parent_names = (const char *[]) { #_name "_sel" },\
+ .num_parents = 1, \
+ .flags = CLK_SET_RATE_PARENT, \
+ }, \
+}
+
+#define AML_PWM_CLK_GATE(_name, _reg, _bit) { \
+ .data = &(struct clk_regmap_gate_data) { \
+ .offset = _reg, \
+ .bit_idx = _bit, \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = #_name, \
+ .ops = &clk_regmap_gate_ops, \
+ .parent_names = (const char *[]) { #_name "_div" },\
+ .num_parents = 1, \
+ .flags = CLK_SET_RATE_PARENT, \
+ }, \
+}
+
+static struct clk_regmap pwm_a_sel =
+ AML_PWM_CLK_MUX(pwm_a, PWM_CLK_AB_CTRL, 9);
+static struct clk_regmap pwm_a_div =
+ AML_PWM_CLK_DIV(pwm_a, PWM_CLK_AB_CTRL, 0);
+static struct clk_regmap pwm_a =
+ AML_PWM_CLK_GATE(pwm_a, PWM_CLK_AB_CTRL, 8);
+
+static struct clk_regmap pwm_b_sel =
+ AML_PWM_CLK_MUX(pwm_b, PWM_CLK_AB_CTRL, 25);
+static struct clk_regmap pwm_b_div =
+ AML_PWM_CLK_DIV(pwm_b, PWM_CLK_AB_CTRL, 16);
+static struct clk_regmap pwm_b =
+ AML_PWM_CLK_GATE(pwm_b, PWM_CLK_AB_CTRL, 24);
+
+static struct clk_regmap pwm_c_sel =
+ AML_PWM_CLK_MUX(pwm_c, PWM_CLK_CD_CTRL, 9);
+static struct clk_regmap pwm_c_div =
+ AML_PWM_CLK_DIV(pwm_c, PWM_CLK_CD_CTRL, 0);
+static struct clk_regmap pwm_c =
+ AML_PWM_CLK_GATE(pwm_c, PWM_CLK_CD_CTRL, 8);
+
+static struct clk_regmap pwm_d_sel =
+ AML_PWM_CLK_MUX(pwm_d, PWM_CLK_CD_CTRL, 25);
+static struct clk_regmap pwm_d_div =
+ AML_PWM_CLK_DIV(pwm_d, PWM_CLK_CD_CTRL, 16);
+static struct clk_regmap pwm_d =
+ AML_PWM_CLK_GATE(pwm_d, PWM_CLK_CD_CTRL, 24);
+
+static struct clk_regmap pwm_e_sel =
+ AML_PWM_CLK_MUX(pwm_e, PWM_CLK_EF_CTRL, 9);
+static struct clk_regmap pwm_e_div =
+ AML_PWM_CLK_DIV(pwm_e, PWM_CLK_EF_CTRL, 0);
+static struct clk_regmap pwm_e =
+ AML_PWM_CLK_GATE(pwm_e, PWM_CLK_EF_CTRL, 8);
+
+static struct clk_regmap pwm_f_sel =
+ AML_PWM_CLK_MUX(pwm_f, PWM_CLK_EF_CTRL, 25);
+static struct clk_regmap pwm_f_div =
+ AML_PWM_CLK_DIV(pwm_f, PWM_CLK_EF_CTRL, 16);
+static struct clk_regmap pwm_f =
+ AML_PWM_CLK_GATE(pwm_f, PWM_CLK_EF_CTRL, 24);
+
+static struct clk_regmap pwm_g_sel =
+ AML_PWM_CLK_MUX(pwm_g, PWM_CLK_GH_CTRL, 9);
+static struct clk_regmap pwm_g_div =
+ AML_PWM_CLK_DIV(pwm_g, PWM_CLK_GH_CTRL, 0);
+static struct clk_regmap pwm_g =
+ AML_PWM_CLK_GATE(pwm_g, PWM_CLK_GH_CTRL, 8);
+
+static struct clk_regmap pwm_h_sel =
+ AML_PWM_CLK_MUX(pwm_h, PWM_CLK_GH_CTRL, 25);
+static struct clk_regmap pwm_h_div =
+ AML_PWM_CLK_DIV(pwm_h, PWM_CLK_GH_CTRL, 16);
+static struct clk_regmap pwm_h =
+ AML_PWM_CLK_GATE(pwm_h, PWM_CLK_GH_CTRL, 24);
+
+static struct clk_regmap pwm_i_sel =
+ AML_PWM_CLK_MUX(pwm_i, PWM_CLK_IJ_CTRL, 9);
+static struct clk_regmap pwm_i_div =
+ AML_PWM_CLK_DIV(pwm_i, PWM_CLK_IJ_CTRL, 0);
+static struct clk_regmap pwm_i =
+ AML_PWM_CLK_GATE(pwm_i, PWM_CLK_IJ_CTRL, 8);
+
+static struct clk_regmap pwm_j_sel =
+ AML_PWM_CLK_MUX(pwm_j, PWM_CLK_IJ_CTRL, 25);
+static struct clk_regmap pwm_j_div =
+ AML_PWM_CLK_DIV(pwm_j, PWM_CLK_IJ_CTRL, 16);
+static struct clk_regmap pwm_j =
+ AML_PWM_CLK_GATE(pwm_j, PWM_CLK_IJ_CTRL, 24);
+
+static struct clk_regmap pwm_k_sel =
+ AML_PWM_CLK_MUX(pwm_k, PWM_CLK_KL_CTRL, 9);
+static struct clk_regmap pwm_k_div =
+ AML_PWM_CLK_DIV(pwm_k, PWM_CLK_KL_CTRL, 0);
+static struct clk_regmap pwm_k =
+ AML_PWM_CLK_GATE(pwm_k, PWM_CLK_KL_CTRL, 8);
+
+static struct clk_regmap pwm_l_sel =
+ AML_PWM_CLK_MUX(pwm_l, PWM_CLK_KL_CTRL, 25);
+static struct clk_regmap pwm_l_div =
+ AML_PWM_CLK_DIV(pwm_l, PWM_CLK_KL_CTRL, 16);
+static struct clk_regmap pwm_l =
+ AML_PWM_CLK_GATE(pwm_l, PWM_CLK_KL_CTRL, 24);
+
+static struct clk_regmap pwm_m_sel =
+ AML_PWM_CLK_MUX(pwm_m, PWM_CLK_MN_CTRL, 9);
+static struct clk_regmap pwm_m_div =
+ AML_PWM_CLK_DIV(pwm_m, PWM_CLK_MN_CTRL, 0);
+static struct clk_regmap pwm_m =
+ AML_PWM_CLK_GATE(pwm_m, PWM_CLK_MN_CTRL, 8);
+
+static struct clk_regmap pwm_n_sel =
+ AML_PWM_CLK_MUX(pwm_n, PWM_CLK_MN_CTRL, 25);
+static struct clk_regmap pwm_n_div =
+ AML_PWM_CLK_DIV(pwm_n, PWM_CLK_MN_CTRL, 16);
+static struct clk_regmap pwm_n =
+ AML_PWM_CLK_GATE(pwm_n, PWM_CLK_MN_CTRL, 24);
+
+static const struct clk_parent_data spicc_parent_data[] = {
+ { .fw_name = "oscin" },
+ { .fw_name = "sysclk" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" },
+ { .fw_name = "gp1" }
+};
+
+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" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "hifi" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" }
+};
+
+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 const struct clk_parent_data emmc_parent_data[] = {
+ { .fw_name = "oscin" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "hifi" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "gp1" },
+ { .fw_name = "gp0" }
+};
+
+static struct clk_regmap sd_emmc_a_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = SD_EMMC_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ },
+ .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,
+ },
+ .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,
+ },
+ .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,
+ },
+};
+
+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 = &(const struct clk_parent_data) {
+ .fw_name = "oscin",
+ },
+ .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 = "fdiv2",
+};
+
+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 = ð_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 *[]) {
+ ð_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 = ð_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 *[]) {
+ ð_rmii_div.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
+ { .fw_name = "oscin" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp1" },
+ { .fw_name = "gp0" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv7" }
+};
+
+static struct clk_regmap mipi_dsi_meas_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = VDIN_MEAS_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 21,
+ },
+ .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 const struct clk_parent_data dsi_phy_parent_data[] = {
+ { .fw_name = "gp1" },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv7" }
+};
+
+static struct clk_regmap dsi_phy_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = MIPIDSI_PHY_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 12,
+ },
+ .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 const struct clk_parent_data vout_mclk_parent_data[] = {
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi" },
+ { .fw_name = "gp1" },
+ { .fw_name = "fdiv7" }
+};
+
+static struct clk_regmap vout_mclk_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = VOUTENC_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vout_mclk_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = vout_mclk_parent_data,
+ .num_parents = ARRAY_SIZE(vout_mclk_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 = VOUTENC_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 const struct clk_parent_data vout_enc_parent_data[] = {
+ { .fw_name = "gp1" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv7" }
+};
+
+static struct clk_regmap vout_enc_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = VOUTENC_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 25,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vout_enc_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = vout_enc_parent_data,
+ .num_parents = ARRAY_SIZE(vout_enc_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 = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" },
+ { .fw_name = "hifi" },
+ { .fw_name = "gp0" },
+ { .fw_name = "oscin" }
+};
+
+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 = "oscin" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "hifi" },
+ { .fw_name = "gp0" }
+};
+
+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 const struct clk_parent_data csi_phy_parent_data[] = {
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi" },
+ { .fw_name = "gp1" },
+ { .fw_name = "oscin" }
+};
+
+static struct clk_regmap csi_phy0_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = ISP0_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 25,
+ },
+ .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 const struct clk_parent_data dewarpa_parent_data[] = {
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi" },
+ { .fw_name = "gp1" },
+ { .fw_name = "fdiv7" }
+};
+
+static struct clk_regmap dewarpa_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = DEWARPA_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ },
+ .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 const struct clk_parent_data isp_parent_data[] = {
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi" },
+ { .fw_name = "gp1" },
+ { .fw_name = "oscin" }
+};
+
+static struct clk_regmap isp0_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = ISP0_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ },
+ .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 const struct clk_parent_data nna_core_parent_data[] = {
+ { .fw_name = "oscin" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "gp1" },
+ { .fw_name = "hifi" }
+};
+
+static struct clk_regmap nna_core_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = NNA_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ },
+ .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 = "oscin" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "hifi" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp0" },
+ { .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 const struct clk_parent_data vapb_parent_data[] = {
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi" },
+ { .fw_name = "gp1" },
+ { .fw_name = "oscin" },
+};
+
+static struct clk_regmap vapb_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = VAPB_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ },
+ .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_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_RESET_CTRL] = &sys_reset_ctrl.hw,
+ [CLKID_SYS_PWR_CTRL] = &sys_pwr_ctrl.hw,
+ [CLKID_SYS_PAD_CTRL] = &sys_pad_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_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_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] = ð_125m_div.hw,
+ [CLKID_ETH_125M] = ð_125m.hw,
+ [CLKID_ETH_RMII_DIV] = ð_rmii_div.hw,
+ [CLKID_ETH_RMII] = ð_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[] = {
+ &rtc_xtal_clkin,
+ &rtc_32k_div,
+ &rtc_32k_mux,
+ &rtc_32k,
+ &rtc_clk,
+ &sys_reset_ctrl,
+ &sys_pwr_ctrl,
+ &sys_pad_ctrl,
+ &sys_ctrl,
+ &sys_ts_pll,
+ &sys_dev_arb,
+ &sys_mmc_pclk,
+ &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_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,
+ ð_125m,
+ ð_rmii_div,
+ ð_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,
+ .max_register = NNA_CLK_CTRL,
+};
+
+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",
+ },
+ { /* sentinel */ }
+};
+
+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 <[email protected]>");
+MODULE_LICENSE("GPL");
--
2.39.2
On Tue 30 Apr 2024 at 14:44, Xianwei Zhao <[email protected]> wrote:
> Add the C3 peripherals clock controller driver in the C3 SoC family.
>
> Co-developed-by: Chuan Liu <[email protected]>
> Signed-off-by: Chuan Liu <[email protected]>
> Signed-off-by: Xianwei Zhao <[email protected]>
> ---
> drivers/clk/meson/Kconfig | 15 +
> drivers/clk/meson/Makefile | 1 +
> drivers/clk/meson/c3-peripherals.c | 2365 ++++++++++++++++++++++++++++
> 3 files changed, 2381 insertions(+)
> create mode 100644 drivers/clk/meson/c3-peripherals.c
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 9f975a980581..0b85d584910e 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -142,6 +142,21 @@ config COMMON_CLK_C3_PLL
> AKA C3. 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"
> + depends on ARM64
> + depends on ARM_SCMI_PROTOCOL
Rob has commented on v7 that this is not OK.
It was on the PLL patch but you can guess that if this is not OK for the
PLL controller, it is not OK for the peripheral controller either.
So please drop this
> + depends on COMMON_CLK_SCMI
imply, not depends
> + depends on COMMON_CLK_C3_PLL
Same.
> + default y
> + select COMMON_CLK_MESON_REGMAP
> + select COMMON_CLK_MESON_DUALDIV
> + select COMMON_CLK_MESON_CLKC_UTILS
> + help
> + Support for the Peripherals clock controller on Amlogic C302X and
> + C308L devices, AKA C3. 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..b786d8ff9be0
> --- /dev/null
> +++ b/drivers/clk/meson/c3-peripherals.c
> @@ -0,0 +1,2365 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Amlogic C3 Peripherals Clock Controller Driver
> + *
> + * Copyright (c) 2023 Amlogic, inc.
> + * Author: Chuan Liu <[email protected]>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +#include "clk-regmap.h"
> +#include "clk-dualdiv.h"
> +#include "meson-clkc-utils.h"
> +#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
> +
> +#define RTC_BY_OSCIN_CTRL0 0x8
> +#define RTC_BY_OSCIN_CTRL1 0xc
> +#define RTC_CTRL 0x10
> +#define SYS_CLK_EN0_REG0 0x44
> +#define SYS_CLK_EN0_REG1 0x48
> +#define SYS_CLK_EN0_REG2 0x4c
> +#define CLK12_24_CTRL 0xa8
> +#define AXI_CLK_EN0 0xac
> +#define VDIN_MEAS_CLK_CTRL 0xf8
> +#define VAPB_CLK_CTRL 0xfc
> +#define MIPIDSI_PHY_CLK_CTRL 0x104
> +#define GE2D_CLK_CTRL 0x10c
> +#define ISP0_CLK_CTRL 0x110
> +#define DEWARPA_CLK_CTRL 0x114
> +#define VOUTENC_CLK_CTRL 0x118
> +#define VDEC_CLK_CTRL 0x140
> +#define VDEC3_CLK_CTRL 0x148
> +#define TS_CLK_CTRL 0x158
> +#define ETH_CLK_CTRL 0x164
> +#define NAND_CLK_CTRL 0x168
> +#define SD_EMMC_CLK_CTRL 0x16c
> +#define SPICC_CLK_CTRL 0x174
> +#define GEN_CLK_CTRL 0x178
> +#define SAR_CLK_CTRL0 0x17c
> +#define PWM_CLK_AB_CTRL 0x180
> +#define PWM_CLK_CD_CTRL 0x184
> +#define PWM_CLK_EF_CTRL 0x188
> +#define PWM_CLK_GH_CTRL 0x18c
> +#define PWM_CLK_IJ_CTRL 0x190
> +#define PWM_CLK_KL_CTRL 0x194
> +#define PWM_CLK_MN_CTRL 0x198
> +#define VC9000E_CLK_CTRL 0x19c
> +#define SPIFC_CLK_CTRL 0x1a0
> +#define NNA_CLK_CTRL 0x220
> +
> +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 = &(const struct clk_parent_data) {
> + .fw_name = "oscin",
> + },
> + .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 = "oscin" },
> + { .hw = &rtc_32k.hw },
> + { .fw_name = "pad_osc" }
> +};
> +
> +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,
> + },
> +};
> +
> +#define C3_CLK_GATE(_name, _reg, _bit, _fw_name, _ops, _flags) \
> +struct clk_regmap _name = { \
> + .data = &(struct clk_regmap_gate_data){ \
> + .offset = (_reg), \
> + .bit_idx = (_bit), \
> + }, \
> + .hw.init = &(struct clk_init_data) { \
> + .name = #_name, \
> + .ops = _ops, \
> + .parent_data = &(const struct clk_parent_data) { \
> + .fw_name = #_fw_name, \
> + }, \
> + .num_parents = 1, \
> + .flags = (_flags), \
> + }, \
> +}
> +
> +#define C3_SYS_GATE(_name, _reg, _bit, _flags) \
> + C3_CLK_GATE(_name, _reg, _bit, sysclk, \
> + &clk_regmap_gate_ops, _flags)
> +
> +#define C3_SYS_GATE_RO(_name, _reg, _bit) \
> + C3_CLK_GATE(_name, _reg, _bit, sysclk, \
> + &clk_regmap_gate_ro_ops, 0)
> +
> +static C3_SYS_GATE(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1, 0);
> +static C3_SYS_GATE(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3, 0);
> +static C3_SYS_GATE(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4, 0);
> +static C3_SYS_GATE(sys_ctrl, SYS_CLK_EN0_REG0, 5, 0);
> +static C3_SYS_GATE(sys_ts_pll, SYS_CLK_EN0_REG0, 6, 0);
> +
> +/*
> + * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that
> + * access the AXI bus.
> + */
> +static C3_SYS_GATE(sys_dev_arb, SYS_CLK_EN0_REG0, 7, 0);
> +
> +/*
> + * FIXME: sys_mmc_pclk provides the clock for the DDR PHY, DDR will only be
> + * initialized in bl2, and this clock should not be touched in linux.
> + */
> +static C3_SYS_GATE_RO(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
> +
> +/*
> + * NOTE: sys_cpu_ctrl provides the clock for CPU controller. After clock is
> + * disabled, cpu_clk and other key CPU-related configurations cannot take effect.
> + */
> +static C3_SYS_GATE(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11, CLK_IS_CRITICAL);
> +static C3_SYS_GATE(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12, 0);
> +static C3_SYS_GATE(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13, 0);
> +
> +/*
> + * NOTE: sys_irq_ctrl provides the clock for IRQ controller. The IRQ controller
> + * collects and distributes the interrupt signal to the GIC, PWR_CTRL, and
> + * AOCPU. If the clock is disabled, interrupt-related functions will occurs an
> + * exception.
> + */
> +static C3_SYS_GATE(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14, CLK_IS_CRITICAL);
> +static C3_SYS_GATE(sys_msr_clk, SYS_CLK_EN0_REG0, 15, 0);
> +static C3_SYS_GATE(sys_rom, SYS_CLK_EN0_REG0, 16, 0);
> +static C3_SYS_GATE(sys_uart_f, SYS_CLK_EN0_REG0, 17, 0);
> +static C3_SYS_GATE(sys_cpu_apb, SYS_CLK_EN0_REG0, 18, 0);
> +static C3_SYS_GATE(sys_rsa, SYS_CLK_EN0_REG0, 19, 0);
> +static C3_SYS_GATE(sys_sar_adc, SYS_CLK_EN0_REG0, 20, 0);
> +static C3_SYS_GATE(sys_startup, SYS_CLK_EN0_REG0, 21, 0);
> +static C3_SYS_GATE(sys_secure, SYS_CLK_EN0_REG0, 22, 0);
> +static C3_SYS_GATE(sys_spifc, SYS_CLK_EN0_REG0, 23, 0);
> +static C3_SYS_GATE(sys_nna, SYS_CLK_EN0_REG0, 25, 0);
> +static C3_SYS_GATE(sys_eth_mac, SYS_CLK_EN0_REG0, 26, 0);
> +
> +/*
> + * FIXME: sys_gic provides the clock for GIC(Generic Interrupt Controller).
> + * After clock is disabled, The GIC cannot work properly. At present, the driver
> + * used by our GIC is the public driver in kernel, and there is no management
> + * clock in the driver.
> + */
> +static C3_SYS_GATE(sys_gic, SYS_CLK_EN0_REG0, 27, CLK_IS_CRITICAL);
> +static C3_SYS_GATE(sys_rama, SYS_CLK_EN0_REG0, 28, 0);
> +
> +/*
> + * NOTE: sys_big_nic provides the clock to the control bus of the NIC(Network
> + * Interface Controller) between multiple devices(CPU, DDR, RAM, ROM, GIC,
> + * SPIFC, CAPU, JTAG, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC) in the
> + * system. After clock is disabled, The NIC cannot work.
> + */
> +static C3_SYS_GATE(sys_big_nic, SYS_CLK_EN0_REG0, 29, CLK_IS_CRITICAL);
> +static C3_SYS_GATE(sys_ramb, SYS_CLK_EN0_REG0, 30, 0);
> +static C3_SYS_GATE(sys_audio_pclk, SYS_CLK_EN0_REG0, 31, 0);
> +static C3_SYS_GATE(sys_pwm_kl, SYS_CLK_EN0_REG1, 0, 0);
> +static C3_SYS_GATE(sys_pwm_ij, SYS_CLK_EN0_REG1, 1, 0);
> +static C3_SYS_GATE(sys_usb, SYS_CLK_EN0_REG1, 2, 0);
> +static C3_SYS_GATE(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3, 0);
> +static C3_SYS_GATE(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4, 0);
> +static C3_SYS_GATE(sys_pwm_ab, SYS_CLK_EN0_REG1, 5, 0);
> +static C3_SYS_GATE(sys_pwm_cd, SYS_CLK_EN0_REG1, 6, 0);
> +static C3_SYS_GATE(sys_pwm_ef, SYS_CLK_EN0_REG1, 7, 0);
> +static C3_SYS_GATE(sys_pwm_gh, SYS_CLK_EN0_REG1, 8, 0);
> +static C3_SYS_GATE(sys_spicc_1, SYS_CLK_EN0_REG1, 9, 0);
> +static C3_SYS_GATE(sys_spicc_0, SYS_CLK_EN0_REG1, 10, 0);
> +static C3_SYS_GATE(sys_uart_a, SYS_CLK_EN0_REG1, 11, 0);
> +static C3_SYS_GATE(sys_uart_b, SYS_CLK_EN0_REG1, 12, 0);
> +static C3_SYS_GATE(sys_uart_c, SYS_CLK_EN0_REG1, 13, 0);
> +static C3_SYS_GATE(sys_uart_d, SYS_CLK_EN0_REG1, 14, 0);
> +static C3_SYS_GATE(sys_uart_e, SYS_CLK_EN0_REG1, 15, 0);
> +static C3_SYS_GATE(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16, 0);
> +static C3_SYS_GATE(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17, 0);
> +static C3_SYS_GATE(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18, 0);
> +static C3_SYS_GATE(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19, 0);
> +static C3_SYS_GATE(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20, 0);
> +static C3_SYS_GATE(sys_rtc, SYS_CLK_EN0_REG1, 21, 0);
> +static C3_SYS_GATE(sys_ge2d, SYS_CLK_EN0_REG1, 22, 0);
> +static C3_SYS_GATE(sys_isp, SYS_CLK_EN0_REG1, 23, 0);
> +static C3_SYS_GATE(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24, 0);
> +static C3_SYS_GATE(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25, 0);
> +static C3_SYS_GATE(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26, 0);
> +static C3_SYS_GATE(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27, 0);
> +static C3_SYS_GATE(sys_eth_phy, SYS_CLK_EN0_REG1, 28, 0);
> +static C3_SYS_GATE(sys_acodec, SYS_CLK_EN0_REG1, 29, 0);
> +static C3_SYS_GATE(sys_dwap, SYS_CLK_EN0_REG1, 30, 0);
> +static C3_SYS_GATE(sys_dos, SYS_CLK_EN0_REG1, 31, 0);
> +static C3_SYS_GATE(sys_cve, SYS_CLK_EN0_REG2, 0, 0);
> +static C3_SYS_GATE(sys_vout, SYS_CLK_EN0_REG2, 1, 0);
> +static C3_SYS_GATE(sys_vc9000e, SYS_CLK_EN0_REG2, 2, 0);
> +static C3_SYS_GATE(sys_pwm_mn, SYS_CLK_EN0_REG2, 3, 0);
> +static C3_SYS_GATE(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4, 0);
> +
> +#define C3_AXI_GATE(_name, _reg, _bit, _flags) \
> + C3_CLK_GATE(_name, _reg, _bit, axiclk, \
> + &clk_regmap_gate_ops, _flags)
> +
> +/*
> + * NOTE: axi_sys_nic provides the clock to the AXI bus of the system NIC. After
> + * clock is disabled, The NIC cannot work.
> + */
> +static C3_AXI_GATE(axi_sys_nic, AXI_CLK_EN0, 2, CLK_IS_CRITICAL);
> +static C3_AXI_GATE(axi_isp_nic, AXI_CLK_EN0, 3, 0);
> +static C3_AXI_GATE(axi_cve_nic, AXI_CLK_EN0, 4, 0);
> +static C3_AXI_GATE(axi_ramb, AXI_CLK_EN0, 5, 0);
> +static C3_AXI_GATE(axi_rama, AXI_CLK_EN0, 6, 0);
> +
> +/*
> + * NOTE: axi_cpu_dmc provides the clock to the AXI bus where the CPU accesses
> + * the DDR. After clock is disabled, The CPU will not have access to the DDR.
> + */
> +static C3_AXI_GATE(axi_cpu_dmc, AXI_CLK_EN0, 7, CLK_IS_CRITICAL);
> +static C3_AXI_GATE(axi_nic, AXI_CLK_EN0, 8, 0);
> +static C3_AXI_GATE(axi_dma, AXI_CLK_EN0, 9, 0);
> +
> +/*
> + * NOTE: axi_mux_nic provides the clock to the NIC's AXI bus for NN(Neural
> + * Network) and other devices(CPU, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC)
> + * to access RAM space.
> + */
> +static C3_AXI_GATE(axi_mux_nic, AXI_CLK_EN0, 10, 0);
> +static C3_AXI_GATE(axi_cve, AXI_CLK_EN0, 12, 0);
> +
> +/*
> + * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO,
> + * sec_top, USB, Audio, ETH, SPICC) to access the AXI bus of the DDR.
> + */
> +static C3_AXI_GATE(axi_dev1_dmc, AXI_CLK_EN0, 13, 0);
> +static C3_AXI_GATE(axi_dev0_dmc, AXI_CLK_EN0, 14, 0);
> +static C3_AXI_GATE(axi_dsp_dmc, AXI_CLK_EN0, 15, 0);
> +
> +/*
> + * clk_12_24m model
> + *
> + * |------| |-----| clk_12m_24m |-----|
> + * xtal---->| gate |---->| div |------------>| pad |
> + * |------| |-----| |-----|
> + */
> +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 = &(const struct clk_parent_data) {
> + .fw_name = "xtal_24m",
> + },
> + .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,
> + },
> +};
> +
> +/* Fix me: set value 0 will div by 2 like value 1 */
> +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 = &(const struct clk_parent_data) {
> + .fw_name = "fix",
> + },
> + .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,
> + },
> +};
> +
> +/*
> + * Channel 3(ddr_dpll_pt_clk) is manged by the DDR module; channel 12(cts_msr_clk)
> + * is manged by clock measures module. Their hardware are out of clock tree.
> + * Channel 4 8 9 10 11 13 14 15 16 18 are not connected.
> + */
> +static u32 gen_parent_table[] = { 0, 1, 2, 5, 6, 7, 17, 19, 20, 21, 22, 23, 24};
> +
> +static const struct clk_parent_data gen_parent_data[] = {
> + { .fw_name = "oscin" },
> + { .hw = &rtc_clk.hw },
> + { .fw_name = "sysplldiv16" },
> + { .fw_name = "gp0" },
> + { .fw_name = "gp1" },
> + { .fw_name = "hifi" },
> + { .fw_name = "cpudiv16" },
> + { .fw_name = "fdiv2" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "fdiv7" }
> +};
> +
> +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 = "oscin" },
> + { .fw_name = "sysclk" }
> +};
> +
> +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 const struct clk_parent_data pwm_parent_data[] = {
> + { .fw_name = "oscin" },
> + { .fw_name = "gp1" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv3" }
> +};
> +
> +#define AML_PWM_CLK_MUX(_name, _reg, _shift) { \
> + .data = &(struct clk_regmap_mux_data) { \
> + .offset = _reg, \
> + .mask = 0x3, \
> + .shift = _shift, \
> + }, \
> + .hw.init = &(struct clk_init_data) { \
> + .name = #_name "_sel", \
> + .ops = &clk_regmap_mux_ops, \
> + .parent_data = pwm_parent_data, \
> + .num_parents = ARRAY_SIZE(pwm_parent_data), \
> + }, \
> +}
> +
> +#define AML_PWM_CLK_DIV(_name, _reg, _shift) { \
> + .data = &(struct clk_regmap_div_data) { \
> + .offset = _reg, \
> + .shift = _shift, \
> + .width = 8, \
> + }, \
> + .hw.init = &(struct clk_init_data) { \
> + .name = #_name "_div", \
> + .ops = &clk_regmap_divider_ops, \
> + .parent_names = (const char *[]) { #_name "_sel" },\
> + .num_parents = 1, \
> + .flags = CLK_SET_RATE_PARENT, \
> + }, \
> +}
> +
> +#define AML_PWM_CLK_GATE(_name, _reg, _bit) { \
> + .data = &(struct clk_regmap_gate_data) { \
> + .offset = _reg, \
> + .bit_idx = _bit, \
> + }, \
> + .hw.init = &(struct clk_init_data) { \
> + .name = #_name, \
> + .ops = &clk_regmap_gate_ops, \
> + .parent_names = (const char *[]) { #_name "_div" },\
> + .num_parents = 1, \
> + .flags = CLK_SET_RATE_PARENT, \
> + }, \
> +}
> +
> +static struct clk_regmap pwm_a_sel =
> + AML_PWM_CLK_MUX(pwm_a, PWM_CLK_AB_CTRL, 9);
> +static struct clk_regmap pwm_a_div =
> + AML_PWM_CLK_DIV(pwm_a, PWM_CLK_AB_CTRL, 0);
> +static struct clk_regmap pwm_a =
> + AML_PWM_CLK_GATE(pwm_a, PWM_CLK_AB_CTRL, 8);
> +
> +static struct clk_regmap pwm_b_sel =
> + AML_PWM_CLK_MUX(pwm_b, PWM_CLK_AB_CTRL, 25);
> +static struct clk_regmap pwm_b_div =
> + AML_PWM_CLK_DIV(pwm_b, PWM_CLK_AB_CTRL, 16);
> +static struct clk_regmap pwm_b =
> + AML_PWM_CLK_GATE(pwm_b, PWM_CLK_AB_CTRL, 24);
> +
> +static struct clk_regmap pwm_c_sel =
> + AML_PWM_CLK_MUX(pwm_c, PWM_CLK_CD_CTRL, 9);
> +static struct clk_regmap pwm_c_div =
> + AML_PWM_CLK_DIV(pwm_c, PWM_CLK_CD_CTRL, 0);
> +static struct clk_regmap pwm_c =
> + AML_PWM_CLK_GATE(pwm_c, PWM_CLK_CD_CTRL, 8);
> +
> +static struct clk_regmap pwm_d_sel =
> + AML_PWM_CLK_MUX(pwm_d, PWM_CLK_CD_CTRL, 25);
> +static struct clk_regmap pwm_d_div =
> + AML_PWM_CLK_DIV(pwm_d, PWM_CLK_CD_CTRL, 16);
> +static struct clk_regmap pwm_d =
> + AML_PWM_CLK_GATE(pwm_d, PWM_CLK_CD_CTRL, 24);
> +
> +static struct clk_regmap pwm_e_sel =
> + AML_PWM_CLK_MUX(pwm_e, PWM_CLK_EF_CTRL, 9);
> +static struct clk_regmap pwm_e_div =
> + AML_PWM_CLK_DIV(pwm_e, PWM_CLK_EF_CTRL, 0);
> +static struct clk_regmap pwm_e =
> + AML_PWM_CLK_GATE(pwm_e, PWM_CLK_EF_CTRL, 8);
> +
> +static struct clk_regmap pwm_f_sel =
> + AML_PWM_CLK_MUX(pwm_f, PWM_CLK_EF_CTRL, 25);
> +static struct clk_regmap pwm_f_div =
> + AML_PWM_CLK_DIV(pwm_f, PWM_CLK_EF_CTRL, 16);
> +static struct clk_regmap pwm_f =
> + AML_PWM_CLK_GATE(pwm_f, PWM_CLK_EF_CTRL, 24);
> +
> +static struct clk_regmap pwm_g_sel =
> + AML_PWM_CLK_MUX(pwm_g, PWM_CLK_GH_CTRL, 9);
> +static struct clk_regmap pwm_g_div =
> + AML_PWM_CLK_DIV(pwm_g, PWM_CLK_GH_CTRL, 0);
> +static struct clk_regmap pwm_g =
> + AML_PWM_CLK_GATE(pwm_g, PWM_CLK_GH_CTRL, 8);
> +
> +static struct clk_regmap pwm_h_sel =
> + AML_PWM_CLK_MUX(pwm_h, PWM_CLK_GH_CTRL, 25);
> +static struct clk_regmap pwm_h_div =
> + AML_PWM_CLK_DIV(pwm_h, PWM_CLK_GH_CTRL, 16);
> +static struct clk_regmap pwm_h =
> + AML_PWM_CLK_GATE(pwm_h, PWM_CLK_GH_CTRL, 24);
> +
> +static struct clk_regmap pwm_i_sel =
> + AML_PWM_CLK_MUX(pwm_i, PWM_CLK_IJ_CTRL, 9);
> +static struct clk_regmap pwm_i_div =
> + AML_PWM_CLK_DIV(pwm_i, PWM_CLK_IJ_CTRL, 0);
> +static struct clk_regmap pwm_i =
> + AML_PWM_CLK_GATE(pwm_i, PWM_CLK_IJ_CTRL, 8);
> +
> +static struct clk_regmap pwm_j_sel =
> + AML_PWM_CLK_MUX(pwm_j, PWM_CLK_IJ_CTRL, 25);
> +static struct clk_regmap pwm_j_div =
> + AML_PWM_CLK_DIV(pwm_j, PWM_CLK_IJ_CTRL, 16);
> +static struct clk_regmap pwm_j =
> + AML_PWM_CLK_GATE(pwm_j, PWM_CLK_IJ_CTRL, 24);
> +
> +static struct clk_regmap pwm_k_sel =
> + AML_PWM_CLK_MUX(pwm_k, PWM_CLK_KL_CTRL, 9);
> +static struct clk_regmap pwm_k_div =
> + AML_PWM_CLK_DIV(pwm_k, PWM_CLK_KL_CTRL, 0);
> +static struct clk_regmap pwm_k =
> + AML_PWM_CLK_GATE(pwm_k, PWM_CLK_KL_CTRL, 8);
> +
> +static struct clk_regmap pwm_l_sel =
> + AML_PWM_CLK_MUX(pwm_l, PWM_CLK_KL_CTRL, 25);
> +static struct clk_regmap pwm_l_div =
> + AML_PWM_CLK_DIV(pwm_l, PWM_CLK_KL_CTRL, 16);
> +static struct clk_regmap pwm_l =
> + AML_PWM_CLK_GATE(pwm_l, PWM_CLK_KL_CTRL, 24);
> +
> +static struct clk_regmap pwm_m_sel =
> + AML_PWM_CLK_MUX(pwm_m, PWM_CLK_MN_CTRL, 9);
> +static struct clk_regmap pwm_m_div =
> + AML_PWM_CLK_DIV(pwm_m, PWM_CLK_MN_CTRL, 0);
> +static struct clk_regmap pwm_m =
> + AML_PWM_CLK_GATE(pwm_m, PWM_CLK_MN_CTRL, 8);
> +
> +static struct clk_regmap pwm_n_sel =
> + AML_PWM_CLK_MUX(pwm_n, PWM_CLK_MN_CTRL, 25);
> +static struct clk_regmap pwm_n_div =
> + AML_PWM_CLK_DIV(pwm_n, PWM_CLK_MN_CTRL, 16);
> +static struct clk_regmap pwm_n =
> + AML_PWM_CLK_GATE(pwm_n, PWM_CLK_MN_CTRL, 24);
> +
> +static const struct clk_parent_data spicc_parent_data[] = {
> + { .fw_name = "oscin" },
> + { .fw_name = "sysclk" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv2" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "fdiv7" },
> + { .fw_name = "gp1" }
> +};
> +
> +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" },
> + { .fw_name = "fdiv2" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "hifi" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "fdiv7" }
> +};
> +
> +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 const struct clk_parent_data emmc_parent_data[] = {
> + { .fw_name = "oscin" },
> + { .fw_name = "fdiv2" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "hifi" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "gp1" },
> + { .fw_name = "gp0" }
> +};
> +
> +static struct clk_regmap sd_emmc_a_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = SD_EMMC_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 9,
> + },
> + .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,
> + },
> + .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,
> + },
> + .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,
> + },
> +};
> +
> +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 = &(const struct clk_parent_data) {
> + .fw_name = "oscin",
> + },
> + .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 = "fdiv2",
> +};
> +
> +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 = ð_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 *[]) {
> + ð_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 = ð_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 *[]) {
> + ð_rmii_div.hw
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + },
> +};
> +
> +static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
> + { .fw_name = "oscin" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp1" },
> + { .fw_name = "gp0" },
> + { .fw_name = "fdiv2" },
> + { .fw_name = "fdiv7" }
> +};
> +
> +static struct clk_regmap mipi_dsi_meas_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = VDIN_MEAS_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 21,
> + },
> + .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 const struct clk_parent_data dsi_phy_parent_data[] = {
> + { .fw_name = "gp1" },
> + { .fw_name = "gp0" },
> + { .fw_name = "hifi" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv2" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv7" }
> +};
> +
> +static struct clk_regmap dsi_phy_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = MIPIDSI_PHY_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 12,
> + },
> + .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 const struct clk_parent_data vout_mclk_parent_data[] = {
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp0" },
> + { .fw_name = "hifi" },
> + { .fw_name = "gp1" },
> + { .fw_name = "fdiv7" }
> +};
> +
> +static struct clk_regmap vout_mclk_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = VOUTENC_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 9,
> + },
> + .hw.init = &(struct clk_init_data) {
> + .name = "vout_mclk_sel",
> + .ops = &clk_regmap_mux_ops,
> + .parent_data = vout_mclk_parent_data,
> + .num_parents = ARRAY_SIZE(vout_mclk_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 = VOUTENC_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 const struct clk_parent_data vout_enc_parent_data[] = {
> + { .fw_name = "gp1" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp0" },
> + { .fw_name = "hifi" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv7" }
> +};
> +
> +static struct clk_regmap vout_enc_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = VOUTENC_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 25,
> + },
> + .hw.init = &(struct clk_init_data) {
> + .name = "vout_enc_sel",
> + .ops = &clk_regmap_mux_ops,
> + .parent_data = vout_enc_parent_data,
> + .num_parents = ARRAY_SIZE(vout_enc_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 = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "fdiv7" },
> + { .fw_name = "hifi" },
> + { .fw_name = "gp0" },
> + { .fw_name = "oscin" }
> +};
> +
> +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 = "oscin" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "fdiv7" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "hifi" },
> + { .fw_name = "gp0" }
> +};
> +
> +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 const struct clk_parent_data csi_phy_parent_data[] = {
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp0" },
> + { .fw_name = "hifi" },
> + { .fw_name = "gp1" },
> + { .fw_name = "oscin" }
> +};
> +
> +static struct clk_regmap csi_phy0_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = ISP0_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 25,
> + },
> + .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 const struct clk_parent_data dewarpa_parent_data[] = {
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp0" },
> + { .fw_name = "hifi" },
> + { .fw_name = "gp1" },
> + { .fw_name = "fdiv7" }
> +};
> +
> +static struct clk_regmap dewarpa_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = DEWARPA_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 9,
> + },
> + .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 const struct clk_parent_data isp_parent_data[] = {
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp0" },
> + { .fw_name = "hifi" },
> + { .fw_name = "gp1" },
> + { .fw_name = "oscin" }
> +};
> +
> +static struct clk_regmap isp0_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = ISP0_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 9,
> + },
> + .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 const struct clk_parent_data nna_core_parent_data[] = {
> + { .fw_name = "oscin" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "fdiv2" },
> + { .fw_name = "gp1" },
> + { .fw_name = "hifi" }
> +};
> +
> +static struct clk_regmap nna_core_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = NNA_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 9,
> + },
> + .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 = "oscin" },
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "hifi" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp0" },
> + { .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 const struct clk_parent_data vapb_parent_data[] = {
> + { .fw_name = "fdiv2p5" },
> + { .fw_name = "fdiv3" },
> + { .fw_name = "fdiv4" },
> + { .fw_name = "fdiv5" },
> + { .fw_name = "gp0" },
> + { .fw_name = "hifi" },
> + { .fw_name = "gp1" },
> + { .fw_name = "oscin" },
> +};
> +
> +static struct clk_regmap vapb_sel = {
> + .data = &(struct clk_regmap_mux_data) {
> + .offset = VAPB_CLK_CTRL,
> + .mask = 0x7,
> + .shift = 9,
> + },
> + .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_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_RESET_CTRL] = &sys_reset_ctrl.hw,
> + [CLKID_SYS_PWR_CTRL] = &sys_pwr_ctrl.hw,
> + [CLKID_SYS_PAD_CTRL] = &sys_pad_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_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_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] = ð_125m_div.hw,
> + [CLKID_ETH_125M] = ð_125m.hw,
> + [CLKID_ETH_RMII_DIV] = ð_rmii_div.hw,
> + [CLKID_ETH_RMII] = ð_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[] = {
> + &rtc_xtal_clkin,
> + &rtc_32k_div,
> + &rtc_32k_mux,
> + &rtc_32k,
> + &rtc_clk,
> + &sys_reset_ctrl,
> + &sys_pwr_ctrl,
> + &sys_pad_ctrl,
> + &sys_ctrl,
> + &sys_ts_pll,
> + &sys_dev_arb,
> + &sys_mmc_pclk,
> + &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_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,
> + ð_125m,
> + ð_rmii_div,
> + ð_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,
> + .max_register = NNA_CLK_CTRL,
> +};
> +
> +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",
> + },
> + { /* sentinel */ }
> +};
> +
> +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 <[email protected]>");
> +MODULE_LICENSE("GPL");
--
Jerome
On Tue 30 Apr 2024 at 14:44, Xianwei Zhao <[email protected]> wrote:
> Changes since V7 [1]:
> - Remove included head file not used.
> - Link to v7: https://lore.kernel.org/all/[email protected]
>
Overall this v8 looks good. Please address the remaining comments.
There is no need to rush sending a v9. Please allow some time for other
to review this. I will not apply a v9 until the -rc1 is out anyway.
> Changes since V6 [12]:
> - Add pad src for rtc clock.
> - Add SCMI clock controller support, move some clock node in SCMI,such as GP1 PLL DDR USB etc.
> - Fix some spelling mistake.
> - Use lower case for bindings and update some input clocks desc.
> - Update some clock comments.
> - Delete prefix "AML_" for macro definition.
> - Addd some clock annotation and some clock flag CRITICAL.
> - Add maximum for regmap_config.
> - Delete some unused register definition and unused clock inputs.
> - Drop patch subject redundant "bindings". Suggested by Krzysztof.
> - Not reference header file "clk.h" and replace comment. Suggested by Jerome.
> - Modify description about board in Kconfig file help item. Suggested by Jerome.
> - Link to v6: https://lore.kernel.org/all/[email protected]
>
> Changes since V5 [3]:
> - Fix some typo and modify formart for MARCO. Suggested by Jerome.
> - Add pad clock for peripheral input clock in bindings.
> - Add some description for explaining why ddr_dpll_pt_clk and cts_msr_clk are out of tree.
> Changes since V4 [10]:
> - Change some fw_name of clocks. Suggested by Jerome.
> - Delete minItem of clocks.
> - Add CLk_GET_RATE_NOCACHE flags for gp1_pll
> - Fix some format. and fix width as 8 for mclk_pll_dco.
> - exchange gate and divder for fclk_50m clock.
> - add CLK_SET_RATE_PARENT for axi_a_divder & axi_b_divder.
> - add CLK_IS_CRITICAL for axi_clk
> - Optimized macro define for pwm clk.
> - add cts_oscin_clk mux between 24M and 32k
> - add some missing gate clock, such as ddr_pll.
> Changes since V3 [7]:
> - Modify Kconfig desc and PLL yaml clk desc.
> - Fix some format.Suggested by Yixun and Jerome.
> - Add flag CLK_GET_RATE_NOCACHE for sys_clk.
> - Optimized macro define for pwm clk.
> - Use flag CLK_IS_CRITICAL for axi_clk.
> - Add some description for some clocks.
> - Use FCLK_50M instead of FCLK_DIV40.
> Changes since V2 [4]:
> - Modify some format, include clk name & inline, and so on.
> - Define marco for pwm clock.
> - Add GP1_PLL clock.
> - Modify yaml use raw instead of macro.
> Changes since V1 [2]:
> - Fix errors when check binding by using "make dt_binding_check".
> - Delete macro definition.
>
> Xianwei Zhao (5):
> dt-bindings: clock: add Amlogic C3 PLL clock controller
> dt-bindings: clock: add Amlogic C3 SCMI clock controller support
> dt-bindings: clock: add Amlogic C3 peripherals clock controller
> 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 | 120 +
> .../bindings/clock/amlogic,c3-pll-clkc.yaml | 59 +
> drivers/clk/meson/Kconfig | 29 +
> drivers/clk/meson/Makefile | 2 +
> drivers/clk/meson/c3-peripherals.c | 2365 +++++++++++++++++
> drivers/clk/meson/c3-pll.c | 746 ++++++
> .../clock/amlogic,c3-peripherals-clkc.h | 212 ++
> .../dt-bindings/clock/amlogic,c3-pll-clkc.h | 40 +
> .../dt-bindings/clock/amlogic,c3-scmi-clkc.h | 27 +
> 9 files changed, 3600 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-pll.c
> create mode 100644 include/dt-bindings/clock/amlogic,c3-peripherals-clkc.h
> create mode 100644 include/dt-bindings/clock/amlogic,c3-pll-clkc.h
> create mode 100644 include/dt-bindings/clock/amlogic,c3-scmi-clkc.h
>
>
> base-commit: ba535bce57e71463a86f8b33a0ea88c26e3a6418
--
Jerome
On Tue 30 Apr 2024 at 14:44, Xianwei Zhao <[email protected]> wrote:
> Add the C3 PLL clock controller driver for the Amlogic C3 SoC family.
>
> Co-developed-by: Chuan Liu <[email protected]>
> Signed-off-by: Chuan Liu <[email protected]>
> Signed-off-by: Xianwei Zhao <[email protected]>
> ---
> drivers/clk/meson/Kconfig | 14 +
> drivers/clk/meson/Makefile | 1 +
> drivers/clk/meson/c3-pll.c | 746 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 761 insertions(+)
> create mode 100644 drivers/clk/meson/c3-pll.c
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index 29ffd14d267b..9f975a980581 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -128,6 +128,20 @@ 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"
> + depends on ARM64
> + depends on ARM_SCMI_PROTOCOL
There was a comment from Rob on v7 that was not addressed.
Please make sure you address all comments before reposting.
> + depends on COMMON_CLK_SCMI
imply, not depend.
> + 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. 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..74e11add165c
> --- /dev/null
> +++ b/drivers/clk/meson/c3-pll.c
> @@ -0,0 +1,746 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Amlogic C3 PLL Controller Driver
> + *
> + * Copyright (c) 2023 Amlogic, inc.
> + * Author: Chuan Liu <[email protected]>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +#include "clk-regmap.h"
> +#include "clk-pll.h"
> +#include "meson-clkc-utils.h"
> +#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
> +
> +#define ANACTRL_FIXPLL_CTRL4 0x50
> +#define ANACTRL_GP0PLL_CTRL0 0x80
> +#define ANACTRL_GP0PLL_CTRL1 0x84
> +#define ANACTRL_GP0PLL_CTRL2 0x88
> +#define ANACTRL_GP0PLL_CTRL3 0x8c
> +#define ANACTRL_GP0PLL_CTRL4 0x90
> +#define ANACTRL_GP0PLL_CTRL5 0x94
> +#define ANACTRL_GP0PLL_CTRL6 0x98
> +#define ANACTRL_HIFIPLL_CTRL0 0x100
> +#define ANACTRL_HIFIPLL_CTRL1 0x104
> +#define ANACTRL_HIFIPLL_CTRL2 0x108
> +#define ANACTRL_HIFIPLL_CTRL3 0x10c
> +#define ANACTRL_HIFIPLL_CTRL4 0x110
> +#define ANACTRL_HIFIPLL_CTRL5 0x114
> +#define ANACTRL_HIFIPLL_CTRL6 0x118
> +#define ANACTRL_MPLL_CTRL0 0x180
> +#define ANACTRL_MPLL_CTRL1 0x184
> +#define ANACTRL_MPLL_CTRL2 0x188
> +#define ANACTRL_MPLL_CTRL3 0x18c
> +#define ANACTRL_MPLL_CTRL4 0x190
> +
> +static struct clk_regmap fclk_50m_en = {
> + .data = &(struct clk_regmap_gate_data) {
> + .offset = ANACTRL_FIXPLL_CTRL4,
> + .bit_idx = 0,
> + },
> + .hw.init = &(struct clk_init_data) {
> + .name = "fclk_50m_en",
> + .ops = &clk_regmap_gate_ro_ops,
> + .parent_data = &(const struct clk_parent_data) {
> + .fw_name = "fix"
> + },
> + .num_parents = 1,
> + },
> +};
> +
> +static struct clk_fixed_factor fclk_50m = {
> + .mult = 1,
> + .div = 40,
> + .hw.init = &(struct clk_init_data) {
> + .name = "fclk_50m",
> + .ops = &clk_fixed_factor_ops,
> + .parent_hws = (const struct clk_hw *[]) {
> + &fclk_50m_en.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_data = &(const struct clk_parent_data) {
> + .fw_name = "fix"
> + },
> + .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_data = &(const struct clk_parent_data) {
> + .fw_name = "fix"
> + },
> + .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_data = &(const struct clk_parent_data) {
> + .fw_name = "fix"
> + },
> + .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_data = &(const struct clk_parent_data) {
> + .fw_name = "fix"
> + },
> + .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_data = &(const struct clk_parent_data) {
> + .fw_name = "fix"
> + },
> + .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_data = &(const struct clk_parent_data) {
> + .fw_name = "fix"
> + },
> + .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_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 },
> +};
> +
> +static const struct pll_mult_range c3_gp0_pll_mult_range = {
> + .min = 125,
> + .max = 250,
> +};
> +
> +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,
> + },
> + .range = &c3_gp0_pll_mult_range,
> + .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 = &(const struct clk_parent_data) {
> + .fw_name = "top",
> + },
> + .num_parents = 1,
> + },
> +};
> +
> +/* 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 = {
> + .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_CTRL2, .def = 0x0 },
> + { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 },
> + { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
> + { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
> + { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000 },
> +};
> +
> +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,
> + },
> + .range = &c3_gp0_pll_mult_range,
> + .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 = &(const struct clk_parent_data) {
> + .fw_name = "top",
> + },
> + .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_CTRL1, .def = 0x1420500f },
> + { .reg = ANACTRL_MPLL_CTRL2, .def = 0x00023041 },
> + { .reg = ANACTRL_MPLL_CTRL3, .def = 0x18180000 },
> + { .reg = ANACTRL_MPLL_CTRL2, .def = 0x00023001 }
> +};
> +
> +static const struct pll_mult_range c3_mclk_pll_mult_range = {
> + .min = 67,
> + .max = 133,
> +};
> +
> +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 = 8,
> + },
> + .n = {
> + .reg_off = ANACTRL_MPLL_CTRL0,
> + .shift = 16,
> + .width = 5,
> + },
> + .l = {
> + .reg_off = ANACTRL_MPLL_CTRL0,
> + .shift = 31,
> + .width = 1,
> + },
> + .rst = {
> + .reg_off = ANACTRL_MPLL_CTRL0,
> + .shift = 29,
> + .width = 1,
> + },
> + .range = &c3_mclk_pll_mult_range,
> + .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 = &(const struct clk_parent_data) {
> + .fw_name = "mclk",
> + },
> + .num_parents = 1,
> + },
> +};
> +
> +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_od = {
> + .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_od",
> + .ops = &clk_regmap_divider_ops,
> + .parent_hws = (const struct clk_hw *[]) {
> + &mclk_pll_dco.hw },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + },
> +};
> +
> +/* both value 0 and 1 gives divide the input rate by one */
> +static struct clk_regmap mclk_pll = {
> + .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",
> + .ops = &clk_regmap_divider_ops,
> + .parent_hws = (const struct clk_hw *[]) {
> + &mclk_pll_od.hw
> + },
> + .num_parents = 1,
> + .flags = CLK_SET_RATE_PARENT,
> + },
> +};
> +
> +static const struct clk_parent_data mclk_parent[] = {
> + { .hw = &mclk_pll.hw },
> + { .fw_name = "mclk" },
> + { .hw = &fclk_50m.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_div_en = {
> + .data = &(struct clk_regmap_gate_data) {
> + .offset = ANACTRL_MPLL_CTRL4,
> + .bit_idx = 1,
> + },
> + .hw.init = &(struct clk_init_data) {
> + .name = "mclk0_div_en",
> + .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_div_en.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_div_en = {
> + .data = &(struct clk_regmap_gate_data) {
> + .offset = ANACTRL_MPLL_CTRL4,
> + .bit_idx = 9,
> + },
> + .hw.init = &(struct clk_init_data) {
> + .name = "mclk1_div_en",
> + .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_div_en.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_FCLK_50M_EN] = &fclk_50m_en.hw,
> + [CLKID_FCLK_50M] = &fclk_50m.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_OD] = &mclk_pll_od.hw,
> + [CLKID_MCLK_PLL] = &mclk_pll.hw,
> + [CLKID_MCLK0_SEL] = &mclk0_sel.hw,
> + [CLKID_MCLK0_SEL_EN] = &mclk0_div_en.hw,
> + [CLKID_MCLK0_DIV] = &mclk0_div.hw,
> + [CLKID_MCLK0] = &mclk0.hw,
> + [CLKID_MCLK1_SEL] = &mclk1_sel.hw,
> + [CLKID_MCLK1_SEL_EN] = &mclk1_div_en.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[] = {
> + &fclk_50m_en,
> + &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_od,
> + &mclk_pll,
> + &mclk0_sel,
> + &mclk0_div_en,
> + &mclk0_div,
> + &mclk0,
> + &mclk1_sel,
> + &mclk1_div_en,
> + &mclk1_div,
> + &mclk1,
> +};
> +
> +static struct regmap_config clkc_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = ANACTRL_MPLL_CTRL4,
> +};
> +
> +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 <[email protected]>");
> +MODULE_LICENSE("GPL");
--
Jerome
Hi Jerome,
Thanks for your reply.
On 2024/5/3 22:11, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
>
> On Tue 30 Apr 2024 at 14:44, Xianwei Zhao <[email protected]> wrote:
>
>> Add the C3 PLL clock controller driver for the Amlogic C3 SoC family.
>>
>> Co-developed-by: Chuan Liu <[email protected]>
>> Signed-off-by: Chuan Liu <[email protected]>
>> Signed-off-by: Xianwei Zhao <[email protected]>
>> ---
>> drivers/clk/meson/Kconfig | 14 +
>> drivers/clk/meson/Makefile | 1 +
>> drivers/clk/meson/c3-pll.c | 746 +++++++++++++++++++++++++++++++++++++
>> 3 files changed, 761 insertions(+)
>> create mode 100644 drivers/clk/meson/c3-pll.c
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index 29ffd14d267b..9f975a980581 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -128,6 +128,20 @@ 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"
>> + depends on ARM64
>> + depends on ARM_SCMI_PROTOCOL
>
> There was a comment from Rob on v7 that was not addressed.
> Please make sure you address all comments before reposting.
>
Will detete it.
>> + depends on COMMON_CLK_SCMI
>
> imply, not depend.
Will fix it "imply COMMON_CLK_SCMI"
>
>> + 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. 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..74e11add165c
>> --- /dev/null
>> +++ b/drivers/clk/meson/c3-pll.c
>> @@ -0,0 +1,746 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Amlogic C3 PLL Controller Driver
>> + *
>> + * Copyright (c) 2023 Amlogic, inc.
>> + * Author: Chuan Liu <[email protected]>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/platform_device.h>
>> +#include "clk-regmap.h"
>> +#include "clk-pll.h"
>> +#include "meson-clkc-utils.h"
>> +#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
>> +
>> +#define ANACTRL_FIXPLL_CTRL4 0x50
>> +#define ANACTRL_GP0PLL_CTRL0 0x80
>> +#define ANACTRL_GP0PLL_CTRL1 0x84
>> +#define ANACTRL_GP0PLL_CTRL2 0x88
>> +#define ANACTRL_GP0PLL_CTRL3 0x8c
>> +#define ANACTRL_GP0PLL_CTRL4 0x90
>> +#define ANACTRL_GP0PLL_CTRL5 0x94
>> +#define ANACTRL_GP0PLL_CTRL6 0x98
>> +#define ANACTRL_HIFIPLL_CTRL0 0x100
>> +#define ANACTRL_HIFIPLL_CTRL1 0x104
>> +#define ANACTRL_HIFIPLL_CTRL2 0x108
>> +#define ANACTRL_HIFIPLL_CTRL3 0x10c
>> +#define ANACTRL_HIFIPLL_CTRL4 0x110
>> +#define ANACTRL_HIFIPLL_CTRL5 0x114
>> +#define ANACTRL_HIFIPLL_CTRL6 0x118
>> +#define ANACTRL_MPLL_CTRL0 0x180
>> +#define ANACTRL_MPLL_CTRL1 0x184
>> +#define ANACTRL_MPLL_CTRL2 0x188
>> +#define ANACTRL_MPLL_CTRL3 0x18c
>> +#define ANACTRL_MPLL_CTRL4 0x190
>> +
>> +static struct clk_regmap fclk_50m_en = {
>> + .data = &(struct clk_regmap_gate_data) {
>> + .offset = ANACTRL_FIXPLL_CTRL4,
>> + .bit_idx = 0,
>> + },
>> + .hw.init = &(struct clk_init_data) {
>> + .name = "fclk_50m_en",
>> + .ops = &clk_regmap_gate_ro_ops,
>> + .parent_data = &(const struct clk_parent_data) {
>> + .fw_name = "fix"
>> + },
>> + .num_parents = 1,
>> + },
>> +};
>> +
>> +static struct clk_fixed_factor fclk_50m = {
>> + .mult = 1,
>> + .div = 40,
>> + .hw.init = &(struct clk_init_data) {
>> + .name = "fclk_50m",
>> + .ops = &clk_fixed_factor_ops,
>> + .parent_hws = (const struct clk_hw *[]) {
>> + &fclk_50m_en.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_data = &(const struct clk_parent_data) {
>> + .fw_name = "fix"
>> + },
>> + .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_data = &(const struct clk_parent_data) {
>> + .fw_name = "fix"
>> + },
>> + .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_data = &(const struct clk_parent_data) {
>> + .fw_name = "fix"
>> + },
>> + .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_data = &(const struct clk_parent_data) {
>> + .fw_name = "fix"
>> + },
>> + .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_data = &(const struct clk_parent_data) {
>> + .fw_name = "fix"
>> + },
>> + .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_data = &(const struct clk_parent_data) {
>> + .fw_name = "fix"
>> + },
>> + .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_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 },
>> +};
>> +
>> +static const struct pll_mult_range c3_gp0_pll_mult_range = {
>> + .min = 125,
>> + .max = 250,
>> +};
>> +
>> +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,
>> + },
>> + .range = &c3_gp0_pll_mult_range,
>> + .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 = &(const struct clk_parent_data) {
>> + .fw_name = "top",
>> + },
>> + .num_parents = 1,
>> + },
>> +};
>> +
>> +/* 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 = {
>> + .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_CTRL2, .def = 0x0 },
>> + { .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 },
>> + { .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
>> + { .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
>> + { .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000 },
>> +};
>> +
>> +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,
>> + },
>> + .range = &c3_gp0_pll_mult_range,
>> + .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 = &(const struct clk_parent_data) {
>> + .fw_name = "top",
>> + },
>> + .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_CTRL1, .def = 0x1420500f },
>> + { .reg = ANACTRL_MPLL_CTRL2, .def = 0x00023041 },
>> + { .reg = ANACTRL_MPLL_CTRL3, .def = 0x18180000 },
>> + { .reg = ANACTRL_MPLL_CTRL2, .def = 0x00023001 }
>> +};
>> +
>> +static const struct pll_mult_range c3_mclk_pll_mult_range = {
>> + .min = 67,
>> + .max = 133,
>> +};
>> +
>> +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 = 8,
>> + },
>> + .n = {
>> + .reg_off = ANACTRL_MPLL_CTRL0,
>> + .shift = 16,
>> + .width = 5,
>> + },
>> + .l = {
>> + .reg_off = ANACTRL_MPLL_CTRL0,
>> + .shift = 31,
>> + .width = 1,
>> + },
>> + .rst = {
>> + .reg_off = ANACTRL_MPLL_CTRL0,
>> + .shift = 29,
>> + .width = 1,
>> + },
>> + .range = &c3_mclk_pll_mult_range,
>> + .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 = &(const struct clk_parent_data) {
>> + .fw_name = "mclk",
>> + },
>> + .num_parents = 1,
>> + },
>> +};
>> +
>> +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_od = {
>> + .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_od",
>> + .ops = &clk_regmap_divider_ops,
>> + .parent_hws = (const struct clk_hw *[]) {
>> + &mclk_pll_dco.hw },
>> + .num_parents = 1,
>> + .flags = CLK_SET_RATE_PARENT,
>> + },
>> +};
>> +
>> +/* both value 0 and 1 gives divide the input rate by one */
>> +static struct clk_regmap mclk_pll = {
>> + .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",
>> + .ops = &clk_regmap_divider_ops,
>> + .parent_hws = (const struct clk_hw *[]) {
>> + &mclk_pll_od.hw
>> + },
>> + .num_parents = 1,
>> + .flags = CLK_SET_RATE_PARENT,
>> + },
>> +};
>> +
>> +static const struct clk_parent_data mclk_parent[] = {
>> + { .hw = &mclk_pll.hw },
>> + { .fw_name = "mclk" },
>> + { .hw = &fclk_50m.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_div_en = {
>> + .data = &(struct clk_regmap_gate_data) {
>> + .offset = ANACTRL_MPLL_CTRL4,
>> + .bit_idx = 1,
>> + },
>> + .hw.init = &(struct clk_init_data) {
>> + .name = "mclk0_div_en",
>> + .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_div_en.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_div_en = {
>> + .data = &(struct clk_regmap_gate_data) {
>> + .offset = ANACTRL_MPLL_CTRL4,
>> + .bit_idx = 9,
>> + },
>> + .hw.init = &(struct clk_init_data) {
>> + .name = "mclk1_div_en",
>> + .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_div_en.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_FCLK_50M_EN] = &fclk_50m_en.hw,
>> + [CLKID_FCLK_50M] = &fclk_50m.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_OD] = &mclk_pll_od.hw,
>> + [CLKID_MCLK_PLL] = &mclk_pll.hw,
>> + [CLKID_MCLK0_SEL] = &mclk0_sel.hw,
>> + [CLKID_MCLK0_SEL_EN] = &mclk0_div_en.hw,
>> + [CLKID_MCLK0_DIV] = &mclk0_div.hw,
>> + [CLKID_MCLK0] = &mclk0.hw,
>> + [CLKID_MCLK1_SEL] = &mclk1_sel.hw,
>> + [CLKID_MCLK1_SEL_EN] = &mclk1_div_en.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[] = {
>> + &fclk_50m_en,
>> + &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_od,
>> + &mclk_pll,
>> + &mclk0_sel,
>> + &mclk0_div_en,
>> + &mclk0_div,
>> + &mclk0,
>> + &mclk1_sel,
>> + &mclk1_div_en,
>> + &mclk1_div,
>> + &mclk1,
>> +};
>> +
>> +static struct regmap_config clkc_regmap_config = {
>> + .reg_bits = 32,
>> + .val_bits = 32,
>> + .reg_stride = 4,
>> + .max_register = ANACTRL_MPLL_CTRL4,
>> +};
>> +
>> +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 <[email protected]>");
>> +MODULE_LICENSE("GPL");
>
>
> --
> Jerome
Hi Jerome,
Thanks for your reply.
On 2024/5/3 22:04, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
>
> On Tue 30 Apr 2024 at 14:44, Xianwei Zhao <[email protected]> wrote:
>
>> Add the C3 peripherals clock controller driver in the C3 SoC family.
>>
>> Co-developed-by: Chuan Liu <[email protected]>
>> Signed-off-by: Chuan Liu <[email protected]>
>> Signed-off-by: Xianwei Zhao <[email protected]>
>> ---
>> drivers/clk/meson/Kconfig | 15 +
>> drivers/clk/meson/Makefile | 1 +
>> drivers/clk/meson/c3-peripherals.c | 2365 ++++++++++++++++++++++++++++
>> 3 files changed, 2381 insertions(+)
>> create mode 100644 drivers/clk/meson/c3-peripherals.c
>>
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index 9f975a980581..0b85d584910e 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -142,6 +142,21 @@ config COMMON_CLK_C3_PLL
>> AKA C3. 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"
>> + depends on ARM64
>> + depends on ARM_SCMI_PROTOCOL
>
> Rob has commented on v7 that this is not OK.
> It was on the PLL patch but you can guess that if this is not OK for the
> PLL controller, it is not OK for the peripheral controller either.
>
> So please drop this
Will do.
>
>> + depends on COMMON_CLK_SCMI
>
> imply, not depends
Will fix it .
>
>> + depends on COMMON_CLK_C3_PLL
>
> Same.
Will fix it.
>
>> + default y
>> + select COMMON_CLK_MESON_REGMAP
>> + select COMMON_CLK_MESON_DUALDIV
>> + select COMMON_CLK_MESON_CLKC_UTILS
>> + help
>> + Support for the Peripherals clock controller on Amlogic C302X and
>> + C308L devices, AKA C3. 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..b786d8ff9be0
>> --- /dev/null
>> +++ b/drivers/clk/meson/c3-peripherals.c
>> @@ -0,0 +1,2365 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Amlogic C3 Peripherals Clock Controller Driver
>> + *
>> + * Copyright (c) 2023 Amlogic, inc.
>> + * Author: Chuan Liu <[email protected]>
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/platform_device.h>
>> +#include "clk-regmap.h"
>> +#include "clk-dualdiv.h"
>> +#include "meson-clkc-utils.h"
>> +#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
>> +
>> +#define RTC_BY_OSCIN_CTRL0 0x8
>> +#define RTC_BY_OSCIN_CTRL1 0xc
>> +#define RTC_CTRL 0x10
>> +#define SYS_CLK_EN0_REG0 0x44
>> +#define SYS_CLK_EN0_REG1 0x48
>> +#define SYS_CLK_EN0_REG2 0x4c
>> +#define CLK12_24_CTRL 0xa8
>> +#define AXI_CLK_EN0 0xac
>> +#define VDIN_MEAS_CLK_CTRL 0xf8
>> +#define VAPB_CLK_CTRL 0xfc
>> +#define MIPIDSI_PHY_CLK_CTRL 0x104
>> +#define GE2D_CLK_CTRL 0x10c
>> +#define ISP0_CLK_CTRL 0x110
>> +#define DEWARPA_CLK_CTRL 0x114
>> +#define VOUTENC_CLK_CTRL 0x118
>> +#define VDEC_CLK_CTRL 0x140
>> +#define VDEC3_CLK_CTRL 0x148
>> +#define TS_CLK_CTRL 0x158
>> +#define ETH_CLK_CTRL 0x164
>> +#define NAND_CLK_CTRL 0x168
>> +#define SD_EMMC_CLK_CTRL 0x16c
>> +#define SPICC_CLK_CTRL 0x174
>> +#define GEN_CLK_CTRL 0x178
>> +#define SAR_CLK_CTRL0 0x17c
>> +#define PWM_CLK_AB_CTRL 0x180
>> +#define PWM_CLK_CD_CTRL 0x184
>> +#define PWM_CLK_EF_CTRL 0x188
>> +#define PWM_CLK_GH_CTRL 0x18c
>> +#define PWM_CLK_IJ_CTRL 0x190
>> +#define PWM_CLK_KL_CTRL 0x194
>> +#define PWM_CLK_MN_CTRL 0x198
>> +#define VC9000E_CLK_CTRL 0x19c
>> +#define SPIFC_CLK_CTRL 0x1a0
>> +#define NNA_CLK_CTRL 0x220
>> +
>> +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 = &(const struct clk_parent_data) {
>> + .fw_name = "oscin",
>> + },
>> + .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 = "oscin" },
>> + { .hw = &rtc_32k.hw },
>> + { .fw_name = "pad_osc" }
>> +};
>> +
>> +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,
>> + },
>> +};
>> +
>> +#define C3_CLK_GATE(_name, _reg, _bit, _fw_name, _ops, _flags) \
>> +struct clk_regmap _name = { \
>> + .data = &(struct clk_regmap_gate_data){ \
>> + .offset = (_reg), \
>> + .bit_idx = (_bit), \
>> + }, \
>> + .hw.init = &(struct clk_init_data) { \
>> + .name = #_name, \
>> + .ops = _ops, \
>> + .parent_data = &(const struct clk_parent_data) { \
>> + .fw_name = #_fw_name, \
>> + }, \
>> + .num_parents = 1, \
>> + .flags = (_flags), \
>> + }, \
>> +}
>> +
>> +#define C3_SYS_GATE(_name, _reg, _bit, _flags) \
>> + C3_CLK_GATE(_name, _reg, _bit, sysclk, \
>> + &clk_regmap_gate_ops, _flags)
>> +
>> +#define C3_SYS_GATE_RO(_name, _reg, _bit) \
>> + C3_CLK_GATE(_name, _reg, _bit, sysclk, \
>> + &clk_regmap_gate_ro_ops, 0)
>> +
>> +static C3_SYS_GATE(sys_reset_ctrl, SYS_CLK_EN0_REG0, 1, 0);
>> +static C3_SYS_GATE(sys_pwr_ctrl, SYS_CLK_EN0_REG0, 3, 0);
>> +static C3_SYS_GATE(sys_pad_ctrl, SYS_CLK_EN0_REG0, 4, 0);
>> +static C3_SYS_GATE(sys_ctrl, SYS_CLK_EN0_REG0, 5, 0);
>> +static C3_SYS_GATE(sys_ts_pll, SYS_CLK_EN0_REG0, 6, 0);
>> +
>> +/*
>> + * NOTE: sys_dev_arb provides the clock to the ETH and SPICC arbiters that
>> + * access the AXI bus.
>> + */
>> +static C3_SYS_GATE(sys_dev_arb, SYS_CLK_EN0_REG0, 7, 0);
>> +
>> +/*
>> + * FIXME: sys_mmc_pclk provides the clock for the DDR PHY, DDR will only be
>> + * initialized in bl2, and this clock should not be touched in linux.
>> + */
>> +static C3_SYS_GATE_RO(sys_mmc_pclk, SYS_CLK_EN0_REG0, 8);
>> +
>> +/*
>> + * NOTE: sys_cpu_ctrl provides the clock for CPU controller. After clock is
>> + * disabled, cpu_clk and other key CPU-related configurations cannot take effect.
>> + */
>> +static C3_SYS_GATE(sys_cpu_ctrl, SYS_CLK_EN0_REG0, 11, CLK_IS_CRITICAL);
>> +static C3_SYS_GATE(sys_jtag_ctrl, SYS_CLK_EN0_REG0, 12, 0);
>> +static C3_SYS_GATE(sys_ir_ctrl, SYS_CLK_EN0_REG0, 13, 0);
>> +
>> +/*
>> + * NOTE: sys_irq_ctrl provides the clock for IRQ controller. The IRQ controller
>> + * collects and distributes the interrupt signal to the GIC, PWR_CTRL, and
>> + * AOCPU. If the clock is disabled, interrupt-related functions will occurs an
>> + * exception.
>> + */
>> +static C3_SYS_GATE(sys_irq_ctrl, SYS_CLK_EN0_REG0, 14, CLK_IS_CRITICAL);
>> +static C3_SYS_GATE(sys_msr_clk, SYS_CLK_EN0_REG0, 15, 0);
>> +static C3_SYS_GATE(sys_rom, SYS_CLK_EN0_REG0, 16, 0);
>> +static C3_SYS_GATE(sys_uart_f, SYS_CLK_EN0_REG0, 17, 0);
>> +static C3_SYS_GATE(sys_cpu_apb, SYS_CLK_EN0_REG0, 18, 0);
>> +static C3_SYS_GATE(sys_rsa, SYS_CLK_EN0_REG0, 19, 0);
>> +static C3_SYS_GATE(sys_sar_adc, SYS_CLK_EN0_REG0, 20, 0);
>> +static C3_SYS_GATE(sys_startup, SYS_CLK_EN0_REG0, 21, 0);
>> +static C3_SYS_GATE(sys_secure, SYS_CLK_EN0_REG0, 22, 0);
>> +static C3_SYS_GATE(sys_spifc, SYS_CLK_EN0_REG0, 23, 0);
>> +static C3_SYS_GATE(sys_nna, SYS_CLK_EN0_REG0, 25, 0);
>> +static C3_SYS_GATE(sys_eth_mac, SYS_CLK_EN0_REG0, 26, 0);
>> +
>> +/*
>> + * FIXME: sys_gic provides the clock for GIC(Generic Interrupt Controller).
>> + * After clock is disabled, The GIC cannot work properly. At present, the driver
>> + * used by our GIC is the public driver in kernel, and there is no management
>> + * clock in the driver.
>> + */
>> +static C3_SYS_GATE(sys_gic, SYS_CLK_EN0_REG0, 27, CLK_IS_CRITICAL);
>> +static C3_SYS_GATE(sys_rama, SYS_CLK_EN0_REG0, 28, 0);
>> +
>> +/*
>> + * NOTE: sys_big_nic provides the clock to the control bus of the NIC(Network
>> + * Interface Controller) between multiple devices(CPU, DDR, RAM, ROM, GIC,
>> + * SPIFC, CAPU, JTAG, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC) in the
>> + * system. After clock is disabled, The NIC cannot work.
>> + */
>> +static C3_SYS_GATE(sys_big_nic, SYS_CLK_EN0_REG0, 29, CLK_IS_CRITICAL);
>> +static C3_SYS_GATE(sys_ramb, SYS_CLK_EN0_REG0, 30, 0);
>> +static C3_SYS_GATE(sys_audio_pclk, SYS_CLK_EN0_REG0, 31, 0);
>> +static C3_SYS_GATE(sys_pwm_kl, SYS_CLK_EN0_REG1, 0, 0);
>> +static C3_SYS_GATE(sys_pwm_ij, SYS_CLK_EN0_REG1, 1, 0);
>> +static C3_SYS_GATE(sys_usb, SYS_CLK_EN0_REG1, 2, 0);
>> +static C3_SYS_GATE(sys_sd_emmc_a, SYS_CLK_EN0_REG1, 3, 0);
>> +static C3_SYS_GATE(sys_sd_emmc_c, SYS_CLK_EN0_REG1, 4, 0);
>> +static C3_SYS_GATE(sys_pwm_ab, SYS_CLK_EN0_REG1, 5, 0);
>> +static C3_SYS_GATE(sys_pwm_cd, SYS_CLK_EN0_REG1, 6, 0);
>> +static C3_SYS_GATE(sys_pwm_ef, SYS_CLK_EN0_REG1, 7, 0);
>> +static C3_SYS_GATE(sys_pwm_gh, SYS_CLK_EN0_REG1, 8, 0);
>> +static C3_SYS_GATE(sys_spicc_1, SYS_CLK_EN0_REG1, 9, 0);
>> +static C3_SYS_GATE(sys_spicc_0, SYS_CLK_EN0_REG1, 10, 0);
>> +static C3_SYS_GATE(sys_uart_a, SYS_CLK_EN0_REG1, 11, 0);
>> +static C3_SYS_GATE(sys_uart_b, SYS_CLK_EN0_REG1, 12, 0);
>> +static C3_SYS_GATE(sys_uart_c, SYS_CLK_EN0_REG1, 13, 0);
>> +static C3_SYS_GATE(sys_uart_d, SYS_CLK_EN0_REG1, 14, 0);
>> +static C3_SYS_GATE(sys_uart_e, SYS_CLK_EN0_REG1, 15, 0);
>> +static C3_SYS_GATE(sys_i2c_m_a, SYS_CLK_EN0_REG1, 16, 0);
>> +static C3_SYS_GATE(sys_i2c_m_b, SYS_CLK_EN0_REG1, 17, 0);
>> +static C3_SYS_GATE(sys_i2c_m_c, SYS_CLK_EN0_REG1, 18, 0);
>> +static C3_SYS_GATE(sys_i2c_m_d, SYS_CLK_EN0_REG1, 19, 0);
>> +static C3_SYS_GATE(sys_i2c_s_a, SYS_CLK_EN0_REG1, 20, 0);
>> +static C3_SYS_GATE(sys_rtc, SYS_CLK_EN0_REG1, 21, 0);
>> +static C3_SYS_GATE(sys_ge2d, SYS_CLK_EN0_REG1, 22, 0);
>> +static C3_SYS_GATE(sys_isp, SYS_CLK_EN0_REG1, 23, 0);
>> +static C3_SYS_GATE(sys_gpv_isp_nic, SYS_CLK_EN0_REG1, 24, 0);
>> +static C3_SYS_GATE(sys_gpv_cve_nic, SYS_CLK_EN0_REG1, 25, 0);
>> +static C3_SYS_GATE(sys_mipi_dsi_host, SYS_CLK_EN0_REG1, 26, 0);
>> +static C3_SYS_GATE(sys_mipi_dsi_phy, SYS_CLK_EN0_REG1, 27, 0);
>> +static C3_SYS_GATE(sys_eth_phy, SYS_CLK_EN0_REG1, 28, 0);
>> +static C3_SYS_GATE(sys_acodec, SYS_CLK_EN0_REG1, 29, 0);
>> +static C3_SYS_GATE(sys_dwap, SYS_CLK_EN0_REG1, 30, 0);
>> +static C3_SYS_GATE(sys_dos, SYS_CLK_EN0_REG1, 31, 0);
>> +static C3_SYS_GATE(sys_cve, SYS_CLK_EN0_REG2, 0, 0);
>> +static C3_SYS_GATE(sys_vout, SYS_CLK_EN0_REG2, 1, 0);
>> +static C3_SYS_GATE(sys_vc9000e, SYS_CLK_EN0_REG2, 2, 0);
>> +static C3_SYS_GATE(sys_pwm_mn, SYS_CLK_EN0_REG2, 3, 0);
>> +static C3_SYS_GATE(sys_sd_emmc_b, SYS_CLK_EN0_REG2, 4, 0);
>> +
>> +#define C3_AXI_GATE(_name, _reg, _bit, _flags) \
>> + C3_CLK_GATE(_name, _reg, _bit, axiclk, \
>> + &clk_regmap_gate_ops, _flags)
>> +
>> +/*
>> + * NOTE: axi_sys_nic provides the clock to the AXI bus of the system NIC. After
>> + * clock is disabled, The NIC cannot work.
>> + */
>> +static C3_AXI_GATE(axi_sys_nic, AXI_CLK_EN0, 2, CLK_IS_CRITICAL);
>> +static C3_AXI_GATE(axi_isp_nic, AXI_CLK_EN0, 3, 0);
>> +static C3_AXI_GATE(axi_cve_nic, AXI_CLK_EN0, 4, 0);
>> +static C3_AXI_GATE(axi_ramb, AXI_CLK_EN0, 5, 0);
>> +static C3_AXI_GATE(axi_rama, AXI_CLK_EN0, 6, 0);
>> +
>> +/*
>> + * NOTE: axi_cpu_dmc provides the clock to the AXI bus where the CPU accesses
>> + * the DDR. After clock is disabled, The CPU will not have access to the DDR.
>> + */
>> +static C3_AXI_GATE(axi_cpu_dmc, AXI_CLK_EN0, 7, CLK_IS_CRITICAL);
>> +static C3_AXI_GATE(axi_nic, AXI_CLK_EN0, 8, 0);
>> +static C3_AXI_GATE(axi_dma, AXI_CLK_EN0, 9, 0);
>> +
>> +/*
>> + * NOTE: axi_mux_nic provides the clock to the NIC's AXI bus for NN(Neural
>> + * Network) and other devices(CPU, EMMC, SDIO, sec_top, USB, Audio, ETH, SPICC)
>> + * to access RAM space.
>> + */
>> +static C3_AXI_GATE(axi_mux_nic, AXI_CLK_EN0, 10, 0);
>> +static C3_AXI_GATE(axi_cve, AXI_CLK_EN0, 12, 0);
>> +
>> +/*
>> + * NOTE: axi_dev1_dmc provides the clock for the peripherals(EMMC, SDIO,
>> + * sec_top, USB, Audio, ETH, SPICC) to access the AXI bus of the DDR.
>> + */
>> +static C3_AXI_GATE(axi_dev1_dmc, AXI_CLK_EN0, 13, 0);
>> +static C3_AXI_GATE(axi_dev0_dmc, AXI_CLK_EN0, 14, 0);
>> +static C3_AXI_GATE(axi_dsp_dmc, AXI_CLK_EN0, 15, 0);
>> +
>> +/*
>> + * clk_12_24m model
>> + *
>> + * |------| |-----| clk_12m_24m |-----|
>> + * xtal---->| gate |---->| div |------------>| pad |
>> + * |------| |-----| |-----|
>> + */
>> +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 = &(const struct clk_parent_data) {
>> + .fw_name = "xtal_24m",
>> + },
>> + .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,
>> + },
>> +};
>> +
>> +/* Fix me: set value 0 will div by 2 like value 1 */
>> +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 = &(const struct clk_parent_data) {
>> + .fw_name = "fix",
>> + },
>> + .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,
>> + },
>> +};
>> +
>> +/*
>> + * Channel 3(ddr_dpll_pt_clk) is manged by the DDR module; channel 12(cts_msr_clk)
>> + * is manged by clock measures module. Their hardware are out of clock tree.
>> + * Channel 4 8 9 10 11 13 14 15 16 18 are not connected.
>> + */
>> +static u32 gen_parent_table[] = { 0, 1, 2, 5, 6, 7, 17, 19, 20, 21, 22, 23, 24};
>> +
>> +static const struct clk_parent_data gen_parent_data[] = {
>> + { .fw_name = "oscin" },
>> + { .hw = &rtc_clk.hw },
>> + { .fw_name = "sysplldiv16" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "cpudiv16" },
>> + { .fw_name = "fdiv2" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "fdiv7" }
>> +};
>> +
>> +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 = "oscin" },
>> + { .fw_name = "sysclk" }
>> +};
>> +
>> +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 const struct clk_parent_data pwm_parent_data[] = {
>> + { .fw_name = "oscin" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv3" }
>> +};
>> +
>> +#define AML_PWM_CLK_MUX(_name, _reg, _shift) { \
>> + .data = &(struct clk_regmap_mux_data) { \
>> + .offset = _reg, \
>> + .mask = 0x3, \
>> + .shift = _shift, \
>> + }, \
>> + .hw.init = &(struct clk_init_data) { \
>> + .name = #_name "_sel", \
>> + .ops = &clk_regmap_mux_ops, \
>> + .parent_data = pwm_parent_data, \
>> + .num_parents = ARRAY_SIZE(pwm_parent_data), \
>> + }, \
>> +}
>> +
>> +#define AML_PWM_CLK_DIV(_name, _reg, _shift) { \
>> + .data = &(struct clk_regmap_div_data) { \
>> + .offset = _reg, \
>> + .shift = _shift, \
>> + .width = 8, \
>> + }, \
>> + .hw.init = &(struct clk_init_data) { \
>> + .name = #_name "_div", \
>> + .ops = &clk_regmap_divider_ops, \
>> + .parent_names = (const char *[]) { #_name "_sel" },\
>> + .num_parents = 1, \
>> + .flags = CLK_SET_RATE_PARENT, \
>> + }, \
>> +}
>> +
>> +#define AML_PWM_CLK_GATE(_name, _reg, _bit) { \
>> + .data = &(struct clk_regmap_gate_data) { \
>> + .offset = _reg, \
>> + .bit_idx = _bit, \
>> + }, \
>> + .hw.init = &(struct clk_init_data) { \
>> + .name = #_name, \
>> + .ops = &clk_regmap_gate_ops, \
>> + .parent_names = (const char *[]) { #_name "_div" },\
>> + .num_parents = 1, \
>> + .flags = CLK_SET_RATE_PARENT, \
>> + }, \
>> +}
>> +
>> +static struct clk_regmap pwm_a_sel =
>> + AML_PWM_CLK_MUX(pwm_a, PWM_CLK_AB_CTRL, 9);
>> +static struct clk_regmap pwm_a_div =
>> + AML_PWM_CLK_DIV(pwm_a, PWM_CLK_AB_CTRL, 0);
>> +static struct clk_regmap pwm_a =
>> + AML_PWM_CLK_GATE(pwm_a, PWM_CLK_AB_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_b_sel =
>> + AML_PWM_CLK_MUX(pwm_b, PWM_CLK_AB_CTRL, 25);
>> +static struct clk_regmap pwm_b_div =
>> + AML_PWM_CLK_DIV(pwm_b, PWM_CLK_AB_CTRL, 16);
>> +static struct clk_regmap pwm_b =
>> + AML_PWM_CLK_GATE(pwm_b, PWM_CLK_AB_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_c_sel =
>> + AML_PWM_CLK_MUX(pwm_c, PWM_CLK_CD_CTRL, 9);
>> +static struct clk_regmap pwm_c_div =
>> + AML_PWM_CLK_DIV(pwm_c, PWM_CLK_CD_CTRL, 0);
>> +static struct clk_regmap pwm_c =
>> + AML_PWM_CLK_GATE(pwm_c, PWM_CLK_CD_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_d_sel =
>> + AML_PWM_CLK_MUX(pwm_d, PWM_CLK_CD_CTRL, 25);
>> +static struct clk_regmap pwm_d_div =
>> + AML_PWM_CLK_DIV(pwm_d, PWM_CLK_CD_CTRL, 16);
>> +static struct clk_regmap pwm_d =
>> + AML_PWM_CLK_GATE(pwm_d, PWM_CLK_CD_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_e_sel =
>> + AML_PWM_CLK_MUX(pwm_e, PWM_CLK_EF_CTRL, 9);
>> +static struct clk_regmap pwm_e_div =
>> + AML_PWM_CLK_DIV(pwm_e, PWM_CLK_EF_CTRL, 0);
>> +static struct clk_regmap pwm_e =
>> + AML_PWM_CLK_GATE(pwm_e, PWM_CLK_EF_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_f_sel =
>> + AML_PWM_CLK_MUX(pwm_f, PWM_CLK_EF_CTRL, 25);
>> +static struct clk_regmap pwm_f_div =
>> + AML_PWM_CLK_DIV(pwm_f, PWM_CLK_EF_CTRL, 16);
>> +static struct clk_regmap pwm_f =
>> + AML_PWM_CLK_GATE(pwm_f, PWM_CLK_EF_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_g_sel =
>> + AML_PWM_CLK_MUX(pwm_g, PWM_CLK_GH_CTRL, 9);
>> +static struct clk_regmap pwm_g_div =
>> + AML_PWM_CLK_DIV(pwm_g, PWM_CLK_GH_CTRL, 0);
>> +static struct clk_regmap pwm_g =
>> + AML_PWM_CLK_GATE(pwm_g, PWM_CLK_GH_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_h_sel =
>> + AML_PWM_CLK_MUX(pwm_h, PWM_CLK_GH_CTRL, 25);
>> +static struct clk_regmap pwm_h_div =
>> + AML_PWM_CLK_DIV(pwm_h, PWM_CLK_GH_CTRL, 16);
>> +static struct clk_regmap pwm_h =
>> + AML_PWM_CLK_GATE(pwm_h, PWM_CLK_GH_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_i_sel =
>> + AML_PWM_CLK_MUX(pwm_i, PWM_CLK_IJ_CTRL, 9);
>> +static struct clk_regmap pwm_i_div =
>> + AML_PWM_CLK_DIV(pwm_i, PWM_CLK_IJ_CTRL, 0);
>> +static struct clk_regmap pwm_i =
>> + AML_PWM_CLK_GATE(pwm_i, PWM_CLK_IJ_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_j_sel =
>> + AML_PWM_CLK_MUX(pwm_j, PWM_CLK_IJ_CTRL, 25);
>> +static struct clk_regmap pwm_j_div =
>> + AML_PWM_CLK_DIV(pwm_j, PWM_CLK_IJ_CTRL, 16);
>> +static struct clk_regmap pwm_j =
>> + AML_PWM_CLK_GATE(pwm_j, PWM_CLK_IJ_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_k_sel =
>> + AML_PWM_CLK_MUX(pwm_k, PWM_CLK_KL_CTRL, 9);
>> +static struct clk_regmap pwm_k_div =
>> + AML_PWM_CLK_DIV(pwm_k, PWM_CLK_KL_CTRL, 0);
>> +static struct clk_regmap pwm_k =
>> + AML_PWM_CLK_GATE(pwm_k, PWM_CLK_KL_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_l_sel =
>> + AML_PWM_CLK_MUX(pwm_l, PWM_CLK_KL_CTRL, 25);
>> +static struct clk_regmap pwm_l_div =
>> + AML_PWM_CLK_DIV(pwm_l, PWM_CLK_KL_CTRL, 16);
>> +static struct clk_regmap pwm_l =
>> + AML_PWM_CLK_GATE(pwm_l, PWM_CLK_KL_CTRL, 24);
>> +
>> +static struct clk_regmap pwm_m_sel =
>> + AML_PWM_CLK_MUX(pwm_m, PWM_CLK_MN_CTRL, 9);
>> +static struct clk_regmap pwm_m_div =
>> + AML_PWM_CLK_DIV(pwm_m, PWM_CLK_MN_CTRL, 0);
>> +static struct clk_regmap pwm_m =
>> + AML_PWM_CLK_GATE(pwm_m, PWM_CLK_MN_CTRL, 8);
>> +
>> +static struct clk_regmap pwm_n_sel =
>> + AML_PWM_CLK_MUX(pwm_n, PWM_CLK_MN_CTRL, 25);
>> +static struct clk_regmap pwm_n_div =
>> + AML_PWM_CLK_DIV(pwm_n, PWM_CLK_MN_CTRL, 16);
>> +static struct clk_regmap pwm_n =
>> + AML_PWM_CLK_GATE(pwm_n, PWM_CLK_MN_CTRL, 24);
>> +
>> +static const struct clk_parent_data spicc_parent_data[] = {
>> + { .fw_name = "oscin" },
>> + { .fw_name = "sysclk" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv2" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "fdiv7" },
>> + { .fw_name = "gp1" }
>> +};
>> +
>> +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" },
>> + { .fw_name = "fdiv2" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "fdiv7" }
>> +};
>> +
>> +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 const struct clk_parent_data emmc_parent_data[] = {
>> + { .fw_name = "oscin" },
>> + { .fw_name = "fdiv2" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "gp0" }
>> +};
>> +
>> +static struct clk_regmap sd_emmc_a_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = SD_EMMC_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 9,
>> + },
>> + .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,
>> + },
>> + .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,
>> + },
>> + .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,
>> + },
>> +};
>> +
>> +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 = &(const struct clk_parent_data) {
>> + .fw_name = "oscin",
>> + },
>> + .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 = "fdiv2",
>> +};
>> +
>> +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 = ð_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 *[]) {
>> + ð_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 = ð_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 *[]) {
>> + ð_rmii_div.hw
>> + },
>> + .num_parents = 1,
>> + .flags = CLK_SET_RATE_PARENT,
>> + },
>> +};
>> +
>> +static const struct clk_parent_data mipi_dsi_meas_parent_data[] = {
>> + { .fw_name = "oscin" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "fdiv2" },
>> + { .fw_name = "fdiv7" }
>> +};
>> +
>> +static struct clk_regmap mipi_dsi_meas_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = VDIN_MEAS_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 21,
>> + },
>> + .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 const struct clk_parent_data dsi_phy_parent_data[] = {
>> + { .fw_name = "gp1" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv2" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv7" }
>> +};
>> +
>> +static struct clk_regmap dsi_phy_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = MIPIDSI_PHY_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 12,
>> + },
>> + .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 const struct clk_parent_data vout_mclk_parent_data[] = {
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "fdiv7" }
>> +};
>> +
>> +static struct clk_regmap vout_mclk_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = VOUTENC_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 9,
>> + },
>> + .hw.init = &(struct clk_init_data) {
>> + .name = "vout_mclk_sel",
>> + .ops = &clk_regmap_mux_ops,
>> + .parent_data = vout_mclk_parent_data,
>> + .num_parents = ARRAY_SIZE(vout_mclk_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 = VOUTENC_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 const struct clk_parent_data vout_enc_parent_data[] = {
>> + { .fw_name = "gp1" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv7" }
>> +};
>> +
>> +static struct clk_regmap vout_enc_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = VOUTENC_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 25,
>> + },
>> + .hw.init = &(struct clk_init_data) {
>> + .name = "vout_enc_sel",
>> + .ops = &clk_regmap_mux_ops,
>> + .parent_data = vout_enc_parent_data,
>> + .num_parents = ARRAY_SIZE(vout_enc_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 = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "fdiv7" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "oscin" }
>> +};
>> +
>> +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 = "oscin" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "fdiv7" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "gp0" }
>> +};
>> +
>> +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 const struct clk_parent_data csi_phy_parent_data[] = {
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "oscin" }
>> +};
>> +
>> +static struct clk_regmap csi_phy0_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = ISP0_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 25,
>> + },
>> + .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 const struct clk_parent_data dewarpa_parent_data[] = {
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "fdiv7" }
>> +};
>> +
>> +static struct clk_regmap dewarpa_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = DEWARPA_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 9,
>> + },
>> + .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 const struct clk_parent_data isp_parent_data[] = {
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "oscin" }
>> +};
>> +
>> +static struct clk_regmap isp0_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = ISP0_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 9,
>> + },
>> + .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 const struct clk_parent_data nna_core_parent_data[] = {
>> + { .fw_name = "oscin" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "fdiv2" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "hifi" }
>> +};
>> +
>> +static struct clk_regmap nna_core_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = NNA_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 9,
>> + },
>> + .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 = "oscin" },
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp0" },
>> + { .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 const struct clk_parent_data vapb_parent_data[] = {
>> + { .fw_name = "fdiv2p5" },
>> + { .fw_name = "fdiv3" },
>> + { .fw_name = "fdiv4" },
>> + { .fw_name = "fdiv5" },
>> + { .fw_name = "gp0" },
>> + { .fw_name = "hifi" },
>> + { .fw_name = "gp1" },
>> + { .fw_name = "oscin" },
>> +};
>> +
>> +static struct clk_regmap vapb_sel = {
>> + .data = &(struct clk_regmap_mux_data) {
>> + .offset = VAPB_CLK_CTRL,
>> + .mask = 0x7,
>> + .shift = 9,
>> + },
>> + .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_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_RESET_CTRL] = &sys_reset_ctrl.hw,
>> + [CLKID_SYS_PWR_CTRL] = &sys_pwr_ctrl.hw,
>> + [CLKID_SYS_PAD_CTRL] = &sys_pad_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_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_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] = ð_125m_div.hw,
>> + [CLKID_ETH_125M] = ð_125m.hw,
>> + [CLKID_ETH_RMII_DIV] = ð_rmii_div.hw,
>> + [CLKID_ETH_RMII] = ð_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[] = {
>> + &rtc_xtal_clkin,
>> + &rtc_32k_div,
>> + &rtc_32k_mux,
>> + &rtc_32k,
>> + &rtc_clk,
>> + &sys_reset_ctrl,
>> + &sys_pwr_ctrl,
>> + &sys_pad_ctrl,
>> + &sys_ctrl,
>> + &sys_ts_pll,
>> + &sys_dev_arb,
>> + &sys_mmc_pclk,
>> + &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_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,
>> + ð_125m,
>> + ð_rmii_div,
>> + ð_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,
>> + .max_register = NNA_CLK_CTRL,
>> +};
>> +
>> +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",
>> + },
>> + { /* sentinel */ }
>> +};
>> +
>> +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 <[email protected]>");
>> +MODULE_LICENSE("GPL");
>
>
> --
> Jerome