* [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi
@ 2026-10-21 19:53 Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add Zhihe Han Gao via B4 Relay
` (17 more replies)
0 siblings, 18 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
This series adds initial support for the Zhihe A210 SoC and the Melon Pi
V1 and V2 boards.
The A210 features eight RISC-V cores in two clusters: four C908 cores
and four C920 cores.
This series provides UART, clock, reset and pinctrl support, together
with the required bindings and device trees.
It is based on Linux v7.3 and has been boot-tested on a Melon Pi V2
with all eight CPUs online.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
Han Gao (6):
dt-bindings: clock: add Zhihe A210 AON clock controller
dt-bindings: timer: add Zhihe A210 CLINT
riscv: dts: zhihe: add A210 module memory
riscv: dts: zhihe: add Melon Pi V1 and V2
riscv: defconfig: enable A210 support
MAINTAINERS: add Zhihe A210
Zhiguo Zhu (12):
dt-bindings: vendor-prefixes: add Zhihe
riscv: add Zhihe A210 support
dt-bindings: clock: add Zhihe A210 clock controllers
clk: zhihe: add A210 support
dt-bindings: reset: add Zhihe A210 reset controllers
reset: zhihe: add A210 support
dt-bindings: pinctrl: add Zhihe A210 pin controller
pinctrl: zhihe: add A210 support
dt-bindings: interrupt-controller: add Zhihe A210 PLIC
dt-bindings: riscv: add Melon Pi V1 and V2
riscv: dts: zhihe: add A210 core support
riscv: dts: zhihe: add A210 UARTs
.../bindings/clock/zhihe,a210-aon-clk.yaml | 58 +
.../devicetree/bindings/clock/zhihe,a210-clk.yaml | 231 ++
.../interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
.../bindings/pinctrl/zhihe,a210-pinctrl.yaml | 206 ++
.../bindings/reset/zhihe,a210-reset.yaml | 56 +
Documentation/devicetree/bindings/riscv/zhihe.yaml | 27 +
.../devicetree/bindings/timer/sifive,clint.yaml | 1 +
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 16 +
arch/riscv/Kconfig.socs | 10 +
arch/riscv/boot/dts/Makefile | 1 +
arch/riscv/boot/dts/zhihe/Makefile | 2 +
arch/riscv/boot/dts/zhihe/a210-melonpi-common.dtsi | 55 +
arch/riscv/boot/dts/zhihe/a210-melonpi-v1.dts | 9 +
arch/riscv/boot/dts/zhihe/a210-melonpi-v2.dts | 9 +
arch/riscv/boot/dts/zhihe/a210-som.dtsi | 11 +
arch/riscv/boot/dts/zhihe/a210.dtsi | 645 ++++++
arch/riscv/configs/defconfig | 4 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/zhihe/Kconfig | 12 +
drivers/clk/zhihe/Makefile | 2 +
drivers/clk/zhihe/clk-a210-aon.c | 94 +
drivers/clk/zhihe/clk-a210-ap.c | 2283 ++++++++++++++++++++
drivers/pinctrl/Kconfig | 14 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-a210.c | 1206 +++++++++++
drivers/reset/Kconfig | 11 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-a210.c | 589 +++++
include/dt-bindings/clock/zhihe,a210-aon-clk.h | 9 +
include/dt-bindings/clock/zhihe,a210-clk.h | 649 ++++++
include/dt-bindings/reset/zhihe,a210-resets.h | 351 +++
33 files changed, 6568 insertions(+)
---
base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222
change-id: 20261022-a210-init-d38cb9e6456a
Best regards,
--
Han Gao <gaohan@iscas.ac.cn>
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/18] dt-bindings: vendor-prefixes: add Zhihe
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 02/18] riscv: add Zhihe A210 support Han Gao via B4 Relay
` (16 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add the vendor prefix for Zhihe Computing.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index ba2002969373..21142578837b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1973,6 +1973,8 @@ patternProperties:
description: Zealz
"^zeitec,.*":
description: ZEITEC Semiconductor Co., LTD.
+ "^zhihe,.*":
+ description: Zhihe Computing Limited
"^zidoo,.*":
description: Shenzhen Zidoo Technology Co., Ltd.
"^zii,.*":
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 02/18] riscv: add Zhihe A210 support
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add Zhihe Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 03/18] dt-bindings: clock: add Zhihe A210 clock controllers Han Gao via B4 Relay
` (15 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add the ARCH_ZHIHE option for the Zhihe A210 SoC.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/Kconfig.socs | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index cecbce0c4983..b9863ebd88c7 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -91,6 +91,16 @@ config ARCH_ULTRARISC
This enables support for UltraRISC SoC platform hardware,
including boards based on the UR-DP1000.
+config ARCH_ZHIHE
+ bool "ZhiHe SoCs"
+ depends on 64BIT && MMU
+ select ARCH_HAS_RESET_CONTROLLER
+ help
+ Enable support for the Zhihe A210 SoC.
+ A210 has four C908 and four C920 RISC-V CPU cores.
+ Supported boards include the Melon Pi V1 and V2.
+ Say Y here to build a kernel for these boards.
+
config ARCH_VIRT
bool "QEMU Virt Machine"
select POWER_RESET
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 03/18] dt-bindings: clock: add Zhihe A210 clock controllers
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add Zhihe Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 02/18] riscv: add Zhihe A210 support Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-22 18:52 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 04/18] dt-bindings: clock: add Zhihe A210 AON clock controller Han Gao via B4 Relay
` (14 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add bindings for the A210 clock controllers, including register ranges,
input clocks and clock IDs.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
.../devicetree/bindings/clock/zhihe,a210-clk.yaml | 231 ++++++++
include/dt-bindings/clock/zhihe,a210-clk.h | 649 +++++++++++++++++++++
2 files changed, 880 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/zhihe,a210-clk.yaml b/Documentation/devicetree/bindings/clock/zhihe,a210-clk.yaml
new file mode 100644
index 000000000000..a3546d2f5977
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/zhihe,a210-clk.yaml
@@ -0,0 +1,231 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/zhihe,a210-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ZhiHe A210 Clock Controller
+
+maintainers:
+ - Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
+
+description:
+ The ZhiHe A210 SoC contains several clock controllers spread across
+ different subsystems. Each controller manages PLLs, dividers, gates and
+ muxes for its subsystem. The register regions consumed by a controller
+ depend on the specific compatible string.
+
+properties:
+ compatible:
+ enum:
+ - zhihe,a210-clk
+ - zhihe,a210-peri-clk
+ - zhihe,a210-gpu-clk
+ - zhihe,a210-pcie-clk
+ - zhihe,a210-usb-clk
+ - zhihe,a210-vi-clk
+ - zhihe,a210-vp-clk
+ - zhihe,a210-vo-clk
+ - zhihe,a210-npu-clk
+
+ reg:
+ minItems: 1
+ maxItems: 9
+
+ reg-names:
+ minItems: 1
+ maxItems: 9
+
+ clocks:
+ description: Input reference oscillators.
+ minItems: 1
+ maxItems: 3
+
+ clock-names:
+ minItems: 1
+ maxItems: 3
+ items:
+ enum:
+ - osc-32k
+ - osc-24m
+ - rc-24m
+
+ power-domains:
+ maxItems: 1
+
+ "#clock-cells":
+ const: 1
+ description:
+ The single cell is the clock ID defined in
+ include/dt-bindings/clock/zhihe,a210-clk.h.
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - "#clock-cells"
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-clk
+ then:
+ properties:
+ reg:
+ minItems: 9
+ reg-names:
+ items:
+ - const: pll-wrap
+ - const: top-crg
+ - const: cpu-ss-clk-sysreg
+ - const: cpu-ss-cpu-pll
+ - const: ddr0-sysreg
+ - const: ddr1-sysreg
+ - const: slc-dual-sysreg
+ - const: top-crg-t
+ - const: cpu-ss-ccu
+ clocks:
+ minItems: 3
+ clock-names:
+ items:
+ - const: osc-32k
+ - const: osc-24m
+ - const: rc-24m
+ required:
+ - clocks
+ - clock-names
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-peri-clk
+ then:
+ properties:
+ reg:
+ minItems: 5
+ maxItems: 5
+ reg-names:
+ items:
+ - const: peri0-sysreg
+ - const: peri1-sysreg
+ - const: peri2-sysreg
+ - const: peri3-sysreg
+ - const: tee-crg
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-gpu-clk
+ then:
+ properties:
+ reg:
+ minItems: 2
+ maxItems: 2
+ reg-names:
+ items:
+ - const: gpu-ss-pwrap-clk-en
+ - const: gpu-ss-top-clk-en
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-pcie-clk
+ then:
+ properties:
+ reg:
+ maxItems: 1
+ reg-names:
+ items:
+ - const: pcie-clk-en
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-usb-clk
+ then:
+ properties:
+ reg:
+ maxItems: 1
+ reg-names:
+ items:
+ - const: usb-clk-en
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-vi-clk
+ then:
+ properties:
+ reg:
+ minItems: 2
+ maxItems: 2
+ reg-names:
+ items:
+ - const: vi-clk
+ - const: vi-misc-ctrl
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-vp-clk
+ then:
+ properties:
+ reg:
+ maxItems: 1
+ reg-names:
+ items:
+ - const: vp-clk
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-vo-clk
+ then:
+ properties:
+ reg:
+ minItems: 2
+ maxItems: 2
+ reg-names:
+ items:
+ - const: vo-clk
+ - const: vo-path-ctrl
+
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-npu-clk
+ then:
+ properties:
+ reg:
+ minItems: 2
+ maxItems: 2
+ reg-names:
+ items:
+ - const: npu-clk
+ - const: npu-top-clk
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/zhihe,a210-clk.h>
+
+ clock-controller@260000 {
+ compatible = "zhihe,a210-clk";
+ reg = <0x00260000 0x1000>,
+ <0x00250000 0x1000>,
+ <0x10141600 0x100>,
+ <0x10141400 0x100>,
+ <0x04810000 0x1000>,
+ <0x05810000 0x1000>,
+ <0x04900000 0x1000>,
+ <0x20250000 0x1000>,
+ <0x10140000 0xe00>;
+ reg-names = "pll-wrap", "top-crg", "cpu-ss-clk-sysreg", "cpu-ss-cpu-pll",
+ "ddr0-sysreg", "ddr1-sysreg", "slc-dual-sysreg", "top-crg-t",
+ "cpu-ss-ccu";
+ #clock-cells = <1>;
+ clocks = <&osc_32k>, <&osc_24m>, <&rc_24m>;
+ clock-names = "osc-32k", "osc-24m", "rc-24m";
+ };
diff --git a/include/dt-bindings/clock/zhihe,a210-clk.h b/include/dt-bindings/clock/zhihe,a210-clk.h
new file mode 100644
index 000000000000..aa59d91a9ad0
--- /dev/null
+++ b/include/dt-bindings/clock/zhihe,a210-clk.h
@@ -0,0 +1,649 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+#ifndef _DT_BINDINGS_CLOCK_ZHIHE_A210_CLK_H
+#define _DT_BINDINGS_CLOCK_ZHIHE_A210_CLK_H
+
+// PLL_WRAP
+#define AUDIO0_PLL_FOUTVCO 0
+#define AUDIO0_PLL_FOUTPOSTDIV 1
+#define AUDIO0_PLL_FOUT2 2
+#define AUDIO1_PLL_FOUTVCO 3
+#define AUDIO1_PLL_FOUTPOSTDIV 4
+#define AUDIO1_PLL_FOUT2 5
+#define GMAC_PLL_FOUTVCO 6
+#define GMAC_PLL_FOUTPOSTDIV 7
+#define GMAC_PLL_FOUT1PH0 8
+#define DVFS_PLL_FOUTVCO 9
+#define DPU0_PLL_FOUTPOSTDIV 10
+#define DPU1_PLL_FOUTVCO 11
+#define DPU1_PLL_FOUTPOSTDIV 12
+#define DPU2_PLL_FOUTVCO 13
+#define DPU2_PLL_FOUTPOSTDIV 14
+#define VIDEO_PLL_FOUTVCO 15
+#define VIDEO_PLL_FOUTPOSTDIV 16
+#define VIDEO_PLL_FOUT1PH0 17
+#define VIDEO_PLL_FOUT3 18
+#define TEE_PLL_FOUTVCO 19
+
+// TOP_CRG
+#define IOMMU_PTW_ACLK_DIV 20
+#define NOC_CCLK_DIV 21
+#define NOC_CCLK_MUX 22
+#define TOP_CFG_ACLK_DIV 23
+#define TOP_PCLK_DIV 24
+#define TOP_CPU_BAK_PLL0_CLK_DIV4 25
+#define TOP_CPUSYS_PIC_CLK_DIV 26
+#define TOP_CPU_DDR1_ACLK_MUX 27
+#define TOP_CPU_DDR0_ACLK_MUX 28
+#define TOP_CPU_BAK_PLL0_CLK_MUX0 29
+#define TOP_CPU_BAK_PLL0_CLK_DIV0 30
+#define TOP_CPU_BAK_PLL0_CLK_DIV1 31
+#define TOP_CPU_BAK_PLL0_CLK_DIV3 32
+#define TOP_CPUSYS_PIC_CLK_MUX 33
+#define TOP_CPU_BAK_PLL0_CLK_MUX 34
+#define TOP_CPU_BAK_PLL1_CLK_DIV1 35
+#define TOP_CPUSYS_BUS_CLK_DIV 36
+#define TOP_CPUSYS_BUS_CLK_MUX 37
+#define TOP_CPU_BAK_PLL1_CLK_DIV0 38
+#define TOP_CPU_BAK_PLL1_CLK_MUX0 39
+#define TOP_CPU_BAK_PLL1_CLK_DIV3 40
+#define TOP_CPU_BAK_PLL1_CLK_MUX 41
+#define TOP_D2D_REF_CLK_MUX 42
+#define TOP_D2D_SCAN_CLK0_DIV 43
+#define TOP_D2D_SCAN_CLK1_DIV 44
+#define TOP_D2D_ACLK_DIV 45
+#define TOP_D2D_ACLK_MUX 46
+#define AMUX_CLK_DIV 47
+#define TOP_GPU_CORE_CLK_DIV 48
+#define TOP_GPU_CORE_CLK_MUX 49
+#define TOP_PCIE_SCAN_REF_CLK1_DIV 50
+#define TOP_PCIE_SCAN_REF_CLK0_DIV 51
+#define TOP_PCIE_AXI_M_ACLK_DIV 52
+#define TOP_PCIE_AXI_M_ACLK_MUX 53
+#define TOP_PERI_SPI_SSI_CLK0_DIV 54
+#define TOP_PERI_MST_ACLK0_DIV 55
+#define TOP_PERI_TIMER_CLK_MUX 56
+#define TOP_PERI_I2S_8CH0_SRC_CLK_MUX 57
+#define TOP_PERI_I2S_2CH0_SRC_CLK_MUX 58
+#define TOP_PERI_QSPI_SSI_CLK_MUX0 59
+#define TOP_PERI_QSPI0_SSI_CLK_DIV0 60
+#define TOP_PERI_QSPI0_SSI_CLK_DIV1 61
+#define TOP_PERI_SPI_SSI_CLK1_DIV 62
+#define TOP_PERI_HIRES_CLK0_DIV 63
+#define TOP_PERI_HIRES_CLK1_DIV 64
+#define TOP_PERI_TDM_SRC_CLK_MUX 65
+#define TOP_UART_SCLK_MUX 66
+#define TOP_PERI_I2S_2CH1_SRC_CLK_MUX 67
+#define TOP_PERI_PDM_MCLK_MUX 68
+#define TOP_PERI_I2S_2CH2_SRC_CLK_MUX 69
+#define TOP_PERI_QSPI_SSI_CLK_MUX1 70
+#define TOP_PERI_QSPI1_SSI_CLK_DIV0 71
+#define TOP_PERI_QSPI1_SSI_CLK_DIV1 72
+#define TOP_PERI_MST_CLK1_DIV 73
+#define TOP_PERI_EMMC_REF_CLK_DIV 74
+#define TOP_PERI_PDM_MCLK_DIV 75
+#define TOP_PERI_EMMC_REF_CLK_MUX 76
+#define TOP_PAD_SENSOR_VCLK_MUX1 77
+#define TOP_PAD_SENSOR_VCLK_MUX0 78
+#define TOP_PAD_SENSOR_VCLK1_DIV 79
+#define TOP_PAD_SENSOR_VCLK0_DIV 80
+#define TOP_TEE_CLK_DIV 81
+#define TOP_TEE_CLK_MUX 82
+#define TOP_USB_BUS_ACLK_DIV 83
+#define TOP_USB_DP_AUX_CLK_DIV 84
+#define TOP_VP_ACLK_MUX 85
+#define TOP_VP_ACLK_DIV 86
+#define TOP_VP_G2D_CCLK_DIV 87
+#define TOP_VP_G2D_CCLK_MUX 88
+#define TOP_VP_VDEC_CCLK_DIV 89
+#define TOP_VP_VDEC_CCLK_MUX 90
+#define TOP_VP_VENC_CCLK_DIV 91
+#define TOP_VP_VENC_CCLK_MUX 92
+#define TOP_NPU_ACLK_DIV 93
+#define TOP_NPU_ACLK_MUX 94
+#define TOP_NPU_CCLK_DIV 95
+#define TOP_NPU_CCLK_MUX 96
+#define TOP_USB_USB20_SCAN_REF_CLK_DIV 97
+#define TOP_USB_SCAN_REF_CLK3_DIV 98
+#define TOP_USB_SCAN_REF_CLK2_DIV 99
+#define TOP_USB_SCAN_REF_CLK1_DIV 100
+#define TOP_USB_SCAN_REF_CLK0_DIV 101
+#define TOP_CPU_BAK_PLL1_CLK_DIV4 102
+#define SW_TOP_PAD_SENSOR_VCLK1_EN 103
+#define SW_TOP_PAD_SENSOR_VCLK0_EN 104
+#define SW_NOC_CCLK_EN 105
+#define SW_TOP_OSC_CLK_LOGIC_EN 106
+#define SW_IOMMU_PTW_330_ACLK_EN 107
+#define SW_AMUX_660_CLK_EN 108
+#define SW_NPU_SS_CLK_EN 109
+#define SW_CPU_SS_CLK_EN 110
+#define SW_DDR_SS_CLK_EN 111
+#define SW_D2D_SS_CLK_EN 112
+#define SW_VP_SS_CLK_EN 113
+#define SW_VO_SS_CLK_EN 114
+#define SW_VI_SS_CLK_EN 115
+#define SW_PCIE_SS_CLK_EN 116
+#define SW_USB_SS_CLK_EN 117
+#define SW_PERI1_SS_CLK_EN 118
+#define SW_PERI3_SS_CLK_EN 119
+#define SW_GPU_SS_CLK_EN 120
+
+// CPU_SS_CLK_SYSREG
+#define C908_CPU_TO_CDE_CLK_MUX 121
+#define C920_CPU_TO_CDE_CLK_MUX 122
+
+// CPU_SS_CPU_PLL
+#define C908_PLL_FOUTVCO 123
+#define C920_PLL_FOUTVCO 124
+
+// GPU_SS_SYSREG
+#define SW_PWR_WRAP_X2P_PCLK_EN 125
+#define SW_PWR_WRAP_SYSREG_PCLK_EN 126
+#define SW_PWR_WRAP_DFMU_PCLK_EN 127
+#define SW_PWR_WRAP_X2P_ACLK_EN 128
+#define SW_PWR_WRAP_CFG_ACLK_EN 129
+#define SW_PWR_WRAP_CFG_AAB_MST_ACLK_EN 130
+#define SW_PWR_WRAP_GPU_SYS_CLK_EN 131
+#define SW_PWR_WRAP_MEMIF_AAB_SLV_CORE_CLK_EN 132
+#define SW_PWR_WRAP_DFMU_CORE_CLK_EN 133
+#define SW_PWR_WRAP_GPU_CORE_CLK_EN 134
+
+// GPU_SS_TOP_SYSREG
+#define SW_TOP_CFG_AAB_SLV_ACLK_EN 135
+#define SW_TOP_X2P_PCLK_EN 136
+#define SW_TOP_SYSREG_PCLK_EN 137
+#define SW_TOP_X2P_ACLK_EN 138
+#define SW_TOP_CFG_ACLK_EN 139
+#define SW_TOP_AFENCE_ACLK_EN 140
+#define SW_MEMIF_AAB_MST_BUS_CLK_EN 141
+
+// NPU_CRG
+#define NPU_CCLK_BUF_CDE_RATIO 142
+#define NPU_CCLK_BUF_CDE_MUX 143
+#define NPU_ACLK_BUF_CDE_RATIO 144
+#define NPU_ACLK_BUF_CDE_MUX 145
+#define SW_DROOP_PCLK_EN 146
+#define SW_DROOP_CLK_EN 147
+#define SW_DROOP_CCTRL_PCLK_EN 148
+#define SW_DROOP_CCTRL_CLK_EN 149
+#define SW_SEMA_PCLK_EN 150
+#define SW_SEMA_ACLK_EN 151
+#define SW_NPU_X2P_ACLK_EN 152
+#define SW_NPU_X2H_ACLK_EN 153
+#define SW_NPU_PTW_CCU_PCLK_EN 154
+#define SW_NPU_PTW_CCU_CLK_EN 155
+#define SW_NPU_PCTRL_PCLK_EN 156
+#define SW_NPU_PCTRL_EN 157
+#define SW_NPU_LPE_C_PCLK_EN 158
+#define SW_NPU_LPE_C_CLK_EN 159
+#define SW_NPU_LPC_C_CLK_EN 160
+#define SW_NPU_IP_HCLK_EN 161
+#define SW_NPU_IP_CCLK_EN 162
+#define SW_NPU_IP_ACLK_EN 163
+#define SW_NPU_DFMU_PTWCLK_EN 164
+#define SW_NPU_DFMU_PCLK_EN 165
+#define SW_NPU_CLK_CALC_EN 166
+#define SW_NPU_AXI_M2S1_ACLK_EN 167
+#define SW_NPU_AXI_CCU_PCLK_EN 168
+#define SW_NPU_AXI_CCU_CLK_EN 169
+#define SW_NPU_AXI_ACLK_EN 170
+#define SW_NPU_AFENCE_EN 171
+#define SW_NPU_AAB_MST_ACLK_EN 172
+#define SW_DFMU_ACLK_EN 173
+
+// NPU_TOP_CRG
+#define SW_NPUSS_AAB_SLV_CLK_EN 174
+#define SW_NPUSS_FENCE_CLK_EN 175
+
+// DDR0_SYSREG
+#define DDR0_PHY_DFICLK_EN 176
+#define DDR0_DDRC_ACLK_EN 177
+#define DDR0_DDRC_CCLK_EN 178
+#define DDR0_SBR_CLK_EN 179
+
+// DDR1_SYSREG
+#define DDR1_PHY_DFICLK_EN 180
+#define DDR1_DDRC_ACLK_EN 181
+#define DDR1_DDRC_CCLK_EN 182
+#define DDR1_SBR_CLK_EN 183
+
+// SLC_DUAL_SYSREG
+#define DDR_PLL_FOUTVCO 184
+#define DDR_PLL_FOUTPOSTDIV 185
+#define DDR_PLL_FOUT1PH0 186
+#define DDR_PLL_FOUT2 187
+#define DDR_PLL_FOUT4 188
+#define DDR_PLL_CLK_SEL 189
+#define DDR_PLL_CLK_EN 190
+#define DDR_CBUS2DDR_ACLK0 191
+#define DDR_CBUS2DDR_ACLK1 192
+
+// D2D_CRG_REG_T
+#define D2D_SS_CTRL0_CLK_EN 193
+#define D2D_SS_CTRL1_CLK_EN 194
+
+// PCIE_CPR
+#define AXI4_PCIE_MST_PCLK_EN 195
+#define AXI4_PCIE_MST_ACLK_EN 196
+#define X2X_PERI3_MST_ACLK_EN 197
+#define X2X_PERI3_SLV_ACLK_EN 198
+#define PCIE_SS_DFMU_ACLK_EN 199
+#define PCIE_SS_DFMU_IOMMU_PTW_ACLK_EN 200
+#define PCIE_SS_DFMU_PCLK_EN 201
+#define E16PHY_PCLK_EN 202
+#define SATA_MST_AFENCE_ACLK_EN 203
+#define SATA_SLV_AFENCE_ACLK_EN 204
+#define SATA_GEN3X2_ACLK_EN 205
+#define X2X_SATA_SLV_ACLK_EN 206
+#define X2X_SATA_MST_ACLK_EN 207
+#define SATA_RXOOB1_CLK_EN 208
+#define SATA_RXOOB0_CLK_EN 209
+#define SATA_PMALIVE_CLK_EN 210
+#define PCIE_DM_MST_AFENCE_ACLK_EN 211
+#define PCIE_DM_SLV_AFENCE_ACLK_EN 212
+#define PCIE_DM_GEN3X4_AUX_CLK_EN 213
+#define PCIE_DM_GEN3X4_MST_ACLK_EN 214
+#define PCIE_DM_GEN3X4_PCLK_EN 215
+#define PCIE_DM_GEN3X4_SLV_ACLK_EN 216
+#define PCIE_RP_MST_AFENCE_ACLK_EN 217
+#define PCIE_RP_SLV_AFENCE_ACLK_EN 218
+#define PCIE_RP_GEN3X1_AUX_CLK_EN 219
+#define PCIE_RP_GEN3X1_MST_ACLK_EN 220
+#define PCIE_RP_GEN3X1_PCLK_EN 221
+#define PCIE_RP_GEN3X1_SLV_ACLK_EN 222
+
+// USB_CPR
+#define USB_SS_AXI_MST_PCLK_EN 223
+#define USB_SS_AXI_MST_ACLK_EN 224
+#define USB_SS_DFMU_IOMMU_PTW_ACLK_EN 225
+#define USB_SS_DFMU_ACLK_EN 226
+#define USB_SS_DFMU_PCLK_EN 227
+#define DPTX_I2S_CLK_EN 228
+#define DPTX_IPI_CLK_EN 229
+#define DPTX_AUX_CLK_EN 230
+#define DPTX_GTC_CLK_EN 231
+#define DPTX_PCLK_EN 232
+#define USB31_SLV_AFENCE_ACLK_EN 233
+#define USB31_REF_CLK_EN 234
+#define USB31_SUSPEND_CLK_EN 235
+#define USB31_BUS_CLK_EN 236
+#define USB31_PCLK_EN 237
+#define C10PHY_SUSPEND_CLK_EN 238
+#define C10PHY_PCLK_EN 239
+#define USB2_SYSREG_PCLK_EN 240
+#define USB2_AXI_MST_ACLK_EN 241
+#define USB2_AHB_SLV_HCLK_EN 242
+#define USB2_H2P_HCLK_EN 243
+#define USB2_SLV_AFENCE_ACLK_EN 244
+#define USB2_X2H_ACLK_EN 245
+#define USB2_X2H_HCLK_EN 246
+#define USB2_WRAP_A2X1_ACLK_EN 247
+#define USB2_WRAP_A2X1_HCLK_EN 248
+#define USB2_WRAP_A2X0_ACLK_EN 249
+#define USB2_WRAP_A2X0_HCLK_EN 250
+#define USB2_WRAP1_HCLK_EN 251
+#define USB2_WRAP0_HCLK_EN 252
+#define USB_SS_PERI2_SLV_AFENCE_ACLK_EN 253
+#define USB_SS_PERI2_CFG_ACLK_EN 254
+
+// VI_SYSREG
+#define VI_DW_SCLK_EN 255
+#define VI_VSE_CLK_EN 256
+#define VI_DWE_CLK_EN 257
+#define VI_DW200_ACLK_EN 258
+#define VI_DW200_HCLK_EN 259
+#define VI_DECOMP_CLK_EN 260
+#define VI_COMP1_CLK_EN 261
+#define VI_COMP0_CLK_EN 262
+#define VI_VSEOUT_CLK_EN 263
+#define VI_DECOUT_CLK_EN 264
+#define VI_ISPOUT_CLK_EN 265
+#define VI_COMP_ACLK_EN 266
+#define VI_COMP_PCLK_EN 267
+#define VI_ISP_CLK_EN 268
+#define VI_VIPRE_ACLK_EN 269
+#define VI_VIPRE_SCLK_EN 270
+#define VI_VIPRE_I1_PIXCLK_EN 271
+#define VI_VIPRE_I0_PIXCLK_EN 272
+#define VI_VIPRE_PCLK_EN 273
+#define VI_MIPI1_CSI1_PIXCLK_EN 274
+#define VI_MIPI1_CSI0_PIXCLK_EN 275
+#define VI_MIPI1B_CFGCLK_EN 276
+#define VI_MIPI1A_CFGCLK_EN 277
+#define VI_MIPI1CSI1_PCLK_EN 278
+#define VI_MIPI1CSI0_PCLK_EN 279
+#define VI_MIPI0_CSI1_PIXCLK_EN 280
+#define VI_MIPI0_CSI0_PIXCLK_EN 281
+#define VI_MIPI0B_CFGCLK_EN 282
+#define VI_MIPI0A_CFGCLK_EN 283
+#define VI_MIPI0CSI1_PCLK_EN 284
+#define VI_MIPI0CSI0_PCLK_EN 285
+#define VI_REC_ACLK_EN 286
+#define VI_REC_PCLK_EN 287
+#define VI_FENCE_ACLK_EN 288
+#define VI_MIPI1CSI1_FPCLK_EN 289
+#define VI_MIPI1CSI0_FPCLK_EN 290
+#define VI_MIPI0CSI1_FPCLK_EN 291
+#define VI_MIPI0CSI0_FPCLK_EN 292
+#define VI_X2H2_CLK_EN 293
+#define VI_X2H1_CLK_EN 294
+#define VI_X2H0_CLK_EN 295
+#define VI_ARB_ACLK_EN 296
+#define VI_ARB_PCLK_EN 297
+#define VI_PTW_ACLK_EN 298
+#define VI_DFMU_ACLK_EN 299
+#define VI_DFMU_PCLK_EN 300
+#define VI_PRE_ISP_CORE_CLK_DIV_EN 301
+#define VI_PRE_ISP_IF_CLK_DIV_EN 302
+#define VI_PRE_MIPI1_PIXCLK_DIV_EN 303
+#define VI_PRE_MIPI0_PIXCLK_DIV_EN 304
+#define VI_ISP_IF_REF_SWITCH_SEL 305
+#define VI_MIPI1_PIX_REF_SWITCH_SEL 306
+#define VI_MIPI0_PIX_REF_SWITCH_SEL 307
+#define VI_PRE_ISP_CORE_CLK_DIV_NUM 308
+#define VI_PRE_ISP_IF_CLK_DIV_NUM 309
+#define VI_PRE_MIPI1_PIXCLK_DIV_NUM 310
+#define VI_PRE_MIPI0_PIXCLK_DIV_NUM 311
+#define VI_PRE_DECOMP_CLK_DIV_EN 312
+#define VI_PRE_COMP_CLK_DIV_EN 313
+#define VI_PRE_DWE_CLK_DIV_EN 314
+#define VI_PRE_VSE_CLK_DIV_EN 315
+#define VI_PRE_AXI_CLK_DIV_EN 316
+#define VI_PRE_DECOMP_CLK_DIV_NUM 317
+#define VI_PRE_COMP_CLK_DIV_NUM 318
+#define VI_PRE_DWE_CLK_DIV_NUM 319
+#define VI_PRE_VSE_CLK_DIV_NUM 320
+#define VI_PRE_AXI_CLK_DIV_NUM 321
+
+// VO_SYSREG
+#define VO_X2H1_CLK_EN 322
+#define VO_X2H0_CLK_EN 323
+#define VO_PTW_ACLK_EN 324
+#define VO_DFMU_ACLK_EN 325
+#define VO_DFMU_PCLK_EN 326
+#define VO_ARB_ACLK_EN 327
+#define VO_ARB_PCLK_EN 328
+#define VO_DECOMP_ACLK_EN 329
+#define VO_DECOMP1_CLK_EN 330
+#define VO_DECOMP0_CLK_EN 331
+#define VO_DECOMP_PCLK_EN 332
+#define VO_MIPI_CFGCLK_EN 333
+#define VO_MIPI_PCLK_EN 334
+#define VO_HDMI_SFRCLK_EN 335
+#define VO_CEC_CLK_EN 336
+#define VO_I2S_CLK_EN 337
+#define VO_HDMI_PCLK_EN 338
+#define VO_AUXDISP_ACLK_EN 339
+#define VO_AUXDISP_PCLK_EN 340
+#define VO_CH2_PIXCLK_EN 341
+#define VO_DPU_ACLK_EN 342
+#define VO_DPUC_CLK_EN 343
+#define VO_DPU_HCLK_EN 344
+#define VO_CH1_PIXCLK_EN 345
+#define VO_CH0_PIXCLK_EN 346
+#define VO_PLL2_DIV_EN 347
+#define VO_PLL2_DIV_NUM 348
+#define VO_PLL1_DIV_EN 349
+#define VO_PLL1_DIV_NUM 350
+#define VO_PLL0_DIV_EN 351
+#define VO_PLL0_DIV_NUM 352
+#define VO_DECOMP_DIV_EN 353
+#define VO_DECOMP_DIV_NUM 354
+#define VO_DPUC_DIV_EN 355
+#define VO_DPUC_DIV_NUM 356
+#define VO_ACLK_DIV_EN 357
+#define VO_ACLK_DIV_NUM 358
+
+// VP_SYSREG
+#define VP_DECOMP_EXTPCLK_EN 359
+#define VP_COMP_EXTPCLK_EN 360
+#define VP_VENC_RS_ACLK_EN 361
+#define VP_VDEC_RS_ACLK_EN 362
+#define VP_ARB_ACLK_EN 363
+#define VP_ARB_PCLK_EN 364
+#define VP_PTW_ACLK_EN 365
+#define VP_DFMU_ACLK_EN 366
+#define VP_DFMU_PCLK_EN 367
+#define VP_DECOMP_ACLK_EN 368
+#define VP_DECOMP_CCLK_EN 369
+#define VP_DECOMP_PCLK_EN 370
+#define VP_COMP_ACLK_EN 371
+#define VP_COMP_CCLK_EN 372
+#define VP_COMP_PCLK_EN 373
+#define VP_G2D_ACLK_EN 374
+#define VP_G2D_CCLK_EN 375
+#define VP_G2D_PCLK_EN 376
+#define VP_VENC_ACLK_EN 377
+#define VP_VENC_CCLK_EN 378
+#define VP_VENC_PCLK_EN 379
+#define VP_VDEC_ACLK_EN 380
+#define VP_VDEC_CCLK_EN 381
+#define VP_VDEC_PCLK_EN 382
+#define VP_DECOMP_DIV_EN 383
+#define VP_DECOMP_DIV_NUM 384
+#define VP_COMP_DIV_EN 385
+#define VP_COMP_DIV_NUM 386
+
+// PERI0_SYSREG
+#define PERI0_MBOX1_PCLK_EN 387
+#define PERI0_MBOX0_PCLK_EN 388
+#define PERI0_WDT0_PCLK_EN 389
+#define PERI0_TIMER1_PCLK_EN 390
+#define PERI0_TIMER1_CCLK_EN 391
+#define PERI0_TIMER0_PCLK_EN 392
+#define PERI0_TIMER0_CCLK_EN 393
+
+// PERI1_SYSREG
+#define PERI1_UART3_SCLK_EN 394
+#define PERI1_UART3_PCLK_EN 395
+#define PERI1_UART2_SCLK_EN 396
+#define PERI1_UART2_PCLK_EN 397
+#define PERI1_UART1_SCLK_EN 398
+#define PERI1_UART1_PCLK_EN 399
+#define PERI1_UART0_SCLK_EN 400
+#define PERI1_UART0_PCLK_EN 401
+#define PERI1_SPI0_SSI_CLK_EN 402
+#define PERI1_SPI0_PCLK_EN 403
+#define PERI1_QSPI0_SSI_CLK_EN 404
+#define PERI1_QSPI0_PCLK_EN 405
+#define PERI1_PWM0_PCLK_EN 406
+#define PERI1_PWM0_CCLK_EN 407
+#define PERI1_MST_BUS_PCLK_EN 408
+#define PERI1_MST_BUS_ACLK_EN 409
+#define PERI1_I2S0_SRC_CLK_EN 410
+#define PERI1_I2S0_PCLK_EN 411
+#define PERI1_I2C2_PCLK_EN 412
+#define PERI1_I2C2_IC_CLK_EN 413
+#define PERI1_I2C1_PCLK_EN 414
+#define PERI1_I2C1_IC_CLK_EN 415
+#define PERI1_I2C0_PCLK_EN 416
+#define PERI1_I2C0_IC_CLK_EN 417
+#define PERI1_GPIO1_PCLK_EN 418
+#define PERI1_GPIO1_DBCLK_EN 419
+#define PERI1_GPIO0_PCLK_EN 420
+#define PERI1_GPIO0_DBCLK_EN 421
+#define PERI1_GMAC1_HCLK_EN 422
+#define PERI1_GMAC1_ACLK_EN 423
+#define PERI1_GMAC0_HCLK_EN 424
+#define PERI1_GMAC0_ACLK_EN 425
+
+// PERI2_SYSREG
+#define PERI2_I2S3_PCLK_EN 426
+#define PERI2_I2S3_SRC_CLK_EN 427
+#define PERI2_I2S2_PCLK_EN 428
+#define PERI2_I2S2_SRC_CLK_EN 429
+#define PERI2_I2S1_PCLK_EN 430
+#define PERI2_I2S1_SRC_CLK_EN 431
+#define PERI2_I2C7_IC_CLK_EN 432
+#define PERI2_I2C7_PCLK_EN 433
+#define PERI2_I2C6_IC_CLK_EN 434
+#define PERI2_I2C6_PCLK_EN 435
+#define PERI2_I2C5_IC_CLK_EN 436
+#define PERI2_I2C5_PCLK_EN 437
+#define PERI2_I2C4_IC_CLK_EN 438
+#define PERI2_I2C4_PCLK_EN 439
+#define PERI2_I2C3_IC_CLK_EN 440
+#define PERI2_I2C3_PCLK_EN 441
+#define PERI2_GPIO3_DBCLK_EN 442
+#define PERI2_GPIO3_PCLK_EN 443
+#define PERI2_PAD_CTRL_PCLK_EN 444
+#define PERI2_UART6_PCLK_EN 445
+#define PERI2_UART5_PCLK_EN 446
+#define PERI2_UART4_PCLK_EN 447
+#define PERI2_SPI1_PCLK_EN 448
+#define PERI2_GPIO2_PCLK_EN 449
+#define PERI2_CAN2_PCLK_EN 450
+#define PERI2_UART6_SCLK_EN 451
+#define PERI2_UART5_SCLK_EN 452
+#define PERI2_UART4_SCLK_EN 453
+#define PERI2_SPI1_SSI_CLK_EN 454
+#define PERI2_GPIO2_DBCLK_EN 455
+#define PERI2_CAN2_OSC_CLK_EN 456
+#define PERI2_CAN2_HIRES_CLK_EN 457
+#define PERI2_QSPI1_PCLK_EN 458
+#define PERI2_QSPI1_SSI_CLK_EN 459
+#define PERI2_UART9_PCLK_EN 460
+#define PERI2_UART9_SCLK_EN 461
+#define PERI2_UART8_PCLK_EN 462
+#define PERI2_UART8_SCLK_EN 463
+#define PERI2_UART7_PCLK_EN 464
+#define PERI2_UART7_SCLK_EN 465
+#define PERI2_PWM2_PCLK_EN 466
+#define PERI2_PWM2_CCLK_EN 467
+#define PERI2_PWM1_PCLK_EN 468
+#define PERI2_PWM1_CCLK_EN 469
+
+// PERI3_SYSREG
+#define PERI3_PAD_CTRL_PCLK_EN 470
+#define PERI3_GPIO4_PCLK_EN 471
+#define PERI3_GPIO4_DBCLK_EN 472
+#define CLKCTRL_PERI3_TEE_H2H_SHCLKEN 473
+#define CLKCTRL_PERI3_TEE_H2H_MHCLKEN 474
+#define PERI3_TEE_X2X_ACLK_S_EN 475
+#define PERI3_ADC_PCLK_EN 476
+#define AXI_PERI3_MST_PCLK_EN 477
+#define AXI_PERI3_MST_ACLK_EN 478
+#define PERI3_SDIO_X2X_ACLK_S_EN 479
+#define PERI3_SDIO_X2X_ACLK_M_EN 480
+#define PERI3_SDIO_OSC_CLK_EN 481
+#define PERI3_SDIO_HCLK_EN 482
+#define PERI3_EMMC_X2X_ACLK_S_EN 483
+#define PERI3_EMMC_X2X_ACLK_M_EN 484
+#define PERI3_EMMC_OSC_CLK_EN 485
+#define PERI3_EMMC_HCLK_EN 486
+#define PERI3_EMMC_ACLK_EN 487
+#define PERI3_EMMC_SDIO_REF_CLK_CG_EN 488
+#define PERI3_DMAC_HCLK_EN 489
+#define PERI3_DMAC_ACLK_EN 490
+
+// TEE_CRG
+#define TEE_PCLK_CDE_RATIO 491
+#define TEE_AHB2_TEESYS_CLKEN 492
+#define TEE_APB3_TEESYS_CLKEN 493
+#define TEE_AXI4_TEESYS_CLKEN 494
+#define TEE_X2P_TEESYS_CLKEN 495
+#define TEE_EIP120SI_CLKEN 496
+#define TEE_EIP120SII_CLKEN 497
+#define TEE_EIP120SIII_CLKEN 498
+#define TEE_EIP150B_CLKEN 499
+#define TEE_DMAC_CLKEN 500
+#define TEE_DS_CLKEN 501
+#define TEE_OCRAM_CLKEN 502
+#define TEE_EFUSE_CLKEN 503
+#define TEE_KEYRAM_CLKEN 504
+
+#define CLK_DUMMY 505
+#define OSC_32K 506
+#define OSC_24M 507
+#define RC_24M 508
+
+#define TOP_PLL_REF_CLK 509
+#define AON_OSC_CLK_PHY 510
+#define AON_OSC_CLK_LOGIC 511
+#define PLL_OSC_CLK 512
+#define D2D_PHY_REF_CLK_100M 513
+#define D2D_PHY_SCAN_CLK2 514
+#define TOP_PERI_TIMER_CLK_100M 515
+#define PERI1_UART_SCLK 516
+#define PERI2_UART_SCLK 517
+#define UART_SCLK_100M 518
+#define GPU_TOP_SYS_CLK 519
+#define GPU_PCLK_CDT 520
+#define PCIE_SS_APB_CLK 521
+#define USB_SS_GTC_CLK 522
+#define USB_SS_PAD_OSC_CLK_1M 523
+#define USB20_BUS_CLK 524
+#define USB20_CORE_CLK 525
+#define VI_PCLK 526
+#define VO_PCLK 527
+#define AON_RTC_CLK 528
+#define PERI1_PWM_CLK 529
+#define PERI2_PWM_CLK 530
+#define I2C_IC_CLK 531
+#define PERI3_SDIO_ACLK_EN 532
+
+#define PERI1_ZGMAC_X2X_ACLK_EN 533
+#define PERI1_GMAC2_HCLK_EN 534
+#define PERI1_GMAC2_ACLK_EN 535
+#define PERI1_X2H_GMAC2_HCLK_EN 536
+#define PERI1_X2H_GMAC2_ACLK_EN 537
+#define PERI1_CHIP_DBG_PCLK_EN 538
+#define PERI1_CHIP_DBG_CCLK_EN 539
+#define PERI1_CHIP_DBG_ACLK_EN 540
+#define PERI1_TDM0_SCLK_EN 541
+#define PERI1_TDM0_PCLK_EN 542
+#define PERI1_PDM0_PCLK_EN 543
+#define PERI1_PDM0_MCLK_EN 544
+#define PERI1_CAN1_PCLK_EN 545
+#define PERI1_CAN1_OSC_CLK_EN 546
+#define PERI1_CAN1_HIRES_CLK_EN 547
+#define PERI1_CAN0_PCLK_EN 548
+#define PERI1_CAN0_OSC_CLK_EN 549
+#define PERI1_CAN0_HIRES_CLK_EN 550
+#define PERI1_PAD_CTRL_PCLK_EN 551
+#define PERI1_DFMU_PTW_ACLK_EN 552
+#define PERI1_DFMU_PCLK_EN 553
+#define PERI1_DFMU_ACLK_EN 554
+#define PERI1_X2H_GMAC1_HCLK_EN 555
+#define PERI1_X2H_GMAC1_ACLK_EN 556
+#define PERI1_X2H_GMAC0_HCLK_EN 557
+#define PERI1_X2H_GMAC0_ACLK_EN 558
+#define DPU0_PLL_FOUTVCO 559
+
+#define PERI3_EMMC_SDIO_REF_CLK 560
+
+#define VO_MIPI_PIXCLK 561
+#define VO_HDMI_PIXCLK 562
+#define VO_DPTX_PIXCLK 563
+
+#define TOP_CPUSYS_CFG_ACLK_DIV 564
+#define TOP_CPUSYS_COM_APB_CLK_DIV 565
+#define TOP_CPUSYS_APB_CLK_DIV 566
+
+#define VI_MISC_CTRL_H0CLK_CLK_EN 567
+#define VI_MISC_CTRL_H1CLK_CLK_EN 568
+#define VI_MISC_CTRL_ISP_ACLK_CLK_EN 569
+#define VI_MISC_CTRL_ISP_SCLK_CLK0_EN 570
+#define VI_MISC_CTRL_ISP_SCLK_CLK1_EN 571
+#define VI_MISC_CTRL_ISP_SCLK_CLK2_EN 572
+#define VI_MISC_CTRL_ISP_SCLK_CLK3_EN 573
+#define VI_MISC_CTRL_ISP_CORE_CLK_EN 574
+#define VI_MISC_CTRL_ISP_FLEXA_CLK_EN 575
+#define VI_MISC_CTRL_ISP_MCM_CLK_EN 576
+#define VI_MISC_CTRL_BUS_CLK_GT_DISABLE 577
+
+#define USB20_X2H_HCLK 578
+#define USB20_X2H_ACLK 579
+#define USB20_SLV_AFENCE_ACLK 580
+#define USB20_H2P_HCLK 581
+#define USB20_AHB_SLV_HCLK 582
+#define USB20_SYSREG_PCLK 583
+#define USB20_WRAP0_HCLK 584
+#define USB20_WRAP1_HCLK 585
+#define USB20_A2X0_HCLK 586
+#define USB20_A2X0_ACLK 587
+#define USB20_A2X1_HCLK 588
+#define USB20_A2X1_ACLK 589
+
+#define CLK_END 590
+
+#endif
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 04/18] dt-bindings: clock: add Zhihe A210 AON clock controller
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (2 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 03/18] dt-bindings: clock: add Zhihe A210 clock controllers Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 05/18] clk: zhihe: add A210 support Han Gao via B4 Relay
` (13 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Add bindings for the A210 AON clock controller, including input clocks,
the system clock and I2C1 gates.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
.../bindings/clock/zhihe,a210-aon-clk.yaml | 58 ++++++++++++++++++++++
include/dt-bindings/clock/zhihe,a210-aon-clk.h | 9 ++++
2 files changed, 67 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/zhihe,a210-aon-clk.yaml b/Documentation/devicetree/bindings/clock/zhihe,a210-aon-clk.yaml
new file mode 100644
index 000000000000..bc1587e3fa81
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/zhihe,a210-aon-clk.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/zhihe,a210-aon-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Zhihe A210 always-on peripheral clock controller
+
+maintainers:
+ - Han Gao <gaohan@iscas.ac.cn>
+
+description: |
+ The AON clock controller provides a system clock multiplexer and
+ divider, along with peripheral clock gates.
+
+properties:
+ compatible:
+ const: zhihe,a210-aon-clk
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: High-speed AON reference
+ - description: External oscillator
+ - description: Internal RC oscillator
+ - description: RTC oscillator
+
+ clock-names:
+ items:
+ - const: high
+ - const: osc
+ - const: rc
+ - const: rtc
+
+ '#clock-cells':
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@30844000 {
+ compatible = "zhihe,a210-aon-clk";
+ reg = <0x30844000 0x1c>;
+ #clock-cells = <1>;
+ clocks = <&aon_high>, <&osc24m>, <&rc26m>, <&rtc32k>;
+ clock-names = "high", "osc", "rc", "rtc";
+ };
+...
diff --git a/include/dt-bindings/clock/zhihe,a210-aon-clk.h b/include/dt-bindings/clock/zhihe,a210-aon-clk.h
new file mode 100644
index 000000000000..29d7e9183adf
--- /dev/null
+++ b/include/dt-bindings/clock/zhihe,a210-aon-clk.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+#ifndef _DT_BINDINGS_CLOCK_ZHIHE_A210_AON_H
+#define _DT_BINDINGS_CLOCK_ZHIHE_A210_AON_H
+
+#define A210_AON_SYS_CLK 0
+#define A210_AON_I2C1_IC_CLK 1
+#define A210_AON_I2C1_PCLK 2
+
+#endif
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 05/18] clk: zhihe: add A210 support
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (3 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 04/18] dt-bindings: clock: add Zhihe A210 AON clock controller Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 06/18] dt-bindings: reset: add Zhihe A210 reset controllers Han Gao via B4 Relay
` (12 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add AP and AON clock providers for A210. Preserve the PLL settings at
probe and keep the AON system clock read-only.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/zhihe/Kconfig | 12 +
drivers/clk/zhihe/Makefile | 2 +
drivers/clk/zhihe/clk-a210-aon.c | 94 ++
drivers/clk/zhihe/clk-a210-ap.c | 2283 ++++++++++++++++++++++++++++++++++++++
6 files changed, 2393 insertions(+)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index f9592fd9ec2b..6f4d7a829a89 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -547,6 +547,7 @@ source "drivers/clk/uniphier/Kconfig"
source "drivers/clk/visconti/Kconfig"
source "drivers/clk/x86/Kconfig"
source "drivers/clk/xilinx/Kconfig"
+source "drivers/clk/zhihe/Kconfig"
source "drivers/clk/zynqmp/Kconfig"
# Kunit test cases
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index b18af485d7f0..63b9f69803fd 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -181,5 +181,6 @@ ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_X86) += x86/
endif
obj-y += xilinx/
+obj-$(CONFIG_CLK_ZHIHE_A210) += zhihe/
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/
diff --git a/drivers/clk/zhihe/Kconfig b/drivers/clk/zhihe/Kconfig
new file mode 100644
index 000000000000..3319817709e6
--- /dev/null
+++ b/drivers/clk/zhihe/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config CLK_ZHIHE_A210
+ tristate "ZhiHe A210 clock driver"
+ depends on OF && (ARCH_ZHIHE || COMPILE_TEST)
+ default ARCH_ZHIHE
+ help
+ Build the clock controller driver for the ZhiHe A210 SoC.
+
+ This driver provides clock tree management including PLLs,
+ dividers, gates, and muxes for the A210 platform. Say Y if
+ you are building a kernel for the ZhiHe A210.
diff --git a/drivers/clk/zhihe/Makefile b/drivers/clk/zhihe/Makefile
new file mode 100644
index 000000000000..90f7075f9eab
--- /dev/null
+++ b/drivers/clk/zhihe/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_CLK_ZHIHE_A210) += clk-a210-ap.o clk-a210-aon.o
diff --git a/drivers/clk/zhihe/clk-a210-aon.c b/drivers/clk/zhihe/clk-a210-aon.c
new file mode 100644
index 000000000000..5e311b1008c8
--- /dev/null
+++ b/drivers/clk/zhihe/clk-a210-aon.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Read the firmware-selected AON clock and gate the AP-owned I2C bus. */
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include <dt-bindings/clock/zhihe,a210-aon-clk.h>
+
+#define AON_CLOCK_CONFIG 0x00
+#define AON_CLOCK_GATE 0x04
+#define AON_SOURCE_SHIFT 4
+#define AON_SOURCE_WIDTH 2
+#define AON_DIVIDER_WIDTH 3
+#define AON_I2C1_IC_ENABLE 20
+#define AON_I2C1_APB_ENABLE 21
+
+struct a210_aon_clock {
+ /* Protects the AP-owned AON gate register bits. */
+ spinlock_t lock;
+ struct clk_hw_onecell_data data;
+};
+
+static int a210_aon_clock_probe(struct platform_device *pdev)
+{
+ static const struct clk_parent_data parents[] = {
+ { .fw_name = "high" },
+ { .fw_name = "osc" },
+ { .fw_name = "rc" },
+ { .fw_name = "rtc" },
+ };
+ struct device *dev = &pdev->dev;
+ struct a210_aon_clock *priv;
+ struct clk_hw *mux, *sys, *hw;
+ void __iomem *base;
+ int i;
+
+ priv = devm_kzalloc(dev, struct_size(priv, data.hws, 3), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ spin_lock_init(&priv->lock);
+ priv->data.num = 3;
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ /* E902 firmware owns source selection and the synchronized divider. */
+ mux = devm_clk_hw_register_mux_parent_data_table(dev, "aon_mux", parents,
+ ARRAY_SIZE(parents), CLK_GET_RATE_NOCACHE,
+ base + AON_CLOCK_CONFIG, AON_SOURCE_SHIFT,
+ AON_SOURCE_WIDTH, CLK_MUX_READ_ONLY, NULL,
+ &priv->lock);
+ if (IS_ERR(mux))
+ return PTR_ERR(mux);
+ sys = devm_clk_hw_register_divider_parent_hw(dev, "aon_sys", mux,
+ CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE,
+ base + AON_CLOCK_CONFIG, 0, AON_DIVIDER_WIDTH,
+ CLK_DIVIDER_READ_ONLY, &priv->lock);
+ if (IS_ERR(sys))
+ return PTR_ERR(sys);
+ priv->data.hws[A210_AON_SYS_CLK] = sys;
+
+ for (i = 0; i < 2; i++) {
+ const char *name = i ? "aon_i2c1_pclk" : "aon_i2c1_ic_clk";
+ unsigned int bit = i ? AON_I2C1_APB_ENABLE : AON_I2C1_IC_ENABLE;
+
+ hw = devm_clk_hw_register_gate_parent_hw(dev, name, sys, 0,
+ base + AON_CLOCK_GATE, bit, 0,
+ &priv->lock);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+ priv->data.hws[A210_AON_I2C1_IC_CLK + i] = hw;
+ }
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &priv->data);
+}
+
+static const struct of_device_id a210_aon_clock_match[] = {
+ { .compatible = "zhihe,a210-aon-clk" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, a210_aon_clock_match);
+
+static struct platform_driver a210_aon_clock_driver = {
+ .probe = a210_aon_clock_probe,
+ .driver = {
+ .name = "a210-aon-clock",
+ .of_match_table = a210_aon_clock_match,
+ },
+};
+module_platform_driver(a210_aon_clock_driver);
+
+MODULE_DESCRIPTION("Zhihe A210 AON peripheral clocks");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/zhihe/clk-a210-ap.c b/drivers/clk/zhihe/clk-a210-ap.c
new file mode 100644
index 000000000000..6f47388684bf
--- /dev/null
+++ b/drivers/clk/zhihe/clk-a210-ap.c
@@ -0,0 +1,2283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Zhihe Computing Limited.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <dt-bindings/clock/zhihe,a210-clk.h>
+
+/* Serializes updates to registers shared by clocks in each controller. */
+static DEFINE_SPINLOCK(a210_clk_lock);
+
+#define div_mask(d) GENMASK((d)->width - 1, 0)
+
+#define PLL_RATE(_vco, _rate, _r, _b, _f, _p, _k) \
+ { \
+ .vco_rate = (_vco), \
+ .rate = (_rate), \
+ .refdiv = (_r), \
+ .fbdiv = (_b), \
+ .frac = (_f), \
+ .postdiv1 = (_p), \
+ .postdiv2 = (_k), \
+ }
+
+#define REG_NAMED(n, _name) \
+ [(n)] = { .name = (_name) }
+
+#define CLK(_type, _id, _name, _parent) \
+ .type = (_type), \
+ .id = (_id), \
+ .name = (_name), \
+ .parent = (_parent)
+
+#define PLL(_id, _name, _parent, _reg, _shift, _pll) { \
+ CLK(A210_CLK_PLL, (_id), (_name), (_parent)), \
+ .reg = (_reg), \
+ .shift = (_shift), \
+ .pll = (_pll), \
+}
+
+#define PLL_POSTDIV(_id, _name, _parent, _reg, _pll) { \
+ CLK(A210_CLK_PLL_POSTDIV, (_id), (_name), (_parent)), \
+ .reg = (_reg), \
+ .pll = (_pll), \
+}
+
+#define FIXED_FACTOR(_id, _name, _parent, _mult, _div) { \
+ CLK(A210_CLK_FIXED_FACTOR, (_id), (_name), (_parent)), \
+ .fixed_factor = { .mult = (_mult), .div = (_div) }, \
+}
+
+#define DIV(_id, _name, _parent, _reg, _shift, _bit_idx, _width, _sync, \
+ _div_type, _min, _max) { \
+ CLK(A210_CLK_DIVIDER, (_id), (_name), (_parent)), \
+ .reg = (_reg), \
+ .shift = (_shift), \
+ .bit_idx = (_bit_idx), \
+ .width = (_width), \
+ .divider = { \
+ .sync = (_sync), \
+ .div_type = (_div_type), \
+ .min = (_min), \
+ .max = (_max) \
+ } \
+}
+
+#define DIV_CLOSEST(_id, _name, _parent, _reg, _shift, _bit_idx, \
+ _width, _sync, _div_type, _min, _max) { \
+ CLK(A210_CLK_DIVIDER_CLOSEST, (_id), (_name), (_parent)), \
+ .reg = (_reg), \
+ .shift = (_shift), \
+ .bit_idx = (_bit_idx), \
+ .width = (_width), \
+ .divider = { \
+ .sync = (_sync), \
+ .div_type = (_div_type), \
+ .min = (_min), \
+ .max = (_max) \
+ } \
+}
+
+#define GATE(_id, _name, _parent, _reg, _shift, _bit_idx) { \
+ CLK(A210_CLK_GATE, (_id), (_name), (_parent)), \
+ .reg = (_reg), \
+ .shift = (_shift), \
+ .bit_idx = (_bit_idx), \
+}
+
+#define GATE_FLAGS(_id, _name, _parent, _reg, _shift, _bit_idx, _flags) { \
+ CLK(A210_CLK_GATE, (_id), (_name), (_parent)), \
+ .reg = (_reg), \
+ .shift = (_shift), \
+ .bit_idx = (_bit_idx), \
+ .flags = (_flags), \
+}
+
+#define GATE_SHARED(_id, _name, _parent, _reg, _shift, _bit_idx, \
+ _count, _flags) { \
+ CLK(A210_CLK_GATE_SHARED, (_id), (_name), (_parent)), \
+ .flags = (_flags), \
+ .reg = (_reg), \
+ .shift = (_shift), \
+ .bit_idx = (_bit_idx), \
+ .gate_shared = { \
+ .share_count = (_count) \
+ }, \
+}
+
+#define MUX(_id, _name, _reg, _shift, _bit_idx, _width, _parents, _flags) { \
+ CLK(A210_CLK_MUX, (_id), (_name), ""), \
+ .reg = (_reg), \
+ .shift = (_shift), \
+ .bit_idx = (_bit_idx), \
+ .width = (_width), \
+ .mux = { \
+ .parents = (_parents), \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = (_flags) \
+ }, \
+}
+
+#define PLL_PARAM(_pll, _out, _table, _cfg0, _sts, _lock, \
+ _bypass, _rst, _mode, _name) \
+ [(_pll)] = { \
+ .out_type = (_out), \
+ .rate_table = (_table), \
+ .rate_count = ARRAY_SIZE(_table), \
+ .cfg0_reg_off = (_cfg0), \
+ .pll_sts_off = (_sts), \
+ .pll_lock_bit = (_lock), \
+ .pll_bypass_bit = (_bypass), \
+ .pll_rst_bit = (_rst), \
+ .pll_mode = (_mode), \
+ .name = (_name), \
+ }
+
+#define CLK_SUBSYS(_name, _regs, _info) { \
+ .name = (_name), \
+ .regs = (_regs), \
+ .num_regs = ARRAY_SIZE(_regs), \
+ .info = (_info), \
+ .num_info = ARRAY_SIZE(_info), \
+}
+
+enum a210_pll_outtype {
+ A210_PLL_VCO,
+ A210_PLL_DIV,
+};
+
+enum a210_div_type {
+ MUX_TYPE_DIV,
+ MUX_TYPE_CDE,
+};
+
+enum a210_div_sync_type {
+ NO_DIV_EN = 255,
+};
+
+enum a210_clk_type {
+ A210_CLK_PLL,
+ A210_CLK_PLL_POSTDIV,
+ A210_CLK_FIXED_FACTOR,
+ A210_CLK_DIVIDER,
+ A210_CLK_DIVIDER_CLOSEST,
+ A210_CLK_GATE,
+ A210_CLK_GATE_SHARED,
+ A210_CLK_MUX,
+};
+
+enum a210_pll_mode {
+ PLL_MODE_FRAC,
+ PLL_MODE_INT,
+};
+
+struct a210_clk_reg {
+ void __iomem *base;
+ const char *name;
+};
+
+/* clk summary info at subsys level */
+struct a210_ccu {
+ const char *name;
+ struct a210_clk_reg *regs;
+ u32 num_regs;
+ const struct a210_clk_desc *info;
+ u32 num_info;
+ struct clk_hw_onecell_data *clk_data;
+ struct clk_bulk_data *inputs;
+ int num_inputs;
+};
+
+struct a210_pll {
+ struct clk_hw hw;
+ void __iomem *base;
+ enum a210_pll_outtype out_type;
+ enum a210_pll_mode pll_mode;
+ const struct a210_pll_rate *rate_table;
+ int rate_count;
+
+ u32 cfg0_reg_off;
+ u32 pll_sts_off;
+ int pll_lock_bit;
+ int pll_rst_bit;
+ int pll_bypass_bit;
+};
+
+struct a210_div {
+ struct clk_divider divider;
+ enum a210_div_type div_type;
+ u8 sync_en;
+ struct clk_div_table table[];
+};
+
+struct a210_shared_gate {
+ struct clk_gate gate;
+ unsigned int *share_count;
+ const struct clk_ops *ops;
+};
+
+struct a210_pll_rate {
+ unsigned long vco_rate;
+ unsigned long rate;
+ unsigned int refdiv;
+ unsigned int fbdiv;
+ unsigned int frac;
+ unsigned int postdiv1;
+ unsigned int postdiv2;
+};
+
+/* detailed clk info for each clk */
+
+struct a210_pll_desc {
+ enum a210_pll_outtype out_type;
+ const struct a210_pll_rate *rate_table;
+ int rate_count;
+ int flags;
+ const char *name;
+ u32 cfg0_reg_off;
+ u32 pll_sts_off;
+ int pll_lock_bit;
+ int pll_rst_bit;
+ int pll_bypass_bit;
+ enum a210_pll_mode pll_mode;
+};
+
+struct a210_factor_desc {
+ unsigned int mult;
+ unsigned int div;
+};
+
+struct a210_div_desc {
+ u8 sync;
+ enum a210_div_type div_type;
+ u16 min;
+ u16 max;
+};
+
+struct a210_shared_gate_desc {
+ unsigned int *share_count;
+};
+
+struct a210_mux_desc {
+ const char *const *parents;
+ int num_parents;
+ unsigned long flags;
+};
+
+struct a210_clk_desc {
+ enum a210_clk_type type;
+ u32 id;
+ const char *name;
+ const char *parent;
+ u8 reg;
+ u32 shift;
+ u8 width;
+ u8 bit_idx;
+ unsigned long flags;
+ union {
+ struct a210_factor_desc fixed_factor;
+ const struct a210_pll_desc *pll;
+ struct a210_div_desc divider;
+ struct a210_shared_gate_desc gate_shared;
+ struct a210_mux_desc mux;
+ };
+};
+
+#define A210_PLL_CFG0 0x0
+#define A210_PLL_CFG1 0x04
+#define A210_PLL_CFG2 0x8
+#define A210_POSTDIV2_SHIFT 24
+#define A210_POSTDIV2_MASK GENMASK(26, 24)
+#define A210_POSTDIV1_SHIFT 20
+#define A210_POSTDIV1_MASK GENMASK(22, 20)
+#define A210_FBDIV_SHIFT 8
+#define A210_FBDIV_MASK GENMASK(19, 8)
+#define A210_REFDIV_SHIFT 0
+#define A210_REFDIV_MASK GENMASK(5, 0)
+#define A210_BYPASS_MASK BIT(30)
+#define A210_RST_MASK BIT(29)
+#define A210_DSMPD_MASK BIT(24)
+#define A210_DACPD_MASK BIT(25)
+#define A210_FRAC_MASK GENMASK(23, 0)
+#define A210_FRAC_SHIFT 0
+#define A210_FRAC_DIV BIT(24)
+
+#define LOCK_TIMEOUT_US 10000
+
+#define to_a210_pll(_hw) container_of(_hw, struct a210_pll, hw)
+
+static int a210_pll_wait_lock(struct a210_pll *pll)
+{
+ u32 val;
+
+ return readl_poll_timeout(pll->base + pll->pll_sts_off, val, val & pll->pll_lock_bit, 0,
+ LOCK_TIMEOUT_US);
+}
+
+static int a210_pll_prepare(struct clk_hw *hw)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ void __iomem *cfg1_off;
+ u32 val;
+ int ret;
+
+ cfg1_off = pll->base + pll->cfg0_reg_off + A210_PLL_CFG1;
+ val = readl_relaxed(cfg1_off);
+ if (!(val & pll->pll_rst_bit))
+ return 0;
+
+ /* Enable RST */
+ val |= pll->pll_rst_bit;
+ writel_relaxed(val, cfg1_off);
+
+ udelay(3);
+
+ /* Disable RST */
+ val &= ~pll->pll_rst_bit;
+ writel_relaxed(val, cfg1_off);
+
+ ret = a210_pll_wait_lock(pll);
+ if (ret)
+ writel_relaxed(val | pll->pll_rst_bit, cfg1_off);
+
+ return ret;
+}
+
+static int a210_pll_is_prepared(struct clk_hw *hw)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + pll->cfg0_reg_off + A210_PLL_CFG1);
+
+ return (val & pll->pll_rst_bit) ? 0 : 1;
+}
+
+static void a210_pll_unprepare(struct clk_hw *hw)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base + pll->cfg0_reg_off + A210_PLL_CFG1);
+ val |= pll->pll_rst_bit;
+ writel_relaxed(val, pll->base + pll->cfg0_reg_off + A210_PLL_CFG1);
+}
+
+static unsigned long a210_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ u32 refdiv, fbdiv, postdiv1, postdiv2, frac;
+ u32 pll_cfg0, pll_cfg1;
+ u64 fvco = 0;
+
+ pll_cfg0 = readl_relaxed(pll->base + pll->cfg0_reg_off);
+ pll_cfg1 = readl_relaxed(pll->base + pll->cfg0_reg_off + A210_PLL_CFG1);
+ if (pll->out_type == A210_PLL_DIV && (pll_cfg1 & pll->pll_bypass_bit))
+ return parent_rate;
+
+ refdiv = (pll_cfg0 & A210_REFDIV_MASK) >> A210_REFDIV_SHIFT;
+ fbdiv = (pll_cfg0 & A210_FBDIV_MASK) >> A210_FBDIV_SHIFT;
+ postdiv1 = (pll_cfg0 & A210_POSTDIV1_MASK) >> A210_POSTDIV1_SHIFT;
+ postdiv2 = (pll_cfg0 & A210_POSTDIV2_MASK) >> A210_POSTDIV2_SHIFT;
+ frac = (pll_cfg1 & A210_FRAC_MASK) >> A210_FRAC_SHIFT;
+
+ if (!refdiv || (pll->out_type == A210_PLL_DIV && (!postdiv1 || !postdiv2)))
+ return 0;
+
+ /* Read the mode selected by firmware until a rate change requests it. */
+ if (!(pll_cfg1 & A210_DSMPD_MASK))
+ fvco = ((u64)parent_rate * frac) / A210_FRAC_DIV;
+
+ fvco += (u64)parent_rate * fbdiv;
+ do_div(fvco, refdiv);
+
+ if (pll->out_type == A210_PLL_DIV)
+ do_div(fvco, postdiv1 * postdiv2);
+
+ return fvco;
+}
+
+static const struct a210_pll_rate *a210_get_pll_div_settings(struct a210_pll *pll,
+ unsigned long rate)
+{
+ const struct a210_pll_rate *rate_table = pll->rate_table;
+ int i;
+
+ for (i = 0; i < pll->rate_count; i++)
+ if (rate == rate_table[i].rate)
+ return &rate_table[i];
+
+ return NULL;
+}
+
+static const struct a210_pll_rate *a210_get_pll_vco_settings(struct a210_pll *pll,
+ unsigned long rate)
+{
+ const struct a210_pll_rate *rate_table = pll->rate_table;
+ int i;
+
+ for (i = 0; i < pll->rate_count; i++)
+ if (rate == rate_table[i].vco_rate)
+ return &rate_table[i];
+
+ return NULL;
+}
+
+static inline bool a210_pll_change(struct a210_pll *pll, const struct a210_pll_rate *rate)
+{
+ u32 refdiv_old, fbdiv_old, postdiv1_old, postdiv2_old, frac_old;
+ u32 cfg0, cfg1;
+ bool pll_changed;
+
+ cfg0 = readl_relaxed(pll->base + pll->cfg0_reg_off);
+ cfg1 = readl_relaxed(pll->base + pll->cfg0_reg_off + A210_PLL_CFG1);
+
+ refdiv_old = (cfg0 & A210_REFDIV_MASK) >> A210_REFDIV_SHIFT;
+ fbdiv_old = (cfg0 & A210_FBDIV_MASK) >> A210_FBDIV_SHIFT;
+ postdiv1_old = (cfg0 & A210_POSTDIV1_MASK) >> A210_POSTDIV1_SHIFT;
+ postdiv2_old = (cfg0 & A210_POSTDIV2_MASK) >> A210_POSTDIV2_SHIFT;
+ frac_old = (cfg1 & A210_FRAC_MASK) >> A210_FRAC_SHIFT;
+
+ pll_changed = (pll->out_type == A210_PLL_DIV && (cfg1 & pll->pll_bypass_bit)) ||
+ (!!(cfg1 & A210_DSMPD_MASK) != (pll->pll_mode == PLL_MODE_INT)) ||
+ rate->refdiv != refdiv_old || rate->fbdiv != fbdiv_old ||
+ rate->postdiv1 != postdiv1_old || rate->postdiv2 != postdiv2_old;
+ if (pll->pll_mode == PLL_MODE_FRAC)
+ pll_changed |= (rate->frac != frac_old);
+
+ return pll_changed;
+}
+
+static int a210_pll_set_rate(struct clk_hw *hw, unsigned long drate, unsigned long prate)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ const struct a210_pll_rate *rate;
+ void __iomem *cfg1_off;
+ u32 tmp, div_val, old_cfg0, old_cfg1;
+ int ret;
+
+ if (pll->out_type == A210_PLL_VCO) {
+ rate = a210_get_pll_vco_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, drate,
+ clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+ } else {
+ rate = a210_get_pll_div_settings(pll, drate);
+ if (!rate) {
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, drate,
+ clk_hw_get_name(hw));
+ return -EINVAL;
+ }
+ }
+
+ if (!a210_pll_change(pll, rate))
+ return 0;
+
+ /* Enable RST */
+ cfg1_off = pll->base + pll->cfg0_reg_off + A210_PLL_CFG1;
+ old_cfg0 = readl_relaxed(pll->base + pll->cfg0_reg_off);
+ old_cfg1 = readl_relaxed(cfg1_off);
+ tmp = old_cfg1 | pll->pll_rst_bit;
+ writel_relaxed(tmp, cfg1_off);
+
+ div_val = (rate->refdiv << A210_REFDIV_SHIFT) | (rate->fbdiv << A210_FBDIV_SHIFT) |
+ (rate->postdiv1 << A210_POSTDIV1_SHIFT) | (rate->postdiv2 << A210_POSTDIV2_SHIFT);
+ div_val |= old_cfg0 &
+ ~(A210_REFDIV_MASK | A210_FBDIV_MASK | A210_POSTDIV1_MASK | A210_POSTDIV2_MASK);
+ writel_relaxed(div_val, pll->base + pll->cfg0_reg_off);
+
+ tmp &= ~(A210_FRAC_MASK | A210_DSMPD_MASK | A210_DACPD_MASK);
+ if (pll->pll_mode == PLL_MODE_FRAC)
+ tmp |= rate->frac;
+ else
+ tmp |= A210_DSMPD_MASK | A210_DACPD_MASK;
+ writel_relaxed(tmp, cfg1_off);
+
+ udelay(3);
+
+ /* Disable RST */
+ tmp &= ~pll->pll_rst_bit;
+ writel_relaxed(tmp, cfg1_off);
+
+ ret = a210_pll_wait_lock(pll);
+ if (ret) {
+ /* Restore the previous configuration on a failed transition. */
+ writel_relaxed(tmp | pll->pll_rst_bit, cfg1_off);
+ writel_relaxed(old_cfg0, pll->base + pll->cfg0_reg_off);
+ writel_relaxed(old_cfg1, cfg1_off);
+ return ret;
+ }
+
+ /* Retain the reference settling time before selecting the PLL output. */
+ usleep_range(30, 40);
+ if (pll->out_type == A210_PLL_DIV)
+ tmp &= ~pll->pll_bypass_bit;
+ tmp |= old_cfg1 & pll->pll_rst_bit;
+ writel_relaxed(tmp, cfg1_off);
+
+ return 0;
+}
+
+static int a210_pllvco_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ const struct a210_pll_rate *rate_table = pll->rate_table;
+ unsigned long best_diff;
+ unsigned int best_i = 0;
+ unsigned int i;
+
+ if (!pll->rate_count)
+ return -EINVAL;
+
+ best_diff = abs_diff(rate_table[0].vco_rate, req->rate);
+
+ for (i = 1; i < pll->rate_count; i++) {
+ unsigned long diff = abs_diff(rate_table[i].vco_rate, req->rate);
+
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_i = i;
+ }
+ }
+
+ req->rate = rate_table[best_i].vco_rate;
+
+ return 0;
+}
+
+static int a210_plldiv_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ const struct a210_pll_rate *rate_table = pll->rate_table;
+ unsigned long best_diff;
+ unsigned int best_i = 0;
+ unsigned int i;
+
+ if (!pll->rate_count)
+ return -EINVAL;
+
+ best_diff = abs_diff(rate_table[0].rate, req->rate);
+
+ for (i = 1; i < pll->rate_count; i++) {
+ unsigned long diff = abs_diff(rate_table[i].rate, req->rate);
+
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_i = i;
+ }
+ }
+
+ req->rate = rate_table[best_i].rate;
+
+ return 0;
+}
+
+static const struct clk_ops a210_pll_def_ops = {
+ .recalc_rate = a210_pll_recalc_rate,
+};
+
+static const struct clk_ops a210_pllvco_ops = {
+ .prepare = a210_pll_prepare,
+ .unprepare = a210_pll_unprepare,
+ .is_prepared = a210_pll_is_prepared,
+ .recalc_rate = a210_pll_recalc_rate,
+ .determine_rate = a210_pllvco_determine_rate,
+ .set_rate = a210_pll_set_rate,
+};
+
+static const struct clk_ops a210_plldiv_ops = {
+ .prepare = a210_pll_prepare,
+ .unprepare = a210_pll_unprepare,
+ .is_prepared = a210_pll_is_prepared,
+ .recalc_rate = a210_pll_recalc_rate,
+ .determine_rate = a210_plldiv_determine_rate,
+ .set_rate = a210_pll_set_rate,
+};
+
+static struct clk_hw *a210_register_pll(struct device *dev, const char *name,
+ const char *parent_name, void __iomem *base,
+ const struct a210_pll_desc *pll_clk)
+{
+ struct a210_pll *pll;
+ int ret;
+ struct clk_init_data init = {};
+
+ pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = pll_clk->flags | CLK_SET_RATE_GATE;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ switch (pll_clk->out_type) {
+ case A210_PLL_VCO:
+ if (pll_clk->rate_table)
+ init.ops = &a210_pllvco_ops;
+ break;
+ case A210_PLL_DIV:
+ if (pll_clk->rate_table)
+ init.ops = &a210_plldiv_ops;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!pll_clk->rate_table)
+ init.ops = &a210_pll_def_ops;
+
+ pll->base = base;
+ pll->hw.init = &init;
+ pll->out_type = pll_clk->out_type;
+ pll->rate_table = pll_clk->rate_table;
+ pll->rate_count = pll_clk->rate_count;
+ pll->cfg0_reg_off = pll_clk->cfg0_reg_off;
+ pll->pll_sts_off = pll_clk->pll_sts_off;
+ pll->pll_lock_bit = pll_clk->pll_lock_bit;
+ pll->pll_bypass_bit = pll_clk->pll_bypass_bit;
+ pll->pll_rst_bit = pll_clk->pll_rst_bit;
+ pll->pll_mode = pll_clk->pll_mode;
+
+ /* Registration must preserve the firmware-selected PLL state. */
+ ret = devm_clk_hw_register(dev, &pll->hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &pll->hw;
+}
+
+static u8 a210_postdiv_get_parent(struct clk_hw *hw)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ u32 value = readl_relaxed(pll->base + pll->cfg0_reg_off + A210_PLL_CFG1);
+
+ return !!(value & pll->pll_bypass_bit);
+}
+
+static unsigned long a210_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct a210_pll *pll = to_a210_pll(hw);
+ u32 value, div1, div2;
+
+ if (a210_postdiv_get_parent(hw))
+ return parent_rate;
+
+ value = readl_relaxed(pll->base + pll->cfg0_reg_off);
+ div1 = (value & A210_POSTDIV1_MASK) >> A210_POSTDIV1_SHIFT;
+ div2 = (value & A210_POSTDIV2_MASK) >> A210_POSTDIV2_SHIFT;
+ if (!div1 || !div2)
+ return 0;
+
+ return parent_rate / (div1 * div2);
+}
+
+static const struct clk_ops a210_postdiv_ops = {
+ .get_parent = a210_postdiv_get_parent,
+ .recalc_rate = a210_postdiv_recalc_rate,
+};
+
+static struct clk_hw *a210_register_postdiv(struct device *dev, const char *name,
+ const char *parent_name, void __iomem *base,
+ const struct a210_pll_desc *pll_clk)
+{
+ const char *const parents[] = { parent_name, "pll_osc_clk" };
+ struct clk_init_data init = {
+ .name = name,
+ .ops = &a210_postdiv_ops,
+ .parent_names = parents,
+ .num_parents = ARRAY_SIZE(parents),
+ };
+ struct a210_pll *pll;
+ int ret;
+
+ pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+ pll->cfg0_reg_off = pll_clk->cfg0_reg_off;
+ pll->pll_bypass_bit = pll_clk->pll_bypass_bit;
+ pll->hw.init = &init;
+ ret = devm_clk_hw_register(dev, &pll->hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return &pll->hw;
+}
+
+static inline struct a210_div *to_a210_div(struct clk_hw *hw)
+{
+ struct clk_divider *divider = to_clk_divider(hw);
+
+ return container_of(divider, struct a210_div, divider);
+}
+
+static unsigned long a210_div_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct a210_div *cd = to_a210_div(hw);
+ struct clk_divider *div = &cd->divider;
+ u32 value = (readl(div->reg) >> div->shift) & div_mask(div);
+ unsigned long flags = cd->div_type == MUX_TYPE_DIV ? CLK_DIVIDER_ONE_BASED : 0;
+
+ /* Report the actual firmware setting even outside the writable range. */
+ return divider_recalc_rate(hw, parent_rate, value, NULL, flags, div->width);
+}
+
+static int a210_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ struct a210_div *cd = to_a210_div(hw);
+ struct clk_divider *div = &cd->divider;
+
+ return divider_determine_rate(hw, req, div->table, div->width, div->flags);
+}
+
+static int a210_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+ struct a210_div *cd = to_a210_div(hw);
+ struct clk_divider *div = to_clk_divider(hw);
+ int value;
+ unsigned long flags = 0;
+ u32 val;
+
+ if (!rate)
+ return -EINVAL;
+
+ value = divider_get_val(rate, parent_rate, div->table, div->width, div->flags);
+ if (value < 0)
+ return value;
+
+ spin_lock_irqsave(div->lock, flags);
+
+ val = readl(div->reg);
+
+ if (cd->sync_en != NO_DIV_EN) {
+ val &= ~BIT(cd->sync_en);
+ writel(val, div->reg);
+ udelay(1);
+ }
+
+ val &= ~(div_mask(div) << div->shift);
+ val |= value << div->shift;
+ writel(val, div->reg);
+
+ if (cd->sync_en != NO_DIV_EN) {
+ udelay(1);
+ val |= BIT(cd->sync_en);
+ writel(val, div->reg);
+ }
+
+ spin_unlock_irqrestore(div->lock, flags);
+
+ return 0;
+}
+
+static const struct clk_ops a210_div_ops = {
+ .recalc_rate = a210_div_recalc_rate,
+ .determine_rate = a210_div_determine_rate,
+ .set_rate = a210_div_set_rate,
+};
+
+static struct clk_hw *a210_register_divider(struct device *dev, const char *name,
+ const char *parent, void __iomem *reg, u8 shift,
+ u8 width, u8 sync, enum a210_div_type div_type, u16 min,
+ u16 max, bool closest)
+{
+ struct a210_div *div;
+ struct clk_hw *hw;
+ struct clk_init_data init;
+ unsigned int i, count;
+ int ret;
+
+ if (!width || width > 16 || min > max || max >= BIT(width) ||
+ (div_type == MUX_TYPE_DIV && !min))
+ return ERR_PTR(-EINVAL);
+
+ count = max - min + 1;
+ div = devm_kzalloc(dev, struct_size(div, table, count + 1), GFP_KERNEL);
+ if (!div)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &a210_div_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = parent ? &parent : NULL;
+ init.num_parents = parent ? 1 : 0;
+
+ div->divider.reg = reg;
+ div->divider.shift = shift;
+ div->divider.width = width;
+ div->divider.lock = &a210_clk_lock;
+ div->divider.hw.init = &init;
+ div->sync_en = sync;
+ div->div_type = div_type;
+ if (closest)
+ div->divider.flags = CLK_DIVIDER_ROUND_CLOSEST;
+
+ for (i = 0; i < count; i++) {
+ div->table[i].val = min + i;
+ div->table[i].div = min + i + (div_type == MUX_TYPE_CDE);
+ }
+ div->divider.table = div->table;
+
+ hw = &div->divider.hw;
+
+ ret = devm_clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return hw;
+}
+
+static inline struct a210_shared_gate *to_a210_shared_gate(struct clk_hw *hw)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+
+ return container_of(gate, struct a210_shared_gate, gate);
+}
+
+static int a210_shared_gate_is_enabled(struct clk_hw *hw)
+{
+ struct a210_shared_gate *gate = to_a210_shared_gate(hw);
+
+ return gate->ops->is_enabled(hw);
+}
+
+static int a210_shared_gate_enable(struct clk_hw *hw)
+{
+ struct a210_shared_gate *gate = to_a210_shared_gate(hw);
+
+ if (gate->share_count && (*gate->share_count)++ > 0)
+ return 0;
+
+ return gate->ops->enable(hw);
+}
+
+static void a210_shared_gate_disable(struct clk_hw *hw)
+{
+ struct a210_shared_gate *gate = to_a210_shared_gate(hw);
+
+ if (gate->share_count) {
+ if (WARN_ON(*gate->share_count == 0))
+ return;
+ else if (--(*gate->share_count) > 0)
+ return;
+ }
+
+ gate->ops->disable(hw);
+}
+
+static void a210_shared_gate_disable_unused(struct clk_hw *hw)
+{
+ struct a210_shared_gate *gate = to_a210_shared_gate(hw);
+
+ if (!gate->share_count || *gate->share_count == 0)
+ return gate->ops->disable(hw);
+}
+
+static const struct clk_ops a210_shared_gate_ops = {
+ .enable = a210_shared_gate_enable,
+ .disable = a210_shared_gate_disable,
+ .disable_unused = a210_shared_gate_disable_unused,
+ .is_enabled = a210_shared_gate_is_enabled,
+};
+
+static struct clk_hw *a210_register_shared_gate(struct device *dev, const char *name,
+ const char *parent, unsigned long flags,
+ void __iomem *reg, u8 shift, spinlock_t *lock,
+ unsigned int *share_count)
+{
+ struct a210_shared_gate *gate;
+ struct clk_hw *hw;
+ struct clk_init_data init;
+ int ret;
+
+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ gate->gate.reg = reg;
+ gate->gate.bit_idx = shift;
+ gate->gate.flags = 0;
+ gate->gate.lock = lock;
+ gate->gate.hw.init = &init;
+ gate->ops = &clk_gate_ops;
+ gate->share_count = share_count;
+
+ init.name = name;
+ init.ops = &a210_shared_gate_ops;
+ init.flags = flags;
+ init.parent_names = parent ? &parent : NULL;
+ init.num_parents = parent ? 1 : 0;
+
+ hw = &gate->gate.hw;
+
+ ret = devm_clk_hw_register(dev, hw);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return hw;
+}
+
+static int a210_map_registers(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct a210_ccu *priv = dev_get_drvdata(dev);
+ int ret = 0;
+
+ for (int i = 0; i < priv->num_regs; i++) {
+ priv->regs[i].base =
+ devm_platform_ioremap_resource_byname(pdev, priv->regs[i].name);
+ if (IS_ERR(priv->regs[i].base)) {
+ ret = PTR_ERR(priv->regs[i].base);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int a210_register_clocks(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct a210_ccu *priv = dev_get_drvdata(dev);
+ struct clk_hw **hws = priv->clk_data->hws;
+ int i;
+
+ for (i = 0; i < priv->num_info; i++) {
+ const struct a210_clk_desc *info = &priv->info[i];
+ const char *name = info->name;
+ const char *parent = info->parent;
+ struct clk_hw *hw;
+ void __iomem *base;
+ u32 id = info->id;
+ int j;
+
+ for (j = 0; j < priv->num_inputs; j++)
+ if (priv->inputs[j].id && !strcmp(parent, priv->inputs[j].id)) {
+ parent = __clk_get_name(priv->inputs[j].clk);
+ break;
+ }
+
+ if (id >= priv->clk_data->num)
+ return dev_err_probe(dev, -EINVAL, "invalid clock id %u for %s\n", id,
+ info->name);
+ if (info->reg >= priv->num_regs)
+ return dev_err_probe(dev, -EINVAL, "invalid register index %u for %s\n",
+ info->reg, info->name);
+
+ base = priv->regs[info->reg].base + info->shift;
+
+ switch (info->type) {
+ case A210_CLK_FIXED_FACTOR:
+ hw = devm_clk_hw_register_fixed_factor(dev, name, parent,
+ CLK_SET_RATE_PARENT,
+ info->fixed_factor.mult,
+ info->fixed_factor.div);
+ break;
+ case A210_CLK_PLL:
+ hw = a210_register_pll(dev, name, parent, base, info->pll);
+ break;
+ case A210_CLK_PLL_POSTDIV:
+ hw = a210_register_postdiv(dev, name, parent, base, info->pll);
+ break;
+ case A210_CLK_DIVIDER:
+ case A210_CLK_DIVIDER_CLOSEST:
+ hw = a210_register_divider(dev, name, parent, base, info->bit_idx,
+ info->width, info->divider.sync,
+ info->divider.div_type, info->divider.min,
+ info->divider.max,
+ info->type == A210_CLK_DIVIDER_CLOSEST);
+ break;
+ case A210_CLK_GATE:
+ hw = devm_clk_hw_register_gate(dev, name, parent,
+ CLK_SET_RATE_PARENT | info->flags, base,
+ info->bit_idx, 0, &a210_clk_lock);
+ break;
+ case A210_CLK_GATE_SHARED:
+ hw = a210_register_shared_gate(dev, name, parent,
+ CLK_SET_RATE_PARENT | info->flags, base,
+ info->bit_idx, &a210_clk_lock,
+ info->gate_shared.share_count);
+ break;
+ case A210_CLK_MUX:
+ hw = devm_clk_hw_register_mux(dev, name, info->mux.parents,
+ info->mux.num_parents, info->mux.flags, base,
+ info->bit_idx, info->width, 0,
+ &a210_clk_lock);
+ break;
+ default:
+ return dev_err_probe(dev, -EINVAL, "invalid clock type %u for %s\n",
+ info->type, name);
+ }
+
+ if (IS_ERR(hw))
+ return dev_err_probe(dev, PTR_ERR(hw), "failed to register clock %s\n",
+ name);
+ hws[id] = hw;
+ }
+
+ return 0;
+}
+
+/* top reg idx */
+#define PLL_WRAP 0
+#define TOP_CRG 1
+#define CPU_SS_CLK_SYSREG 2
+#define CPU_SS_CPU_PLL 3
+#define DDR0_SYSREG 4
+#define DDR1_SYSREG 5
+#define SLC_DUAL_SYSREG 6
+#define TOP_CRG_T 7
+#define CPU_SS_CCU 8
+/* gpu reg idx */
+#define GPU_SS_PWRAP_CLK_EN 0
+#define GPU_SS_TOP_CLK_EN 1
+/* pcie reg idx */
+#define PCIE_CLK_EN 0
+/* usb reg idx */
+#define USB_CLK_EN 0
+/* vi reg idx */
+#define VI_CLK 0
+#define VI_MISC_CTRL 1
+/* vp reg idx */
+#define VP_CLK 0
+/* vo reg idx */
+#define VO_CLK 0
+#define VO_PATH_CTRL 1
+/* npu reg idx */
+#define NPU_CLK 0
+#define NPU_TOP_CLK 1
+/* peri reg idx */
+#define PERI0_SYSREG 0
+#define PERI1_SYSREG 1
+#define PERI2_SYSREG 2
+#define PERI3_SYSREG 3
+#define TEE_CRG 4
+
+static u32 share_cnt_ddr_pll_clk_en;
+
+enum a210_pll_clktype {
+ AUDIO0_PLL,
+ AUDIO1_PLL,
+ VIDEO_PLL,
+ GMAC_PLL,
+ DVFS_PLL,
+ DPU0_PLL,
+ DPU1_PLL,
+ DPU2_PLL,
+ TEE_PLL,
+ DDR_PLL,
+ C920_PLL,
+ C908_PLL,
+};
+
+static const char *const uart_sclk_parents[] = {
+ "uart_sclk_100m",
+ "aon_osc_clk_logic",
+};
+
+static const char *const noc_cclk_mux_parents[] = {
+ "dpu1_pll_foutvco",
+ "video_pll_foutvco",
+ "gmac_pll_foutvco",
+};
+
+static const char *const top_cpu_ddr1_aclk_parents[] = {
+ "cbus2ddr_aclk1",
+ "gmac_pll_foutpostdiv",
+};
+
+static const char *const top_cpu_ddr0_aclk_parents[] = {
+ "cbus2ddr_aclk0",
+ "gmac_pll_foutpostdiv",
+};
+
+static const char *const ddr_pll_clkout_parents[] = {
+ "ddr_pll_foutpostdiv",
+ "ddr_pll_fout1ph0",
+ "ddr_pll_fout2",
+};
+
+static const char *const top_cpu_bak_pll0_clk_mux0_parents[] = {
+ "audio0_pll_foutvco",
+ "dvfs_pll_foutvco",
+ "top_cpu_bak_pll0_clk_div0",
+ "top_cpu_bak_pll0_clk_div1",
+};
+
+static const char *const top_cpu_bak_pll0_clk_mux_parents[] = {
+ "dpu1_pll_foutvco", "top_cpu_bak_pll0_clk_mux0", "dvfs_pll_foutvco",
+ "audio0_pll_foutvco", "top_cpu_bak_pll0_clk_div0", "top_cpu_bak_pll0_clk_div4",
+ "top_cpu_bak_pll0_clk_div3", "top_cpu_bak_pll0_clk_div1",
+};
+
+static const char *const top_cpu_bak_pll1_clk_mux0_parents[] = {
+ "audio0_pll_foutvco",
+ "dvfs_pll_foutvco",
+ "top_cpu_bak_pll1_clk_div0",
+ "top_cpu_bak_pll1_clk_div1",
+};
+
+static const char *const top_cpu_bak_pll1_clk_mux_parents[] = {
+ "dpu1_pll_foutvco", "top_cpu_bak_pll1_clk_mux0", "dvfs_pll_foutvco",
+ "audio0_pll_foutvco", "top_cpu_bak_pll1_clk_div0", "top_cpu_bak_pll1_clk_div4",
+ "top_cpu_bak_pll1_clk_div3", "top_cpu_bak_pll1_clk_div1",
+};
+
+static const char *const top_cpusys_pic_clk_mux_parents[] = {
+ "gmac_pll_foutvco",
+ "video_pll_foutvco",
+};
+
+static const char *const top_cpusys_bus_clk_mux_parents[] = {
+ "video_pll_foutvco",
+ "gmac_pll_foutvco",
+ "audio0_pll_foutvco",
+ "dpu2_pll_foutvco",
+};
+
+static const char *const d2d_phy_ref_clk_parents[] = {
+ "d2d_phy_ref_clk_100M",
+ "aon_osc_clk_logic",
+};
+
+static const char *const top_d2d_aclk_mux_parents[] = {
+ "dpu1_pll_foutvco",
+ "gmac_pll_foutvco",
+ "audio1_pll_foutvco",
+ "audio0_pll_foutvco",
+};
+
+static const char *const top_gpu_core_clk_mux_parents[] = {
+ "dpu2_pll_foutvco",
+ "video_pll_foutvco",
+ "dvfs_pll_foutvco",
+ "audio0_pll_foutvco",
+};
+
+static const char *const pcie_ss_axi_m_aclk_mux_parents[] = {
+ "audio0_pll_foutvco",
+ "video_pll_foutvco",
+};
+
+static const char *const peri0_timer_clk_parents[] = {
+ "peri0_timer_clk_100M",
+ "aon_osc_clk_logic",
+};
+
+static const char *const peri2_i2s3_src_clk_parents[] = {
+ "audio1_pll_fout2",
+ "audio0_pll_fout2",
+};
+
+static const char *const peri1_i2s0_src_clk_parents[] = {
+ "audio1_pll_fout2",
+ "audio0_pll_fout2",
+};
+
+static const char *const peri2_i2s1_src_clk_parents[] = {
+ "audio1_pll_fout2",
+ "audio0_pll_fout2",
+};
+
+static const char *const peri2_i2s2_src_clk_parents[] = {
+ "audio1_pll_fout2",
+ "audio0_pll_fout2",
+};
+
+static const char *const peri1_qspi_ssi_clk_parents[] = {
+ "peri1_qspi_ssi_clk_div1",
+ "peri1_qspi_ssi_clk_div0",
+};
+
+static const char *const peri2_qspi_ssi_clk_parents[] = {
+ "peri2_qspi_ssi_clk_div1",
+ "peri2_qspi_ssi_clk_div0",
+};
+
+static const char *const peri1_tdm_src_clk_parents[] = {
+ "audio1_pll_fout2",
+ "audio0_pll_fout2",
+};
+
+static const char *const pdm_clk_mux_parents[] = {
+ "audio1_pll_fout2",
+ "audio0_pll_fout2",
+};
+
+static const char *const emmc_ref_clk_mux_parents[] = {
+ "audio0_pll_foutvco",
+ "video_pll_foutvco",
+};
+
+static const char *const pad_sensor_vclk0_mux_parents[] = {
+ "dpu0_pll_foutpostdiv",
+ "dpu1_pll_foutpostdiv",
+ "dpu2_pll_foutpostdiv",
+ "aon_osc_clk_logic",
+};
+
+static const char *const pad_sensor_vclk1_mux_parents[] = {
+ "dpu0_pll_foutpostdiv",
+ "dpu1_pll_foutpostdiv",
+ "dpu2_pll_foutpostdiv",
+ "aon_osc_clk_logic",
+};
+
+static const char *const vp_aclk_mux_parents[] = {
+ "video_pll_foutvco",
+ "audio0_pll_foutvco",
+};
+
+static const char *const g2d_cclk_mux_parents[] = {
+ "audio0_pll_foutvco",
+ "gmac_pll_foutvco",
+ "video_pll_foutvco",
+};
+
+static const char *const vdec_cclk_mux_parents[] = {
+ "audio0_pll_foutvco",
+ "video_pll_foutvco",
+ "gmac_pll_foutvco",
+ "audio1_pll_foutvco",
+};
+
+static const char *const venc_cclk_mux_parents[] = {
+ "gmac_pll_foutvco",
+ "video_pll_foutvco",
+ "audio0_pll_foutvco",
+ "audio1_pll_foutvco",
+};
+
+static const char *const npu_aclk_mux_parents[] = {
+ "gmac_pll_foutvco",
+ "video_pll_foutvco",
+ "audio0_pll_foutvco",
+ "audio1_pll_foutvco",
+};
+
+static const char *const npu_cclk_mux_parents[] = {
+ "gmac_pll_foutvco",
+ "video_pll_foutvco",
+ "audio0_pll_foutvco",
+ "audio1_pll_foutvco",
+};
+
+static const char *const c908_cpu_clk_parents[] = {
+ "c908_pll_foutvco",
+ "top_cpu_bak_pll0_clk",
+};
+
+static const char *const c920_cpu_clk_parents[] = {
+ "c920_pll_foutvco",
+ "top_cpu_bak_pll1_clk",
+};
+
+static const char *const tee_clk_mux_parents[] = {
+ "video_pll_foutvco",
+ "tee_pll_foutvco",
+};
+
+static const char *const isp_if_ref_mux_parents[] = {
+ "audio0_pll_foutvco",
+ "video_pll_foutvco",
+};
+
+static const char *const vi_preocc_mipi0_ifclk_mux_parents[] = {
+ "audio0_pll_foutvco",
+ "video_pll_foutvco",
+};
+
+static const char *const vi_preocc_mipi1_ifclk_mux_parents[] = {
+ "audio0_pll_foutvco",
+ "video_pll_foutvco",
+};
+
+static const char *const vo_mipi_pixclk_mux_parents[] = {
+ "dpu0_pixclk",
+ "dpu1_pixclk",
+ "dpu2_pixclk",
+};
+
+static const char *const vo_hdmi_pixclk_mux_parents[] = {
+ "dpu0_pixclk",
+ "dpu1_pixclk",
+ "dpu2_pixclk",
+};
+
+static const char *const vo_dptx_pixclk_mux_parents[] = {
+ "dpu0_pixclk",
+ "dpu1_pixclk",
+ "dpu2_pixclk",
+};
+
+static const struct a210_pll_rate a210_teepll_tbl[] = {
+ PLL_RATE(2400000000, 800000000U, 1, 100, 0, 3, 1),
+};
+
+static const struct a210_pll_rate a210_dpu2pll_tbl[] = {
+ PLL_RATE(2376000000, 1188000000U, 1, 99, 0, 2, 1),
+};
+
+static const struct a210_pll_rate a210_dpu1pll_tbl[] = {
+ PLL_RATE(2376000000, 1188000000U, 1, 99, 0, 2, 1),
+};
+
+static const struct a210_pll_rate a210_dpu0pll_tbl[] = {
+ PLL_RATE(2376000000, 1188000000U, 1, 99, 0, 2, 1),
+};
+
+static const struct a210_pll_rate a210_dvfspll_tbl[] = {
+ PLL_RATE(1920000000, 960000000U, 1, 80, 0, 2, 1),
+};
+
+static const struct a210_pll_rate a210_gmacpll_tbl[] = {
+ PLL_RATE(3000000000, 1000000000U, 1, 125, 0, 3, 1),
+};
+
+static const struct a210_pll_rate a210_videopll_tbl[] = {
+ PLL_RATE(2640000000U, 1320000000U, 1, 110, 0, 2, 1),
+};
+
+static const struct a210_pll_rate a210_audio0pll_tbl[] = {
+ PLL_RATE(2359296000U, 1179648000U, 1, 98, 5100274, 2, 1),
+};
+
+static const struct a210_pll_rate a210_audio1pll_tbl[] = {
+ PLL_RATE(2528870400U, 1264435200U, 1, 105, 6200859, 2, 1),
+};
+
+static const struct a210_pll_rate a210_c908pll_tbl[] = {
+ PLL_RATE(1200000000U, 1200000000U, 1, 50, 0, 1, 1),
+ PLL_RATE(1500000000U, 1500000000U, 2, 125, 0, 1, 1),
+ PLL_RATE(1698000000U, 1698000000U, 4, 283, 0, 1, 1),
+ PLL_RATE(1896000000U, 1896000000U, 1, 79, 0, 1, 1),
+};
+
+static const struct a210_pll_rate a210_c920pll_tbl[] = {
+ PLL_RATE(1500000000U, 1500000000U, 2, 125, 0, 1, 1),
+ PLL_RATE(1698000000U, 1698000000U, 4, 283, 0, 1, 1),
+ PLL_RATE(1896000000U, 1896000000U, 1, 79, 0, 1, 1),
+ PLL_RATE(2298000000U, 2298000000U, 4, 383, 0, 1, 1),
+};
+
+static const struct a210_pll_desc plls_top[] = {
+ PLL_PARAM(TEE_PLL, A210_PLL_VCO, a210_teepll_tbl, 0x160, 0x170, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, "tee_pll_foutvco_frequency"),
+ PLL_PARAM(DPU2_PLL, A210_PLL_VCO, a210_dpu2pll_tbl, 0x120, 0x130, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, "dpu2_pll_foutvco_frequency"),
+ PLL_PARAM(DPU1_PLL, A210_PLL_VCO, a210_dpu1pll_tbl, 0x100, 0x110, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, "dpu1_pll_foutvco_frequency"),
+ PLL_PARAM(DPU0_PLL, A210_PLL_VCO, a210_dpu0pll_tbl, 0x80, 0x90, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, "dpu0_pll_foutvco_frequency"),
+ PLL_PARAM(DVFS_PLL, A210_PLL_VCO, a210_dvfspll_tbl, 0x60, 0x70, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, "dvfs_pll_foutvco_frequency"),
+ PLL_PARAM(AUDIO0_PLL, A210_PLL_VCO, a210_audio0pll_tbl, 0x0, 0x10, BIT(0), BIT(31),
+ BIT(30), PLL_MODE_FRAC, "audio0_pll_foutvco_frequency"),
+ PLL_PARAM(AUDIO1_PLL, A210_PLL_VCO, a210_audio1pll_tbl, 0x20, 0x30, BIT(0), BIT(31),
+ BIT(30), PLL_MODE_FRAC, "audio1_pll_foutvco_frequency"),
+ PLL_PARAM(GMAC_PLL, A210_PLL_VCO, a210_gmacpll_tbl, 0x40, 0x50, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, "gmac_pll_foutvco_frequency"),
+ PLL_PARAM(VIDEO_PLL, A210_PLL_VCO, a210_videopll_tbl, 0x140, 0x150, BIT(0), BIT(31),
+ BIT(30), PLL_MODE_INT, "video_pll_foutvco_frequency"),
+ PLL_PARAM(C908_PLL, A210_PLL_VCO, a210_c908pll_tbl, 0x0, 0x10, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, ""),
+ PLL_PARAM(C920_PLL, A210_PLL_VCO, a210_c920pll_tbl, 0x40, 0x50, BIT(0), BIT(31), BIT(30),
+ PLL_MODE_INT, ""),
+};
+
+/* DDR PLL programming belongs to the firmware that trains the memory. */
+static const struct a210_pll_desc ddr_pll = {
+ .out_type = A210_PLL_VCO,
+ .cfg0_reg_off = 0x8,
+ .pll_bypass_bit = BIT(31),
+};
+
+static struct a210_clk_reg regs_top[] = {
+ REG_NAMED(PLL_WRAP, "pll-wrap"),
+ REG_NAMED(TOP_CRG, "top-crg"),
+ REG_NAMED(CPU_SS_CLK_SYSREG, "cpu-ss-clk-sysreg"),
+ REG_NAMED(CPU_SS_CPU_PLL, "cpu-ss-cpu-pll"),
+ REG_NAMED(DDR0_SYSREG, "ddr0-sysreg"),
+ REG_NAMED(DDR1_SYSREG, "ddr1-sysreg"),
+ REG_NAMED(SLC_DUAL_SYSREG, "slc-dual-sysreg"),
+ REG_NAMED(TOP_CRG_T, "top-crg-t"),
+ REG_NAMED(CPU_SS_CCU, "cpu-ss-ccu"),
+};
+
+static struct a210_clk_reg regs_gpu[] = {
+ REG_NAMED(GPU_SS_PWRAP_CLK_EN, "gpu-ss-pwrap-clk-en"),
+ REG_NAMED(GPU_SS_TOP_CLK_EN, "gpu-ss-top-clk-en"),
+};
+
+static struct a210_clk_reg regs_pcie[] = {
+ REG_NAMED(PCIE_CLK_EN, "pcie-clk-en"),
+};
+
+static struct a210_clk_reg regs_usb[] = {
+ REG_NAMED(USB_CLK_EN, "usb-clk-en"),
+};
+
+static struct a210_clk_reg regs_vi[] = {
+ REG_NAMED(VI_CLK, "vi-clk"),
+ REG_NAMED(VI_MISC_CTRL, "vi-misc-ctrl"),
+};
+
+static struct a210_clk_reg regs_vp[] = {
+ REG_NAMED(VP_CLK, "vp-clk"),
+};
+
+static struct a210_clk_reg regs_vo[] = {
+ REG_NAMED(VO_CLK, "vo-clk"),
+ REG_NAMED(VO_PATH_CTRL, "vo-path-ctrl"),
+};
+
+static struct a210_clk_reg regs_npu[] = {
+ REG_NAMED(NPU_CLK, "npu-clk"),
+ REG_NAMED(NPU_TOP_CLK, "npu-top-clk"),
+};
+
+static struct a210_clk_reg regs_peri[] = {
+ REG_NAMED(PERI0_SYSREG, "peri0-sysreg"),
+ REG_NAMED(PERI1_SYSREG, "peri1-sysreg"),
+ REG_NAMED(PERI2_SYSREG, "peri2-sysreg"),
+ REG_NAMED(PERI3_SYSREG, "peri3-sysreg"),
+ REG_NAMED(TEE_CRG, "tee-crg"),
+};
+
+static const struct a210_clk_desc info_top[] = {
+ /* Reference oscillator aliases. */
+ FIXED_FACTOR(AON_OSC_CLK_PHY, "aon_osc_clk_phy", "osc-24m", 1, 1),
+ FIXED_FACTOR(AON_OSC_CLK_LOGIC, "aon_osc_clk_logic", "osc-24m", 1, 1),
+ FIXED_FACTOR(TOP_PLL_REF_CLK, "top_pll_ref_clk", "osc-24m", 1, 1),
+ FIXED_FACTOR(PLL_OSC_CLK, "pll_osc_clk", "osc-24m", 1, 1),
+ FIXED_FACTOR(AON_RTC_CLK, "aon_rtc_clk", "osc-32k", 1, 1),
+ /* PLL */
+ PLL(AUDIO0_PLL_FOUTVCO, "audio0_pll_foutvco", "osc-24m", PLL_WRAP, 0,
+ &plls_top[AUDIO0_PLL]),
+ PLL_POSTDIV(AUDIO0_PLL_FOUTPOSTDIV, "audio0_pll_foutpostdiv",
+ "audio0_pll_foutvco", PLL_WRAP, &plls_top[AUDIO0_PLL]),
+ FIXED_FACTOR(AUDIO0_PLL_FOUT2, "audio0_pll_fout2", "audio0_pll_foutpostdiv", 1, 4),
+ PLL(AUDIO1_PLL_FOUTVCO, "audio1_pll_foutvco", "osc-24m", PLL_WRAP, 0,
+ &plls_top[AUDIO1_PLL]),
+ PLL_POSTDIV(AUDIO1_PLL_FOUTPOSTDIV, "audio1_pll_foutpostdiv",
+ "audio1_pll_foutvco", PLL_WRAP, &plls_top[AUDIO1_PLL]),
+ FIXED_FACTOR(AUDIO1_PLL_FOUT2, "audio1_pll_fout2", "audio1_pll_foutpostdiv", 1, 4),
+ PLL(C908_PLL_FOUTVCO, "c908_pll_foutvco", "osc-24m", CPU_SS_CPU_PLL, 0,
+ &plls_top[C908_PLL]),
+ PLL(C920_PLL_FOUTVCO, "c920_pll_foutvco", "osc-24m", CPU_SS_CPU_PLL, 0,
+ &plls_top[C920_PLL]),
+ PLL(VIDEO_PLL_FOUTVCO, "video_pll_foutvco", "top_pll_ref_clk", PLL_WRAP, 0,
+ &plls_top[VIDEO_PLL]),
+ PLL_POSTDIV(VIDEO_PLL_FOUTPOSTDIV, "video_pll_foutpostdiv",
+ "video_pll_foutvco", PLL_WRAP, &plls_top[VIDEO_PLL]),
+ FIXED_FACTOR(VIDEO_PLL_FOUT1PH0, "video_pll_fout1ph0", "video_pll_foutpostdiv", 1, 2),
+ FIXED_FACTOR(VIDEO_PLL_FOUT3, "video_pll_fout3", "video_pll_foutpostdiv", 1, 6),
+ PLL(GMAC_PLL_FOUTVCO, "gmac_pll_foutvco", "top_pll_ref_clk", PLL_WRAP, 0,
+ &plls_top[GMAC_PLL]),
+ PLL_POSTDIV(GMAC_PLL_FOUTPOSTDIV, "gmac_pll_foutpostdiv",
+ "gmac_pll_foutvco", PLL_WRAP, &plls_top[GMAC_PLL]),
+ FIXED_FACTOR(GMAC_PLL_FOUT1PH0, "gmac_pll_fout1ph0", "gmac_pll_foutpostdiv", 1, 2),
+ PLL(DVFS_PLL_FOUTVCO, "dvfs_pll_foutvco", "top_pll_ref_clk", PLL_WRAP, 0,
+ &plls_top[DVFS_PLL]),
+ PLL(DPU0_PLL_FOUTVCO, "dpu0_pll_foutvco", "top_pll_ref_clk", PLL_WRAP, 0,
+ &plls_top[DPU0_PLL]),
+ PLL_POSTDIV(DPU0_PLL_FOUTPOSTDIV, "dpu0_pll_foutpostdiv",
+ "dpu0_pll_foutvco", PLL_WRAP, &plls_top[DPU0_PLL]),
+ PLL(DPU1_PLL_FOUTVCO, "dpu1_pll_foutvco", "top_pll_ref_clk", PLL_WRAP, 0,
+ &plls_top[DPU1_PLL]),
+ PLL_POSTDIV(DPU1_PLL_FOUTPOSTDIV, "dpu1_pll_foutpostdiv",
+ "dpu1_pll_foutvco", PLL_WRAP, &plls_top[DPU1_PLL]),
+ PLL(DPU2_PLL_FOUTVCO, "dpu2_pll_foutvco", "top_pll_ref_clk", PLL_WRAP, 0,
+ &plls_top[DPU2_PLL]),
+ PLL_POSTDIV(DPU2_PLL_FOUTPOSTDIV, "dpu2_pll_foutpostdiv",
+ "dpu2_pll_foutvco", PLL_WRAP, &plls_top[DPU2_PLL]),
+ PLL(TEE_PLL_FOUTVCO, "tee_pll_foutvco", "top_pll_ref_clk", PLL_WRAP, 0, &plls_top[TEE_PLL]),
+ /* TOP SS */
+ DIV(TOP_CFG_ACLK_DIV, "top_cfg_aclk", "video_pll_fout1ph0", TOP_CRG, 0, 8, 8, NO_DIV_EN,
+ MUX_TYPE_DIV, 2, 255),
+ DIV(TOP_PCLK_DIV, "top_pclk", "video_pll_fout1ph0", TOP_CRG, 0, 0, 8, NO_DIV_EN,
+ MUX_TYPE_DIV, 4, 255),
+ DIV(AMUX_CLK_DIV, "top_amux_clk_div", "video_pll_foutvco", TOP_CRG, 0x18, 8, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 4, 15),
+ GATE_FLAGS(SW_TOP_OSC_CLK_LOGIC_EN, "top_osc_clk_logic", "aon_osc_clk_logic", TOP_CRG,
+ 0x200, 2, CLK_IS_CRITICAL),
+ GATE_FLAGS(SW_AMUX_660_CLK_EN, "top_amux_clk", "top_amux_clk_div", TOP_CRG, 0x200, 0,
+ CLK_IS_CRITICAL),
+ /* TOP SS - IOMMU_PTW_ACLK */
+ GATE(SW_IOMMU_PTW_330_ACLK_EN, "iommu_ptw_aclk", "iommu_ptw_aclk_div", TOP_CRG, 0x200, 1),
+ DIV(IOMMU_PTW_ACLK_DIV, "iommu_ptw_aclk_div", "video_pll_fout1ph0", TOP_CRG, 0, 24, 3,
+ NO_DIV_EN, MUX_TYPE_DIV, 2, 7),
+ /* TOP SS - CPU SS */
+ DIV(TOP_CPUSYS_BUS_CLK_DIV, "top_cpusys_bus_clk", "top_cpusys_bus_clk_mux", TOP_CRG, 0x8,
+ 20, 4, NO_DIV_EN, MUX_TYPE_DIV, 2, 15),
+ MUX(TOP_CPUSYS_BUS_CLK_MUX, "top_cpusys_bus_clk_mux", TOP_CRG, 0x8, 16, 2,
+ top_cpusys_bus_clk_mux_parents, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+ DIV(TOP_CPUSYS_PIC_CLK_DIV, "top_cpusys_pic_clk", "top_cpusys_pic_clk_mux", TOP_CRG, 0x4,
+ 20, 4, NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_CPUSYS_PIC_CLK_MUX, "top_cpusys_pic_clk_mux", TOP_CRG, 0x4, 3, 1,
+ top_cpusys_pic_clk_mux_parents, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+ MUX(TOP_CPU_BAK_PLL0_CLK_MUX, "top_cpu_bak_pll0_clk", TOP_CRG, 0x4, 0, 3,
+ top_cpu_bak_pll0_clk_mux_parents, CLK_SET_RATE_PARENT),
+ MUX(TOP_CPU_BAK_PLL0_CLK_MUX0, "top_cpu_bak_pll0_clk_mux0", TOP_CRG, 0x4, 16, 2,
+ top_cpu_bak_pll0_clk_mux0_parents, CLK_SET_RATE_PARENT),
+ DIV(TOP_CPU_BAK_PLL0_CLK_DIV0, "top_cpu_bak_pll0_clk_div0", "gmac_pll_foutvco", TOP_CRG,
+ 0x4, 12, 4, NO_DIV_EN, MUX_TYPE_DIV, 2, 15),
+ DIV(TOP_CPU_BAK_PLL0_CLK_DIV1, "top_cpu_bak_pll0_clk_div1", "gmac_pll_foutvco", TOP_CRG,
+ 0x4, 8, 4, NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ DIV(TOP_CPU_BAK_PLL0_CLK_DIV3, "top_cpu_bak_pll0_clk_div3", "audio1_pll_foutvco", TOP_CRG,
+ 0x4, 4, 4, NO_DIV_EN, MUX_TYPE_DIV, 2, 15),
+ DIV(TOP_CPU_BAK_PLL0_CLK_DIV4, "top_cpu_bak_pll0_clk_div4", "video_pll_foutvco", TOP_CRG,
+ 0x4, 24, 8, NO_DIV_EN, MUX_TYPE_DIV, 2, 255),
+ MUX(TOP_CPU_BAK_PLL1_CLK_MUX, "top_cpu_bak_pll1_clk", TOP_CRG, 0x8, 0, 3,
+ top_cpu_bak_pll1_clk_mux_parents, CLK_SET_RATE_PARENT),
+ MUX(TOP_CPU_BAK_PLL1_CLK_MUX0, "top_cpu_bak_pll1_clk_mux0", TOP_CRG, 0x8, 8, 2,
+ top_cpu_bak_pll1_clk_mux0_parents, CLK_SET_RATE_PARENT),
+ DIV(TOP_CPU_BAK_PLL1_CLK_DIV0, "top_cpu_bak_pll1_clk_div0", "gmac_pll_foutvco", TOP_CRG,
+ 0x8, 12, 4, NO_DIV_EN, MUX_TYPE_DIV, 2, 15),
+ DIV(TOP_CPU_BAK_PLL1_CLK_DIV1, "top_cpu_bak_pll1_clk_div1", "gmac_pll_foutvco", TOP_CRG,
+ 0x8, 24, 4, NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ DIV(TOP_CPU_BAK_PLL1_CLK_DIV3, "top_cpu_bak_pll1_clk_div3", "audio1_pll_foutvco", TOP_CRG,
+ 0x8, 4, 4, NO_DIV_EN, MUX_TYPE_DIV, 2, 15),
+ DIV(TOP_CPU_BAK_PLL1_CLK_DIV4, "top_cpu_bak_pll1_clk_div4", "video_pll_foutvco", TOP_CRG,
+ 0x44, 0, 8, NO_DIV_EN, MUX_TYPE_DIV, 2, 255),
+ DIV(TOP_CPUSYS_CFG_ACLK_DIV, "top_cpusys_sys_cfg_axi_clk", "video_pll_fout1ph0", CPU_SS_CCU,
+ 0x1c, 0, 16, NO_DIV_EN, MUX_TYPE_CDE, 1, 5),
+ DIV(TOP_CPUSYS_COM_APB_CLK_DIV, "top_cpusys_sys_com_apb_clk", "video_pll_fout1ph0",
+ CPU_SS_CCU, 0x21c, 0, 16, NO_DIV_EN, MUX_TYPE_CDE, 3, 7),
+ DIV(TOP_CPUSYS_APB_CLK_DIV, "top_cpusys_cpu_apb_clk", "video_pll_fout1ph0", CPU_SS_CCU,
+ 0x41c, 0, 16, NO_DIV_EN, MUX_TYPE_CDE, 3, 7),
+ /* TOP SS - NOC_CCLK */
+ GATE_FLAGS(SW_NOC_CCLK_EN, "noc_cclk", "noc_cclk_div", TOP_CRG, 0x200, 3, CLK_IS_CRITICAL),
+ DIV(NOC_CCLK_DIV, "noc_cclk_div", "noc_cclk_mux", TOP_CRG, 0, 20, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(NOC_CCLK_MUX, "noc_cclk_mux", TOP_CRG, 0, 16, 2, noc_cclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ /* TOP SS - DDR SS */
+ MUX(TOP_CPU_DDR1_ACLK_MUX, "top_ddr1_aclk", TOP_CRG, 0x4, 19, 1, top_cpu_ddr1_aclk_parents,
+ CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+ MUX(TOP_CPU_DDR0_ACLK_MUX, "top_ddr0_aclk", TOP_CRG, 0x4, 18, 1, top_cpu_ddr0_aclk_parents,
+ CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+ FIXED_FACTOR(DDR_CBUS2DDR_ACLK0, "cbus2ddr_aclk0", "ddr_pll_clk_en", 1, 1),
+ FIXED_FACTOR(DDR_CBUS2DDR_ACLK1, "cbus2ddr_aclk1", "ddr_pll_clk_en", 1, 1),
+ PLL(DDR_PLL_FOUTVCO, "ddr_pll_foutvco", "pll_osc_clk", SLC_DUAL_SYSREG, 0, &ddr_pll),
+ PLL_POSTDIV(DDR_PLL_FOUTPOSTDIV, "ddr_pll_foutpostdiv",
+ "ddr_pll_foutvco", SLC_DUAL_SYSREG, &ddr_pll),
+ FIXED_FACTOR(DDR_PLL_FOUT1PH0, "ddr_pll_fout1ph0", "ddr_pll_foutpostdiv", 1, 2),
+ FIXED_FACTOR(DDR_PLL_FOUT2, "ddr_pll_fout2", "ddr_pll_foutpostdiv", 1, 4),
+ FIXED_FACTOR(DDR_PLL_FOUT4, "ddr_pll_fout4", "ddr_pll_foutpostdiv", 1, 8),
+ /* TOP SS - D2D SS */
+ FIXED_FACTOR(D2D_PHY_REF_CLK_100M, "d2d_phy_ref_clk_100M", "gmac_pll_foutpostdiv", 1, 10),
+ MUX(TOP_D2D_REF_CLK_MUX, "d2d_phy_ref_clk", TOP_CRG, 0x14, 15, 1, d2d_phy_ref_clk_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_D2D_SCAN_CLK0_DIV, "d2d_phy_scan_clk0", "dpu1_pll_foutvco", TOP_CRG, 0x14, 12, 3,
+ NO_DIV_EN, MUX_TYPE_DIV, 3, 7),
+ DIV(TOP_D2D_SCAN_CLK1_DIV, "d2d_phy_scan_clk1", "dpu1_pll_foutvco", TOP_CRG, 0x14, 8, 4,
+ NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ FIXED_FACTOR(D2D_PHY_SCAN_CLK2, "d2d_phy_scan_clk2", "dpu2_pll_foutpostdiv", 1, 1),
+ DIV(TOP_D2D_ACLK_DIV, "top_d2d_aclk", "top_d2d_aclk_mux", TOP_CRG, 0x14, 4, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_D2D_ACLK_MUX, "top_d2d_aclk_mux", TOP_CRG, 0x14, 0, 2, top_d2d_aclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ /* TOP SS - GPU SS */
+ DIV(TOP_GPU_CORE_CLK_DIV, "top_gpu_core_clk", "top_gpu_core_clk_mux", TOP_CRG, 0x18, 4, 4,
+ NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_GPU_CORE_CLK_MUX, "top_gpu_core_clk_mux", TOP_CRG, 0x18, 0, 2,
+ top_gpu_core_clk_mux_parents, CLK_SET_RATE_PARENT),
+ /* TOP SS - PCIE SS */
+ DIV(TOP_PCIE_SCAN_REF_CLK0_DIV, "scan_ref_clk0", "dpu1_pll_foutvco", TOP_CRG, 0x1c, 8, 4,
+ NO_DIV_EN, MUX_TYPE_DIV, 6, 15),
+ DIV(TOP_PCIE_SCAN_REF_CLK1_DIV, "scan_ref_clk1", "gmac_pll_foutvco", TOP_CRG, 0x1c, 12, 4,
+ NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ DIV(TOP_PCIE_AXI_M_ACLK_DIV, "pcie_ss_axi_m_aclk", "pcie_ss_axi_m_aclk_mux", TOP_CRG, 0x1c,
+ 4, 4, NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_PCIE_AXI_M_ACLK_MUX, "pcie_ss_axi_m_aclk_mux", TOP_CRG, 0x1c, 0, 1,
+ pcie_ss_axi_m_aclk_mux_parents, CLK_SET_RATE_PARENT),
+ /* TOP SS - PERI SS */
+ DIV(TOP_PERI_SPI_SSI_CLK0_DIV, "peri1_spi_ssi_clk", "audio1_pll_foutvco", TOP_CRG, 0x20, 20,
+ 8, NO_DIV_EN, MUX_TYPE_DIV, 6, 255),
+ DIV(TOP_PERI_MST_ACLK0_DIV, "peri1_mst_aclk", "video_pll_fout1ph0", TOP_CRG, 0x20, 16, 3,
+ NO_DIV_EN, MUX_TYPE_DIV, 2, 7),
+ FIXED_FACTOR(TOP_PERI_TIMER_CLK_100M, "peri0_timer_clk_100M", "gmac_pll_foutpostdiv", 1,
+ 10),
+ MUX(TOP_PERI_TIMER_CLK_MUX, "peri0_timer_clk", TOP_CRG, 0x20, 15, 1,
+ peri0_timer_clk_parents, CLK_SET_RATE_PARENT),
+ MUX(TOP_PERI_I2S_8CH0_SRC_CLK_MUX, "peri2_i2s3_src_clk", TOP_CRG, 0x28, 21, 1,
+ peri2_i2s3_src_clk_parents, CLK_SET_RATE_PARENT),
+ MUX(TOP_PERI_I2S_2CH0_SRC_CLK_MUX, "peri1_i2s0_src_clk", TOP_CRG, 0x20, 13, 1,
+ peri1_i2s0_src_clk_parents, CLK_SET_RATE_PARENT),
+ MUX(TOP_PERI_I2S_2CH1_SRC_CLK_MUX, "peri2_i2s1_src_clk", TOP_CRG, 0x20, 14, 1,
+ peri2_i2s1_src_clk_parents, CLK_SET_RATE_PARENT),
+ MUX(TOP_PERI_I2S_2CH2_SRC_CLK_MUX, "peri2_i2s2_src_clk", TOP_CRG, 0x28, 23, 1,
+ peri2_i2s2_src_clk_parents, CLK_SET_RATE_PARENT),
+ DIV(TOP_PERI_QSPI0_SSI_CLK_DIV0, "peri1_qspi_ssi_clk_div0", "video_pll_foutvco", TOP_CRG,
+ 0x20, 8, 4, NO_DIV_EN, MUX_TYPE_DIV, 2, 15),
+ DIV(TOP_PERI_QSPI0_SSI_CLK_DIV1, "peri1_qspi_ssi_clk_div1", "audio1_pll_foutvco", TOP_CRG,
+ 0x20, 0, 8, NO_DIV_EN, MUX_TYPE_DIV, 6, 255),
+ MUX(TOP_PERI_QSPI_SSI_CLK_MUX0, "peri1_qspi_ssi_clk", TOP_CRG, 0x20, 12, 1,
+ peri1_qspi_ssi_clk_parents, CLK_SET_RATE_PARENT),
+ DIV(TOP_PERI_SPI_SSI_CLK1_DIV, "peri2_spi_ssi_clk", "audio1_pll_foutvco", TOP_CRG, 0x24, 24,
+ 8, NO_DIV_EN, MUX_TYPE_DIV, 6, 255),
+ DIV(TOP_PERI_HIRES_CLK0_DIV, "peri1_hires_clk", "video_pll_foutvco", TOP_CRG, 0x24, 16, 6,
+ NO_DIV_EN, MUX_TYPE_DIV, 33, 63),
+ DIV(TOP_PERI_HIRES_CLK1_DIV, "peri2_hires_clk", "video_pll_foutvco", TOP_CRG, 0x24, 0, 6,
+ NO_DIV_EN, MUX_TYPE_DIV, 33, 63),
+ MUX(TOP_PERI_TDM_SRC_CLK_MUX, "peri1_tdm_src_clk", TOP_CRG, 0x28, 25, 1,
+ peri1_tdm_src_clk_parents, CLK_SET_RATE_PARENT),
+ FIXED_FACTOR(UART_SCLK_100M, "uart_sclk_100m", "gmac_pll_foutpostdiv", 1, 10),
+ MUX(TOP_UART_SCLK_MUX, "uart_sclk", TOP_CRG, 0x28, 24, 1, uart_sclk_parents, 0),
+ FIXED_FACTOR(PERI1_UART_SCLK, "peri1_uart_sclk", "uart_sclk", 1, 1),
+ FIXED_FACTOR(PERI2_UART_SCLK, "peri2_uart_sclk", "uart_sclk", 1, 1),
+ DIV(TOP_PERI_PDM_MCLK_DIV, "peri1_pdm_mclk", "pdm_clk_mux", TOP_CRG, 0x2c, 24, 8, NO_DIV_EN,
+ MUX_TYPE_DIV, 10, 255),
+ MUX(TOP_PERI_PDM_MCLK_MUX, "pdm_clk_mux", TOP_CRG, 0x28, 22, 1, pdm_clk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_PERI_QSPI1_SSI_CLK_DIV0, "peri2_qspi_ssi_clk_div0", "video_pll_foutvco", TOP_CRG,
+ 0x28, 16, 4, NO_DIV_EN, MUX_TYPE_DIV, 2, 15),
+ DIV(TOP_PERI_QSPI1_SSI_CLK_DIV1, "peri2_qspi_ssi_clk_div1", "audio1_pll_foutvco", TOP_CRG,
+ 0x28, 8, 8, NO_DIV_EN, MUX_TYPE_DIV, 6, 255),
+ MUX(TOP_PERI_QSPI_SSI_CLK_MUX1, "peri2_qspi_ssi_clk", TOP_CRG, 0x28, 20, 1,
+ peri2_qspi_ssi_clk_parents, CLK_SET_RATE_PARENT),
+ DIV(TOP_PERI_MST_CLK1_DIV, "peri3_mst_aclk", "video_pll_foutvco", TOP_CRG, 0x28, 4, 4,
+ NO_DIV_EN, MUX_TYPE_DIV, 6, 15),
+ DIV(TOP_PERI_EMMC_REF_CLK_DIV, "emmc_ref_clk", "emmc_ref_clk_mux", TOP_CRG, 0x28, 0, 4,
+ NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_PERI_EMMC_REF_CLK_MUX, "emmc_ref_clk_mux", TOP_CRG, 0x2c, 20, 1,
+ emmc_ref_clk_mux_parents, CLK_SET_RATE_PARENT),
+ FIXED_FACTOR(PERI1_PWM_CLK, "peri1_pwm_clk", "gmac_pll_fout1ph0", 1, 10),
+ FIXED_FACTOR(PERI2_PWM_CLK, "peri2_pwm_clk", "gmac_pll_fout1ph0", 1, 10),
+ FIXED_FACTOR(I2C_IC_CLK, "i2c_ic_clk", "gmac_pll_foutpostdiv", 1, 10),
+ MUX(TOP_PAD_SENSOR_VCLK_MUX0, "pad_sensor_vclk0_mux", TOP_CRG, 0x2c, 16, 2,
+ pad_sensor_vclk0_mux_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
+ DIV(TOP_PAD_SENSOR_VCLK0_DIV, "top_pad_sensor_vclk0_div", "pad_sensor_vclk0_mux", TOP_CRG,
+ 0x2c, 0, 8, NO_DIV_EN, MUX_TYPE_DIV, 16, 255),
+ MUX(TOP_PAD_SENSOR_VCLK_MUX1, "pad_sensor_vclk1_mux", TOP_CRG, 0x2c, 18, 2,
+ pad_sensor_vclk1_mux_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
+ DIV(TOP_PAD_SENSOR_VCLK1_DIV, "top_pad_sensor_vclk1_div", "pad_sensor_vclk1_mux", TOP_CRG,
+ 0x2c, 8, 8, NO_DIV_EN, MUX_TYPE_DIV, 16, 255),
+ MUX(TOP_TEE_CLK_MUX, "tee_clk_mux", TOP_CRG, 0x30, 0, 1, tee_clk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV_CLOSEST(TOP_TEE_CLK_DIV, "tee_clk", "tee_clk_mux", TOP_CRG, 0x30, 4, 8, NO_DIV_EN,
+ MUX_TYPE_DIV, 7, 255),
+ DIV(TOP_USB_BUS_ACLK_DIV, "clkgen_usb_ss_bus_clk", "video_pll_fout1ph0", TOP_CRG, 0x34, 8,
+ 3, NO_DIV_EN, MUX_TYPE_DIV, 2, 7),
+ DIV(TOP_USB_DP_AUX_CLK_DIV, "clkgen_usb_ss_aux_clk", "video_pll_foutvco", TOP_CRG, 0x34, 0,
+ 8, NO_DIV_EN, MUX_TYPE_DIV, 165, 255),
+ DIV(TOP_VP_ACLK_DIV, "vp_aclk", "vp_aclk_mux", TOP_CRG, 0x38, 24, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_VP_ACLK_MUX, "vp_aclk_mux", TOP_CRG, 0x38, 28, 1, vp_aclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_VP_G2D_CCLK_DIV, "g2d_cclk", "g2d_cclk_mux", TOP_CRG, 0x38, 20, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_VP_G2D_CCLK_MUX, "g2d_cclk_mux", TOP_CRG, 0x38, 16, 2, g2d_cclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_VP_VDEC_CCLK_DIV, "vdec_cclk", "vdec_cclk_mux", TOP_CRG, 0x38, 12, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_VP_VDEC_CCLK_MUX, "vdec_cclk_mux", TOP_CRG, 0x38, 8, 2, vdec_cclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_VP_VENC_CCLK_DIV, "venc_cclk", "venc_cclk_mux", TOP_CRG, 0x38, 4, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 5, 15),
+ MUX(TOP_VP_VENC_CCLK_MUX, "venc_cclk_mux", TOP_CRG, 0x38, 0, 2, venc_cclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_NPU_ACLK_DIV, "npu_aclk", "npu_aclk_mux", TOP_CRG, 0x3c, 12, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_NPU_ACLK_MUX, "npu_aclk_mux", TOP_CRG, 0x3c, 8, 2, npu_aclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_NPU_CCLK_DIV, "npu_cclk", "npu_cclk_mux", TOP_CRG, 0x3c, 4, 4, NO_DIV_EN,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(TOP_NPU_CCLK_MUX, "npu_cclk_mux", TOP_CRG, 0x3c, 0, 2, npu_cclk_mux_parents,
+ CLK_SET_RATE_PARENT),
+ DIV(TOP_USB_USB20_SCAN_REF_CLK_DIV, "clkgen_usb20phy_scan_ref_clk", "dpu1_pll_foutvco",
+ TOP_CRG, 0x40, 16, 4, NO_DIV_EN, MUX_TYPE_DIV, 5, 15),
+ DIV(TOP_USB_SCAN_REF_CLK3_DIV, "clkgen_c10phy_scan_ref_clk3", "dpu1_pll_foutvco", TOP_CRG,
+ 0x40, 12, 4, NO_DIV_EN, MUX_TYPE_DIV, 3, 15),
+ DIV(TOP_USB_SCAN_REF_CLK2_DIV, "clkgen_c10phy_scan_ref_clk2", "gmac_pll_foutvco", TOP_CRG,
+ 0x40, 8, 4, NO_DIV_EN, MUX_TYPE_DIV, 5, 15),
+ DIV(TOP_USB_SCAN_REF_CLK1_DIV, "clkgen_c10phy_scan_ref_clk1", "gmac_pll_foutvco", TOP_CRG,
+ 0x40, 4, 4, NO_DIV_EN, MUX_TYPE_DIV, 6, 15),
+ DIV(TOP_USB_SCAN_REF_CLK0_DIV, "clkgen_c10phy_scan_ref_clk0", "dpu1_pll_foutvco", TOP_CRG,
+ 0x40, 0, 4, NO_DIV_EN, MUX_TYPE_DIV, 6, 15),
+ GATE(SW_TOP_PAD_SENSOR_VCLK0_EN, "top_pad_sensor_vclk0", "top_pad_sensor_vclk0_div",
+ TOP_CRG, 0x200, 4),
+ GATE(SW_TOP_PAD_SENSOR_VCLK1_EN, "top_pad_sensor_vclk1", "top_pad_sensor_vclk1_div",
+ TOP_CRG, 0x200, 5),
+ /* CPU SS */
+ MUX(C908_CPU_TO_CDE_CLK_MUX, "c908_cpu_clk", CPU_SS_CLK_SYSREG, 0x0, 0, 1,
+ c908_cpu_clk_parents, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+ MUX(C920_CPU_TO_CDE_CLK_MUX, "c920_cpu_clk", CPU_SS_CLK_SYSREG, 0x4, 0, 1,
+ c920_cpu_clk_parents, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
+ /* DDR SS */
+ GATE_FLAGS(DDR0_PHY_DFICLK_EN, "ddr0_phy_dficlk", "ddr_pll_foutpostdiv", DDR0_SYSREG, 0x8,
+ 3, CLK_IS_CRITICAL),
+ GATE_FLAGS(DDR0_DDRC_ACLK_EN, "ddr0_aclk", "ddr_pll_foutpostdiv", DDR0_SYSREG, 0x8, 2,
+ CLK_IS_CRITICAL),
+ GATE_FLAGS(DDR0_DDRC_CCLK_EN, "ddr0_cclk", "ddr_pll_foutpostdiv", DDR0_SYSREG, 0x8, 1,
+ CLK_IS_CRITICAL),
+ GATE(DDR0_SBR_CLK_EN, "ddr0_sbr_clk", "ddr_pll_foutpostdiv", DDR0_SYSREG, 0x8, 0),
+ GATE_FLAGS(DDR1_PHY_DFICLK_EN, "ddr1_phy_dficlk", "ddr_pll_foutpostdiv", DDR1_SYSREG, 0x8,
+ 3, CLK_IS_CRITICAL),
+ GATE_FLAGS(DDR1_DDRC_ACLK_EN, "ddr1_aclk", "ddr_pll_foutpostdiv", DDR1_SYSREG, 0x8, 2,
+ CLK_IS_CRITICAL),
+ GATE_FLAGS(DDR1_DDRC_CCLK_EN, "ddr1_cclk", "ddr_pll_foutpostdiv", DDR1_SYSREG, 0x8, 1,
+ CLK_IS_CRITICAL),
+ GATE(DDR1_SBR_CLK_EN, "ddr1_sbr_clk", "ddr_pll_foutpostdiv", DDR1_SYSREG, 0x8, 0),
+ GATE_SHARED(DDR_PLL_CLK_EN, "ddr_pll_clk_en", "ddr_pll_clkout", SLC_DUAL_SYSREG, 0x18, 16,
+ &share_cnt_ddr_pll_clk_en, CLK_IS_CRITICAL),
+ MUX(DDR_PLL_CLK_SEL, "ddr_pll_clkout", SLC_DUAL_SYSREG, 0x18, 17, 2, ddr_pll_clkout_parents,
+ CLK_SET_RATE_PARENT),
+};
+
+static const struct a210_clk_desc info_gpu[] = {
+ FIXED_FACTOR(GPU_TOP_SYS_CLK, "gpu_top_sys_clk", "top_cfg_aclk", 1, 1),
+ FIXED_FACTOR(GPU_PCLK_CDT, "gpu_pclk_cdt", "gpu_top_sys_clk", 1, 2),
+ GATE(SW_PWR_WRAP_DFMU_PCLK_EN, "gpu_top_pclk", "gpu_pclk_cdt", GPU_SS_PWRAP_CLK_EN, 0, 7),
+ GATE(SW_PWR_WRAP_GPU_SYS_CLK_EN, "gpu_top_aclk", "gpu_top_sys_clk", GPU_SS_PWRAP_CLK_EN, 0,
+ 3),
+ GATE(SW_PWR_WRAP_DFMU_CORE_CLK_EN, "gpu_dfmu_core_clk", "top_cfg_aclk", GPU_SS_PWRAP_CLK_EN,
+ 0, 1),
+ GATE(SW_PWR_WRAP_GPU_CORE_CLK_EN, "gpu_core_clk", "top_gpu_core_clk", GPU_SS_PWRAP_CLK_EN,
+ 0, 0),
+};
+
+static const struct a210_clk_desc info_pcie[] = {
+ FIXED_FACTOR(PCIE_SS_APB_CLK, "pcie_ss_apb_clk", "gmac_pll_foutpostdiv", 1, 10),
+ GATE(E16PHY_PCLK_EN, "e16phy_apbs_pclk", "pcie_ss_apb_clk", PCIE_CLK_EN, 0x8, 0),
+ GATE(SATA_MST_AFENCE_ACLK_EN, "sata_mst_afence_aclk", "pcie_ss_axi_m_aclk", PCIE_CLK_EN,
+ 0x10, 20),
+ GATE(SATA_SLV_AFENCE_ACLK_EN, "sata_slv_afence_aclk", "top_cfg_aclk", PCIE_CLK_EN, 0x10,
+ 16),
+ GATE(X2X_SATA_SLV_ACLK_EN, "x2x_sata_slv_aclk", "pcie_ss_axi_m_aclk", PCIE_CLK_EN, 0x10, 4),
+ GATE(X2X_SATA_MST_ACLK_EN, "x2x_sata_mst_aclk", "top_cfg_aclk", PCIE_CLK_EN, 0x10, 0),
+ GATE(SATA_PMALIVE_CLK_EN, "sata_pmalive_clk", "aon_osc_clk_logic", PCIE_CLK_EN, 0x14, 0),
+ GATE(SATA_RXOOB0_CLK_EN, "sata_rxoob0_clk", "pcie_ss_apb_clk", PCIE_CLK_EN, 0x14, 16),
+ GATE(SATA_RXOOB1_CLK_EN, "sata_rxoob1_clk", "pcie_ss_apb_clk", PCIE_CLK_EN, 0x14, 20),
+ GATE(SATA_GEN3X2_ACLK_EN, "sata_gen3x2_aclk", "pcie_ss_axi_m_aclk", PCIE_CLK_EN, 0x10, 8),
+ GATE(PCIE_DM_GEN3X4_AUX_CLK_EN, "pcie_dm_gen3x4_aux_clk", "aon_osc_clk_logic", PCIE_CLK_EN,
+ 0x20, 12),
+ GATE(PCIE_DM_GEN3X4_SLV_ACLK_EN, "pcie_dm_gen3x4_slv_aclk", "top_cfg_aclk", PCIE_CLK_EN,
+ 0x20, 0),
+ GATE(PCIE_DM_GEN3X4_MST_ACLK_EN, "pcie_dm_gen3x4_mst_aclk", "pcie_ss_axi_m_aclk",
+ PCIE_CLK_EN, 0x20, 8),
+ GATE(PCIE_DM_GEN3X4_PCLK_EN, "pcie_dm_gen3x4_pclk", "pcie_ss_apb_clk", PCIE_CLK_EN, 0x20,
+ 4),
+ GATE(PCIE_RP_GEN3X1_AUX_CLK_EN, "pcie_rp_gen3x1_aux_clk", "aon_osc_clk_logic", PCIE_CLK_EN,
+ 0x24, 12),
+ GATE(PCIE_RP_GEN3X1_SLV_ACLK_EN, "pcie_rp_gen3x1_slv_aclk", "top_cfg_aclk", PCIE_CLK_EN,
+ 0x24, 0),
+ GATE(PCIE_RP_GEN3X1_MST_ACLK_EN, "pcie_rp_gen3x1_mst_aclk", "pcie_ss_axi_m_aclk",
+ PCIE_CLK_EN, 0x24, 8),
+ GATE(PCIE_RP_GEN3X1_PCLK_EN, "pcie_rp_gen3x1_pclk", "pcie_ss_apb_clk", PCIE_CLK_EN, 0x24,
+ 4),
+};
+
+static const struct a210_clk_desc info_usb[] = {
+ GATE(USB_SS_AXI_MST_PCLK_EN, "usb_axi_mst_pclk", "usb_ss_gtc_clk", USB_CLK_EN, 0, 16),
+ GATE(USB_SS_AXI_MST_ACLK_EN, "usb_axi_mst_aclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0,
+ 12),
+ GATE(USB_SS_DFMU_IOMMU_PTW_ACLK_EN, "usb_dfmu_ptw_aclk", "clkgen_usb_ss_bus_clk",
+ USB_CLK_EN, 0, 8),
+ GATE(USB_SS_DFMU_ACLK_EN, "usb_dfmu_aclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0, 4),
+ GATE(USB_SS_DFMU_PCLK_EN, "usb_dfmu_pclk", "usb_ss_gtc_clk", USB_CLK_EN, 0, 0),
+ GATE(DPTX_I2S_CLK_EN, "usb_dptx_i2s_clk", "audio0_pll_foutvco", USB_CLK_EN, 0x4, 16),
+ GATE(DPTX_IPI_CLK_EN, "usb_dptx_ipi_clk", "usb_ss_gtc_clk", USB_CLK_EN, 0x4, 12),
+ GATE(DPTX_AUX_CLK_EN, "usb_dptx_aux_clk", "clkgen_usb_ss_aux_clk", USB_CLK_EN, 0x4, 8),
+ FIXED_FACTOR(USB_SS_GTC_CLK, "usb_ss_gtc_clk", "gmac_pll_foutpostdiv", 1, 10),
+ GATE(DPTX_GTC_CLK_EN, "usb_dptx_gtc_clk", "usb_ss_gtc_clk", USB_CLK_EN, 0x4, 4),
+ GATE(DPTX_PCLK_EN, "usb_dptx_pclk", "usb_ss_gtc_clk", USB_CLK_EN, 0x4, 0),
+ GATE(USB31_REF_CLK_EN, "usb31_ref_clk", "aon_osc_clk_logic", USB_CLK_EN, 0x8, 16),
+ GATE(USB31_SLV_AFENCE_ACLK_EN, "usb31_slv_afence_aclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN,
+ 0x8, 20),
+ FIXED_FACTOR(USB_SS_PAD_OSC_CLK_1M, "usb_ss_pad_osc_clk_1m", "aon_osc_clk_logic", 1, 24),
+ GATE(USB31_SUSPEND_CLK_EN, "usb31_suspend_clk", "usb_ss_pad_osc_clk_1m", USB_CLK_EN, 0x8,
+ 8),
+ GATE(USB31_BUS_CLK_EN, "usb31_bus_clk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x8, 4),
+ GATE(USB31_PCLK_EN, "usb31_pclk", "usb_ss_gtc_clk", USB_CLK_EN, 0x8, 0),
+ GATE(C10PHY_SUSPEND_CLK_EN, "usb_c10phy_suspend_clk", "usb_ss_pad_osc_clk_1m", USB_CLK_EN,
+ 0xc, 4),
+ GATE(C10PHY_PCLK_EN, "usb_c10phy_pclk", "usb_ss_gtc_clk", USB_CLK_EN, 0xc, 0),
+ FIXED_FACTOR(USB20_CORE_CLK, "usb20_core_clk", "aon_osc_clk_logic", 1, 1),
+ GATE(USB_SS_PERI2_CFG_ACLK_EN, "usb_peri2_cfg_aclk", "aon_osc_clk_logic", USB_CLK_EN, 0x20,
+ 4),
+ GATE(USB20_BUS_CLK, "usb20_bus_clk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x10, 24),
+ GATE(USB20_X2H_HCLK, "usb20_x2h_hclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x10, 0),
+ GATE(USB20_X2H_ACLK, "usb20_x2h_aclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x10, 4),
+ GATE(USB20_SLV_AFENCE_ACLK, "usb20_slv_afence_aclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN,
+ 0x10, 8),
+ GATE(USB20_H2P_HCLK, "usb20_h2p_hclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x10, 16),
+ GATE(USB20_AHB_SLV_HCLK, "usb20_ahb_slv_hclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x10,
+ 20),
+ GATE(USB20_SYSREG_PCLK, "usb20_sysreg_pclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x10, 28),
+ GATE(USB20_WRAP0_HCLK, "usb20_wrap0_hclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x14, 0),
+ GATE(USB20_WRAP1_HCLK, "usb20_wrap1_hclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x14, 4),
+ GATE(USB20_A2X0_HCLK, "usb20_a2x0_hclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x14, 16),
+ GATE(USB20_A2X0_ACLK, "usb20_a2x0_aclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x14, 20),
+ GATE(USB20_A2X1_HCLK, "usb20_a2x1_hclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x14, 24),
+ GATE(USB20_A2X1_ACLK, "usb20_a2x1_aclk", "clkgen_usb_ss_bus_clk", USB_CLK_EN, 0x14, 28),
+
+};
+
+static const struct a210_clk_desc info_vi[] = {
+ GATE(VI_VSE_CLK_EN, "dw200_vseclk", "vi_pre_vse_clk_div", VI_CLK, 0, 29),
+ GATE(VI_VSEOUT_CLK_EN, "dw200_vseout_clk", "vi_pre_vse_clk_div", VI_CLK, 0, 22),
+ DIV(VI_PRE_VSE_CLK_DIV_NUM, "vi_pre_vse_clk_div", "gmac_pll_foutpostdiv", VI_CLK, 0xc, 4, 4,
+ 25, MUX_TYPE_DIV, 1, 15),
+ GATE(VI_DWE_CLK_EN, "dw200_dweclk", "vi_pre_dwe_clk_div", VI_CLK, 0, 28),
+ GATE(VI_DW_SCLK_EN, "dw_sclk", "vi_pre_dwe_clk_div", VI_CLK, 0, 30),
+ DIV(VI_PRE_DWE_CLK_DIV_NUM, "vi_pre_dwe_clk_div", "video_pll_foutvco", VI_CLK, 0xc, 8, 4,
+ 26, MUX_TYPE_DIV, 3, 15),
+ DIV(VI_PRE_AXI_CLK_DIV_NUM, "vi_preocc_aclk", "video_pll_foutvco", VI_CLK, 0xc, 0, 4, 24,
+ MUX_TYPE_DIV, 3, 15),
+ GATE(VI_DW200_ACLK_EN, "dw200_aclk", "vi_preocc_aclk", VI_CLK, 0, 27),
+ GATE(VI_DW200_HCLK_EN, "dw200_hclk", "top_cfg_aclk", VI_CLK, 0, 26),
+ DIV(VI_PRE_DECOMP_CLK_DIV_NUM, "vi_pre_decomp_clk", "audio0_pll_foutvco", VI_CLK, 0xc, 20,
+ 4, 29, MUX_TYPE_DIV, 4, 15),
+ GATE(VI_DECOMP_CLK_EN, "decomp_clk", "vi_pre_decomp_clk", VI_CLK, 0, 25),
+ GATE(VI_DECOUT_CLK_EN, "decout_clk", "vi_pre_decomp_clk", VI_CLK, 0, 21),
+ DIV(VI_PRE_COMP_CLK_DIV_NUM, "vi_pre_comp_clk", "audio0_pll_foutvco", VI_CLK, 0xc, 16, 4,
+ 28, MUX_TYPE_DIV, 4, 15),
+ GATE(VI_COMP0_CLK_EN, "comp0_clk", "vi_pre_comp_clk", VI_CLK, 0, 23),
+ GATE(VI_COMP1_CLK_EN, "comp1_clk", "vi_pre_comp_clk", VI_CLK, 0, 24),
+ GATE(VI_COMP_ACLK_EN, "comp_aclk", "vi_preocc_aclk", VI_CLK, 0, 19),
+ GATE(VI_COMP_PCLK_EN, "comp_pclk", "vi_pclk", VI_CLK, 0, 18),
+ GATE(VI_MIPI0CSI0_PCLK_EN, "mipi0_csi0_pclk", "vi_pclk", VI_CLK, 0, 0),
+ GATE(VI_MIPI0CSI1_PCLK_EN, "mipi0_csi1_pclk", "vi_pclk", VI_CLK, 0, 1),
+ GATE(VI_MIPI1CSI0_PCLK_EN, "mipi1_csi0_pclk", "vi_pclk", VI_CLK, 0, 6),
+ GATE(VI_MIPI1CSI1_PCLK_EN, "mipi1_csi1_pclk", "vi_pclk", VI_CLK, 0, 7),
+ GATE(VI_VIPRE_PCLK_EN, "vipre_pclk", "vi_pclk", VI_CLK, 0, 12),
+ GATE(VI_MIPI0CSI0_FPCLK_EN, "mipi0_csi0_fpclk", "vi_pclk", VI_CLK, 0x4, 8),
+ GATE(VI_MIPI0CSI1_FPCLK_EN, "mipi0_csi1_fpclk", "vi_pclk", VI_CLK, 0x4, 9),
+ GATE(VI_MIPI1CSI0_FPCLK_EN, "mipi1_csi0_fpclk", "vi_pclk", VI_CLK, 0x4, 10),
+ GATE(VI_MIPI1CSI1_FPCLK_EN, "mipi1_csi1_fpclk", "vi_pclk", VI_CLK, 0x4, 11),
+ FIXED_FACTOR(VI_PCLK, "vi_pclk", "top_cfg_aclk", 1, 2),
+ MUX(VI_ISP_IF_REF_SWITCH_SEL, "isp_if_ref_mux", VI_CLK, 0x8, 22, 2, isp_if_ref_mux_parents,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
+ GATE(VI_VIPRE_SCLK_EN, "vipre_sclk", "isp_if_ref_clk_div", VI_CLK, 0, 15),
+ DIV_CLOSEST(VI_PRE_ISP_IF_CLK_DIV_NUM, "isp_if_ref_clk_div", "isp_if_ref_mux", VI_CLK, 0x8,
+ 11, 4, 26, MUX_TYPE_DIV, 3, 15),
+ GATE(VI_ISP_CLK_EN, "isp_entire_clk", "video_pll_foutvco", VI_CLK, 0, 17),
+ DIV(VI_PRE_ISP_CORE_CLK_DIV_NUM, "isp_core_clk", "video_pll_foutvco", VI_CLK, 0x8, 16, 4,
+ 27, MUX_TYPE_DIV, 4, 15),
+ GATE(VI_ISPOUT_CLK_EN, "ispout_clk", "isp_core_clk", VI_CLK, 0, 20),
+ GATE(VI_VIPRE_ACLK_EN, "vipre_aclk", "vi_preocc_aclk", VI_CLK, 0, 16),
+ GATE(VI_VIPRE_I0_PIXCLK_EN, "vipre_m0if_clk", "vi_preocc_mipi0_ifclk", VI_CLK, 0, 13),
+ GATE(VI_MIPI0_CSI0_PIXCLK_EN, "mipi0_csi0if_clk", "vi_preocc_mipi0_ifclk", VI_CLK, 0, 4),
+ GATE(VI_MIPI0_CSI1_PIXCLK_EN, "mipi0_csi1if_clk", "vi_preocc_mipi0_ifclk", VI_CLK, 0, 5),
+ DIV_CLOSEST(VI_PRE_MIPI0_PIXCLK_DIV_NUM, "vi_preocc_mipi0_ifclk",
+ "vi_preocc_mipi0_ifclk_mux", VI_CLK, 0x8, 0, 4, 24, MUX_TYPE_DIV, 3, 15),
+ MUX(VI_MIPI0_PIX_REF_SWITCH_SEL, "vi_preocc_mipi0_ifclk_mux", VI_CLK, 0x8, 20, 1,
+ vi_preocc_mipi0_ifclk_mux_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
+ GATE(VI_VIPRE_I1_PIXCLK_EN, "vipre_m1if_clk", "vi_preocc_mipi1_ifclk", VI_CLK, 0, 14),
+ GATE(VI_MIPI1_CSI0_PIXCLK_EN, "mipi1_csi0if_clk", "vi_preocc_mipi1_ifclk", VI_CLK, 0, 10),
+ GATE(VI_MIPI1_CSI1_PIXCLK_EN, "mipi1_csi1if_clk", "vi_preocc_mipi1_ifclk", VI_CLK, 0, 11),
+ DIV_CLOSEST(VI_PRE_MIPI1_PIXCLK_DIV_NUM, "vi_preocc_mipi1_ifclk",
+ "vi_preocc_mipi1_ifclk_mux", VI_CLK, 0x8, 4, 4, 25, MUX_TYPE_DIV, 3, 15),
+ MUX(VI_MIPI1_PIX_REF_SWITCH_SEL, "vi_preocc_mipi1_ifclk_mux", VI_CLK, 0x8, 21, 1,
+ vi_preocc_mipi1_ifclk_mux_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT),
+ GATE(VI_MIPI1B_CFGCLK_EN, "mipi1_csi0_cfgclk", "aon_osc_clk_logic", VI_CLK, 0, 9),
+ GATE(VI_MIPI1A_CFGCLK_EN, "mipi1_csi1_cfgclk", "aon_osc_clk_logic", VI_CLK, 0, 8),
+ GATE(VI_MIPI0B_CFGCLK_EN, "mipi0_csi0_cfgclk", "aon_osc_clk_logic", VI_CLK, 0, 3),
+ GATE(VI_MIPI0A_CFGCLK_EN, "mipi0_csi1_cfgclk", "aon_osc_clk_logic", VI_CLK, 0, 2),
+ GATE(VI_X2H0_CLK_EN, "vi_x2h0_clk", "top_cfg_aclk", VI_CLK, 0x4, 5),
+ GATE(VI_X2H1_CLK_EN, "vi_x2h1_clk", "top_cfg_aclk", VI_CLK, 0x4, 6),
+ GATE(VI_X2H2_CLK_EN, "vi_x2h2_clk", "top_cfg_aclk", VI_CLK, 0x4, 7),
+ GATE(VI_REC_PCLK_EN, "vi_rec_pclk", "top_cfg_aclk", VI_CLK, 0x4, 13),
+ GATE(VI_REC_ACLK_EN, "vi_rec_aclk", "top_cfg_aclk", VI_CLK, 0x4, 14),
+ GATE(VI_MISC_CTRL_H0CLK_CLK_EN, "vi_misc_ctrl_h0clk", "top_cfg_aclk", VI_MISC_CTRL, 0x0, 1),
+ GATE(VI_MISC_CTRL_H1CLK_CLK_EN, "vi_misc_ctrl_h1clk", "top_cfg_aclk", VI_MISC_CTRL, 0x0, 2),
+ GATE(VI_MISC_CTRL_ISP_ACLK_CLK_EN, "vi_misc_ctrl_isp_aclk", "top_cfg_aclk", VI_MISC_CTRL,
+ 0x0, 3),
+ GATE(VI_MISC_CTRL_ISP_SCLK_CLK0_EN, "vi_misc_ctrl_isp_sclk0", "top_cfg_aclk", VI_MISC_CTRL,
+ 0x0, 4),
+ GATE(VI_MISC_CTRL_ISP_SCLK_CLK1_EN, "vi_misc_ctrl_isp_sclk1", "top_cfg_aclk", VI_MISC_CTRL,
+ 0x0, 5),
+ GATE(VI_MISC_CTRL_ISP_SCLK_CLK2_EN, "vi_misc_ctrl_isp_sclk2", "top_cfg_aclk", VI_MISC_CTRL,
+ 0x0, 6),
+ GATE(VI_MISC_CTRL_ISP_SCLK_CLK3_EN, "vi_misc_ctrl_isp_sclk3", "top_cfg_aclk", VI_MISC_CTRL,
+ 0x0, 7),
+ GATE(VI_MISC_CTRL_ISP_CORE_CLK_EN, "vi_misc_ctrl_isp_core_clk", "isp_core_clk",
+ VI_MISC_CTRL, 0x0, 8),
+ GATE(VI_MISC_CTRL_ISP_FLEXA_CLK_EN, "vi_misc_ctrl_isp_flexa_clk", "isp_core_clk",
+ VI_MISC_CTRL, 0x0, 9),
+ GATE(VI_MISC_CTRL_ISP_MCM_CLK_EN, "vi_misc_ctrl_isp_mcm_clk", "isp_core_clk", VI_MISC_CTRL,
+ 0x0, 10),
+ GATE(VI_MISC_CTRL_BUS_CLK_GT_DISABLE, "vi_misc_ctrl_bus_clk", "isp_core_clk", VI_MISC_CTRL,
+ 0x0, 11),
+};
+
+static const struct a210_clk_desc info_vp[] = {
+ GATE(VP_DECOMP_EXTPCLK_EN, "vp_decomp_extpclk", "top_cfg_aclk", VP_CLK, 0, 23),
+ GATE(VP_COMP_EXTPCLK_EN, "vp_comp_extpclk", "top_cfg_aclk", VP_CLK, 0, 22),
+ GATE(VP_DECOMP_ACLK_EN, "vp_decomp_aclk", "vp_aclk", VP_CLK, 0, 14),
+ GATE(VP_DECOMP_CCLK_EN, "vp_decomp_cclk", "vp_decomp_clk_div", VP_CLK, 0, 13),
+ GATE(VP_DECOMP_PCLK_EN, "vp_decomp_pclk", "top_cfg_aclk", VP_CLK, 0, 12),
+ GATE(VP_COMP_ACLK_EN, "vp_comp_aclk", "vp_aclk", VP_CLK, 0, 11),
+ GATE(VP_COMP_CCLK_EN, "vp_comp_cclk", "vp_comp_clk_div", VP_CLK, 0, 10),
+ GATE(VP_COMP_PCLK_EN, "vp_comp_pclk", "top_cfg_aclk", VP_CLK, 0, 9),
+ GATE(VP_G2D_ACLK_EN, "vp_g2d_aclk", "vp_aclk", VP_CLK, 0, 8),
+ GATE(VP_G2D_CCLK_EN, "vp_g2d_cclk", "g2d_cclk", VP_CLK, 0, 7),
+ GATE(VP_G2D_PCLK_EN, "vp_g2d_pclk", "top_cfg_aclk", VP_CLK, 0, 6),
+ GATE(VP_VENC_ACLK_EN, "vp_venc_aclk", "vp_aclk", VP_CLK, 0, 5),
+ GATE(VP_VENC_CCLK_EN, "vp_venc_cclk", "venc_cclk", VP_CLK, 0, 4),
+ GATE(VP_VENC_PCLK_EN, "vp_venc_pclk", "top_cfg_aclk", VP_CLK, 0, 3),
+ GATE(VP_VDEC_ACLK_EN, "vp_vdec_aclk", "vp_aclk", VP_CLK, 0, 2),
+ GATE(VP_VDEC_CCLK_EN, "vp_vdec_cclk", "vdec_cclk", VP_CLK, 0, 1),
+ GATE(VP_VDEC_PCLK_EN, "vp_vdec_pclk", "top_cfg_aclk", VP_CLK, 0, 0),
+ DIV(VP_DECOMP_DIV_NUM, "vp_decomp_clk_div", "vp_aclk", VP_CLK, 0x4, 16, 4, 20, MUX_TYPE_DIV,
+ 2, 15),
+ DIV(VP_COMP_DIV_NUM, "vp_comp_clk_div", "vp_aclk", VP_CLK, 0x4, 8, 4, 12, MUX_TYPE_DIV, 2,
+ 15),
+};
+
+#define VO_PIXCLK_MUX_FLAGS (CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT)
+
+static const struct a210_clk_desc info_vo[] = {
+ GATE(VO_DFMU_PCLK_EN, "vo_dfmu_pclk", "vo_pclk", VO_CLK, 0, 20),
+ GATE(VO_DFMU_ACLK_EN, "vo_dfmu_aclk", "vo_preocc_aclk", VO_CLK, 0, 21),
+ GATE(VO_PTW_ACLK_EN, "vo_ptw_aclk", "vo_preocc_aclk", VO_CLK, 0, 22),
+ GATE(VO_X2H1_CLK_EN, "vo_x2h1_clk", "top_cfg_aclk", VO_CLK, 0, 24),
+ GATE(VO_X2H0_CLK_EN, "vo_x2h0_clk", "top_cfg_aclk", VO_CLK, 0, 23),
+ GATE(VO_ARB_ACLK_EN, "vo_arb_aclk", "vo_preocc_aclk", VO_CLK, 0, 19),
+ GATE(VO_DPU_ACLK_EN, "vo_dpu_aclk", "vo_preocc_aclk", VO_CLK, 0, 4),
+ GATE(VO_AUXDISP_ACLK_EN, "vo_disp_aclk", "vo_preocc_aclk", VO_CLK, 0, 7),
+ GATE(VO_DECOMP_ACLK_EN, "vo_decomp_aclk", "vo_preocc_aclk", VO_CLK, 0, 17),
+ DIV(VO_ACLK_DIV_NUM, "vo_preocc_aclk", "video_pll_foutvco", VO_CLK, 0x8, 0, 4, 4,
+ MUX_TYPE_DIV, 3, 15),
+ GATE(VO_DECOMP_PCLK_EN, "vo_decomp_pclk", "vo_pclk", VO_CLK, 0, 14),
+ GATE(VO_HDMI_PCLK_EN, "vo_hdmi_pclk", "vo_pclk", VO_CLK, 0, 8),
+ GATE(VO_MIPI_PCLK_EN, "vo_mipi_pclk", "vo_pclk", VO_CLK, 0, 12),
+ GATE(VO_AUXDISP_PCLK_EN, "vo_auxdisp_pclk", "vo_pclk", VO_CLK, 0, 6),
+ GATE(VO_ARB_PCLK_EN, "vo_arb_pclk", "vo_pclk", VO_CLK, 0, 18),
+ FIXED_FACTOR(VO_PCLK, "vo_pclk", "top_cfg_aclk", 1, 2),
+ GATE(VO_DECOMP0_CLK_EN, "vo_decomp0_clk", "vo_decomp_div", VO_CLK, 0, 15),
+ GATE(VO_DECOMP1_CLK_EN, "vo_decomp1_clk", "vo_decomp_div", VO_CLK, 0, 16),
+ DIV(VO_DECOMP_DIV_NUM, "vo_decomp_div", "video_pll_foutvco", VO_CLK, 0x8, 16, 4, 20,
+ MUX_TYPE_DIV, 12, 15),
+ GATE(VO_MIPI_CFGCLK_EN, "vo_mipi_cfgclk", "aon_osc_clk_logic", VO_CLK, 0, 13),
+ GATE(VO_HDMI_SFRCLK_EN, "vo_hdmi_sfrclk", "aon_osc_clk_logic", VO_CLK, 0, 11),
+ GATE(VO_CEC_CLK_EN, "vo_hdmi_cecclk", "aon_rtc_clk", VO_CLK, 0, 10),
+ GATE(VO_I2S_CLK_EN, "vo_hdmi_i2sclk", "audio0_pll_foutvco", VO_CLK, 0, 9),
+ GATE(VO_CH0_PIXCLK_EN, "dpu0_pixclk", "vo_pll0_div", VO_CLK, 0, 0),
+ DIV(VO_PLL0_DIV_NUM, "vo_pll0_div", "dpu0_pll_foutpostdiv", VO_CLK, 0x4, 0, 8, 8,
+ MUX_TYPE_DIV, 2, 255),
+ GATE(VO_CH1_PIXCLK_EN, "dpu1_pixclk", "vo_pll1_div", VO_CLK, 0, 1),
+ DIV(VO_PLL1_DIV_NUM, "vo_pll1_div", "dpu1_pll_foutpostdiv", VO_CLK, 0x4, 10, 8, 18,
+ MUX_TYPE_DIV, 2, 255),
+ GATE(VO_CH2_PIXCLK_EN, "dpu2_pixclk", "vo_pll2_div", VO_CLK, 0, 5),
+ DIV(VO_PLL2_DIV_NUM, "vo_pll2_div", "dpu2_pll_foutpostdiv", VO_CLK, 0x4, 20, 8, 28,
+ MUX_TYPE_DIV, 2, 255),
+ GATE(VO_DPU_HCLK_EN, "vo_dpuc_hclk", "top_cfg_aclk", VO_CLK, 0, 2),
+ GATE(VO_DPUC_CLK_EN, "vo_dpuc_clk", "vo_dpuc_div", VO_CLK, 0, 3),
+ DIV(VO_DPUC_DIV_NUM, "vo_dpuc_div", "video_pll_foutvco", VO_CLK, 0x8, 8, 4, 12,
+ MUX_TYPE_DIV, 3, 15),
+ MUX(VO_MIPI_PIXCLK, "vo_mipi_pixclk", VO_PATH_CTRL, 0x0, 0, 2, vo_mipi_pixclk_mux_parents,
+ VO_PIXCLK_MUX_FLAGS),
+ MUX(VO_HDMI_PIXCLK, "vo_hdmi_pixclk", VO_PATH_CTRL, 0x0, 2, 2, vo_hdmi_pixclk_mux_parents,
+ VO_PIXCLK_MUX_FLAGS),
+ MUX(VO_DPTX_PIXCLK, "vo_dptx_pixclk", VO_PATH_CTRL, 0x0, 4, 2, vo_dptx_pixclk_mux_parents,
+ VO_PIXCLK_MUX_FLAGS),
+};
+
+static const struct a210_clk_desc info_npu[] = {
+ GATE(SW_SEMA_PCLK_EN, "npu_clkgen_sema_pclk", "top_cfg_aclk", NPU_CLK, 0, 23),
+ GATE(SW_SEMA_ACLK_EN, "npu_clkgen_sema_aclk", "npu_aclk", NPU_CLK, 0, 22),
+ GATE(SW_NPU_X2P_ACLK_EN, "npu_x2p_aclk", "top_cfg_aclk", NPU_CLK, 0, 21),
+ GATE(SW_NPU_X2H_ACLK_EN, "npu_x2h_aclk", "top_cfg_aclk", NPU_CLK, 0, 20),
+ GATE(SW_NPU_IP_HCLK_EN, "npu_ip_hclk", "top_cfg_aclk", NPU_CLK, 0, 12),
+ GATE(SW_NPU_IP_CCLK_EN, "npu_ip_cclk", "npu_cclk", NPU_CLK, 0, 11),
+ GATE(SW_NPU_IP_ACLK_EN, "npu_ip_aclk", "npu_aclk", NPU_CLK, 0, 10),
+};
+
+static const struct a210_clk_desc info_peri[] = {
+ /* PERI0 SS */
+ GATE(PERI0_MBOX1_PCLK_EN, "peri0_mbox1_pclk", "top_cfg_aclk", PERI0_SYSREG, 0, 6),
+ GATE(PERI0_MBOX0_PCLK_EN, "peri0_mbox0_pclk", "top_cfg_aclk", PERI0_SYSREG, 0, 5),
+ GATE(PERI0_WDT0_PCLK_EN, "peri0_wdt0_pclk", "top_cfg_aclk", PERI0_SYSREG, 0, 4),
+ GATE(PERI0_TIMER1_PCLK_EN, "peri0_timer1_pclk", "top_cfg_aclk", PERI0_SYSREG, 0, 3),
+ GATE(PERI0_TIMER1_CCLK_EN, "peri0_timer1_cclk", "top_cfg_aclk", PERI0_SYSREG, 0, 2),
+ GATE(PERI0_TIMER0_PCLK_EN, "peri0_timer0_pclk", "top_cfg_aclk", PERI0_SYSREG, 0, 1),
+ GATE(PERI0_TIMER0_CCLK_EN, "peri0_timer0_cclk", "top_cfg_aclk", PERI0_SYSREG, 0, 0),
+ /* PERI1 SS */
+ GATE(PERI1_UART3_SCLK_EN, "peri1_clkgen_uart3_sclk", "uart_sclk", PERI1_SYSREG, 0, 31),
+ GATE(PERI1_UART3_PCLK_EN, "peri1_clkgen_uart3_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 30),
+ GATE(PERI1_UART2_SCLK_EN, "peri1_clkgen_uart2_sclk", "uart_sclk", PERI1_SYSREG, 0, 29),
+ GATE(PERI1_UART2_PCLK_EN, "peri1_clkgen_uart2_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 28),
+ GATE(PERI1_UART1_SCLK_EN, "peri1_clkgen_uart1_sclk", "uart_sclk", PERI1_SYSREG, 0, 27),
+ GATE(PERI1_UART1_PCLK_EN, "peri1_clkgen_uart1_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 26),
+ GATE(PERI1_UART0_SCLK_EN, "peri1_clkgen_uart0_sclk", "uart_sclk", PERI1_SYSREG, 0, 25),
+ GATE(PERI1_UART0_PCLK_EN, "peri1_clkgen_uart0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 24),
+ GATE(PERI1_SPI0_SSI_CLK_EN, "peri1_clkgen_spi0_ssi_clk", "peri1_spi_ssi_clk", PERI1_SYSREG,
+ 0, 23),
+ GATE(PERI1_SPI0_PCLK_EN, "peri1_clkgen_spi0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 22),
+ GATE(PERI1_QSPI0_SSI_CLK_EN, "peri1_clkgen_qspi0_ssi_clk", "peri1_qspi_ssi_clk",
+ PERI1_SYSREG, 0, 21),
+ GATE(PERI1_QSPI0_PCLK_EN, "peri1_clkgen_qspi0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 20),
+ GATE(PERI1_PWM0_PCLK_EN, "peri1_clkgen_pwm0_pclk", "peri1_pwm_clk", PERI1_SYSREG, 0, 19),
+ GATE(PERI1_PWM0_CCLK_EN, "peri1_clkgen_pwm0_cclk", "peri1_clkgen_pwm0_pclk", PERI1_SYSREG,
+ 0, 18),
+ /* E902 firmware accesses AP peripherals through this shared bus. */
+ GATE_FLAGS(PERI1_MST_BUS_PCLK_EN, "peri1_clkgen_mst_bus_pclk", "top_cfg_aclk", PERI1_SYSREG,
+ 0, 17, CLK_IS_CRITICAL),
+ GATE_FLAGS(PERI1_MST_BUS_ACLK_EN, "peri1_clkgen_mst_bus_aclk", "peri1_mst_aclk",
+ PERI1_SYSREG, 0, 16, CLK_IS_CRITICAL),
+ GATE(PERI1_I2S0_SRC_CLK_EN, "peri1_clkgen_i2s0_src_clk", "peri1_i2s0_src_clk", PERI1_SYSREG,
+ 0, 15),
+ GATE(PERI1_I2S0_PCLK_EN, "peri1_clkgen_i2s0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 14),
+ GATE(PERI1_I2C2_PCLK_EN, "peri1_clkgen_i2c2_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 13),
+ GATE(PERI1_I2C2_IC_CLK_EN, "peri1_clkgen_i2c2_ic_clk", "i2c_ic_clk", PERI1_SYSREG, 0, 12),
+ GATE(PERI1_I2C1_PCLK_EN, "peri1_clkgen_i2c1_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 11),
+ GATE(PERI1_I2C1_IC_CLK_EN, "peri1_clkgen_i2c1_ic_clk", "i2c_ic_clk", PERI1_SYSREG, 0, 10),
+ GATE(PERI1_I2C0_PCLK_EN, "peri1_clkgen_i2c0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 9),
+ GATE(PERI1_I2C0_IC_CLK_EN, "peri1_clkgen_i2c0_ic_clk", "i2c_ic_clk", PERI1_SYSREG, 0, 8),
+ GATE(PERI1_GPIO1_PCLK_EN, "peri1_clkgen_gpio1_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 7),
+ GATE(PERI1_GPIO1_DBCLK_EN, "peri1_clkgen_gpio1_dbclk", "aon_rtc_clk", PERI1_SYSREG, 0, 6),
+ GATE(PERI1_GPIO0_PCLK_EN, "peri1_clkgen_gpio0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0, 5),
+ GATE(PERI1_GPIO0_DBCLK_EN, "peri1_clkgen_gpio0_dbclk", "aon_rtc_clk", PERI1_SYSREG, 0, 4),
+ GATE(PERI1_GMAC1_HCLK_EN, "peri1_gmac1_hclk", "top_cfg_aclk", PERI1_SYSREG, 0, 3),
+ GATE(PERI1_GMAC1_ACLK_EN, "peri1_gmac1_aclk", "peri1_mst_aclk", PERI1_SYSREG, 0, 2),
+ GATE(PERI1_GMAC0_HCLK_EN, "peri1_gmac0_hclk", "top_cfg_aclk", PERI1_SYSREG, 0, 1),
+ GATE(PERI1_GMAC0_ACLK_EN, "peri1_gmac0_aclk", "peri1_mst_aclk", PERI1_SYSREG, 0, 0),
+ GATE(PERI1_ZGMAC_X2X_ACLK_EN, "peri1_zgmac0_x2x_aclk", "peri1_mst_aclk", PERI1_SYSREG, 0x4,
+ 25),
+ GATE(PERI1_GMAC2_HCLK_EN, "peri1_gmac2_hclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 24),
+ GATE(PERI1_GMAC2_ACLK_EN, "peri1_gmac2_aclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 23),
+ GATE(PERI1_X2H_GMAC2_HCLK_EN, "peri1_x2h_gmac2_hclk", "top_cfg_aclk", PERI1_SYSREG, 0x4,
+ 22),
+ GATE(PERI1_X2H_GMAC2_ACLK_EN, "peri1_x2h_gmac2_aclk", "top_cfg_aclk", PERI1_SYSREG, 0x4,
+ 21),
+ GATE(PERI1_CHIP_DBG_PCLK_EN, "peri1_chip_dbg_pclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 20),
+ GATE(PERI1_CHIP_DBG_CCLK_EN, "peri1_chip_dbg_cclk", "aon_osc_clk_logic", PERI1_SYSREG, 0x4,
+ 19),
+ GATE(PERI1_CHIP_DBG_ACLK_EN, "peri1_chip_dbg_aclk", "peri1_mst_aclk", PERI1_SYSREG, 0x4,
+ 18),
+ GATE(PERI1_TDM0_SCLK_EN, "peri1_tdm0_sclk", "peri1_tdm_src_clk", PERI1_SYSREG, 0x4, 17),
+ GATE(PERI1_TDM0_PCLK_EN, "peri1_tdm0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 16),
+ GATE(PERI1_PDM0_PCLK_EN, "peri1_pdm0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 15),
+ GATE(PERI1_PDM0_MCLK_EN, "peri1_pdm0_mclk", "peri1_pdm_mclk", PERI1_SYSREG, 0x4, 14),
+ GATE(PERI1_CAN1_PCLK_EN, "peri1_can1_pclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 13),
+ GATE(PERI1_CAN1_OSC_CLK_EN, "peri1_can1_osc_clk", "peri1_hires_clk", PERI1_SYSREG, 0x4, 12),
+ GATE(PERI1_CAN1_HIRES_CLK_EN, "peri1_can1_hires_clk", "peri1_can1_osc_clk", PERI1_SYSREG,
+ 0x4, 11),
+ GATE(PERI1_CAN0_PCLK_EN, "peri1_can0_pclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 10),
+ GATE(PERI1_CAN0_OSC_CLK_EN, "peri1_can0_osc_clk", "peri1_hires_clk", PERI1_SYSREG, 0x4, 9),
+ GATE(PERI1_CAN0_HIRES_CLK_EN, "peri1_can0_hires_clk", "peri1_can0_osc_clk", PERI1_SYSREG,
+ 0x4, 8),
+ GATE(PERI1_PAD_CTRL_PCLK_EN, "peri1_pad_ctrl_pclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 7),
+ GATE(PERI1_X2H_GMAC1_HCLK_EN, "peri1_x2h_gmac1_hclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 3),
+ GATE(PERI1_X2H_GMAC1_ACLK_EN, "peri1_x2h_gmac1_aclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 2),
+ GATE(PERI1_X2H_GMAC0_HCLK_EN, "peri1_x2h_gmac0_hclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 1),
+ GATE(PERI1_X2H_GMAC0_ACLK_EN, "peri1_x2h_gmac0_aclk", "top_cfg_aclk", PERI1_SYSREG, 0x4, 0),
+ /* PERI2 SS */
+ GATE(PERI2_I2S3_PCLK_EN, "peri2_clkgen_i2s3_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 31),
+ GATE(PERI2_I2S3_SRC_CLK_EN, "peri2_clkgen_i2s3_src_clk", "peri2_i2s3_src_clk", PERI2_SYSREG,
+ 0, 30),
+ GATE(PERI2_I2S2_PCLK_EN, "peri2_clkgen_i2s2_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 29),
+ GATE(PERI2_I2S2_SRC_CLK_EN, "peri2_clkgen_i2s2_src_clk", "peri2_i2s2_src_clk", PERI2_SYSREG,
+ 0, 28),
+ GATE(PERI2_I2S1_PCLK_EN, "peri2_clkgen_i2s1_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 27),
+ GATE_FLAGS(PERI2_I2S1_SRC_CLK_EN, "peri2_clkgen_i2s1_src_clk", "peri2_i2s1_src_clk",
+ PERI2_SYSREG, 0, 26, CLK_SET_RATE_PARENT),
+ GATE(PERI2_I2C7_IC_CLK_EN, "peri2_clkgen_i2c7_ic_clk", "i2c_ic_clk", PERI2_SYSREG, 0, 25),
+ GATE(PERI2_I2C7_PCLK_EN, "peri2_clkgen_i2c7_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 24),
+ GATE(PERI2_I2C6_IC_CLK_EN, "peri2_clkgen_i2c6_ic_clk", "i2c_ic_clk", PERI2_SYSREG, 0, 23),
+ GATE(PERI2_I2C6_PCLK_EN, "peri2_clkgen_i2c6_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 22),
+ GATE(PERI2_I2C5_IC_CLK_EN, "peri2_clkgen_i2c5_ic_clk", "i2c_ic_clk", PERI2_SYSREG, 0, 21),
+ GATE(PERI2_I2C5_PCLK_EN, "peri2_clkgen_i2c5_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 20),
+ GATE(PERI2_I2C4_IC_CLK_EN, "peri2_clkgen_i2c4_ic_clk", "i2c_ic_clk", PERI2_SYSREG, 0, 19),
+ GATE(PERI2_I2C4_PCLK_EN, "peri2_clkgen_i2c4_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 18),
+ GATE(PERI2_I2C3_IC_CLK_EN, "peri2_clkgen_i2c3_ic_clk", "i2c_ic_clk", PERI2_SYSREG, 0, 17),
+ GATE(PERI2_I2C3_PCLK_EN, "peri2_clkgen_i2c3_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 16),
+ GATE(PERI2_GPIO3_DBCLK_EN, "peri2_clkgen_gpio3_dbclk", "aon_rtc_clk", PERI2_SYSREG, 0, 15),
+ GATE(PERI2_GPIO3_PCLK_EN, "peri2_clkgen_gpio3_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 14),
+ GATE(PERI2_PAD_CTRL_PCLK_EN, "peri2_clkgen_pad_ctrl_pclk", "top_cfg_aclk", PERI2_SYSREG, 0,
+ 13),
+ GATE(PERI2_UART6_PCLK_EN, "peri2_clkgen_uart6_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 12),
+ GATE(PERI2_UART5_PCLK_EN, "peri2_clkgen_uart5_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 11),
+ GATE_FLAGS(PERI2_UART4_PCLK_EN, "peri2_clkgen_uart4_pclk", "top_cfg_aclk", PERI2_SYSREG, 0,
+ 10, CLK_IS_CRITICAL),
+ GATE(PERI2_SPI1_PCLK_EN, "peri2_clkgen_spi1_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 9),
+ GATE(PERI2_GPIO2_PCLK_EN, "peri2_clkgen_gpio2_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 8),
+ GATE(PERI2_CAN2_PCLK_EN, "peri2_clkgen_can2_pclk", "top_cfg_aclk", PERI2_SYSREG, 0, 7),
+ GATE(PERI2_UART6_SCLK_EN, "peri2_clkgen_uart6_sclk", "uart_sclk", PERI2_SYSREG, 0, 6),
+ GATE(PERI2_UART5_SCLK_EN, "peri2_clkgen_uart5_sclk", "uart_sclk", PERI2_SYSREG, 0, 5),
+ GATE_FLAGS(PERI2_UART4_SCLK_EN, "peri2_clkgen_uart4_sclk", "uart_sclk", PERI2_SYSREG, 0, 4,
+ CLK_IS_CRITICAL),
+ GATE(PERI2_SPI1_SSI_CLK_EN, "peri2_clkgen_spi1_ssi_clk", "peri2_spi_ssi_clk", PERI2_SYSREG,
+ 0, 3),
+ GATE(PERI2_GPIO2_DBCLK_EN, "peri2_clkgen_gpio2_dbclk", "aon_rtc_clk", PERI2_SYSREG, 0, 2),
+ GATE(PERI2_CAN2_OSC_CLK_EN, "peri2_clkgen_can2_osc_clk", "peri2_hires_clk", PERI2_SYSREG, 0,
+ 1),
+ GATE(PERI2_CAN2_HIRES_CLK_EN, "peri2_clkgen_can2_hires_clk", "peri2_clkgen_can2_osc_clk",
+ PERI2_SYSREG, 0, 0),
+ GATE(PERI2_QSPI1_PCLK_EN, "peri2_clkgen_qspi1_pclk", "top_cfg_aclk", PERI2_SYSREG, 0x4, 11),
+ GATE(PERI2_QSPI1_SSI_CLK_EN, "peri2_clkgen_qspi1_ssi_clk", "peri2_qspi_ssi_clk",
+ PERI2_SYSREG, 0x4, 10),
+ GATE(PERI2_UART9_PCLK_EN, "peri2_clkgen_uart9_pclk", "top_cfg_aclk", PERI2_SYSREG, 0x4, 9),
+ GATE(PERI2_UART9_SCLK_EN, "peri2_clkgen_uart9_sclk", "uart_sclk", PERI2_SYSREG, 0x4, 8),
+ GATE(PERI2_UART8_PCLK_EN, "peri2_clkgen_uart8_pclk", "top_cfg_aclk", PERI2_SYSREG, 0x4, 7),
+ GATE(PERI2_UART8_SCLK_EN, "peri2_clkgen_uart8_sclk", "uart_sclk", PERI2_SYSREG, 0x4, 6),
+ GATE(PERI2_UART7_PCLK_EN, "peri2_clkgen_uart7_pclk", "top_cfg_aclk", PERI2_SYSREG, 0x4, 5),
+ GATE(PERI2_UART7_SCLK_EN, "peri2_clkgen_uart7_sclk", "uart_sclk", PERI2_SYSREG, 0x4, 4),
+ GATE(PERI2_PWM2_PCLK_EN, "peri2_clkgen_pwm2_pclk", "peri2_pwm_clk", PERI2_SYSREG, 0x4, 3),
+ GATE(PERI2_PWM2_CCLK_EN, "peri2_clkgen_pwm2_cclk", "peri2_clkgen_pwm2_pclk", PERI2_SYSREG,
+ 0x4, 2),
+ GATE(PERI2_PWM1_PCLK_EN, "peri2_clkgen_pwm1_pclk", "peri2_pwm_clk", PERI2_SYSREG, 0x4, 1),
+ GATE(PERI2_PWM1_CCLK_EN, "peri2_clkgen_pwm1_cclk", "peri2_clkgen_pwm1_pclk", PERI2_SYSREG,
+ 0x4, 0),
+ /* PERI3 SS */
+ GATE(PERI3_PAD_CTRL_PCLK_EN, "peri3_clkgen_pad_ctrl_pclk", "top_cfg_aclk", PERI3_SYSREG, 0,
+ 21),
+ GATE(PERI3_GPIO4_PCLK_EN, "peri3_clkgen_gpio4_pclk", "top_cfg_aclk", PERI3_SYSREG, 0, 20),
+ GATE(PERI3_GPIO4_DBCLK_EN, "peri3_clkgen_gpio4_dbclk", "aon_rtc_clk", PERI3_SYSREG, 0, 19),
+ GATE(CLKCTRL_PERI3_TEE_H2H_SHCLKEN, "peri3_clkgen_tee_h2h_shclk", "top_cfg_aclk",
+ PERI3_SYSREG, 0, 18),
+ GATE(CLKCTRL_PERI3_TEE_H2H_MHCLKEN, "peri3_clkgen_tee_h2h_mhclk", "top_cfg_aclk",
+ PERI3_SYSREG, 0, 17),
+ GATE(PERI3_TEE_X2X_ACLK_S_EN, "peri3_clkgen_tee_x2x_aclk", "top_cfg_aclk", PERI3_SYSREG, 0,
+ 16),
+ GATE(PERI3_ADC_PCLK_EN, "peri3_clkgen_adc_pclk", "top_cfg_aclk", PERI3_SYSREG, 0, 15),
+ GATE(AXI_PERI3_MST_PCLK_EN, "peri3_clkgen_axi_mst_pclk", "top_cfg_aclk", PERI3_SYSREG, 0,
+ 14),
+ GATE(AXI_PERI3_MST_ACLK_EN, "peri3_clkgen_axi_mst_aclk", "peri3_mst_aclk", PERI3_SYSREG, 0,
+ 13),
+ GATE(PERI3_SDIO_X2X_ACLK_S_EN, "peri3_clkgen_sdio_x2x_aclk_s", "peri3_mst_aclk",
+ PERI3_SYSREG, 0, 12),
+ GATE(PERI3_SDIO_X2X_ACLK_M_EN, "peri3_clkgen_sdio_x2x_aclk_m", "top_cfg_aclk", PERI3_SYSREG,
+ 0, 11),
+ GATE(PERI3_SDIO_OSC_CLK_EN, "peri3_clkgen_sdio_osc_clk", "aon_osc_clk_logic", PERI3_SYSREG,
+ 0, 10),
+ GATE(PERI3_SDIO_HCLK_EN, "peri3_clkgen_sdio_hclk", "top_cfg_aclk", PERI3_SYSREG, 0, 9),
+ GATE(PERI3_SDIO_ACLK_EN, "peri3_clkgen_sdio_aclk", "top_cfg_aclk", PERI3_SYSREG, 0, 8),
+ GATE(PERI3_EMMC_X2X_ACLK_S_EN, "peri3_clkgen_emmc_x2x_aclk_s", "peri3_mst_aclk",
+ PERI3_SYSREG, 0, 7),
+ GATE(PERI3_EMMC_X2X_ACLK_M_EN, "peri3_clkgen_emmc_x2x_aclk_m", "top_cfg_aclk", PERI3_SYSREG,
+ 0, 6),
+ GATE(PERI3_EMMC_OSC_CLK_EN, "peri3_clkgen_emmc_osc_clk", "aon_osc_clk_logic", PERI3_SYSREG,
+ 0, 5),
+ GATE(PERI3_EMMC_HCLK_EN, "peri3_clkgen_emmc_hclk", "top_cfg_aclk", PERI3_SYSREG, 0, 4),
+ GATE(PERI3_EMMC_ACLK_EN, "peri3_clkgen_emmc_aclk", "top_cfg_aclk", PERI3_SYSREG, 0, 3),
+ FIXED_FACTOR(PERI3_EMMC_SDIO_REF_CLK, "peri3_emmc_sdio_ref_clk", "emmc_ref_clk", 1, 4),
+ GATE(PERI3_EMMC_SDIO_REF_CLK_CG_EN, "peri3_clkgen_sdio_ref_clk", "peri3_emmc_sdio_ref_clk",
+ PERI3_SYSREG, 0, 2),
+ GATE(PERI3_DMAC_HCLK_EN, "peri3_clkgen_dmac_hclk", "top_cfg_aclk", PERI3_SYSREG, 0, 1),
+ GATE(PERI3_DMAC_ACLK_EN, "peri3_clkgen_dmac_aclk", "peri3_mst_aclk", PERI3_SYSREG, 0, 0),
+ /* TEE SS */
+ GATE(TEE_AHB2_TEESYS_CLKEN, "tee_ahb2_teesys_clk", "tee_clk", TEE_CRG, 0, 19),
+ GATE(TEE_APB3_TEESYS_CLKEN, "tee_apb3_teesys_clk", "tee_clk", TEE_CRG, 0, 18),
+ GATE(TEE_AXI4_TEESYS_CLKEN, "tee_axi4_teesys_clk", "tee_clk", TEE_CRG, 0, 17),
+ GATE(TEE_X2P_TEESYS_CLKEN, "tee_x2p_teesys_clk", "tee_clk", TEE_CRG, 0, 16),
+ GATE(TEE_EIP120SI_CLKEN, "tee_eip120si_clk", "tee_clk", TEE_CRG, 0, 12),
+ GATE(TEE_EIP120SII_CLKEN, "tee_eip120sii_clk", "tee_clk", TEE_CRG, 0, 11),
+ GATE(TEE_EIP120SIII_CLKEN, "tee_eip120siii_clk", "tee_clk", TEE_CRG, 0, 10),
+ GATE(TEE_EIP150B_CLKEN, "tee_eip150b_clk", "tee_clk", TEE_CRG, 0, 9),
+ GATE(TEE_DMAC_CLKEN, "tee_dmac_clk", "tee_clk", TEE_CRG, 0, 8),
+ FIXED_FACTOR(TEE_PCLK_CDE_RATIO, "tee_pclk", "tee_clk", 1, 4),
+ GATE(TEE_DS_CLKEN, "tee_ds_clk", "tee_pclk", TEE_CRG, 0, 3),
+ GATE(TEE_OCRAM_CLKEN, "tee_ocram_clk", "tee_clk", TEE_CRG, 0, 2),
+ GATE(TEE_EFUSE_CLKEN, "tee_efuse_clk", "tee_pclk", TEE_CRG, 0, 1),
+ GATE(TEE_KEYRAM_CLKEN, "tee_keyram_clk", "tee_pclk", TEE_CRG, 0, 0),
+};
+
+static const struct a210_ccu top_clk = CLK_SUBSYS("top clk", regs_top, info_top);
+static const struct a210_ccu gpu_clk = CLK_SUBSYS("gpu clk", regs_gpu, info_gpu);
+static const struct a210_ccu pcie_clk = CLK_SUBSYS("pcie clk", regs_pcie, info_pcie);
+static const struct a210_ccu usb_clk = CLK_SUBSYS("usb clk", regs_usb, info_usb);
+static const struct a210_ccu vi_clk = CLK_SUBSYS("vi clk", regs_vi, info_vi);
+static const struct a210_ccu vp_clk = CLK_SUBSYS("vp clk", regs_vp, info_vp);
+static const struct a210_ccu vo_clk = CLK_SUBSYS("vo clk", regs_vo, info_vo);
+static const struct a210_ccu npu_clk = CLK_SUBSYS("npu clk", regs_npu, info_npu);
+static const struct a210_ccu peri_clk = CLK_SUBSYS("peri clk", regs_peri, info_peri);
+
+static int a210_clocks_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct clk_hw_onecell_data *clk_data;
+ const struct a210_ccu *data;
+ struct a210_ccu *priv;
+ int i, ret;
+
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
+
+ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, CLK_END), GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->num = CLK_END;
+ for (i = 0; i < CLK_END; i++)
+ clk_data->hws[i] = ERR_PTR(-ENOENT);
+
+ data = device_get_match_data(dev);
+ if (!data)
+ return -EINVAL;
+
+ priv = devm_kmemdup(dev, data, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->regs =
+ devm_kmemdup(dev, data->regs, sizeof(*data->regs) * data->num_regs, GFP_KERNEL);
+ if (!priv->regs)
+ return -ENOMEM;
+ priv->num_inputs = devm_clk_bulk_get_all(dev, &priv->inputs);
+ if (priv->num_inputs < 0)
+ return dev_err_probe(dev, priv->num_inputs, "failed to get input clocks\n");
+
+ priv->clk_data = clk_data;
+ dev_set_drvdata(dev, priv);
+
+ ret = a210_map_registers(pdev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to parse register base\n");
+
+ ret = a210_register_clocks(pdev);
+ if (ret)
+ return ret;
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+}
+
+static const struct of_device_id a210_clk_of_match[] = {
+ { .compatible = "zhihe,a210-clk", .data = &top_clk },
+ { .compatible = "zhihe,a210-gpu-clk", .data = &gpu_clk },
+ { .compatible = "zhihe,a210-pcie-clk", .data = &pcie_clk },
+ { .compatible = "zhihe,a210-usb-clk", .data = &usb_clk },
+ { .compatible = "zhihe,a210-vi-clk", .data = &vi_clk },
+ { .compatible = "zhihe,a210-vp-clk", .data = &vp_clk },
+ { .compatible = "zhihe,a210-vo-clk", .data = &vo_clk },
+ { .compatible = "zhihe,a210-npu-clk", .data = &npu_clk },
+ { .compatible = "zhihe,a210-peri-clk", .data = &peri_clk },
+ { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, a210_clk_of_match);
+
+static struct platform_driver a210_clk_driver = {
+ .probe = a210_clocks_probe,
+ .driver = {
+ .name = "a210-clk",
+ .of_match_table = a210_clk_of_match,
+ },
+};
+
+module_platform_driver(a210_clk_driver);
+
+MODULE_AUTHOR("dong.yan <yand@zhihecomputing.com>");
+MODULE_DESCRIPTION("Zhihe A210 clock driver");
+MODULE_LICENSE("GPL");
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 06/18] dt-bindings: reset: add Zhihe A210 reset controllers
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (4 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 05/18] clk: zhihe: add A210 support Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 07/18] reset: zhihe: add A210 support Han Gao via B4 Relay
` (11 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add bindings for the A210 reset controllers and their reset IDs.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
.../bindings/reset/zhihe,a210-reset.yaml | 56 ++++
include/dt-bindings/reset/zhihe,a210-resets.h | 351 +++++++++++++++++++++
2 files changed, 407 insertions(+)
diff --git a/Documentation/devicetree/bindings/reset/zhihe,a210-reset.yaml b/Documentation/devicetree/bindings/reset/zhihe,a210-reset.yaml
new file mode 100644
index 000000000000..708cb49444eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/zhihe,a210-reset.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/zhihe,a210-reset.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Zhihe A210 Reset Controller
+
+maintainers:
+ - Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
+
+description:
+ Reset controllers for the Zhihe A210 SoC. Each subsystem exposes a
+ separate reset controller register block and has its own compatible.
+
+properties:
+ compatible:
+ enum:
+ - zhihe,a210-vp-reset
+ - zhihe,a210-vi-reset
+ - zhihe,a210-npu-reset
+ - zhihe,a210-vo-reset
+ - zhihe,a210-peri0-reset
+ - zhihe,a210-peri1-reset
+ - zhihe,a210-peri2-reset
+ - zhihe,a210-peri3-reset
+ - zhihe,a210-pcie-reset
+ - zhihe,a210-usb-reset
+ - zhihe,a210-tee-reset
+ - zhihe,a210-gpu-reset
+
+ reg:
+ maxItems: 1
+
+ "#reset-cells":
+ const: 1
+ description:
+ The single cell is the reset ID defined in
+ include/dt-bindings/reset/zhihe,a210-resets.h.
+
+required:
+ - compatible
+ - reg
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/reset/zhihe,a210-resets.h>
+
+ reset-controller@6b20400 {
+ compatible = "zhihe,a210-vp-reset";
+ reg = <0x06b20400 0x200>;
+ #reset-cells = <1>;
+ };
diff --git a/include/dt-bindings/reset/zhihe,a210-resets.h b/include/dt-bindings/reset/zhihe,a210-resets.h
new file mode 100644
index 000000000000..2845c0e9e5ed
--- /dev/null
+++ b/include/dt-bindings/reset/zhihe,a210-resets.h
@@ -0,0 +1,351 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025 Zhihe Computing Limited.
+ */
+
+#ifndef _DT_BINDINGS_RESET_ZHIHE_A210_RESETS_H
+#define _DT_BINDINGS_RESET_ZHIHE_A210_RESETS_H
+
+#define VP_VDEC_PRST 0
+#define VP_VDEC_CRST 1
+#define VP_VDEC_ARST 2
+#define VP_VENC_PRST 3
+#define VP_VENC_CRST 4
+#define VP_VENC_ARST 5
+#define VP_G2D_PRST 6
+#define VP_G2D_CRST 7
+#define VP_G2D_ARST 8
+#define VP_COMP_PRST 9
+#define VP_COMP_CRST 10
+#define VP_COMP_ARST 11
+#define VP_DECOMP_PRST 12
+#define VP_DECOMP_CRST 13
+#define VP_DECOMP_ARST 14
+#define VP_DFMU_PRST 15
+#define VP_DFMU_ARST 16
+#define VP_ARB_PRST 17
+#define VP_ARB_ARST 18
+#define VP_VDEC_RS_ARST 19
+#define VP_VENC_RS_ARST 20
+#define VP_COMP_EXTPRST 21
+#define VP_DECOMP_EXTPRST 22
+
+#define VI_MIPI0_CSI0_PRST 0
+#define VI_MIPI0_CSI1_PRST 1
+#define VI_MIPI0_FIFO_RST 2
+#define VI_MIPI1_CSI0_PRST 3
+#define VI_MIPI1_CSI1_PRST 4
+#define VI_MIPI1_FIFO_RST 5
+#define VI_VIPRE_PRST 6
+#define VI_VIPRE_I0_PIX_RST 7
+#define VI_VIPRE_I1_PIX_RST 8
+#define VI_VIPRE_ISPIF_RST 9
+#define VI_VIPRE_ARST 10
+#define VI_ISP_RST 11
+#define VI_COMP_PRST 12
+#define VI_COMP_ARST 13
+#define VI_COMP_ISPOUT_RST 14
+#define VI_COMP_DECOUT_RST 15
+#define VI_COMP_VSEOUT_RST 16
+#define VI_COMP0_RST 17
+#define VI_COMP1_RST 18
+#define VI_DECOMP_RST 19
+#define VI_DW200_RST 20
+#define VI_DFMU_PRST 21
+#define VI_DFMU_ARST 22
+#define VI_ARB_PRST 23
+#define VI_ARB_ARST 24
+#define VI_X2H0_HRST 25
+#define VI_X2H1_HRST 26
+#define VI_X2H2_HRST 27
+#define VI_REC_PRST 28
+#define VI_REC_ARST 29
+
+#define NPU_AAB_MST_RST 0
+#define NPU_AFENCE_RST 1
+#define NPU_AXI_CCU_PRST 2
+#define NPU_AXI_CCU_RST 3
+#define NPU_AXI_M2S1_RST 4
+#define NPU_AXI_RST 5
+#define NPU_CLK_CALC_RST 6
+#define NPU_DFMU_ARST 7
+#define NPU_DFMU_PRST 8
+#define NPU_LPC_C_RST 9
+#define NPU_LPE_C_PRST 10
+#define NPU_LPE_C_RST 11
+#define NPU_ARST 12
+#define NPU_CRST 13
+#define NPU_HRST 14
+#define NPU_PCTRL_PB_RST 15
+#define NPU_PCTRL_PRST 16
+#define NPU_PCTRL_RST 17
+#define NPU_PTW_CCU_PRST 18
+#define NPU_PTW_CCU_RST 19
+#define NPU_SEMA_ARST 20
+#define NPU_SEMA_PRST 21
+#define NPU_DROOP_CCTRL_PRST 22
+#define NPU_DROOP_CCTRL_RST 23
+#define NPU_X2H_RST 24
+#define NPU_X2P_RST 25
+#define NPU_LDIP_RST 26
+#define NPU_SRAM_RST 27
+
+#define VO_X2H0_RST 0
+#define VO_X2H1_RST 1
+#define VO_DPU_HRST 2
+#define VO_DPU_CRST 3
+#define VO_DPU_ARST 4
+#define VO_AUXDISP_PRST 5
+#define VO_AUXDISP_PIX_RST 6
+#define VO_AUXDISP_ARST 7
+#define VO_HDMI_PRST 8
+#define VO_HDMI_MAIN_RST 9
+#define VO_MIPI_PRST 10
+#define VO_DECOMP_PRST 11
+#define VO_DECOMP0_CRST 12
+#define VO_DECOMP1_CRST 13
+#define VO_DECOMP_ARST 14
+#define VO_ARB_PRST 15
+#define VO_ARB_ARST 16
+#define VO_DFMU_PRST 17
+#define VO_DFMU_ARST 18
+
+#define PERI0_TIMER0_CRST 0
+#define PERI0_TIMER0_PRST 1
+#define PERI0_TIMER1_CRST 2
+#define PERI0_TIMER1_PRST 3
+#define PERI0_WDT0_PRST 4
+#define PERI0_MBOX0_PRST 5
+#define PERI0_MBOX1_PRST 6
+#define PERI0_TIMER0_RST 7
+#define PERI0_TIMER1_RST 8
+
+#define PERI1_GMAC0_ARST 0
+#define PERI1_GMAC0_HRST 1
+#define PERI1_GMAC1_ARST 2
+#define PERI1_GMAC1_HRST 3
+#define PERI1_GPIO0_DBRST 4
+#define PERI1_GPIO0_PRST 5
+#define PERI1_GPIO1_DBRST 6
+#define PERI1_GPIO1_PRST 7
+#define PERI1_I2C0_IC_RST 8
+#define PERI1_I2C0_PRST 9
+#define PERI1_I2C1_IC_RST 10
+#define PERI1_I2C1_PRST 11
+#define PERI1_I2C2_IC_RST 12
+#define PERI1_I2C2_PRST 13
+#define PERI1_I2S0_PRST 14
+#define PERI1_MST_BUS_ARST 15
+#define PERI1_MST_BUS_PRST 16
+#define PERI1_PWM0_CRST 17
+#define PERI1_PWM0_PRST 18
+#define PERI1_QSPI0_PRST 19
+#define PERI1_QSPI0_SSI_RST 20
+#define PERI1_SPI0_PRST 21
+#define PERI1_SPI0_SSI_RST 22
+#define PERI1_UART0_PRST 23
+#define PERI1_UART0_S_RST 24
+#define PERI1_UART1_PRST 25
+#define PERI1_UART1_S_RST 26
+#define PERI1_UART2_PRST 27
+#define PERI1_UART2_S_RST 28
+#define PERI1_UART3_PRST 29
+#define PERI1_UART3_S_RST 30
+#define PERI1_X2H_GMAC0_ARST 31
+#define PERI1_X2H_GMAC0_HRST 32
+#define PERI1_X2H_GMAC1_ARST 33
+#define PERI1_X2H_GMAC1_HRST 34
+#define PERI1_DFMU_ARESET 35
+#define PERI1_DFMU_PRESET 36
+#define PERI1_PAD_CTRL_PRST 37
+#define PERI1_PDM0_MRST 38
+#define PERI1_PDM0_PRST 39
+#define PERI1_TDM0_RST 40
+#define PERI1_CAN0_IPG_PE_RST 41
+#define PERI1_CAN0_IPG_RST 42
+#define PERI1_CAN0_IPG_SOFT_RST 43
+#define PERI1_CAN0_IPG_TS_RST 44
+#define PERI1_CAN0_PRST 45
+#define PERI1_CAN1_IPG_PE_RST 46
+#define PERI1_CAN1_IPG_RST 47
+#define PERI1_CAN1_IPG_SOFT_RST 48
+#define PERI1_CAN1_IPG_TS_RST 49
+#define PERI1_CAN1_PRST 50
+#define PERI1_CHIP_DBG_ARST 51
+#define PERI1_CHIP_DBG_CRST 52
+#define PERI1_CHIP_DBG_PRST 53
+#define PERI1_GMAC_CRST 54
+#define PERI1_X2H_GMAC2_ARST 55
+#define PERI1_X2H_GMAC2_HRST 56
+#define PERI1_ZGMAC_X2X_ARST 57
+#define PERI1_SPI0_RST 58
+#define PERI1_I2C0_RST 59
+#define PERI1_I2C1_RST 60
+#define PERI1_I2C2_RST 61
+#define PERI1_GMAC0_RST 62
+#define PERI1_GMAC0_X2H_RST 63
+#define PERI1_GMAC1_RST 64
+#define PERI1_GMAC1_X2H_RST 65
+
+#define PERI2_CAN2_IPG_PE_RST 0
+#define PERI2_CAN2_IPG_RST 1
+#define PERI2_CAN2_IPG_SOFT_RST 2
+#define PERI2_CAN2_IPG_TS_RST 3
+#define PERI2_CAN2_PRST 4
+#define PERI2_GPIO2_DBRST 5
+#define PERI2_GPIO2_PRST 6
+#define PERI2_I2C4_IC_RST 7
+#define PERI2_I2C4_PRST 8
+#define PERI2_I2S2_PRST 9
+#define PERI2_SPI1_PRST 10
+#define PERI2_SPI1_SSI_RST 11
+#define PERI2_UART4_PRST 12
+#define PERI2_UART4_S_RST 13
+#define PERI2_UART5_PRST 14
+#define PERI2_UART5_S_RST 15
+#define PERI2_UART6_PRST 16
+#define PERI2_UART6_S_RST 17
+#define PERI2_PAD_CTRL_PRST 18
+#define PERI2_GPIO3_DBRST 19
+#define PERI2_GPIO3_PRST 20
+#define PERI2_I2C3_IC_RST 21
+#define PERI2_I2C3_PRST 22
+#define PERI2_I2C5_IC_RST 23
+#define PERI2_I2C5_PRST 24
+#define PERI2_I2C6_IC_RST 25
+#define PERI2_I2C6_PRST 26
+#define PERI2_I2C7_IC_RST 27
+#define PERI2_I2C7_PRST 28
+#define PERI2_I2S1_PRST 29
+#define PERI2_I2S3_PRST 30
+#define PERI2_UART7_PRST 31
+#define PERI2_UART7_S_RST 32
+#define PERI2_UART8_PRST 33
+#define PERI2_UART8_S_RST 34
+#define PERI2_UART9_PRST 35
+#define PERI2_UART9_S_RST 36
+#define PERI2_QSPI1_PRST 37
+#define PERI2_QSPI1_SSI_RST 38
+#define PERI2_PWM1_CRST 39
+#define PERI2_PWM1_PRST 40
+#define PERI2_PWM2_CRST 41
+#define PERI2_PWM2_PRST 42
+#define PERI2_I2C3_RST 43
+#define PERI2_I2C4_RST 44
+#define PERI2_I2C5_RST 45
+#define PERI2_I2C6_RST 46
+#define PERI2_I2C7_RST 47
+#define PERI2_SPI1_RST 48
+
+#define PERI3_DMAC_ARST 0
+#define PERI3_DMAC_HRST 1
+#define PERI3_EMMC_SDIO_CLKGEN_RST 2
+#define PERI3_EMMC_RST 3
+#define PERI3_EMMC_X2X_ARST_M 4
+#define PERI3_EMMC_X2X_ARST_S 5
+#define PERI3_SDIO_RST 6
+#define PERI3_SDIO_X2X_ARST_M 7
+#define PERI3_SDIO_X2X_ARST_S 8
+#define PERI3_AXI_MST_ARST 9
+#define PERI3_AXI_MST_PRST 10
+#define PERI3_ADC_PRST 11
+#define PERI3_TEE_X2X_ARST_M 12
+#define PERI3_TEE_X2X_ARST_S 13
+#define PERI3_TEE_H2H_HRST 14
+#define PERI3_GPIO4_DBRST 15
+#define PERI3_GPIO4_PRST 16
+#define PERI3_PAD_CTRL_PRST 17
+
+/* pcie common */
+#define PCIE_X2X_PERI_SLV_ARST 0
+#define PCIE_X2X_PERI_MST_ARST 1
+#define PCIE_AXI4_PCIE_MST_ARST 2
+#define PCIE_AXI4_PCIE_MST_PRST 3
+#define PCIE_DFMU_PRST 4
+#define PCIE_DFMU_ARST 5
+#define PCIE_E16PHY_PHY_RST 6
+#define PCIE_E16PHY_APBS_PRST 7
+#define PCIE_X2X_SATA_MST_ARST 8
+#define PCIE_X2X_SATA_SLV_ARST 9
+
+/* sata */
+#define PCIE_SATA_ARESET 10
+#define PCIE_SATA_RST_PMALIVE 11
+#define PCIE_SATA_SLV_AFENCE_ARST 12
+#define PCIE_SATA_MST_AFENCE_ARST 13
+#define PCIE_SATA_RST_ASIC0 14
+#define PCIE_SATA_RST_ASIC1 15
+#define PCIE_SATA_RST_RXOOB0 16
+#define PCIE_SATA_RST_RXOOB1 17
+
+/* pcie0 */
+#define PCIE_DM_GEN3X4_APBS_PRST 18
+#define PCIE_DM_GEN3X4_POWER_UP_RST 19
+#define PCIE_DM_SLV_AFENCE_ARST 20
+#define PCIE_DM_MST_AFENCE_ARST 21
+
+/* pcie1 */
+#define PCIE_RP_GEN3X1_APBS_PRST 22
+#define PCIE_RP_GEN3X1_POWER_UP_RST 23
+#define PCIE_RP_SLV_AFENCE_ARST 24
+#define PCIE_RP_MST_AFENCE_ARST 25
+
+#define USB_DFMU_PRST 0
+#define USB_DFMU_ARST 1
+#define USB_AXI4_MST_ARST 2
+#define USB_AXI4_MST_PRST 3
+#define USB_DPTX_APBS_PRST 4
+#define USB_DPTX_VCC_RST 5
+#define USB_USB31_APBS_PRST 6
+#define USB_USB31_VCC_RST 7
+#define USB_USB31_PHY_RST 8
+#define USB_USB31_SLV_AFENCE_ARST 9
+#define USB_C10PHY_PHY_RST 10
+#define USB_C10PHY_APBS_PRST 11
+#define USB_USB20_BLK_X2H_HRST 12
+#define USB_USB20_BLK_X2H_ARST 13
+#define USB_USB20_SLV_AFENCE_ARST 14
+#define USB_USB20_BLK_H2P_HRST 15
+#define USB_USB20_BLK_AHB_SLV_HRST 16
+#define USB_USB20_BLK_AXI_MST_ARST 17
+#define USB_USB20_BLK_USB2_SYSREG_PRST 18
+#define USB_USB20_BLK_USB2_WRAP0_PRST 19
+#define USB_USB20_BLK_USB2_WRAP0_HRST 20
+#define USB_USB20_BLK_USB2_WRAP1_PRST 21
+#define USB_USB20_BLK_USB2_WRAP1_HRST 22
+#define USB_USB20_BLK_A2X0_HRST 23
+#define USB_USB20_BLK_A2X0_ARST 24
+#define USB_USB20_BLK_A2X1_HRST 25
+#define USB_USB20_BLK_A2X1_ARST 26
+#define USB_USB20_BLK_USB0_PHY_PON_RESET 27
+#define USB_USB20_BLK_USB1_PHY_PON_RESET 28
+#define USB_PERI2_SS_RST 29
+#define USB_PERI2_SLV_AFENCE_ARST 30
+
+#define TEE_KEYRAM_PRST 0
+#define TEE_DS_PRST 1
+#define TEE_EFUSE_PRST 2
+#define TEE_OCRAM_HRST 3
+#define TEE_SYSREG_PRST 4
+#define TEE_CCU_PRST 5
+#define TEE_CCU_CRST 6
+#define TEE_EIP150B_HRST 7
+#define TEE_EIP120SIII_HRST 8
+#define TEE_EIP120SIII_ARST 9
+#define TEE_EIP120SII_HRST 10
+#define TEE_EIP120SII_ARST 11
+#define TEE_EIP120SI_HRST 12
+#define TEE_EIP120SI_ARST 13
+#define TEE_DMAC_HRST 14
+#define TEE_DMAC_ARST 15
+#define TEE_X2P_TEESYS_PRST 16
+#define TEE_X2P_TEESYS_ARST 17
+#define TEE_AXI4_TEESYS_ARST 18
+#define TEE_APB3_TEESYS_PRST 19
+#define TEE_APB3_TEESYS_HRST 20
+#define TEE_AHB2_TEESYS_HRST 21
+
+#define GPU_PWR_WRAP_RGX_HOOD_RST 0
+#define GPU_PWR_WRAP_DFMU_RST 1
+
+#endif
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 07/18] reset: zhihe: add A210 support
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (5 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 06/18] dt-bindings: reset: add Zhihe A210 reset controllers Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-22 9:22 ` Philipp Zabel
2026-10-21 19:53 ` [PATCH 08/18] dt-bindings: pinctrl: add Zhihe A210 pin controller Han Gao via B4 Relay
` (10 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add support for A210 reset banks and linked reset signals. Check
register readback to detect rejected writes.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
drivers/reset/Kconfig | 11 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-a210.c | 589 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 601 insertions(+)
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 3168ab1eea88..039e8a4046dc 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -428,6 +428,17 @@ config RESET_UNIPHIER_GLUE
on UniPhier SoCs. Say Y if you want to control reset signals
provided by the glue layer.
+config RESET_ZHIHE_A210
+ tristate "ZhiHe A210 reset controller"
+ depends on OF && (ARCH_ZHIHE || COMPILE_TEST)
+ default ARCH_ZHIHE
+ help
+ Build the reset controller driver for the ZhiHe A210 SoC.
+
+ This driver provides reset control for the various hardware
+ blocks in the A210 SoC. Say Y if you are building a kernel
+ for the ZhiHe A210 platform.
+
config RESET_ZYNQ
bool "ZYNQ Reset Driver" if COMPILE_TEST
default ARCH_ZYNQ
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 45ad17062462..3620e94e4539 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -52,5 +52,6 @@ obj-$(CONFIG_RESET_TI_TPS380X) += reset-tps380x.o
obj-$(CONFIG_RESET_TN48M_CPLD) += reset-tn48m.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
+obj-$(CONFIG_RESET_ZHIHE_A210) += reset-a210.o
obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
diff --git a/drivers/reset/reset-a210.c b/drivers/reset/reset-a210.c
new file mode 100644
index 000000000000..38bad400d6b8
--- /dev/null
+++ b/drivers/reset/reset-a210.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Zhihe Computing Limited.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+
+#include <dt-bindings/reset/zhihe,a210-resets.h>
+
+struct a210_rst_signal {
+ u16 offset;
+ u32 mask;
+ /* Zero terminates a chain of signals that share one reset ID. */
+ u16 nextid;
+};
+
+struct a210_reset_data {
+ const struct a210_rst_signal *signals;
+ unsigned int num_signals;
+};
+
+struct a210_reset {
+ struct reset_controller_dev rcdev;
+ void __iomem *base;
+ const struct a210_reset_data *data;
+ /* Protects register updates and snapshots of linked reset signals. */
+ spinlock_t lock;
+};
+
+static const struct a210_rst_signal vp_rst_signals[] = {
+ [VP_VDEC_PRST] = { 0, BIT(0), 0 },
+ [VP_VDEC_CRST] = { 0, BIT(1), 0 },
+ [VP_VDEC_ARST] = { 0, BIT(2), 0 },
+ [VP_VENC_PRST] = { 0, BIT(3), 0 },
+ [VP_VENC_CRST] = { 0, BIT(4), 0 },
+ [VP_VENC_ARST] = { 0, BIT(5), 0 },
+ [VP_G2D_PRST] = { 0, BIT(6), 0 },
+ [VP_G2D_CRST] = { 0, BIT(7), 0 },
+ [VP_G2D_ARST] = { 0, BIT(8), 0 },
+ [VP_COMP_PRST] = { 0, BIT(9), 0 },
+ [VP_COMP_CRST] = { 0, BIT(10), 0 },
+ [VP_COMP_ARST] = { 0, BIT(11), 0 },
+ [VP_DECOMP_PRST] = { 0, BIT(12), 0 },
+ [VP_DECOMP_CRST] = { 0, BIT(13), 0 },
+ [VP_DECOMP_ARST] = { 0, BIT(14), 0 },
+ [VP_DFMU_PRST] = { 0, BIT(15), 0 },
+ [VP_DFMU_ARST] = { 0, BIT(16), 0 },
+ [VP_ARB_PRST] = { 0, BIT(18), 0 },
+ [VP_ARB_ARST] = { 0, BIT(19), 0 },
+ [VP_VDEC_RS_ARST] = { 0, BIT(20), 0 },
+ [VP_VENC_RS_ARST] = { 0, BIT(21), 0 },
+ [VP_COMP_EXTPRST] = { 0, BIT(22), 0 },
+ [VP_DECOMP_EXTPRST] = { 0, BIT(23), 0 },
+};
+
+static const struct a210_rst_signal vi_rst_signals[] = {
+ [VI_MIPI0_CSI0_PRST] = { 0, BIT(0), 0 },
+ [VI_MIPI0_CSI1_PRST] = { 0, BIT(1), 0 },
+ [VI_MIPI0_FIFO_RST] = { 0, BIT(2), 0 },
+ [VI_MIPI1_CSI0_PRST] = { 0, BIT(3), 0 },
+ [VI_MIPI1_CSI1_PRST] = { 0, BIT(4), 0 },
+ [VI_MIPI1_FIFO_RST] = { 0, BIT(5), 0 },
+ [VI_VIPRE_PRST] = { 0, BIT(6), 0 },
+ [VI_VIPRE_I0_PIX_RST] = { 0, BIT(7), 0 },
+ [VI_VIPRE_I1_PIX_RST] = { 0, BIT(8), 0 },
+ [VI_VIPRE_ISPIF_RST] = { 0, BIT(9), 0 },
+ [VI_VIPRE_ARST] = { 0, BIT(10), 0 },
+ [VI_ISP_RST] = { 0, BIT(11), 0 },
+ [VI_COMP_PRST] = { 0, BIT(12), 0 },
+ [VI_COMP_ARST] = { 0, BIT(13), 0 },
+ [VI_COMP_ISPOUT_RST] = { 0, BIT(14), 0 },
+ [VI_COMP_DECOUT_RST] = { 0, BIT(15), 0 },
+ [VI_COMP_VSEOUT_RST] = { 0, BIT(16), 0 },
+ [VI_COMP0_RST] = { 0, BIT(17), 0 },
+ [VI_COMP1_RST] = { 0, BIT(18), 0 },
+ [VI_DECOMP_RST] = { 0, BIT(19), 0 },
+ [VI_DW200_RST] = { 0, BIT(20), 0 },
+ [VI_DFMU_PRST] = { 0, BIT(21), 0 },
+ [VI_DFMU_ARST] = { 0, BIT(22), 0 },
+ [VI_ARB_PRST] = { 0, BIT(23), 0 },
+ [VI_ARB_ARST] = { 0, BIT(24), 0 },
+ [VI_X2H0_HRST] = { 0, BIT(26), 0 },
+ [VI_X2H1_HRST] = { 0, BIT(27), 0 },
+ [VI_X2H2_HRST] = { 0, BIT(28), 0 },
+ [VI_REC_PRST] = { 0, BIT(29), 0 },
+ [VI_REC_ARST] = { 0, BIT(30), 0 },
+};
+
+static const struct a210_rst_signal npu_rst_signals[] = {
+ [NPU_AAB_MST_RST] = { 0, BIT(0), 0 },
+ [NPU_AFENCE_RST] = { 0, BIT(1), 0 },
+ [NPU_AXI_CCU_PRST] = { 0, BIT(2), 0 },
+ [NPU_AXI_CCU_RST] = { 0, BIT(3), 0 },
+ [NPU_AXI_M2S1_RST] = { 0, BIT(4), 0 },
+ [NPU_AXI_RST] = { 0, BIT(5), 0 },
+ [NPU_CLK_CALC_RST] = { 0, BIT(6), 0 },
+ [NPU_DFMU_ARST] = { 0, BIT(7), 0 },
+ [NPU_DFMU_PRST] = { 0, BIT(8), 0 },
+ [NPU_LPC_C_RST] = { 0, BIT(9), 0 },
+ [NPU_LPE_C_PRST] = { 0, BIT(10), 0 },
+ [NPU_LPE_C_RST] = { 0, BIT(11), 0 },
+ [NPU_ARST] = { 0, BIT(12), 0 },
+ [NPU_CRST] = { 0, BIT(13), 0 },
+ [NPU_HRST] = { 0, BIT(14), 0 },
+ [NPU_PCTRL_PB_RST] = { 0, BIT(15), 0 },
+ [NPU_PCTRL_PRST] = { 0, BIT(16), 0 },
+ [NPU_PCTRL_RST] = { 0, BIT(17), 0 },
+ [NPU_PTW_CCU_PRST] = { 0, BIT(18), 0 },
+ [NPU_PTW_CCU_RST] = { 0, BIT(19), 0 },
+ [NPU_SEMA_ARST] = { 0, BIT(20), 0 },
+ [NPU_SEMA_PRST] = { 0, BIT(21), 0 },
+ [NPU_DROOP_CCTRL_PRST] = { 0, BIT(22), 0 },
+ [NPU_DROOP_CCTRL_RST] = { 0, BIT(23), 0 },
+ [NPU_X2H_RST] = { 0, BIT(24), 0 },
+ [NPU_X2P_RST] = { 0, BIT(25), 0 },
+ [NPU_LDIP_RST] = { 0, BIT(26), 0 },
+ [NPU_SRAM_RST] = { 0, BIT(27), 0 },
+};
+
+static const struct a210_rst_signal vo_rst_signals[] = {
+ [VO_X2H0_RST] = { 0, BIT(0), 0 },
+ [VO_X2H1_RST] = { 0, BIT(1), 0 },
+ [VO_DPU_HRST] = { 0, BIT(2), 0 },
+ [VO_DPU_CRST] = { 0, BIT(3), 0 },
+ [VO_DPU_ARST] = { 0, BIT(4), 0 },
+ [VO_AUXDISP_PRST] = { 0, BIT(5), 0 },
+ [VO_AUXDISP_PIX_RST] = { 0, BIT(6), 0 },
+ [VO_AUXDISP_ARST] = { 0, BIT(7), 0 },
+ [VO_HDMI_PRST] = { 0, BIT(8), 0 },
+ [VO_HDMI_MAIN_RST] = { 0, BIT(9), 0 },
+ [VO_MIPI_PRST] = { 0, BIT(10), 0 },
+ [VO_DECOMP_PRST] = { 0, BIT(11), 0 },
+ [VO_DECOMP0_CRST] = { 0, BIT(12), 0 },
+ [VO_DECOMP1_CRST] = { 0, BIT(13), 0 },
+ [VO_DECOMP_ARST] = { 0, BIT(14), 0 },
+ [VO_ARB_PRST] = { 0, BIT(15), 0 },
+ [VO_ARB_ARST] = { 0, BIT(16), 0 },
+ [VO_DFMU_PRST] = { 0, BIT(17), 0 },
+ [VO_DFMU_ARST] = { 0, BIT(18), 0 },
+};
+
+static const struct a210_rst_signal peri0_rst_signals[] = {
+ [PERI0_TIMER0_CRST] = { 0, BIT(0), 0 },
+ [PERI0_TIMER0_PRST] = { 0, BIT(1), 0 },
+ [PERI0_TIMER1_CRST] = { 0, BIT(2), 0 },
+ [PERI0_TIMER1_PRST] = { 0, BIT(3), 0 },
+ [PERI0_WDT0_PRST] = { 0, BIT(4), 0 },
+ [PERI0_MBOX0_PRST] = { 0, BIT(5), 0 },
+ [PERI0_MBOX1_PRST] = { 0, BIT(6), 0 },
+ [PERI0_TIMER0_RST] = { 0, BIT(0) | BIT(1), 0 },
+ [PERI0_TIMER1_RST] = { 0, BIT(2) | BIT(3), 0 },
+};
+
+static const struct a210_rst_signal peri1_rst_signals[] = {
+ [PERI1_GMAC0_ARST] = { 0, BIT(0), 0 },
+ [PERI1_GMAC0_HRST] = { 0, BIT(1), 0 },
+ [PERI1_GMAC1_ARST] = { 0, BIT(2), 0 },
+ [PERI1_GMAC1_HRST] = { 0, BIT(3), 0 },
+ [PERI1_GPIO0_DBRST] = { 0, BIT(4), 0 },
+ [PERI1_GPIO0_PRST] = { 0, BIT(5), 0 },
+ [PERI1_GPIO1_DBRST] = { 0, BIT(6), 0 },
+ [PERI1_GPIO1_PRST] = { 0, BIT(7), 0 },
+ [PERI1_I2C0_IC_RST] = { 0, BIT(8), 0 },
+ [PERI1_I2C0_PRST] = { 0, BIT(9), 0 },
+ [PERI1_I2C1_IC_RST] = { 0, BIT(10), 0 },
+ [PERI1_I2C1_PRST] = { 0, BIT(11), 0 },
+ [PERI1_I2C2_IC_RST] = { 0, BIT(12), 0 },
+ [PERI1_I2C2_PRST] = { 0, BIT(13), 0 },
+ [PERI1_I2S0_PRST] = { 0, BIT(14), 0 },
+ [PERI1_MST_BUS_ARST] = { 0, BIT(15), 0 },
+ [PERI1_MST_BUS_PRST] = { 0, BIT(16), 0 },
+ [PERI1_PWM0_CRST] = { 0, BIT(17), 0 },
+ [PERI1_PWM0_PRST] = { 0, BIT(18), 0 },
+ [PERI1_QSPI0_PRST] = { 0, BIT(19), 0 },
+ [PERI1_QSPI0_SSI_RST] = { 0, BIT(20), 0 },
+ [PERI1_SPI0_PRST] = { 0, BIT(21), 0 },
+ [PERI1_SPI0_SSI_RST] = { 0, BIT(22), 0 },
+ [PERI1_UART0_PRST] = { 0, BIT(23), PERI1_UART0_S_RST },
+ [PERI1_UART0_S_RST] = { 0, BIT(24), 0 },
+ [PERI1_UART1_PRST] = { 0, BIT(25), PERI1_UART1_S_RST },
+ [PERI1_UART1_S_RST] = { 0, BIT(26), 0 },
+ [PERI1_UART2_PRST] = { 0, BIT(27), PERI1_UART2_S_RST },
+ [PERI1_UART2_S_RST] = { 0, BIT(28), 0 },
+ [PERI1_UART3_PRST] = { 0, BIT(29), PERI1_UART3_S_RST },
+ [PERI1_UART3_S_RST] = { 0, BIT(30), 0 },
+ [PERI1_X2H_GMAC0_ARST] = { 0, BIT(31), 0 },
+ [PERI1_X2H_GMAC0_HRST] = { 0x4, BIT(0), 0 },
+ [PERI1_X2H_GMAC1_ARST] = { 0x4, BIT(1), 0 },
+ [PERI1_X2H_GMAC1_HRST] = { 0x4, BIT(2), 0 },
+ [PERI1_DFMU_ARESET] = { 0x4, BIT(3), 0 },
+ [PERI1_DFMU_PRESET] = { 0x4, BIT(4), 0 },
+ [PERI1_PAD_CTRL_PRST] = { 0x4, BIT(5), 0 },
+ [PERI1_PDM0_MRST] = { 0x4, BIT(6), 0 },
+ [PERI1_PDM0_PRST] = { 0x4, BIT(7), 0 },
+ [PERI1_TDM0_RST] = { 0x4, BIT(8), 0 },
+ [PERI1_CAN0_IPG_PE_RST] = { 0x4, BIT(9), 0 },
+ [PERI1_CAN0_IPG_RST] = { 0x4, BIT(10), 0 },
+ [PERI1_CAN0_IPG_SOFT_RST] = { 0x4, BIT(11), 0 },
+ [PERI1_CAN0_IPG_TS_RST] = { 0x4, BIT(12), 0 },
+ [PERI1_CAN0_PRST] = { 0x4, BIT(13), 0 },
+ [PERI1_CAN1_IPG_PE_RST] = { 0x4, BIT(14), 0 },
+ [PERI1_CAN1_IPG_RST] = { 0x4, BIT(15), 0 },
+ [PERI1_CAN1_IPG_SOFT_RST] = { 0x4, BIT(16), 0 },
+ [PERI1_CAN1_IPG_TS_RST] = { 0x4, BIT(17), 0 },
+ [PERI1_CAN1_PRST] = { 0x4, BIT(18), 0 },
+ [PERI1_CHIP_DBG_ARST] = { 0x4, BIT(19), 0 },
+ [PERI1_CHIP_DBG_CRST] = { 0x4, BIT(20), 0 },
+ [PERI1_CHIP_DBG_PRST] = { 0x4, BIT(21), 0 },
+ [PERI1_GMAC_CRST] = { 0x4, BIT(22), 0 },
+ [PERI1_X2H_GMAC2_ARST] = { 0x4, BIT(23), 0 },
+ [PERI1_X2H_GMAC2_HRST] = { 0x4, BIT(24), 0 },
+ [PERI1_ZGMAC_X2X_ARST] = { 0x4, BIT(25), 0 },
+ [PERI1_SPI0_RST] = { 0, BIT(21) | BIT(22), 0 },
+ [PERI1_I2C0_RST] = { 0, BIT(8) | BIT(9), 0 },
+ [PERI1_I2C1_RST] = { 0, BIT(10) | BIT(11), 0 },
+ [PERI1_I2C2_RST] = { 0, BIT(12) | BIT(13), 0 },
+ [PERI1_GMAC0_RST] = { 0, BIT(0) | BIT(1) | BIT(31), 0 },
+ [PERI1_GMAC0_X2H_RST] = { 0x4, BIT(0), 0 },
+ [PERI1_GMAC1_RST] = { 0, BIT(2) | BIT(3), 0 },
+ [PERI1_GMAC1_X2H_RST] = { 0x4, BIT(1) | BIT(2), 0 },
+};
+
+static const struct a210_rst_signal peri2_rst_signals[] = {
+ [PERI2_CAN2_IPG_PE_RST] = { 0, BIT(0), 0 },
+ [PERI2_CAN2_IPG_RST] = { 0, BIT(1), 0 },
+ [PERI2_CAN2_IPG_SOFT_RST] = { 0, BIT(2), 0 },
+ [PERI2_CAN2_IPG_TS_RST] = { 0, BIT(3), 0 },
+ [PERI2_CAN2_PRST] = { 0, BIT(4), 0 },
+ [PERI2_GPIO2_DBRST] = { 0, BIT(5), 0 },
+ [PERI2_GPIO2_PRST] = { 0, BIT(6), 0 },
+ [PERI2_I2C4_IC_RST] = { 0, BIT(7), 0 },
+ [PERI2_I2C4_PRST] = { 0, BIT(8), 0 },
+ [PERI2_I2S2_PRST] = { 0, BIT(9), 0 },
+ [PERI2_SPI1_PRST] = { 0, BIT(10), 0 },
+ [PERI2_SPI1_SSI_RST] = { 0, BIT(11), 0 },
+ [PERI2_UART4_PRST] = { 0, BIT(12), PERI2_UART4_S_RST },
+ [PERI2_UART4_S_RST] = { 0, BIT(13), 0 },
+ [PERI2_UART5_PRST] = { 0, BIT(14), PERI2_UART5_S_RST },
+ [PERI2_UART5_S_RST] = { 0, BIT(15), 0 },
+ [PERI2_UART6_PRST] = { 0, BIT(16), PERI2_UART6_S_RST },
+ [PERI2_UART6_S_RST] = { 0, BIT(17), 0 },
+ [PERI2_PAD_CTRL_PRST] = { 0, BIT(18), 0 },
+ [PERI2_GPIO3_DBRST] = { 0, BIT(19), 0 },
+ [PERI2_GPIO3_PRST] = { 0, BIT(20), 0 },
+ [PERI2_I2C3_IC_RST] = { 0, BIT(21), 0 },
+ [PERI2_I2C3_PRST] = { 0, BIT(22), 0 },
+ [PERI2_I2C5_IC_RST] = { 0, BIT(23), 0 },
+ [PERI2_I2C5_PRST] = { 0, BIT(24), 0 },
+ [PERI2_I2C6_IC_RST] = { 0, BIT(25), 0 },
+ [PERI2_I2C6_PRST] = { 0, BIT(26), 0 },
+ [PERI2_I2C7_IC_RST] = { 0, BIT(27), 0 },
+ [PERI2_I2C7_PRST] = { 0, BIT(28), 0 },
+ [PERI2_I2S1_PRST] = { 0, BIT(29), 0 },
+ [PERI2_I2S3_PRST] = { 0, BIT(30), 0 },
+ [PERI2_UART7_PRST] = { 0, BIT(31), PERI2_UART7_S_RST },
+ [PERI2_UART7_S_RST] = { 0x4, BIT(0), 0 },
+ [PERI2_UART8_PRST] = { 0x4, BIT(1), PERI2_UART8_S_RST },
+ [PERI2_UART8_S_RST] = { 0x4, BIT(2), 0 },
+ [PERI2_UART9_PRST] = { 0x4, BIT(3), PERI2_UART9_S_RST },
+ [PERI2_UART9_S_RST] = { 0x4, BIT(4), 0 },
+ [PERI2_QSPI1_PRST] = { 0x4, BIT(5), 0 },
+ [PERI2_QSPI1_SSI_RST] = { 0x4, BIT(6), 0 },
+ [PERI2_PWM1_CRST] = { 0x4, BIT(7), 0 },
+ [PERI2_PWM1_PRST] = { 0x4, BIT(8), 0 },
+ [PERI2_PWM2_CRST] = { 0x4, BIT(9), 0 },
+ [PERI2_PWM2_PRST] = { 0x4, BIT(10), 0 },
+ [PERI2_I2C3_RST] = { 0, BIT(21) | BIT(22), 0 },
+ [PERI2_I2C4_RST] = { 0, BIT(7) | BIT(8), 0 },
+ [PERI2_I2C5_RST] = { 0, BIT(23) | BIT(24), 0 },
+ [PERI2_I2C6_RST] = { 0, BIT(25) | BIT(26), 0 },
+ [PERI2_I2C7_RST] = { 0, BIT(27) | BIT(28), 0 },
+ [PERI2_SPI1_RST] = { 0, BIT(10) | BIT(11), 0 },
+};
+
+static const struct a210_rst_signal peri3_rst_signals[] = {
+ [PERI3_DMAC_ARST] = { 0, BIT(0), 0 },
+ [PERI3_DMAC_HRST] = { 0, BIT(1), 0 },
+ [PERI3_EMMC_SDIO_CLKGEN_RST] = { 0, BIT(2), 0 },
+ [PERI3_EMMC_RST] = { 0, BIT(3), 0 },
+ [PERI3_EMMC_X2X_ARST_M] = { 0, BIT(4), 0 },
+ [PERI3_EMMC_X2X_ARST_S] = { 0, BIT(5), 0 },
+ [PERI3_SDIO_RST] = { 0, BIT(6), 0 },
+ [PERI3_SDIO_X2X_ARST_M] = { 0, BIT(7), 0 },
+ [PERI3_SDIO_X2X_ARST_S] = { 0, BIT(8), 0 },
+ [PERI3_AXI_MST_ARST] = { 0, BIT(9), 0 },
+ [PERI3_AXI_MST_PRST] = { 0, BIT(10), 0 },
+ [PERI3_ADC_PRST] = { 0, BIT(11), 0 },
+ [PERI3_TEE_X2X_ARST_M] = { 0, BIT(12), 0 },
+ [PERI3_TEE_X2X_ARST_S] = { 0, BIT(13), 0 },
+ [PERI3_TEE_H2H_HRST] = { 0, BIT(14), 0 },
+ [PERI3_GPIO4_DBRST] = { 0, BIT(15), 0 },
+ [PERI3_GPIO4_PRST] = { 0, BIT(16), 0 },
+ [PERI3_PAD_CTRL_PRST] = { 0, BIT(17), 0 },
+};
+
+static const struct a210_rst_signal pcie_rst_signals[] = {
+ [PCIE_X2X_PERI_SLV_ARST] = { 0, BIT(0), 0 },
+ [PCIE_X2X_PERI_MST_ARST] = { 0, BIT(4), 0 },
+ [PCIE_AXI4_PCIE_MST_ARST] = { 0, BIT(8), 0 },
+ [PCIE_AXI4_PCIE_MST_PRST] = { 0, BIT(12), 0 },
+ [PCIE_DFMU_PRST] = { 0x4, BIT(0), 0 },
+ [PCIE_DFMU_ARST] = { 0x4, BIT(4), 0 },
+ [PCIE_E16PHY_PHY_RST] = { 0x8, BIT(0), 0 },
+ [PCIE_E16PHY_APBS_PRST] = { 0x8, BIT(4), 0 },
+ [PCIE_X2X_SATA_MST_ARST] = { 0x10, BIT(0), 0 },
+ [PCIE_X2X_SATA_SLV_ARST] = { 0x10, BIT(4), 0 },
+ [PCIE_SATA_ARESET] = { 0x10, BIT(8), 0 },
+ [PCIE_SATA_RST_PMALIVE] = { 0x10, BIT(12), 0 },
+ [PCIE_SATA_SLV_AFENCE_ARST] = { 0x10, BIT(16), 0 },
+ [PCIE_SATA_MST_AFENCE_ARST] = { 0x10, BIT(20), 0 },
+ [PCIE_SATA_RST_ASIC0] = { 0x14, BIT(0), 0 },
+ [PCIE_SATA_RST_ASIC1] = { 0x14, BIT(4), 0 },
+ [PCIE_SATA_RST_RXOOB0] = { 0x14, BIT(8), 0 },
+ [PCIE_SATA_RST_RXOOB1] = { 0x14, BIT(12), 0 },
+ [PCIE_DM_GEN3X4_APBS_PRST] = { 0x20, BIT(0), 0 },
+ [PCIE_DM_GEN3X4_POWER_UP_RST] = { 0x20, BIT(4), 0 },
+ [PCIE_DM_SLV_AFENCE_ARST] = { 0x20, BIT(16), 0 },
+ [PCIE_DM_MST_AFENCE_ARST] = { 0x20, BIT(20), 0 },
+ [PCIE_RP_GEN3X1_APBS_PRST] = { 0x24, BIT(0), 0 },
+ [PCIE_RP_GEN3X1_POWER_UP_RST] = { 0x24, BIT(4), 0 },
+ [PCIE_RP_SLV_AFENCE_ARST] = { 0x24, BIT(16), 0 },
+ [PCIE_RP_MST_AFENCE_ARST] = { 0x24, BIT(20), 0 },
+};
+
+static const struct a210_rst_signal usb_rst_signals[] = {
+ [USB_DFMU_PRST] = { 0, BIT(0), 0 },
+ [USB_DFMU_ARST] = { 0, BIT(4), 0 },
+ [USB_AXI4_MST_ARST] = { 0, BIT(8), 0 },
+ [USB_AXI4_MST_PRST] = { 0, BIT(12), 0 },
+ [USB_DPTX_APBS_PRST] = { 0x4, BIT(0), 0 },
+ [USB_DPTX_VCC_RST] = { 0x4, BIT(4), 0 },
+ [USB_USB31_APBS_PRST] = { 0x8, BIT(0), 0 },
+ [USB_USB31_VCC_RST] = { 0x8, BIT(4), 0 },
+ [USB_USB31_PHY_RST] = { 0x8, BIT(8), 0 },
+ [USB_USB31_SLV_AFENCE_ARST] = { 0x8, BIT(12), 0 },
+ [USB_C10PHY_PHY_RST] = { 0xc, BIT(0), 0 },
+ [USB_C10PHY_APBS_PRST] = { 0xc, BIT(4), 0 },
+ [USB_USB20_BLK_X2H_HRST] = { 0x10, BIT(0), 0 },
+ [USB_USB20_BLK_X2H_ARST] = { 0x10, BIT(4), 0 },
+ [USB_USB20_SLV_AFENCE_ARST] = { 0x10, BIT(8), 0 },
+ [USB_USB20_BLK_H2P_HRST] = { 0x10, BIT(16), 0 },
+ [USB_USB20_BLK_AHB_SLV_HRST] = { 0x10, BIT(20), 0 },
+ [USB_USB20_BLK_AXI_MST_ARST] = { 0x10, BIT(24), 0 },
+ [USB_USB20_BLK_USB2_SYSREG_PRST] = { 0x10, BIT(28), 0 },
+ [USB_USB20_BLK_USB2_WRAP0_PRST] = { 0x14, BIT(0), 0 },
+ [USB_USB20_BLK_USB2_WRAP0_HRST] = { 0x14, BIT(4), 0 },
+ [USB_USB20_BLK_USB2_WRAP1_PRST] = { 0x14, BIT(8), 0 },
+ [USB_USB20_BLK_USB2_WRAP1_HRST] = { 0x14, BIT(12), 0 },
+ [USB_USB20_BLK_A2X0_HRST] = { 0x14, BIT(16), 0 },
+ [USB_USB20_BLK_A2X0_ARST] = { 0x14, BIT(20), 0 },
+ [USB_USB20_BLK_A2X1_HRST] = { 0x14, BIT(24), 0 },
+ [USB_USB20_BLK_A2X1_ARST] = { 0x14, BIT(28), 0 },
+ [USB_USB20_BLK_USB0_PHY_PON_RESET] = { 0x18, BIT(0), 0 },
+ [USB_USB20_BLK_USB1_PHY_PON_RESET] = { 0x18, BIT(4), 0 },
+ [USB_PERI2_SS_RST] = { 0x20, BIT(0), 0 },
+ [USB_PERI2_SLV_AFENCE_ARST] = { 0x20, BIT(4), 0 },
+};
+
+static const struct a210_rst_signal tee_rst_signals[] = {
+ [TEE_KEYRAM_PRST] = { 0, BIT(0), 0 },
+ [TEE_DS_PRST] = { 0, BIT(1), 0 },
+ [TEE_EFUSE_PRST] = { 0, BIT(2), 0 },
+ [TEE_OCRAM_HRST] = { 0, BIT(3), 0 },
+ [TEE_SYSREG_PRST] = { 0, BIT(4), 0 },
+ [TEE_CCU_PRST] = { 0, BIT(5), 0 },
+ [TEE_CCU_CRST] = { 0, BIT(6), 0 },
+ [TEE_EIP150B_HRST] = { 0, BIT(8), 0 },
+ [TEE_EIP120SIII_HRST] = { 0, BIT(9), 0 },
+ [TEE_EIP120SIII_ARST] = { 0, BIT(10), 0 },
+ [TEE_EIP120SII_HRST] = { 0, BIT(11), 0 },
+ [TEE_EIP120SII_ARST] = { 0, BIT(12), 0 },
+ [TEE_EIP120SI_HRST] = { 0, BIT(13), 0 },
+ [TEE_EIP120SI_ARST] = { 0, BIT(14), 0 },
+ [TEE_DMAC_HRST] = { 0, BIT(15), 0 },
+ [TEE_DMAC_ARST] = { 0, BIT(16), 0 },
+ [TEE_X2P_TEESYS_PRST] = { 0, BIT(24), 0 },
+ [TEE_X2P_TEESYS_ARST] = { 0, BIT(25), 0 },
+ [TEE_AXI4_TEESYS_ARST] = { 0, BIT(26), 0 },
+ [TEE_APB3_TEESYS_PRST] = { 0, BIT(27), 0 },
+ [TEE_APB3_TEESYS_HRST] = { 0, BIT(28), 0 },
+ [TEE_AHB2_TEESYS_HRST] = { 0, BIT(29), 0 },
+};
+
+static const struct a210_rst_signal gpu_rst_signals[] = {
+ [GPU_PWR_WRAP_RGX_HOOD_RST] = { 0, BIT(0), 0 },
+ [GPU_PWR_WRAP_DFMU_RST] = { 0, BIT(1), 0 },
+};
+
+static inline struct a210_reset *to_a210_reset(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct a210_reset, rcdev);
+}
+
+static int a210_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ struct a210_reset *rst = to_a210_reset(rcdev);
+ const struct a210_rst_signal *signal;
+ unsigned long flags;
+ u32 value;
+ int ret = 0;
+
+ if (id >= rst->data->num_signals)
+ return -EINVAL;
+
+ spin_lock_irqsave(&rst->lock, flags);
+ do {
+ signal = &rst->data->signals[id];
+ value = readl(rst->base + signal->offset);
+ if (assert)
+ value &= ~signal->mask;
+ else
+ value |= signal->mask;
+ writel(value, rst->base + signal->offset);
+ /* Firmware can lock individual reset controls against AP writes. */
+ if ((readl(rst->base + signal->offset) & signal->mask) !=
+ (value & signal->mask)) {
+ ret = -EIO;
+ break;
+ }
+ id = signal->nextid;
+ } while (id);
+ spin_unlock_irqrestore(&rst->lock, flags);
+
+ return ret;
+}
+
+static int a210_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ return a210_reset_update(rcdev, id, true);
+}
+
+static int a210_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ return a210_reset_update(rcdev, id, false);
+}
+
+static int a210_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct a210_reset *rst = to_a210_reset(rcdev);
+ const struct a210_rst_signal *signal;
+ unsigned long flags;
+ bool asserted;
+
+ if (id >= rst->data->num_signals)
+ return -EINVAL;
+
+ /* The logical reset is asserted if any linked signal is asserted. */
+ spin_lock_irqsave(&rst->lock, flags);
+ do {
+ signal = &rst->data->signals[id];
+ asserted = (readl(rst->base + signal->offset) & signal->mask) !=
+ signal->mask;
+ if (asserted)
+ break;
+ id = signal->nextid;
+ } while (id);
+ spin_unlock_irqrestore(&rst->lock, flags);
+
+ return asserted;
+}
+
+static const struct reset_control_ops a210_reset_ops = {
+ .assert = a210_reset_assert,
+ .deassert = a210_reset_deassert,
+ .status = a210_reset_status,
+};
+
+static int a210_reset_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct a210_reset *rst;
+
+ rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
+ if (!rst)
+ return -ENOMEM;
+
+ rst->data = device_get_match_data(dev);
+ if (!rst->data)
+ return -EINVAL;
+
+ rst->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rst->base))
+ return PTR_ERR(rst->base);
+
+ spin_lock_init(&rst->lock);
+ rst->rcdev.ops = &a210_reset_ops;
+ rst->rcdev.owner = THIS_MODULE;
+ rst->rcdev.dev = dev;
+ rst->rcdev.of_node = dev->of_node;
+ rst->rcdev.nr_resets = rst->data->num_signals;
+
+ return devm_reset_controller_register(dev, &rst->rcdev);
+}
+
+static const struct a210_reset_data vp_reset_data = {
+ .signals = vp_rst_signals,
+ .num_signals = ARRAY_SIZE(vp_rst_signals),
+};
+
+static const struct a210_reset_data vi_reset_data = {
+ .signals = vi_rst_signals,
+ .num_signals = ARRAY_SIZE(vi_rst_signals),
+};
+
+static const struct a210_reset_data npu_reset_data = {
+ .signals = npu_rst_signals,
+ .num_signals = ARRAY_SIZE(npu_rst_signals),
+};
+
+static const struct a210_reset_data vo_reset_data = {
+ .signals = vo_rst_signals,
+ .num_signals = ARRAY_SIZE(vo_rst_signals),
+};
+
+static const struct a210_reset_data peri0_reset_data = {
+ .signals = peri0_rst_signals,
+ .num_signals = ARRAY_SIZE(peri0_rst_signals),
+};
+
+static const struct a210_reset_data peri1_reset_data = {
+ .signals = peri1_rst_signals,
+ .num_signals = ARRAY_SIZE(peri1_rst_signals),
+};
+
+static const struct a210_reset_data peri2_reset_data = {
+ .signals = peri2_rst_signals,
+ .num_signals = ARRAY_SIZE(peri2_rst_signals),
+};
+
+static const struct a210_reset_data peri3_reset_data = {
+ .signals = peri3_rst_signals,
+ .num_signals = ARRAY_SIZE(peri3_rst_signals),
+};
+
+static const struct a210_reset_data pcie_reset_data = {
+ .signals = pcie_rst_signals,
+ .num_signals = ARRAY_SIZE(pcie_rst_signals),
+};
+
+static const struct a210_reset_data usb_reset_data = {
+ .signals = usb_rst_signals,
+ .num_signals = ARRAY_SIZE(usb_rst_signals),
+};
+
+static const struct a210_reset_data tee_reset_data = {
+ .signals = tee_rst_signals,
+ .num_signals = ARRAY_SIZE(tee_rst_signals),
+};
+
+static const struct a210_reset_data gpu_reset_data = {
+ .signals = gpu_rst_signals,
+ .num_signals = ARRAY_SIZE(gpu_rst_signals),
+};
+
+static const struct of_device_id a210_reset_of_match[] = {
+ { .compatible = "zhihe,a210-vp-reset", .data = &vp_reset_data },
+ { .compatible = "zhihe,a210-vi-reset", .data = &vi_reset_data },
+ { .compatible = "zhihe,a210-npu-reset", .data = &npu_reset_data },
+ { .compatible = "zhihe,a210-vo-reset", .data = &vo_reset_data },
+ { .compatible = "zhihe,a210-peri0-reset", .data = &peri0_reset_data },
+ { .compatible = "zhihe,a210-peri1-reset", .data = &peri1_reset_data },
+ { .compatible = "zhihe,a210-peri2-reset", .data = &peri2_reset_data },
+ { .compatible = "zhihe,a210-peri3-reset", .data = &peri3_reset_data },
+ { .compatible = "zhihe,a210-pcie-reset", .data = &pcie_reset_data },
+ { .compatible = "zhihe,a210-usb-reset", .data = &usb_reset_data },
+ { .compatible = "zhihe,a210-tee-reset", .data = &tee_reset_data },
+ { .compatible = "zhihe,a210-gpu-reset", .data = &gpu_reset_data },
+ {}
+};
+MODULE_DEVICE_TABLE(of, a210_reset_of_match);
+
+static struct platform_driver a210_reset_driver = {
+ .probe = a210_reset_probe,
+ .driver = {
+ .name = "a210-reset",
+ .of_match_table = a210_reset_of_match,
+ },
+};
+module_platform_driver(a210_reset_driver);
+
+MODULE_AUTHOR("Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>");
+MODULE_DESCRIPTION("Zhihe A210 reset controller driver");
+MODULE_LICENSE("GPL");
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 08/18] dt-bindings: pinctrl: add Zhihe A210 pin controller
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (6 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 07/18] reset: zhihe: add A210 support Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-22 19:01 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 09/18] pinctrl: zhihe: add A210 support Han Gao via B4 Relay
` (9 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add bindings for the four A210 pad controllers. Describe the shared
PERI3 SDIO mux and per-pad bias controls.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
.../bindings/pinctrl/zhihe,a210-pinctrl.yaml | 206 +++++++++++++++++++++
1 file changed, 206 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml
new file mode 100644
index 000000000000..51cbb0189f47
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml
@@ -0,0 +1,206 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/zhihe,a210-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ZhiHe A210 pin controller
+
+maintainers:
+ - Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
+
+description: |
+ Pinmux and pinconf controller of the ZhiHe A210 RISC-V SoC.
+
+ The pads of the A210 are split into four groups, each managed by its
+ own pad controller with a separate register range:
+
+ AON pad controller -> zhihe,a210-aon-pinctrl
+ PADCTRL0 (peripheral1) -> zhihe,a210-peri1-pinctrl
+ PADCTRL1 (peripheral2) -> zhihe,a210-peri2-pinctrl
+ PADCTRL2 (peripheral3) -> zhihe,a210-peri3-pinctrl
+
+ Each pad can be muxed individually to up to 8 different functions,
+ though for most pads only a few of those configurations are valid.
+ A few pads in the AON group do not support muxing or configuration
+ at all.
+
+ AON, PERI1 and PERI2 pads support configurable drive strength, bias,
+ input enable, Schmitt trigger and slew rate. PERI3 has a separate pad
+ layout: its six SDIO pads share one mux bit. Select their function with
+ the "sdio" group. Per-pad bias can be configured independently.
+
+properties:
+ compatible:
+ enum:
+ - zhihe,a210-aon-pinctrl
+ - zhihe,a210-peri1-pinctrl
+ - zhihe,a210-peri2-pinctrl
+ - zhihe,a210-peri3-pinctrl
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ const: pclk
+
+patternProperties:
+ '-[0-9]+$':
+ type: object
+
+ description:
+ A pinmux group referenced by a consumer's pinctrl phandle. It
+ contains one subnode per set of pads sharing the same pinmux and
+ pinconf settings.
+
+ additionalProperties: false
+
+ patternProperties:
+ '-pins$':
+ type: object
+ $ref: /schemas/pinctrl/pincfg-node.yaml#
+
+ description:
+ A pinctrl node describing the pinmux and pinconf settings of
+ one or more pads.
+
+ properties:
+ pins:
+ $ref: /schemas/pinctrl/pinmux-node.yaml#/properties/pins
+ description: List of pads that properties in the node apply to.
+
+ groups:
+ items:
+ - const: sdio
+
+ function:
+ $ref: /schemas/pinctrl/pinmux-node.yaml#/properties/function
+ enum: [ aouart, aouart_ir, aogpio0, aogpio1, aoi2c0, aoi2c1,
+ aospi, jtag, reset, por, pmic, dvs, uart0, uart1,
+ uart2, uart3, uart4, uart5, uart6, uart7, uart8,
+ uart9, uart0_ir, uart1_ir, uart2_ir, uart3_ir,
+ uart4_ir, uart5_ir, uart6_ir, uart7_ir, uart8_ir,
+ uart9_ir, gpio0, gpio1, gpio2, gpio3, gpio4, gmac0,
+ gmac1, spi0, spi1, qspi0, qspi1, pwm0, pwm1, pwm2,
+ can0, can1, can2, i2s0, i2s1, i2s2, i2s3, i2c0, i2c1,
+ i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c7_smb, sdio,
+ isp0, dptx, usb31, sata_p0, sata_p1, hdmi, zmac,
+ bsel, dbgm, cdbg, pdm, tdm, pcie_x1, pcie_x4,
+ sen_vclk ]
+ description: The mux function to select for the given pins.
+
+ bias-disable: true
+
+ bias-pull-up: true
+
+ bias-pull-down: true
+
+ drive-strength:
+ enum: [ 1, 2, 3, 5, 7, 8, 10, 12, 13, 15, 16, 18, 20, 21, 23,
+ 25 ]
+ description: Drive strength in mA.
+
+ input-enable: true
+
+ input-disable: true
+
+ input-schmitt-enable: true
+
+ input-schmitt-disable: true
+
+ slew-rate:
+ maximum: 1
+
+ oneOf:
+ - required: [pins]
+ - required: [groups]
+
+ additionalProperties: false
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ const: zhihe,a210-peri3-pinctrl
+ then:
+ patternProperties:
+ '-[0-9]+$':
+ patternProperties:
+ '-pins$':
+ properties:
+ pins:
+ items:
+ enum: [SDIO_CLK, SDIO_CMD, SDIO_DAT0, SDIO_DAT1,
+ SDIO_DAT2, SDIO_DAT3]
+ function:
+ enum: [sdio, gpio4]
+ drive-strength: false
+ input-enable: false
+ input-disable: false
+ input-schmitt-enable: false
+ input-schmitt-disable: false
+ slew-rate: false
+ if:
+ required: [function]
+ then:
+ required: [groups]
+ else:
+ patternProperties:
+ '-[0-9]+$':
+ patternProperties:
+ '-pins$':
+ properties:
+ groups: false
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ pinctrl@2026000 {
+ compatible = "zhihe,a210-peri1-pinctrl";
+ reg = <0x2026000 0x1000>;
+ clocks = <&clk 0>;
+ clock-names = "pclk";
+
+ gmac0-0 {
+ gmac0-pins {
+ bias-disable;
+ drive-strength = <13>;
+ function = "gmac0";
+ input-disable;
+ input-schmitt-disable;
+ pins = "GPIO0_0", "GPIO0_12";
+ slew-rate = <0>;
+ };
+ };
+ };
+
+ - |
+ pinctrl@542000 {
+ compatible = "zhihe,a210-peri3-pinctrl";
+ reg = <0x542000 0x1000>;
+ clocks = <&clk 0>;
+ clock-names = "pclk";
+
+ sdio-0 {
+ cmd-data-pins {
+ bias-pull-up;
+ pins = "SDIO_CMD", "SDIO_DAT0", "SDIO_DAT1",
+ "SDIO_DAT2", "SDIO_DAT3";
+ };
+
+ sdio-pins {
+ function = "sdio";
+ groups = "sdio";
+ };
+ };
+ };
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 09/18] pinctrl: zhihe: add A210 support
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (7 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 08/18] dt-bindings: pinctrl: add Zhihe A210 pin controller Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 10/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC Han Gao via B4 Relay
` (8 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add mux and pin configuration support for the four A210 pad controllers,
including the shared PERI3 SDIO mux and suspend-state restoration.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
drivers/pinctrl/Kconfig | 14 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-a210.c | 1206 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 1221 insertions(+)
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e1ab3a916086..50fd2732b9b8 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -37,6 +37,20 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
+config PINCTRL_A210
+ tristate "Pinctrl driver for the ZhiHe A210 SoC"
+ depends on 64BIT
+ depends on OF && (ARCH_ZHIHE || COMPILE_TEST)
+ select GENERIC_PINMUX_FUNCTIONS
+ select GENERIC_PINCONF
+ select PINMUX
+ help
+ This selects the pinctrl driver for the ZhiHe A210 RISC-V SoC.
+
+ It provides pin multiplexing and configuration support for
+ the A210 pad controllers (AON, PADCTRL0-2). Say Y if you
+ are building a kernel for the ZhiHe A210 platform.
+
config PINCTRL_AMD
bool "AMD GPIO pin control"
depends on HAS_IOMEM
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a35d71135abf..c79ec78229ae 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_GENERIC_PINCTRL) += pinctrl-generic.o
obj-$(CONFIG_OF) += devicetree.o
+obj-$(CONFIG_PINCTRL_A210) += pinctrl-a210.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
obj-$(CONFIG_PINCTRL_AMDISP) += pinctrl-amdisp.o
obj-$(CONFIG_PINCTRL_APPLE_GPIO) += pinctrl-apple-gpio.o
diff --git a/drivers/pinctrl/pinctrl-a210.c b/drivers/pinctrl/pinctrl-a210.c
new file mode 100644
index 000000000000..753253e35c05
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-a210.c
@@ -0,0 +1,1206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Zhihe Computing Limited.
+ */
+
+#include <linux/bitops.h>
+#include <linux/cleanup.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "core.h"
+#include "pinmux.h"
+#include "pinconf.h"
+
+#define A210_PADCFG_IE BIT(9)
+#define A210_PADCFG_SL BIT(8)
+#define A210_PADCFG_ST BIT(7)
+#define A210_PADCFG_SPU BIT(6)
+#define A210_PADCFG_PS BIT(5)
+#define A210_PADCFG_PE BIT(4)
+#define A210_PADCFG_BIAS (A210_PADCFG_SPU | A210_PADCFG_PS | A210_PADCFG_PE)
+#define A210_PADCFG_DS GENMASK(3, 0)
+
+/* PERI3 has one 32-bit configuration register per SDIO pad. */
+#define A210_SDIO_PULL_UP BIT(1)
+#define A210_SDIO_PULL_DOWN BIT(0)
+#define A210_SDIO_BIAS (A210_SDIO_PULL_UP | A210_SDIO_PULL_DOWN)
+
+#define A210_PULL_DOWN_OHM 44000 /* typ. 44kOhm */
+#define A210_PULL_UP_OHM 48000 /* typ. 48kOhm */
+#define A210_PULL_STRONG_OHM 2100 /* typ. 2.1kOhm */
+
+#define A210_PAD_NO_PADCFG BIT(63)
+#define A210_PAD_MUXDATA GENMASK(55, 0)
+
+#ifdef CONFIG_PM_SLEEP
+#define A210_MAX_CFG_REGS 25
+#define A210_MAX_MUX_REGS 7
+
+struct a210_register_state {
+ u32 mask;
+ u32 value;
+};
+#endif
+
+struct a210_pinctrl;
+
+enum a210_pinctrl_type {
+ A210_PADCTRL_AON,
+ A210_PADCTRL_0,
+ A210_PADCTRL_1,
+ A210_PADCTRL_2,
+};
+
+struct a210_pad_group {
+ const char *name;
+ const struct pinctrl_pin_desc *pins;
+ unsigned int npins;
+ unsigned int offset_mux;
+ unsigned int mask_mux;
+ unsigned int offset_cfg;
+ unsigned int mask_cfg;
+ enum a210_pinctrl_type type;
+};
+
+struct a210_pinctrl {
+ struct pinctrl_desc desc;
+ raw_spinlock_t lock; /* serialize register access */
+ void __iomem *base;
+ struct clk *clk;
+ bool clk_enabled;
+ unsigned int offset_mux;
+ unsigned int mask_mux;
+ unsigned int offset_cfg;
+ unsigned int mask_cfg;
+ enum a210_pinctrl_type type;
+ struct pinctrl_dev *pctl;
+#ifdef CONFIG_PM_SLEEP
+ struct a210_register_state cfg_state[A210_MAX_CFG_REGS];
+ struct a210_register_state mux_state[A210_MAX_MUX_REGS];
+#endif
+};
+
+static void __iomem *a210_padcfg(struct a210_pinctrl *pp, unsigned int pin)
+{
+ int width = hweight32(pp->mask_cfg);
+
+ return pp->base + pp->offset_cfg + 4 * (pin * width / 32);
+}
+
+static unsigned int a210_padcfg_shift(struct a210_pinctrl *pp, unsigned int pin)
+{
+ int width = hweight32(pp->mask_cfg);
+
+ return width * (pin & (32 / width - 1));
+}
+
+static void __iomem *a210_muxcfg(struct a210_pinctrl *pp, unsigned int pin)
+{
+ int width = hweight32(pp->mask_mux);
+
+ return pp->base + pp->offset_mux + 4 * (pin * width / 32);
+}
+
+static unsigned int a210_muxcfg_shift(struct a210_pinctrl *pp, unsigned int pin)
+{
+ int width = hweight32(pp->mask_mux);
+
+ if (pp->type == A210_PADCTRL_2)
+ return 0;
+
+ return width * (pin & (32 / width - 1));
+}
+
+enum a210_muxtype {
+ A210_MUX_____,
+ A210_MUX_AOUART,
+ A210_MUX_AOUART_IR,
+ A210_MUX_AOGPIO0,
+ A210_MUX_AOGPIO1,
+ A210_MUX_AOI2C0,
+ A210_MUX_AOI2C1,
+ A210_MUX_AOSPI,
+ A210_MUX_JTAG,
+ A210_MUX_RST,
+ A210_MUX_POR,
+ A210_MUX_PMIC,
+ A210_MUX_DVS,
+ A210_MUX_UART0,
+ A210_MUX_UART1,
+ A210_MUX_UART2,
+ A210_MUX_UART3,
+ A210_MUX_UART4,
+ A210_MUX_UART5,
+ A210_MUX_UART6,
+ A210_MUX_UART7,
+ A210_MUX_UART8,
+ A210_MUX_UART9,
+ A210_MUX_UART0_IR,
+ A210_MUX_UART1_IR,
+ A210_MUX_UART2_IR,
+ A210_MUX_UART3_IR,
+ A210_MUX_UART4_IR,
+ A210_MUX_UART5_IR,
+ A210_MUX_UART6_IR,
+ A210_MUX_UART7_IR,
+ A210_MUX_UART8_IR,
+ A210_MUX_UART9_IR,
+ A210_MUX_GPIO0,
+ A210_MUX_GPIO1,
+ A210_MUX_GPIO2,
+ A210_MUX_GPIO3,
+ A210_MUX_GPIO4,
+ A210_MUX_GMAC0,
+ A210_MUX_GMAC1,
+ A210_MUX_SPI0,
+ A210_MUX_SPI1,
+ A210_MUX_QSPI0,
+ A210_MUX_QSPI1,
+ A210_MUX_PWM0,
+ A210_MUX_PWM1,
+ A210_MUX_PWM2,
+ A210_MUX_CAN0,
+ A210_MUX_CAN1,
+ A210_MUX_CAN2,
+ A210_MUX_I2S0,
+ A210_MUX_I2S1,
+ A210_MUX_I2S2,
+ A210_MUX_I2S3,
+ A210_MUX_I2C0,
+ A210_MUX_I2C1,
+ A210_MUX_I2C2,
+ A210_MUX_I2C3,
+ A210_MUX_I2C4,
+ A210_MUX_I2C5,
+ A210_MUX_I2C6,
+ A210_MUX_I2C7,
+ A210_MUX_I2C7_SMB,
+ A210_MUX_SDIO,
+ A210_MUX_ISP0,
+ A210_MUX_DPTX,
+ A210_MUX_USB31,
+ A210_MUX_SATA_P0,
+ A210_MUX_SATA_P1,
+ A210_MUX_HDMI,
+ A210_MUX_ZMAC,
+ A210_MUX_BSEL,
+ A210_MUX_DBGM,
+ A210_MUX_CDBG,
+ A210_MUX_PDM,
+ A210_MUX_TDM,
+ A210_MUX_PCIE_X1,
+ A210_MUX_PCIE_X4,
+ A210_MUX_SEN_VCLK,
+ A210_MUX_MAX = 127,
+};
+
+static const char *const a210_muxtype_string[] = {
+ [A210_MUX_AOUART] = "aouart",
+ [A210_MUX_AOUART_IR] = "aouart_ir",
+ [A210_MUX_AOGPIO0] = "aogpio0",
+ [A210_MUX_AOGPIO1] = "aogpio1",
+ [A210_MUX_AOI2C0] = "aoi2c0",
+ [A210_MUX_AOI2C1] = "aoi2c1",
+ [A210_MUX_AOSPI] = "aospi",
+ [A210_MUX_JTAG] = "jtag",
+ [A210_MUX_RST] = "reset",
+ [A210_MUX_POR] = "por",
+ [A210_MUX_PMIC] = "pmic",
+ [A210_MUX_DVS] = "dvs",
+ [A210_MUX_UART0] = "uart0",
+ [A210_MUX_UART1] = "uart1",
+ [A210_MUX_UART2] = "uart2",
+ [A210_MUX_UART3] = "uart3",
+ [A210_MUX_UART4] = "uart4",
+ [A210_MUX_UART5] = "uart5",
+ [A210_MUX_UART6] = "uart6",
+ [A210_MUX_UART7] = "uart7",
+ [A210_MUX_UART8] = "uart8",
+ [A210_MUX_UART9] = "uart9",
+ [A210_MUX_UART0_IR] = "uart0_ir",
+ [A210_MUX_UART1_IR] = "uart1_ir",
+ [A210_MUX_UART2_IR] = "uart2_ir",
+ [A210_MUX_UART3_IR] = "uart3_ir",
+ [A210_MUX_UART4_IR] = "uart4_ir",
+ [A210_MUX_UART5_IR] = "uart5_ir",
+ [A210_MUX_UART6_IR] = "uart6_ir",
+ [A210_MUX_UART7_IR] = "uart7_ir",
+ [A210_MUX_UART8_IR] = "uart8_ir",
+ [A210_MUX_UART9_IR] = "uart9_ir",
+ [A210_MUX_GPIO0] = "gpio0",
+ [A210_MUX_GPIO1] = "gpio1",
+ [A210_MUX_GPIO2] = "gpio2",
+ [A210_MUX_GPIO3] = "gpio3",
+ [A210_MUX_GPIO4] = "gpio4",
+ [A210_MUX_GMAC0] = "gmac0",
+ [A210_MUX_GMAC1] = "gmac1",
+ [A210_MUX_SPI0] = "spi0",
+ [A210_MUX_SPI1] = "spi1",
+ [A210_MUX_QSPI0] = "qspi0",
+ [A210_MUX_QSPI1] = "qspi1",
+ [A210_MUX_PWM0] = "pwm0",
+ [A210_MUX_PWM1] = "pwm1",
+ [A210_MUX_PWM2] = "pwm2",
+ [A210_MUX_CAN0] = "can0",
+ [A210_MUX_CAN1] = "can1",
+ [A210_MUX_CAN2] = "can2",
+ [A210_MUX_I2S0] = "i2s0",
+ [A210_MUX_I2S1] = "i2s1",
+ [A210_MUX_I2S2] = "i2s2",
+ [A210_MUX_I2S3] = "i2s3",
+ [A210_MUX_I2C0] = "i2c0",
+ [A210_MUX_I2C1] = "i2c1",
+ [A210_MUX_I2C2] = "i2c2",
+ [A210_MUX_I2C3] = "i2c3",
+ [A210_MUX_I2C4] = "i2c4",
+ [A210_MUX_I2C5] = "i2c5",
+ [A210_MUX_I2C6] = "i2c6",
+ [A210_MUX_I2C7] = "i2c7",
+ [A210_MUX_I2C7_SMB] = "i2c7_smb",
+ [A210_MUX_SDIO] = "sdio",
+ [A210_MUX_ISP0] = "isp0",
+ [A210_MUX_DPTX] = "dptx",
+ [A210_MUX_USB31] = "usb31",
+ [A210_MUX_SATA_P0] = "sata_p0",
+ [A210_MUX_SATA_P1] = "sata_p1",
+ [A210_MUX_HDMI] = "hdmi",
+ [A210_MUX_ZMAC] = "zmac",
+ [A210_MUX_BSEL] = "bsel",
+ [A210_MUX_DBGM] = "dbgm",
+ [A210_MUX_CDBG] = "cdbg",
+ [A210_MUX_PDM] = "pdm",
+ [A210_MUX_TDM] = "tdm",
+ [A210_MUX_PCIE_X1] = "pcie_x1",
+ [A210_MUX_PCIE_X4] = "pcie_x4",
+ [A210_MUX_SEN_VCLK] = "sen_vclk",
+};
+
+#define A210_PAD(_nr, _name, m0, m1, m2, m3, m4, m5, m6, m7, _flags) \
+ { .number = _nr, \
+ .name = #_name, \
+ .drv_data = \
+ (void *)((_flags) | (A210_MUX_##m0 << 0) | (A210_MUX_##m1 << 7) | \
+ (A210_MUX_##m2 << 14) | (A210_MUX_##m3 << 21) | \
+ ((uintptr_t)A210_MUX_##m4 << 28) | ((uintptr_t)A210_MUX_##m5 << 35) | \
+ ((uintptr_t)A210_MUX_##m6 << 42) | ((uintptr_t)A210_MUX_##m7 << 49)) }
+
+static const struct pinctrl_pin_desc a210_group0_pins[] = {
+ A210_PAD(0, OSC_CLK_IN, ____, ____, ____, ____, ____, ____, ____, ____, A210_PAD_NO_PADCFG),
+ A210_PAD(1, OSC_CLK_OUT, ____, ____, ____, ____, ____, ____, ____, ____,
+ A210_PAD_NO_PADCFG),
+ A210_PAD(2, RST_N_IN, ____, ____, ____, ____, ____, ____, ____, ____, A210_PAD_NO_PADCFG),
+ A210_PAD(3, RTC_CLK_IN, ____, ____, ____, ____, ____, ____, ____, ____, A210_PAD_NO_PADCFG),
+ A210_PAD(4, RTC_CLK_OUT, ____, ____, ____, ____, ____, ____, ____, ____,
+ A210_PAD_NO_PADCFG),
+ A210_PAD(5, TEST_MODE, ____, ____, ____, ____, ____, ____, ____, ____, A210_PAD_NO_PADCFG),
+ A210_PAD(6, POR_SEL, ____, ____, ____, ____, ____, ____, ____, ____, A210_PAD_NO_PADCFG),
+ A210_PAD(7, RST_N_OUT, RST, ____, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(8, BOOT_SEL0, BSEL, ____, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(9, BOOT_SEL1, BSEL, AOUART, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(10, DEBUG_MODE, DBGM, ____, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(11, AOUART_TXD, AOUART, AOUART_IR, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(12, AOUART_RXD, AOUART, AOUART_IR, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(13, AOI2C0_SCL, AOI2C0, AOSPI, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(14, AOI2C0_SDA, AOI2C0, AOSPI, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(15, AOI2C1_SCL, AOI2C1, AOSPI, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(16, AOI2C1_SDA, AOI2C1, AOSPI, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(17, CPU_JTG_TCLK, JTAG, ____, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(18, CPU_JTG_TMS, JTAG, ____, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(19, CPU_JTG_TDI, JTAG, ____, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(20, CPU_JTG_TDO, JTAG, POR, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(21, CPU_JTG_TRST, JTAG, ____, ____, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(22, AOGPIO0_21, AOGPIO0, AOSPI, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(23, AOGPIO0_22, AOGPIO0, AOSPI, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(24, AOGPIO0_23, BSEL, AOSPI, PMIC, AOGPIO0, ____, ____, ____, ____, 0),
+ A210_PAD(25, AOGPIO0_24, AOGPIO0, AOSPI, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(26, AOGPIO0_25, AOGPIO0, AOSPI, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(27, AOGPIO0_26, AOGPIO0, AOI2C1, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(28, AOGPIO0_27, AOGPIO0, AOI2C1, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(29, AOGPIO0_28, AOGPIO0, AOI2C1, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(30, AOGPIO0_29, AOGPIO0, AOI2C1, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(31, AOGPIO0_30, AOGPIO0, AOI2C1, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(32, AOGPIO0_31, AOGPIO0, AOUART, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(33, AOGPIO1_0, AOGPIO1, AOUART, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(34, AOGPIO1_1, AOGPIO1, ____, PMIC, ____, ____, ____, ____, ____, 0),
+ A210_PAD(35, AOGPIO1_2, AOGPIO1, ____, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(36, AOGPIO1_3, AOGPIO1, ____, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(37, AOGPIO1_4, AOGPIO1, ____, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(38, AOGPIO1_5, AOGPIO1, ____, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(39, AOGPIO1_6, AOGPIO1, ____, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(40, AOGPIO1_7, AOGPIO1, ____, PMIC, DVS, ____, ____, ____, ____, 0),
+ A210_PAD(41, AOGPIO1_8, PCIE_X4, ____, PMIC, AOGPIO1, ____, ____, ____, ____, 0),
+ A210_PAD(42, AOGPIO1_9, AOGPIO1, ____, PMIC, ____, ____, ____, ____, ____, 0),
+};
+
+static const struct pinctrl_pin_desc a210_group1_pins[] = {
+ A210_PAD(0, GPIO0_0, GPIO0, GMAC0, ____, ____, ____, ____, ZMAC, ____, 0),
+ A210_PAD(1, GPIO0_1, GPIO0, GMAC0, ____, ____, ____, ____, ZMAC, ____, 0),
+ A210_PAD(2, GPIO0_2, GPIO0, GMAC0, ____, ____, ____, ____, ZMAC, ____, 0),
+ A210_PAD(3, GPIO0_3, GPIO0, GMAC0, UART3, UART3_IR, ____, SATA_P0, ZMAC, ____, 0),
+ A210_PAD(4, GPIO0_4, GPIO0, GMAC0, UART3, UART3_IR, ____, SATA_P1, ZMAC, ____, 0),
+ A210_PAD(5, GPIO0_5, GPIO0, GMAC0, UART3, ____, ____, SATA_P1, ZMAC, ____, 0),
+ A210_PAD(6, GPIO0_6, GPIO0, GMAC0, UART3, ____, ____, SATA_P1, ZMAC, ____, 0),
+ A210_PAD(7, GPIO0_7, GPIO0, GMAC0, ____, ____, ____, SATA_P1, ZMAC, ____, 0),
+ A210_PAD(8, GPIO0_8, GPIO0, GMAC0, I2C0, ____, ____, SATA_P1, ZMAC, ____, 0),
+ A210_PAD(9, GPIO0_9, GPIO0, GMAC0, I2C0, ____, ____, PCIE_X4, ZMAC, ____, 0),
+ A210_PAD(10, GPIO0_10, GPIO0, GMAC0, I2C1, ____, ____, PCIE_X4, ZMAC, ____, 0),
+ A210_PAD(11, GPIO0_11, GPIO0, GMAC0, I2C1, ____, ____, PCIE_X4, ZMAC, ____, 0),
+ A210_PAD(12, GPIO0_12, GPIO0, GMAC0, ____, ____, ____, PCIE_X4, ZMAC, ____, 0),
+ A210_PAD(13, GPIO0_13, GPIO0, GMAC0, ____, ____, ____, PWM0, ZMAC, ____, 0),
+ A210_PAD(14, GPIO0_14, GPIO0, UART0, UART0_IR, ____, SATA_P1, I2S0, ____, ____, 0),
+ A210_PAD(15, GPIO0_15, GPIO0, UART0, UART0_IR, QSPI0, SATA_P1, I2S0, ____, ____, 0),
+ A210_PAD(16, GPIO0_16, GPIO0, UART0, UART1, UART1_IR, SATA_P1, I2S0, ZMAC, ____, 0),
+ A210_PAD(17, GPIO0_17, GPIO0, UART0, UART1, UART1_IR, SATA_P1, I2S0, ZMAC, ____, 0),
+ A210_PAD(18, GPIO0_18, GPIO0, QSPI0, GMAC0, SDIO, SATA_P1, I2S0, ____, PCIE_X1, 0),
+ A210_PAD(19, GPIO0_19, GPIO0, QSPI0, GMAC1, ____, TDM, SATA_P0, ____, PCIE_X1, 0),
+ A210_PAD(20, GPIO0_20, GPIO0, QSPI0, UART3, UART3_IR, TDM, SATA_P0, ZMAC, PCIE_X1, 0),
+ A210_PAD(21, GPIO0_21, GPIO0, QSPI0, UART3, UART3_IR, TDM, SATA_P0, ZMAC, PCIE_X1, 0),
+ A210_PAD(22, GPIO0_22, GPIO0, QSPI0, I2C2, ____, TDM, SATA_P0, ZMAC, PWM0, 0),
+ A210_PAD(23, GPIO0_23, GPIO0, QSPI0, I2C2, ____, ____, SATA_P0, ZMAC, PWM0, 0),
+ A210_PAD(24, GPIO0_24, GPIO0, QSPI0, I2C0, CAN0, CDBG, PCIE_X1, UART0, PWM0, 0),
+ A210_PAD(25, GPIO0_25, GPIO0, QSPI0, I2C0, CAN0, CDBG, PCIE_X1, UART0, PWM0, 0),
+ A210_PAD(26, GPIO0_26, GPIO0, QSPI0, I2C1, CAN1, CDBG, PCIE_X1, UART0, UART0_IR, 0),
+ A210_PAD(27, GPIO0_27, GPIO0, QSPI0, I2C1, CAN1, CDBG, PCIE_X1, UART0, UART0_IR, 0),
+ A210_PAD(28, GPIO0_28, GPIO0, PWM0, SPI0, UART1_IR, I2S0, PCIE_X4, UART1, ____, 0),
+ A210_PAD(29, GPIO0_29, GPIO0, PWM0, SPI0, UART1_IR, I2S0, PCIE_X4, UART1, ____, 0),
+ A210_PAD(30, GPIO0_30, GPIO0, PWM0, SPI0, ____, I2S0, PCIE_X4, UART1, ____, 0),
+ A210_PAD(31, GPIO0_31, GPIO0, PWM0, SPI0, QSPI0, I2S0, PCIE_X4, UART1, ____, 0),
+ A210_PAD(32, GPIO1_0, GPIO1, PWM0, UART2, UART2_IR, I2S0, SDIO, GMAC1, SATA_P0, 0),
+ A210_PAD(33, GPIO1_1, GPIO1, PWM0, UART2, UART2_IR, I2C2, SATA_P1, SPI0, SDIO, 0),
+ A210_PAD(34, GPIO1_2, GPIO1, GMAC1, TDM, PWM0, I2C2, SATA_P1, ____, ____, 0),
+ A210_PAD(35, GPIO1_3, GPIO1, GMAC1, TDM, PWM0, ____, SATA_P1, ____, ____, 0),
+ A210_PAD(36, GPIO1_4, GPIO1, GMAC1, TDM, UART2, ____, SATA_P1, ____, ____, 0),
+ A210_PAD(37, GPIO1_5, GPIO1, GMAC1, ____, UART2, ____, SATA_P1, ____, ____, 0),
+ A210_PAD(38, GPIO1_6, GPIO1, GMAC1, SPI0, PWM0, CDBG, SATA_P0, ____, ____, 0),
+ A210_PAD(39, GPIO1_7, GPIO1, GMAC1, SPI0, PWM0, CDBG, SATA_P0, ____, ____, 0),
+ A210_PAD(40, GPIO1_8, GPIO1, GMAC1, SPI0, PDM, CDBG, SATA_P0, ____, ____, 0),
+ A210_PAD(41, GPIO1_9, GPIO1, GMAC1, SPI0, PWM0, ____, SATA_P0, GMAC0, ____, 0),
+ A210_PAD(42, GPIO1_10, GPIO1, GMAC1, SPI0, PWM0, ____, SATA_P0, ____, ____, 0),
+ A210_PAD(43, GPIO1_11, GPIO1, GMAC1, QSPI0, PDM, I2S0, ISP0, PWM0, ____, 0),
+ A210_PAD(44, GPIO1_12, GPIO1, GMAC1, QSPI0, PDM, I2S0, ISP0, ____, ____, 0),
+ A210_PAD(45, GPIO1_13, GPIO1, GMAC1, QSPI0, PDM, I2S0, ISP0, ____, ____, 0),
+ A210_PAD(46, GPIO1_14, GPIO1, GMAC1, ____, PDM, I2S0, ISP0, ____, ____, 0),
+ A210_PAD(47, GPIO1_15, GPIO1, GMAC1, SDIO, PDM, I2S0, ISP0, ____, ____, 0),
+ A210_PAD(48, GPIO1_16, GPIO1, GMAC0, ____, ____, ____, SDIO, ____, ____, 0),
+};
+
+static const struct pinctrl_pin_desc a210_group2_pins[] = {
+ A210_PAD(0, GPIO2_0, GPIO2, UART4, UART4_IR, PWM2, ____, I2C3, ____, ____, 0),
+ A210_PAD(1, GPIO2_1, GPIO2, UART4, UART4_IR, PWM2, ____, I2C3, ____, ____, 0),
+ A210_PAD(2, GPIO2_2, GPIO2, UART5, UART5_IR, PWM2, ____, I2C5, I2S1, ____, 0),
+ A210_PAD(3, GPIO2_3, GPIO2, UART5, UART5_IR, PWM2, ____, I2C5, I2S1, ____, 0),
+ A210_PAD(4, GPIO2_4, GPIO2, UART6, UART6_IR, PWM2, ____, I2C6, I2S1, ____, 0),
+ A210_PAD(5, GPIO2_5, GPIO2, UART6, UART6_IR, PWM2, ____, I2C6, I2S1, ____, 0),
+ A210_PAD(6, GPIO2_6, GPIO2, UART7, UART7_IR, PWM2, SEN_VCLK, I2C4, I2S1, ____, 0),
+ A210_PAD(7, GPIO2_7, GPIO2, UART7, UART7_IR, PWM2, SEN_VCLK, I2C4, ____, ____, 0),
+ A210_PAD(8, GPIO2_8, GPIO2, I2S2, ____, SPI1, UART6, I2C6, PWM2, ____, 0),
+ A210_PAD(9, GPIO2_9, GPIO2, I2S2, ____, SPI1, UART6, I2C6, PWM2, ____, 0),
+ A210_PAD(10, GPIO2_10, GPIO2, I2S2, PWM1, SPI1, UART9, I2C7, ____, ____, 0),
+ A210_PAD(11, GPIO2_11, GPIO2, I2S2, PWM1, SPI1, UART9, I2C7, ____, ____, 0),
+ A210_PAD(12, GPIO2_12, GPIO2, I2S2, PWM1, SPI1, UART8, I2C7, ____, ____, 0),
+ A210_PAD(13, GPIO2_13, GPIO2, I2S3, PWM1, ____, ____, ____, ____, ____, 0),
+ A210_PAD(14, GPIO2_14, GPIO2, I2S3, PWM1, ____, ____, ____, ____, ____, 0),
+ A210_PAD(15, GPIO2_15, GPIO2, I2S3, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(16, GPIO2_16, GPIO2, I2S3, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(17, GPIO2_17, GPIO2, I2S3, SPI1, I2C4, UART8, I2C7, ____, ____, 0),
+ A210_PAD(18, GPIO2_18, GPIO2, I2S3, SPI1, I2C4, PWM2, UART5, UART5_IR, ____, 0),
+ A210_PAD(19, GPIO2_19, GPIO2, I2S3, SPI1, ____, PWM1, UART5, UART5_IR, ____, 0),
+ A210_PAD(20, GPIO2_20, GPIO2, I2S3, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(21, GPIO2_21, GPIO2, I2S3, SPI1, I2C3, PWM1, UART8, ____, ____, 0),
+ A210_PAD(22, GPIO2_22, GPIO2, I2S3, SPI1, I2C3, PWM1, UART8, ____, ____, 0),
+ A210_PAD(23, GPIO2_23, GPIO2, I2S3, PWM1, ____, ____, ____, ____, ____, 0),
+ A210_PAD(24, GPIO2_24, GPIO2, I2C3, UART5, ____, ____, ____, ____, ____, 0),
+ A210_PAD(25, GPIO2_25, GPIO2, I2C3, UART5, ____, HDMI, QSPI1, PWM2, ____, 0),
+ A210_PAD(26, GPIO2_26, GPIO2, I2C4, UART6, ____, ____, ____, ____, ____, 0),
+ A210_PAD(27, GPIO2_27, GPIO2, I2C4, UART6, ____, ____, ____, ____, ____, 0),
+ A210_PAD(28, GPIO2_28, GPIO2, I2C5, UART7, PWM1, ____, QSPI1, ____, ____, 0),
+ A210_PAD(29, GPIO2_29, GPIO2, I2C5, UART7, PWM1, ____, QSPI1, ____, ____, 0),
+ A210_PAD(30, GPIO2_30, GPIO2, I2C6, UART8, PWM1, HDMI, QSPI1, I2S3, ____, 0),
+ A210_PAD(31, GPIO2_31, GPIO2, I2C6, UART8, PWM1, HDMI, QSPI1, I2S3, ____, 0),
+ A210_PAD(32, GPIO3_0, GPIO3, I2C7, UART9, PWM1, CAN2, QSPI1, I2S3, SEN_VCLK, 0),
+ A210_PAD(33, GPIO3_1, GPIO3, I2C7, UART9, PWM1, CAN2, QSPI1, I2S3, SEN_VCLK, 0),
+ A210_PAD(34, GPIO3_2, GPIO3, QSPI1, UART8, UART8_IR, ____, ____, I2S3, PWM1, 0),
+ A210_PAD(35, GPIO3_3, GPIO3, QSPI1, UART8, UART8_IR, ____, ____, I2S3, PWM1, 0),
+ A210_PAD(36, GPIO3_4, GPIO3, QSPI1, UART9, UART9_IR, ____, ____, I2S3, PWM2, 0),
+ A210_PAD(37, GPIO3_5, GPIO3, QSPI1, UART9, UART9_IR, ____, ____, I2S3, PWM2, 0),
+ A210_PAD(38, GPIO3_6, GPIO3, QSPI1, I2S1, I2C7_SMB, ____, DPTX, I2S3, PWM2, 0),
+ A210_PAD(39, GPIO3_7, GPIO3, QSPI1, I2S1, I2C7_SMB, UART7, I2C5, I2S3, PWM2, 0),
+ A210_PAD(40, GPIO3_8, GPIO3, QSPI1, I2S1, I2C7_SMB, UART7, I2C5, I2S3, PWM2, 0),
+ A210_PAD(41, GPIO3_9, GPIO3, UART4, I2S1, I2C7_SMB, UART5, DPTX, ____, PWM2, 0),
+ A210_PAD(42, GPIO3_10, GPIO3, UART4, I2S1, I2C7_SMB, UART5, USB31, ____, ____, 0),
+};
+
+static const struct pinctrl_pin_desc a210_group3_pins[] = {
+ A210_PAD(0, SDIO_CLK, SDIO, GPIO4, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(1, SDIO_CMD, SDIO, GPIO4, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(2, SDIO_DAT0, SDIO, GPIO4, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(3, SDIO_DAT1, SDIO, GPIO4, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(4, SDIO_DAT2, SDIO, GPIO4, ____, ____, ____, ____, ____, ____, 0),
+ A210_PAD(5, SDIO_DAT3, SDIO, GPIO4, ____, ____, ____, ____, ____, ____, 0),
+};
+
+static const struct a210_pad_group a210_group0 = {
+ /* aon */
+ .name = "a210-group0",
+ .pins = a210_group0_pins,
+ .npins = ARRAY_SIZE(a210_group0_pins),
+ .offset_mux = 0x400,
+ .mask_mux = 0xf,
+ .offset_cfg = 0x0,
+ .mask_cfg = 0xffff,
+ .type = A210_PADCTRL_AON,
+};
+
+static const struct a210_pad_group a210_group1 = {
+ /* peri1 */
+ .name = "a210-group1",
+ .pins = a210_group1_pins,
+ .npins = ARRAY_SIZE(a210_group1_pins),
+ .offset_mux = 0x400,
+ .mask_mux = 0xf,
+ .offset_cfg = 0x0,
+ .mask_cfg = 0xffff,
+ .type = A210_PADCTRL_0,
+};
+
+static const struct a210_pad_group a210_group2 = {
+ /* peri2 */
+ .name = "a210-group2",
+ .pins = a210_group2_pins,
+ .npins = ARRAY_SIZE(a210_group2_pins),
+ .offset_mux = 0x400,
+ .mask_mux = 0xf,
+ .offset_cfg = 0x0,
+ .mask_cfg = 0xffff,
+ .type = A210_PADCTRL_1,
+};
+
+static const struct a210_pad_group a210_group3 = {
+ /* PERI3 has one shared mux bit for all six SDIO pads. */
+ .name = "a210-group3",
+ .pins = a210_group3_pins,
+ .npins = ARRAY_SIZE(a210_group3_pins),
+ .offset_mux = 0x200,
+ .mask_mux = 0x1,
+ .offset_cfg = 0x0,
+ .mask_cfg = U32_MAX,
+ .type = A210_PADCTRL_2,
+};
+
+static int a210_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+
+ return pp->type == A210_PADCTRL_2 ? 1 : pp->desc.npins;
+}
+
+static const char *a210_pinctrl_get_group_name(struct pinctrl_dev *pctldev, unsigned int gsel)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+
+ return pp->type == A210_PADCTRL_2 ? "sdio" : pp->desc.pins[gsel].name;
+}
+
+static const unsigned int a210_sdio_pins[] = { 0, 1, 2, 3, 4, 5 };
+
+static int a210_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int gsel,
+ const unsigned int **pins,
+ unsigned int *npins)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+
+ if (pp->type == A210_PADCTRL_2) {
+ *pins = a210_sdio_pins;
+ *npins = ARRAY_SIZE(a210_sdio_pins);
+ } else {
+ *pins = &pp->desc.pins[gsel].number;
+ *npins = 1;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void a210_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int pin)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+ void __iomem *padcfg = a210_padcfg(pp, pin);
+ void __iomem *muxcfg = a210_muxcfg(pp, pin);
+ u32 pad;
+ u32 mux;
+
+ if ((uintptr_t)pin_desc_get(pctldev, pin)->drv_data & A210_PAD_NO_PADCFG)
+ return;
+
+ scoped_guard(raw_spinlock_irqsave, &pp->lock) {
+ pad = readl_relaxed(padcfg);
+ mux = readl_relaxed(muxcfg);
+ }
+
+ seq_printf(s, "[padcfg=0x%08x muxcfg=0x%08x]", pad, mux);
+}
+#else
+#define a210_pin_dbg_show NULL
+#endif
+
+static const struct pinctrl_ops a210_pinctrl_ops = {
+ .get_groups_count = a210_pinctrl_get_groups_count,
+ .get_group_name = a210_pinctrl_get_group_name,
+ .get_group_pins = a210_pinctrl_get_group_pins,
+ .pin_dbg_show = a210_pin_dbg_show,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static const u8 a210_drive_strength_in_ma[16] = {
+ 1, 2, 3, 5, 7, 8, 10, 12, 13, 15, 16, 18, 20, 21, 23, 25,
+};
+
+static int a210_drive_strength_from_ma(u32 arg)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(a210_drive_strength_in_ma); i++)
+ if (arg == a210_drive_strength_in_ma[i])
+ return i;
+ return -EINVAL;
+}
+
+static int a210_padcfg_rmw(struct a210_pinctrl *pp, unsigned int pin, u32 mask, u32 value)
+{
+ void __iomem *padcfg = a210_padcfg(pp, pin);
+ unsigned int shift = a210_padcfg_shift(pp, pin);
+ u32 tmp;
+
+ mask <<= shift;
+ value <<= shift;
+
+ scoped_guard(raw_spinlock_irqsave, &pp->lock) {
+ tmp = readl_relaxed(padcfg);
+ tmp = (tmp & ~mask) | value;
+ writel_relaxed(tmp, padcfg);
+#ifdef CONFIG_PM_SLEEP
+ pp->cfg_state[pin * hweight32(pp->mask_cfg) / 32].mask |= mask;
+#endif
+ }
+ return 0;
+}
+
+static int a210_sdio_pinconf_get(struct a210_pinctrl *pp, unsigned int pin,
+ unsigned long *config)
+{
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 value = readl_relaxed(a210_padcfg(pp, pin)) & A210_SDIO_BIAS;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ if (value)
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (value != A210_SDIO_PULL_UP)
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (value != A210_SDIO_PULL_DOWN)
+ return -EINVAL;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, param != PIN_CONFIG_BIAS_DISABLE);
+ return 0;
+}
+
+static int a210_sdio_pinconf_set(struct a210_pinctrl *pp, unsigned int pin,
+ unsigned long *configs, unsigned int num_configs)
+{
+ u32 value = 0;
+ unsigned int i;
+
+ for (i = 0; i < num_configs; i++) {
+ enum pin_config_param param = pinconf_to_config_param(configs[i]);
+ u32 arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ value = 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg != 1)
+ return -EINVAL;
+ value = param == PIN_CONFIG_BIAS_PULL_UP ?
+ A210_SDIO_PULL_UP : A210_SDIO_PULL_DOWN;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ }
+
+ if (!num_configs)
+ return 0;
+
+ return a210_padcfg_rmw(pp, pin, A210_SDIO_BIAS, value);
+}
+
+static int a210_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+ const struct pin_desc *desc = pin_desc_get(pctldev, pin);
+ bool enabled;
+ int param;
+ u32 value;
+ u32 arg;
+
+ if ((uintptr_t)desc->drv_data & A210_PAD_NO_PADCFG)
+ return -ENOTSUPP;
+ if (pp->type == A210_PADCTRL_2)
+ return a210_sdio_pinconf_get(pp, pin, config);
+
+ value = readl_relaxed(a210_padcfg(pp, pin));
+ value = (value >> a210_padcfg_shift(pp, pin)) & GENMASK(9, 0);
+
+ param = pinconf_to_config_param(*config);
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ enabled = !(value & (A210_PADCFG_SPU | A210_PADCFG_PE));
+ arg = 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ enabled = (value & A210_PADCFG_BIAS) == A210_PADCFG_PE;
+ arg = enabled ? A210_PULL_DOWN_OHM : 0;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (value & A210_PADCFG_SPU) {
+ enabled = true;
+ arg = A210_PULL_STRONG_OHM;
+ } else if ((value & (A210_PADCFG_PE | A210_PADCFG_PS)) ==
+ (A210_PADCFG_PE | A210_PADCFG_PS)) {
+ enabled = true;
+ arg = A210_PULL_UP_OHM;
+ } else {
+ enabled = false;
+ arg = 0;
+ }
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ enabled = true;
+ arg = a210_drive_strength_in_ma[value & A210_PADCFG_DS];
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ enabled = value & A210_PADCFG_IE;
+ arg = enabled ? 1 : 0;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ enabled = value & A210_PADCFG_ST;
+ arg = enabled ? 1 : 0;
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ enabled = true;
+ arg = !!(value & A210_PADCFG_SL);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+ return enabled ? 0 : -EINVAL;
+}
+
+static int a210_pinconf_group_get(struct pinctrl_dev *pctldev, unsigned int gsel,
+ unsigned long *config)
+{
+ const unsigned int *pins;
+ unsigned int npins, i;
+ unsigned long first = *config;
+ int ret;
+
+ a210_pinctrl_get_group_pins(pctldev, gsel, &pins, &npins);
+ for (i = 0; i < npins; i++) {
+ unsigned long value = *config;
+
+ ret = a210_pinconf_get(pctldev, pins[i], &value);
+ if (ret)
+ return ret;
+ if (i && value != first)
+ return -ENOTSUPP;
+ first = value;
+ }
+ *config = first;
+ return 0;
+}
+
+static int a210_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+ const struct pin_desc *desc = pin_desc_get(pctldev, pin);
+ unsigned int i;
+ u16 mask, value;
+
+ if ((uintptr_t)desc->drv_data & A210_PAD_NO_PADCFG)
+ return -ENOTSUPP;
+ if (pp->type == A210_PADCTRL_2)
+ return a210_sdio_pinconf_set(pp, pin, configs, num_configs);
+
+ mask = 0;
+ value = 0;
+ for (i = 0; i < num_configs; i++) {
+ int param = pinconf_to_config_param(configs[i]);
+ u32 arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ mask |= A210_PADCFG_BIAS;
+ value &= ~A210_PADCFG_BIAS;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (arg != 1 && arg != A210_PULL_DOWN_OHM)
+ return -EINVAL;
+ mask |= A210_PADCFG_BIAS;
+ value &= ~A210_PADCFG_BIAS;
+ value |= A210_PADCFG_PE;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (arg != 1 && arg != A210_PULL_UP_OHM && arg != A210_PULL_STRONG_OHM)
+ return -EINVAL;
+ mask |= A210_PADCFG_BIAS;
+ value &= ~A210_PADCFG_BIAS;
+ if (arg == A210_PULL_STRONG_OHM)
+ value |= A210_PADCFG_SPU;
+ else
+ value |= A210_PADCFG_PE | A210_PADCFG_PS;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH: {
+ int strength = a210_drive_strength_from_ma(arg);
+
+ if (strength < 0)
+ return strength;
+ mask |= A210_PADCFG_DS;
+ value &= ~A210_PADCFG_DS;
+ value |= strength;
+ break;
+ }
+ case PIN_CONFIG_INPUT_ENABLE:
+ mask |= A210_PADCFG_IE;
+ if (arg)
+ value |= A210_PADCFG_IE;
+ else
+ value &= ~A210_PADCFG_IE;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ mask |= A210_PADCFG_ST;
+ if (arg)
+ value |= A210_PADCFG_ST;
+ else
+ value &= ~A210_PADCFG_ST;
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ if (arg > 1)
+ return -EINVAL;
+ mask |= A210_PADCFG_SL;
+ if (arg)
+ value |= A210_PADCFG_SL;
+ else
+ value &= ~A210_PADCFG_SL;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ }
+
+ return a210_padcfg_rmw(pp, pin, mask, value);
+}
+
+static int a210_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned int gsel,
+ unsigned long *configs, unsigned int num_configs)
+{
+ const unsigned int *pins;
+ unsigned int npins, i;
+ int ret;
+
+ a210_pinctrl_get_group_pins(pctldev, gsel, &pins, &npins);
+ for (i = 0; i < npins; i++) {
+ ret = a210_pinconf_set(pctldev, pins[i], configs, num_configs);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void a210_pinconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int pin)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+ u32 value;
+
+ if ((uintptr_t)pin_desc_get(pctldev, pin)->drv_data & A210_PAD_NO_PADCFG)
+ return;
+
+ value = readl_relaxed(a210_padcfg(pp, pin));
+
+ if (pp->type != A210_PADCTRL_2)
+ value = (value >> a210_padcfg_shift(pp, pin)) & GENMASK(9, 0);
+
+ seq_printf(s, " [0x%03x]", value);
+}
+#else
+#define a210_pinconf_dbg_show NULL
+#endif
+
+static const struct pinconf_ops a210_pinconf_ops = {
+ .pin_config_get = a210_pinconf_get,
+ .pin_config_group_get = a210_pinconf_group_get,
+ .pin_config_set = a210_pinconf_set,
+ .pin_config_group_set = a210_pinconf_group_set,
+ .pin_config_dbg_show = a210_pinconf_dbg_show,
+ .is_generic = true,
+};
+
+static int a210_pinmux_set(struct a210_pinctrl *pp, unsigned int pin, unsigned long muxdata,
+ enum a210_muxtype muxtype)
+{
+ void __iomem *muxcfg = a210_muxcfg(pp, pin);
+ unsigned int shift = a210_muxcfg_shift(pp, pin);
+ u32 mask, value, tmp;
+
+ for (value = 0; muxdata; muxdata >>= 7, value++) {
+ if ((muxdata & GENMASK(6, 0)) == muxtype)
+ break;
+ }
+ if (!muxdata) {
+ dev_err(pp->pctl->dev, "invalid mux %s for pin %s\n", a210_muxtype_string[muxtype],
+ pin_get_name(pp->pctl, pin));
+ return -EINVAL;
+ }
+
+ mask = pp->mask_mux << shift;
+ value = value << shift;
+
+ scoped_guard(raw_spinlock_irqsave, &pp->lock) {
+ tmp = readl_relaxed(muxcfg);
+ tmp = (tmp & ~mask) | value;
+ writel_relaxed(tmp, muxcfg);
+#ifdef CONFIG_PM_SLEEP
+ pp->mux_state[pin * hweight32(pp->mask_mux) / 32].mask |= mask;
+#endif
+ }
+
+ return 0;
+}
+
+static int a210_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int fsel, unsigned int gsel)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+ const struct function_desc *func = pinmux_generic_get_function(pctldev, fsel);
+
+ return a210_pinmux_set(pp, pp->desc.pins[gsel].number,
+ (uintptr_t)pp->desc.pins[gsel].drv_data & A210_PAD_MUXDATA,
+ *(enum a210_muxtype *)func->data);
+}
+
+static bool a210_mux_is_gpio(enum a210_muxtype muxtype)
+{
+ switch (muxtype) {
+ case A210_MUX_AOGPIO0:
+ case A210_MUX_AOGPIO1:
+ case A210_MUX_GPIO0:
+ case A210_MUX_GPIO1:
+ case A210_MUX_GPIO2:
+ case A210_MUX_GPIO3:
+ case A210_MUX_GPIO4:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static int a210_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range,
+ unsigned int offset)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+ const struct pin_desc *desc = pin_desc_get(pctldev, offset);
+ unsigned long muxdata = (uintptr_t)desc->drv_data & A210_PAD_MUXDATA;
+
+ if (pp->type == A210_PADCTRL_2)
+ return -EOPNOTSUPP;
+
+ for (; muxdata; muxdata >>= 7) {
+ enum a210_muxtype muxtype = muxdata & GENMASK(6, 0);
+
+ if (a210_mux_is_gpio(muxtype))
+ return a210_pinmux_set(pp, offset,
+ (uintptr_t)desc->drv_data & A210_PAD_MUXDATA,
+ muxtype);
+ }
+
+ dev_err(pp->pctl->dev, "no GPIO mux for pin %s\n", desc->name);
+
+ return -EINVAL;
+}
+
+static int a210_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range,
+ unsigned int offset, bool input)
+{
+ struct a210_pinctrl *pp = pinctrl_dev_get_drvdata(pctldev);
+
+ if (pp->type == A210_PADCTRL_2)
+ return -EOPNOTSUPP;
+
+ return a210_padcfg_rmw(pp, offset, A210_PADCFG_IE, input ? A210_PADCFG_IE : 0);
+}
+
+static const struct pinmux_ops a210_pinmux_ops = {
+ .get_functions_count = pinmux_generic_get_function_count,
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .function_is_gpio = pinmux_generic_function_is_gpio,
+ .set_mux = a210_pinmux_set_mux,
+ .gpio_request_enable = a210_gpio_request_enable,
+ .gpio_set_direction = a210_gpio_set_direction,
+ .strict = true,
+};
+
+struct a210_function {
+ struct pinfunction function;
+ enum a210_muxtype type;
+};
+
+static bool a210_pin_has_function(const struct pinctrl_pin_desc *pin,
+ enum a210_muxtype type)
+{
+ unsigned long muxdata = (uintptr_t)pin->drv_data & A210_PAD_MUXDATA;
+
+ for (; muxdata; muxdata >>= 7)
+ if ((muxdata & GENMASK(6, 0)) == type)
+ return true;
+ return false;
+}
+
+static int a210_register_functions(struct a210_pinctrl *pp)
+{
+ struct device *dev = pp->pctl->dev;
+ unsigned int ngroups = a210_pinctrl_get_groups_count(pp->pctl);
+ enum a210_muxtype type;
+
+ for (type = A210_MUX_AOUART; type < ARRAY_SIZE(a210_muxtype_string); type++) {
+ struct a210_function *function;
+ const char **groups;
+ unsigned int i, count = 0;
+ int ret;
+
+ for (i = 0; i < ngroups; i++)
+ count += a210_pin_has_function(&pp->desc.pins[i], type);
+ if (!count)
+ continue;
+
+ function = devm_kzalloc(dev, sizeof(*function), GFP_KERNEL);
+ if (!function)
+ return -ENOMEM;
+ groups = devm_kcalloc(dev, count, sizeof(*groups), GFP_KERNEL);
+ if (!groups)
+ return -ENOMEM;
+ function->type = type;
+ function->function.name = a210_muxtype_string[type];
+ function->function.groups = groups;
+ function->function.ngroups = count;
+ if (a210_mux_is_gpio(type))
+ function->function.flags = PINFUNCTION_FLAG_GPIO;
+ count = 0;
+ for (i = 0; i < ngroups; i++)
+ if (a210_pin_has_function(&pp->desc.pins[i], type))
+ groups[count++] = a210_pinctrl_get_group_name(pp->pctl, i);
+ ret = pinmux_generic_add_pinfunction(pp->pctl, &function->function,
+ &function->type);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int a210_pinctrl_enable_clock(struct a210_pinctrl *pp)
+{
+ int ret;
+
+ if (pp->clk_enabled)
+ return 0;
+
+ ret = clk_prepare_enable(pp->clk);
+ if (!ret)
+ pp->clk_enabled = true;
+ return ret;
+}
+
+static void a210_pinctrl_disable_clock(void *data)
+{
+ struct a210_pinctrl *pp = data;
+
+ if (pp->clk_enabled) {
+ clk_disable_unprepare(pp->clk);
+ pp->clk_enabled = false;
+ }
+}
+
+static int a210_pinctrl_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct a210_pad_group *group;
+ struct a210_pinctrl *pp;
+ int ret;
+
+ group = device_get_match_data(dev);
+ if (!group)
+ return dev_err_probe(dev, -EINVAL, "missing pad group data\n");
+
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+
+ pp->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pp->base))
+ return PTR_ERR(pp->base);
+
+ pp->desc.name = group->name;
+ pp->desc.pins = group->pins;
+ pp->desc.npins = group->npins;
+ pp->offset_mux = group->offset_mux;
+ pp->mask_mux = group->mask_mux;
+ pp->offset_cfg = group->offset_cfg;
+ pp->mask_cfg = group->mask_cfg;
+ pp->type = group->type;
+ pp->desc.pctlops = &a210_pinctrl_ops;
+ pp->desc.pmxops = &a210_pinmux_ops;
+ pp->desc.confops = &a210_pinconf_ops;
+ pp->desc.owner = THIS_MODULE;
+ raw_spin_lock_init(&pp->lock);
+
+ pp->clk = devm_clk_get(dev, "pclk");
+ if (IS_ERR(pp->clk))
+ return dev_err_probe(dev, PTR_ERR(pp->clk), "error getting clock\n");
+
+ ret = a210_pinctrl_enable_clock(pp);
+ if (ret)
+ return dev_err_probe(dev, ret, "could not enable padctrl clock\n");
+ ret = devm_add_action_or_reset(dev, a210_pinctrl_disable_clock, pp);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, pp);
+ ret = devm_pinctrl_register_and_init(dev, &pp->desc, pp, &pp->pctl);
+ if (ret)
+ return dev_err_probe(dev, ret, "could not register pinctrl driver\n");
+
+ ret = a210_register_functions(pp);
+ if (ret)
+ return ret;
+
+ return pinctrl_enable(pp->pctl);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void a210_pinctrl_save_regs(struct a210_register_state *state,
+ unsigned int count, void __iomem *base)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++)
+ if (state[i].mask)
+ state[i].value = readl(base + i * sizeof(u32)) & state[i].mask;
+}
+
+static void a210_pinctrl_restore_regs(const struct a210_register_state *state,
+ unsigned int count, void __iomem *base)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++) {
+ u32 value;
+
+ if (!state[i].mask)
+ continue;
+ value = readl(base + i * sizeof(u32));
+ value = (value & ~state[i].mask) | state[i].value;
+ writel(value, base + i * sizeof(u32));
+ }
+}
+
+static int a210_pinctrl_suspend(struct device *dev)
+{
+ struct a210_pinctrl *pp = dev_get_drvdata(dev);
+
+ if (!pp->clk_enabled)
+ return 0;
+
+ scoped_guard(raw_spinlock_irqsave, &pp->lock) {
+ a210_pinctrl_save_regs(pp->cfg_state, ARRAY_SIZE(pp->cfg_state),
+ pp->base + pp->offset_cfg);
+ a210_pinctrl_save_regs(pp->mux_state, ARRAY_SIZE(pp->mux_state),
+ pp->base + pp->offset_mux);
+ }
+ if (pp->type != A210_PADCTRL_AON)
+ a210_pinctrl_disable_clock(pp);
+
+ return 0;
+}
+
+static int a210_pinctrl_resume(struct device *dev)
+{
+ struct a210_pinctrl *pp = dev_get_drvdata(dev);
+ int ret;
+
+ ret = a210_pinctrl_enable_clock(pp);
+ if (ret)
+ return dev_err_probe(dev, ret, "could not enable padctrl clock\n");
+
+ /* Leave firmware-owned and reserved fields at their current values. */
+ scoped_guard(raw_spinlock_irqsave, &pp->lock) {
+ a210_pinctrl_restore_regs(pp->cfg_state, ARRAY_SIZE(pp->cfg_state),
+ pp->base + pp->offset_cfg);
+ a210_pinctrl_restore_regs(pp->mux_state, ARRAY_SIZE(pp->mux_state),
+ pp->base + pp->offset_mux);
+ }
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct dev_pm_ops a210_pinctrl_dev_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(a210_pinctrl_suspend, a210_pinctrl_resume)
+};
+
+static const struct of_device_id a210_pinctrl_of_match[] = {
+ { .compatible = "zhihe,a210-aon-pinctrl", .data = &a210_group0 },
+ { .compatible = "zhihe,a210-peri1-pinctrl", .data = &a210_group1 },
+ { .compatible = "zhihe,a210-peri2-pinctrl", .data = &a210_group2 },
+ { .compatible = "zhihe,a210-peri3-pinctrl", .data = &a210_group3 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, a210_pinctrl_of_match);
+
+static struct platform_driver a210_pinctrl_driver = {
+ .probe = a210_pinctrl_probe,
+ .driver = {
+ .name = "pinctrl-a210",
+ .of_match_table = a210_pinctrl_of_match,
+ .pm = &a210_pinctrl_dev_pm_ops,
+ },
+};
+module_platform_driver(a210_pinctrl_driver);
+
+MODULE_DESCRIPTION("Pinctrl driver for the ZhiHe A210 SoC");
+MODULE_AUTHOR("Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>");
+MODULE_LICENSE("GPL");
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 10/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (8 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 09/18] pinctrl: zhihe: add A210 support Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 11/18] dt-bindings: riscv: add Melon Pi V1 and V2 Han Gao via B4 Relay
` (7 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add the A210 PLIC compatible with the thead,c900-plic fallback.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
.../devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
index cde4bb691897..fd5b61db3f5f 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
@@ -80,6 +80,7 @@ properties:
- sophgo,sg2042-plic
- sophgo,sg2044-plic
- thead,th1520-plic
+ - zhihe,a210-plic
- const: thead,c900-plic
- items:
- const: ultrarisc,dp1000-plic
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 11/18] dt-bindings: riscv: add Melon Pi V1 and V2
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (9 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 10/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 12/18] dt-bindings: timer: add Zhihe A210 CLINT Han Gao via B4 Relay
` (6 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add bindings for Melon Pi V1 and V2 with the A210 module. V3 uses the
same board compatible as V2.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
Documentation/devicetree/bindings/riscv/zhihe.yaml | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/Documentation/devicetree/bindings/riscv/zhihe.yaml b/Documentation/devicetree/bindings/riscv/zhihe.yaml
new file mode 100644
index 000000000000..92ac0a99a687
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/zhihe.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/zhihe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ZhiHe SoC-based boards
+
+maintainers:
+ - Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ oneOf:
+ - description: Melon Pi V1 and V2 with the A210 SODIMM module
+ items:
+ - enum:
+ - zhihe,a210-melonpi-v1
+ - zhihe,a210-melonpi-v2
+ - const: zhihe,a210-som
+ - const: zhihe,a210
+
+additionalProperties: true
+
+...
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 12/18] dt-bindings: timer: add Zhihe A210 CLINT
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (10 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 11/18] dt-bindings: riscv: add Melon Pi V1 and V2 Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 13/18] riscv: dts: zhihe: add A210 core support Han Gao via B4 Relay
` (5 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Add the A210 CLINT compatible with the thead,c900-clint fallback.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
index 3673836e14de..805262bb6cd3 100644
--- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
+++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
@@ -56,6 +56,7 @@ properties:
- sophgo,sg2000-clint
- sophgo,sg2002-clint
- thead,th1520-clint
+ - zhihe,a210-clint
- const: thead,c900-clint
- items:
- const: sifive,clint0
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 13/18] riscv: dts: zhihe: add A210 core support
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (11 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 12/18] dt-bindings: timer: add Zhihe A210 CLINT Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-22 18:48 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 14/18] riscv: dts: zhihe: add A210 UARTs Han Gao via B4 Relay
` (4 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add the A210 CPU clusters, caches, interrupt controllers and control
blocks.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/boot/dts/zhihe/a210.dtsi | 495 ++++++++++++++++++++++++++++++++++++
1 file changed, 495 insertions(+)
diff --git a/arch/riscv/boot/dts/zhihe/a210.dtsi b/arch/riscv/boot/dts/zhihe/a210.dtsi
new file mode 100644
index 000000000000..bbad51a3edb0
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/a210.dtsi
@@ -0,0 +1,495 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ */
+
+#include <dt-bindings/clock/zhihe,a210-clk.h>
+#include <dt-bindings/clock/zhihe,a210-aon-clk.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset/zhihe,a210-resets.h>
+
+/ {
+ compatible = "zhihe,a210";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aon_rc: clock-aon-rc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ };
+
+ osc_24m: clock-osc-24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc-24m";
+ };
+
+ osc_32k: clock-osc-32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "osc-32k";
+ };
+
+ aon_110m: clock-osc-110m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <110000000>;
+ clock-output-names = "aon-110m";
+ };
+
+ rc_24m: clock-rc-24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "rc-24m";
+ };
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <24000000>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&c908_0>;
+ };
+
+ core1 {
+ cpu = <&c908_1>;
+ };
+
+ core2 {
+ cpu = <&c908_2>;
+ };
+
+ core3 {
+ cpu = <&c908_3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&c920_4>;
+ };
+
+ core1 {
+ cpu = <&c920_5>;
+ };
+
+ core2 {
+ cpu = <&c920_6>;
+ };
+
+ core3 {
+ cpu = <&c920_7>;
+ };
+ };
+ };
+
+ c0_l2_cache: l2-cache0 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-sets = <512>;
+ cache-size = <524288>;
+ cache-unified;
+ };
+
+ c1_l2_cache: l2-cache1 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-sets = <1024>;
+ cache-size = <1048576>;
+ cache-unified;
+ };
+
+ c908_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <0>;
+ clocks = <&clk C908_CPU_TO_CDE_CLK_MUX>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c908_1: cpu@1 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <1>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu1_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c908_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <2>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu2_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c908_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <3>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu3_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_4: cpu@4 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <4>;
+ clocks = <&clk C920_CPU_TO_CDE_CLK_MUX>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu4_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_5: cpu@5 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <5>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu5_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_6: cpu@6 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <6>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu6_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_7: cpu@7 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <7>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu7_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ dma-noncoherent;
+ #size-cells = <2>;
+
+ clk: clock-controller@260000 {
+ compatible = "zhihe,a210-clk";
+ reg = <0x0 0x00260000 0x0 0x1000>,
+ <0x0 0x00250000 0x0 0x1000>,
+ <0x0 0x10141600 0x0 0x100>,
+ <0x0 0x10141400 0x0 0x100>,
+ <0x0 0x04810000 0x0 0x1000>,
+ <0x0 0x05810000 0x0 0x1000>,
+ <0x0 0x04900000 0x0 0x1000>,
+ <0x0 0x20250000 0x0 0x1000>,
+ <0x0 0x10140000 0x0 0xe00>;
+ reg-names = "pll-wrap", "top-crg", "cpu-ss-clk-sysreg",
+ "cpu-ss-cpu-pll", "ddr0-sysreg",
+ "ddr1-sysreg", "slc-dual-sysreg",
+ "top-crg-t", "cpu-ss-ccu";
+ #clock-cells = <1>;
+ clocks = <&osc_32k>, <&osc_24m>, <&rc_24m>;
+ clock-names = "osc-32k", "osc-24m", "rc-24m";
+ };
+
+ clk_peri: clock-controller@300200 {
+ compatible = "zhihe,a210-peri-clk";
+ reg = <0x0 0x00300200 0x0 0x4>,
+ <0x0 0x02010200 0x0 0x8>,
+ <0x0 0x08400200 0x0 0x8>,
+ <0x0 0x00540200 0x0 0x4>,
+ <0x0 0x27420200 0x0 0x200>;
+ reg-names = "peri0-sysreg", "peri1-sysreg",
+ "peri2-sysreg", "peri3-sysreg", "tee-crg";
+ #clock-cells = <1>;
+ };
+
+ peri3_padctrl: pinctrl@542000 {
+ compatible = "zhihe,a210-peri3-pinctrl";
+ reg = <0x0 0x00542000 0x0 0x1000>;
+ clocks = <&clk_peri PERI3_PAD_CTRL_PCLK_EN>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ rst_peri1: reset-controller@2010400 {
+ compatible = "zhihe,a210-peri1-reset";
+ reg = <0x0 0x02010400 0x0 0x200>;
+ #reset-cells = <1>;
+ };
+
+ peri1_padctrl: pinctrl@2026000 {
+ compatible = "zhihe,a210-peri1-pinctrl";
+ reg = <0x0 0x02026000 0x0 0x1000>;
+ clocks = <&clk_peri PERI1_PAD_CTRL_PCLK_EN>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ rst_peri2: reset-controller@8400400 {
+ compatible = "zhihe,a210-peri2-reset";
+ reg = <0x0 0x08400400 0x0 0x200>;
+ #reset-cells = <1>;
+ };
+
+ peri2_padctrl: pinctrl@8411000 {
+ compatible = "zhihe,a210-peri2-pinctrl";
+ reg = <0x0 0x08411000 0x0 0x1000>;
+ clocks = <&clk_peri PERI2_PAD_CTRL_PCLK_EN>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ intc: interrupt-controller@18000000 {
+ compatible = "zhihe,a210-plic", "thead,c900-plic";
+ reg = <0x0 0x18000000 0x0 0x04000000>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupts-extended = <&cpu0_intc 0xffffffff>,
+ <&cpu0_intc 9>,
+ <&cpu1_intc 0xffffffff>,
+ <&cpu1_intc 9>,
+ <&cpu2_intc 0xffffffff>,
+ <&cpu2_intc 9>,
+ <&cpu3_intc 0xffffffff>,
+ <&cpu3_intc 9>,
+ <&cpu4_intc 0xffffffff>,
+ <&cpu4_intc 9>,
+ <&cpu5_intc 0xffffffff>,
+ <&cpu5_intc 9>,
+ <&cpu6_intc 0xffffffff>,
+ <&cpu6_intc 9>,
+ <&cpu7_intc 0xffffffff>,
+ <&cpu7_intc 9>;
+ riscv,ndev = <351>;
+ };
+
+ clint0: clint@1c000000 {
+ compatible = "zhihe,a210-clint", "thead,c900-clint";
+ reg = <0x0 0x1c000000 0x0 0x0000d800>;
+ interrupts-extended = <&cpu0_intc 3>,
+ <&cpu0_intc 7>,
+ <&cpu1_intc 3>,
+ <&cpu1_intc 7>,
+ <&cpu2_intc 3>,
+ <&cpu2_intc 7>,
+ <&cpu3_intc 3>,
+ <&cpu3_intc 7>,
+ <&cpu4_intc 3>,
+ <&cpu4_intc 7>,
+ <&cpu5_intc 3>,
+ <&cpu5_intc 7>,
+ <&cpu6_intc 3>,
+ <&cpu6_intc 7>,
+ <&cpu7_intc 3>,
+ <&cpu7_intc 7>;
+ };
+
+ clk_aon: clock-controller@30844000 {
+ compatible = "zhihe,a210-aon-clk";
+ reg = <0 0x30844000 0 0x1c>;
+ #clock-cells = <1>;
+ clocks = <&aon_110m>, <&osc_24m>, <&aon_rc>, <&osc_32k>;
+ clock-names = "high", "osc", "rc", "rtc";
+ };
+
+ aon_padctrl: pinctrl@30848000 {
+ compatible = "zhihe,a210-aon-pinctrl";
+ reg = <0x0 0x30848000 0x0 0x2000>;
+ clocks = <&clk_aon A210_AON_SYS_CLK>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+ };
+};
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 14/18] riscv: dts: zhihe: add A210 UARTs
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (12 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 13/18] riscv: dts: zhihe: add A210 core support Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-22 9:22 ` Philipp Zabel
2026-10-21 19:53 ` [PATCH 15/18] riscv: dts: zhihe: add A210 module memory Han Gao via B4 Relay
` (3 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add the ten A210 UARTs with their clocks, resets and interrupts, using
the snps,dw-apb-uart compatible.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/boot/dts/zhihe/a210.dtsi | 150 ++++++++++++++++++++++++++++++++++++
1 file changed, 150 insertions(+)
diff --git a/arch/riscv/boot/dts/zhihe/a210.dtsi b/arch/riscv/boot/dts/zhihe/a210.dtsi
index bbad51a3edb0..a07b67d10633 100644
--- a/arch/riscv/boot/dts/zhihe/a210.dtsi
+++ b/arch/riscv/boot/dts/zhihe/a210.dtsi
@@ -405,6 +405,66 @@ rst_peri1: reset-controller@2010400 {
#reset-cells = <1>;
};
+ uart0: serial@2014000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x02014000 0x0 0x400>;
+ clocks = <&clk_peri PERI1_UART0_SCLK_EN>,
+ <&clk_peri PERI1_UART0_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <321 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri1 PERI1_UART0_PRST>;
+
+ status = "disabled";
+ };
+
+ uart1: serial@2015000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x02015000 0x0 0x1000>;
+ clocks = <&clk_peri PERI1_UART1_SCLK_EN>,
+ <&clk_peri PERI1_UART1_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <322 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri1 PERI1_UART1_PRST>;
+
+ status = "disabled";
+ };
+
+ uart2: serial@2016000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x02016000 0x0 0x1000>;
+ clocks = <&clk_peri PERI1_UART2_SCLK_EN>,
+ <&clk_peri PERI1_UART2_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <323 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri1 PERI1_UART2_PRST>;
+
+ status = "disabled";
+ };
+
+ uart3: serial@2017000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x02017000 0x0 0x1000>;
+ clocks = <&clk_peri PERI1_UART3_SCLK_EN>,
+ <&clk_peri PERI1_UART3_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <324 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri1 PERI1_UART3_PRST>;
+
+ status = "disabled";
+ };
+
peri1_padctrl: pinctrl@2026000 {
compatible = "zhihe,a210-peri1-pinctrl";
reg = <0x0 0x02026000 0x0 0x1000>;
@@ -420,6 +480,96 @@ rst_peri2: reset-controller@8400400 {
#reset-cells = <1>;
};
+ uart4: serial@8401000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x08401000 0x0 0x400>;
+ clocks = <&clk_peri PERI2_UART4_SCLK_EN>,
+ <&clk_peri PERI2_UART4_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <325 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri2 PERI2_UART4_PRST>;
+
+ status = "disabled";
+ };
+
+ uart5: serial@8402000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x08402000 0x0 0x1000>;
+ clocks = <&clk_peri PERI2_UART5_SCLK_EN>,
+ <&clk_peri PERI2_UART5_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <326 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri2 PERI2_UART5_PRST>;
+
+ status = "disabled";
+ };
+
+ uart6: serial@8403000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x08403000 0x0 0x1000>;
+ clocks = <&clk_peri PERI2_UART6_SCLK_EN>,
+ <&clk_peri PERI2_UART6_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <327 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri2 PERI2_UART6_PRST>;
+
+ status = "disabled";
+ };
+
+ uart7: serial@8404000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x08404000 0x0 0x1000>;
+ clocks = <&clk_peri PERI2_UART7_SCLK_EN>,
+ <&clk_peri PERI2_UART7_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <328 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri2 PERI2_UART7_PRST>;
+
+ status = "disabled";
+ };
+
+ uart8: serial@8405000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x08405000 0x0 0x1000>;
+ clocks = <&clk_peri PERI2_UART8_SCLK_EN>,
+ <&clk_peri PERI2_UART8_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <329 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri2 PERI2_UART8_PRST>;
+
+ status = "disabled";
+ };
+
+ uart9: serial@8406000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x0 0x08406000 0x0 0x1000>;
+ clocks = <&clk_peri PERI2_UART9_SCLK_EN>,
+ <&clk_peri PERI2_UART9_PCLK_EN>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <330 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&rst_peri2 PERI2_UART9_PRST>;
+
+ status = "disabled";
+ };
+
peri2_padctrl: pinctrl@8411000 {
compatible = "zhihe,a210-peri2-pinctrl";
reg = <0x0 0x08411000 0x0 0x1000>;
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 15/18] riscv: dts: zhihe: add A210 module memory
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (13 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 14/18] riscv: dts: zhihe: add A210 UARTs Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2 Han Gao via B4 Relay
` (2 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Add the A210 module memory node with a default 4 GiB range for boot
firmware to update with the detected capacity.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/boot/dts/zhihe/a210-som.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/riscv/boot/dts/zhihe/a210-som.dtsi b/arch/riscv/boot/dts/zhihe/a210-som.dtsi
new file mode 100644
index 000000000000..a77447e402d7
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/a210-som.dtsi
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include "a210.dtsi"
+
+/ {
+ /* The loader replaces this reference capacity after DDR training. */
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x1 0x0>;
+ };
+};
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (14 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 15/18] riscv: dts: zhihe: add A210 module memory Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 17/18] riscv: defconfig: enable A210 support Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 18/18] MAINTAINERS: add Zhihe A210 Han Gao via B4 Relay
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Add Melon Pi V1 and V2 with the UART4 console on GPIO2_0 and GPIO2_1.
Use serial aliases to preserve physical UART numbering.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/boot/dts/Makefile | 1 +
arch/riscv/boot/dts/zhihe/Makefile | 2 +
arch/riscv/boot/dts/zhihe/a210-melonpi-common.dtsi | 55 ++++++++++++++++++++++
arch/riscv/boot/dts/zhihe/a210-melonpi-v1.dts | 9 ++++
arch/riscv/boot/dts/zhihe/a210-melonpi-v2.dts | 9 ++++
5 files changed, 76 insertions(+)
diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index 69d8751fb17c..445edde8f107 100644
--- a/arch/riscv/boot/dts/Makefile
+++ b/arch/riscv/boot/dts/Makefile
@@ -12,3 +12,4 @@ subdir-y += spacemit
subdir-y += starfive
subdir-y += tenstorrent
subdir-y += thead
+subdir-y += zhihe
diff --git a/arch/riscv/boot/dts/zhihe/Makefile b/arch/riscv/boot/dts/zhihe/Makefile
new file mode 100644
index 000000000000..553102091d4f
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_ZHIHE) += a210-melonpi-v1.dtb a210-melonpi-v2.dtb
diff --git a/arch/riscv/boot/dts/zhihe/a210-melonpi-common.dtsi b/arch/riscv/boot/dts/zhihe/a210-melonpi-common.dtsi
new file mode 100644
index 000000000000..7a6e6af0aa1f
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/a210-melonpi-common.dtsi
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include "a210-som.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ serial6 = &uart6;
+ serial7 = &uart7;
+ serial8 = &uart8;
+ serial9 = &uart9;
+ };
+
+ chosen {
+ stdout-path = "serial4:115200n8";
+ };
+};
+
+&peri2_padctrl {
+ status = "okay";
+
+ uart4_pins: uart4-0 {
+ rx-pins {
+ bias-disable;
+ drive-strength = <1>;
+ function = "uart4";
+ input-enable;
+ input-schmitt-enable;
+ pins = "GPIO2_1";
+ slew-rate = <0>;
+ };
+
+ tx-pins {
+ bias-disable;
+ drive-strength = <3>;
+ function = "uart4";
+ input-disable;
+ input-schmitt-disable;
+ pins = "GPIO2_0";
+ slew-rate = <0>;
+ };
+ };
+};
+
+&uart4 {
+ pinctrl-0 = <&uart4_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
diff --git a/arch/riscv/boot/dts/zhihe/a210-melonpi-v1.dts b/arch/riscv/boot/dts/zhihe/a210-melonpi-v1.dts
new file mode 100644
index 000000000000..a88e9b949c4a
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/a210-melonpi-v1.dts
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+#include "a210-melonpi-common.dtsi"
+
+/ {
+ compatible = "zhihe,a210-melonpi-v1", "zhihe,a210-som", "zhihe,a210";
+ model = "Melon Pi V1";
+};
diff --git a/arch/riscv/boot/dts/zhihe/a210-melonpi-v2.dts b/arch/riscv/boot/dts/zhihe/a210-melonpi-v2.dts
new file mode 100644
index 000000000000..71752471c5fb
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/a210-melonpi-v2.dts
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+#include "a210-melonpi-common.dtsi"
+
+/ {
+ compatible = "zhihe,a210-melonpi-v2", "zhihe,a210-som", "zhihe,a210";
+ model = "Melon Pi V2";
+};
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 17/18] riscv: defconfig: enable A210 support
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (15 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2 Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
2026-10-22 18:50 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 18/18] MAINTAINERS: add Zhihe A210 Han Gao via B4 Relay
17 siblings, 1 reply; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Enable A210 platform drivers and reserve ten 8250 UART ports.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/configs/defconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index 04ae305d5511..b9b3bca12089 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -33,6 +33,7 @@ CONFIG_SOC_STARFIVE=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_TENSTORRENT=y
CONFIG_ARCH_THEAD=y
+CONFIG_ARCH_ZHIHE=y
CONFIG_ARCH_ULTRARISC=y
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_CANAAN=y
@@ -149,6 +150,8 @@ CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_SUN4I_LRADC=m
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=10
+CONFIG_SERIAL_8250_RUNTIME_UARTS=10
CONFIG_SERIAL_8250_DW=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
@@ -167,6 +170,7 @@ CONFIG_SPI_PL022=m
CONFIG_SPI_SIFIVE=y
CONFIG_SPI_SUN6I=y
# CONFIG_PTP_1588_CLOCK is not set
+CONFIG_PINCTRL_A210=y
CONFIG_PINCTRL_TH1520=y
CONFIG_PINCTRL_SOPHGO_CV1800B=y
CONFIG_PINCTRL_SOPHGO_CV1812H=y
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 18/18] MAINTAINERS: add Zhihe A210
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
` (16 preceding siblings ...)
2026-10-21 19:53 ` [PATCH 17/18] riscv: defconfig: enable A210 support Han Gao via B4 Relay
@ 2026-10-21 19:53 ` Han Gao via B4 Relay
17 siblings, 0 replies; 26+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-21 19:53 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Add Zhiguo Zhu and Han Gao as A210 maintainers.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
MAINTAINERS | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 782389bd5cd3..97cf956fd632 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -30115,6 +30115,22 @@ L: linux-kernel@vger.kernel.org
S: Maintained
F: arch/x86/kernel/cpu/zhaoxin.c
+ZHIHE A210 SOC SUPPORT
+M: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
+M: Han Gao <gaohan@iscas.ac.cn>
+L: linux-riscv@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/clock/zhihe,a210-*.yaml
+F: Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml
+F: Documentation/devicetree/bindings/reset/zhihe,a210-reset.yaml
+F: Documentation/devicetree/bindings/riscv/zhihe.yaml
+F: arch/riscv/boot/dts/zhihe/
+F: drivers/clk/zhihe/
+F: drivers/pinctrl/pinctrl-a210.c
+F: drivers/reset/reset-a210.c
+F: include/dt-bindings/clock/zhihe,a210-*.h
+F: include/dt-bindings/reset/zhihe,a210-resets.h
+
ZONED BLOCK DEVICE (BLOCK LAYER)
M: Damien Le Moal <dlemoal@kernel.org>
L: linux-block@vger.kernel.org
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 07/18] reset: zhihe: add A210 support
2026-10-21 19:53 ` [PATCH 07/18] reset: zhihe: add A210 support Han Gao via B4 Relay
@ 2026-10-22 9:22 ` Philipp Zabel
0 siblings, 0 replies; 26+ messages in thread
From: Philipp Zabel @ 2026-10-22 9:22 UTC (permalink / raw)
To: gaohan, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Zhiguo Zhu, Stephen Boyd, Brian Masney, Jerome Brunet,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley
On Do, 2026-10-22 at 03:53 +0800, Han Gao via B4 Relay wrote:
> From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
>
> Add support for A210 reset banks and linked reset signals. Check
> register readback to detect rejected writes.
Please explain why the linked reset mechanism is required. To me it
looks like these should be separate resets.
> Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
> Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
> Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
> ---
> drivers/reset/Kconfig | 11 +
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-a210.c | 589 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 601 insertions(+)
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index 3168ab1eea88..039e8a4046dc 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -428,6 +428,17 @@ config RESET_UNIPHIER_GLUE
> on UniPhier SoCs. Say Y if you want to control reset signals
> provided by the glue layer.
>
> +config RESET_ZHIHE_A210
> + tristate "ZhiHe A210 reset controller"
> + depends on OF && (ARCH_ZHIHE || COMPILE_TEST)
> + default ARCH_ZHIHE
> + help
> + Build the reset controller driver for the ZhiHe A210 SoC.
> +
> + This driver provides reset control for the various hardware
> + blocks in the A210 SoC. Say Y if you are building a kernel
> + for the ZhiHe A210 platform.
> +
> config RESET_ZYNQ
> bool "ZYNQ Reset Driver" if COMPILE_TEST
> default ARCH_ZYNQ
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 45ad17062462..3620e94e4539 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -52,5 +52,6 @@ obj-$(CONFIG_RESET_TI_TPS380X) += reset-tps380x.o
> obj-$(CONFIG_RESET_TN48M_CPLD) += reset-tn48m.o
> obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
> obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
> +obj-$(CONFIG_RESET_ZHIHE_A210) += reset-a210.o
> obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
> obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o
> diff --git a/drivers/reset/reset-a210.c b/drivers/reset/reset-a210.c
> new file mode 100644
> index 000000000000..38bad400d6b8
> --- /dev/null
> +++ b/drivers/reset/reset-a210.c
> @@ -0,0 +1,589 @@
[...]
> +static int a210_reset_update(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> + struct a210_reset *rst = to_a210_reset(rcdev);
> + const struct a210_rst_signal *signal;
> + unsigned long flags;
> + u32 value;
> + int ret = 0;
> +
> + if (id >= rst->data->num_signals)
> + return -EINVAL;
Unnecessary, the core already checks id < rcdev->num_resets before
creating the reset control.
> +
> + spin_lock_irqsave(&rst->lock, flags);
If you use guard() here ...
> + do {
> + signal = &rst->data->signals[id];
> + value = readl(rst->base + signal->offset);
> + if (assert)
> + value &= ~signal->mask;
> + else
> + value |= signal->mask;
> + writel(value, rst->base + signal->offset);
> + /* Firmware can lock individual reset controls against AP writes. */
> + if ((readl(rst->base + signal->offset) & signal->mask) !=
> + (value & signal->mask)) {
> + ret = -EIO;
> + break;
... this could just return -EIO;
> + }
> + id = signal->nextid;
> + } while (id);
Is this loop a workaround for the UART driver not handling two resets?
Or do the two linked reset bits really have to be asserted, one
directly after the other, without any other write to the same register
in-between and without setting them at the same time? If so, why?
> + spin_unlock_irqrestore(&rst->lock, flags);
> +
> + return ret;
> +}
> +
> +static int a210_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + return a210_reset_update(rcdev, id, true);
> +}
> +
> +static int a210_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + return a210_reset_update(rcdev, id, false);
> +}
> +
> +static int a210_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
Do you actually need this for any consumer?
> +{
> + struct a210_reset *rst = to_a210_reset(rcdev);
> + const struct a210_rst_signal *signal;
> + unsigned long flags;
> + bool asserted;
> +
> + if (id >= rst->data->num_signals)
> + return -EINVAL;
> +
> + /* The logical reset is asserted if any linked signal is asserted. */
What is the "logical reset" in this context?
When there are multiple reset lines that can be in different states,
I'd expect this to return an error.
> + spin_lock_irqsave(&rst->lock, flags);
> + do {
> + signal = &rst->data->signals[id];
> + asserted = (readl(rst->base + signal->offset) & signal->mask) !=
> + signal->mask;
> + if (asserted)
> + break;
> + id = signal->nextid;
> + } while (id);
> + spin_unlock_irqrestore(&rst->lock, flags);
> +
> + return asserted;
> +}
regards
Philipp
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 14/18] riscv: dts: zhihe: add A210 UARTs
2026-10-21 19:53 ` [PATCH 14/18] riscv: dts: zhihe: add A210 UARTs Han Gao via B4 Relay
@ 2026-10-22 9:22 ` Philipp Zabel
0 siblings, 0 replies; 26+ messages in thread
From: Philipp Zabel @ 2026-10-22 9:22 UTC (permalink / raw)
To: gaohan, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Zhiguo Zhu, Stephen Boyd, Brian Masney, Jerome Brunet,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley
On Do, 2026-10-22 at 03:53 +0800, Han Gao via B4 Relay wrote:
> From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
>
> Add the ten A210 UARTs with their clocks, resets and interrupts, using
> the snps,dw-apb-uart compatible.
>
> Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
> Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
> Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
> ---
> arch/riscv/boot/dts/zhihe/a210.dtsi | 150 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 150 insertions(+)
>
> diff --git a/arch/riscv/boot/dts/zhihe/a210.dtsi b/arch/riscv/boot/dts/zhihe/a210.dtsi
> index bbad51a3edb0..a07b67d10633 100644
> --- a/arch/riscv/boot/dts/zhihe/a210.dtsi
> +++ b/arch/riscv/boot/dts/zhihe/a210.dtsi
> @@ -405,6 +405,66 @@ rst_peri1: reset-controller@2010400 {
> #reset-cells = <1>;
> };
>
> + uart0: serial@2014000 {
> + compatible = "snps,dw-apb-uart";
Prepend a vendor compatible if you need two resets, similar to
"starfive,jh7100-uart"?
> + reg = <0x0 0x02014000 0x0 0x400>;
> + clocks = <&clk_peri PERI1_UART0_SCLK_EN>,
> + <&clk_peri PERI1_UART0_PCLK_EN>;
> + clock-names = "baudclk", "apb_pclk";
> + interrupt-parent = <&intc>;
> + interrupts = <321 IRQ_TYPE_LEVEL_HIGH>;
> + reg-io-width = <4>;
> + reg-shift = <2>;
> + resets = <&rst_peri1 PERI1_UART0_PRST>;
This looks to me like it should be
resets = <&rst_peri1 PERI1_UART0_PRST>,
<&rst_peri1 PERI1_UART0_S_RST>;
instead.
regards
Philipp
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 13/18] riscv: dts: zhihe: add A210 core support
2026-10-21 19:53 ` [PATCH 13/18] riscv: dts: zhihe: add A210 core support Han Gao via B4 Relay
@ 2026-10-22 18:48 ` Conor Dooley
0 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2026-10-22 18:48 UTC (permalink / raw)
To: gaohan
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini, devicetree, linux-kernel, linux-riscv, linux-clk,
linux-gpio, Paul Walmsley
[-- Attachment #1: Type: text/plain, Size: 2217 bytes --]
On Thu, Oct 22, 2026 at 03:53:33AM +0800, Han Gao via B4 Relay wrote:
> + soc {
> + compatible = "simple-bus";
> + ranges;
> + #address-cells = <2>;
> + dma-noncoherent;
> + #size-cells = <2>;
> +
> + clk: clock-controller@260000 {
> + compatible = "zhihe,a210-clk";
> + reg = <0x0 0x00260000 0x0 0x1000>,
> + <0x0 0x00250000 0x0 0x1000>,
> + <0x0 0x10141600 0x0 0x100>,
> + <0x0 0x10141400 0x0 0x100>,
> + <0x0 0x04810000 0x0 0x1000>,
> + <0x0 0x05810000 0x0 0x1000>,
> + <0x0 0x04900000 0x0 0x1000>,
> + <0x0 0x20250000 0x0 0x1000>,
> + <0x0 0x10140000 0x0 0xe00>;
This looks very much like an incorrect modelling of the device.
Most of these should be individual devices, and those labeled "sysreg"
probably should be syscons as they likely contain multiple functions,
not just clocks?
> + reg-names = "pll-wrap", "top-crg", "cpu-ss-clk-sysreg",
> + "cpu-ss-cpu-pll", "ddr0-sysreg",
> + "ddr1-sysreg", "slc-dual-sysreg",
> + "top-crg-t", "cpu-ss-ccu";
> + #clock-cells = <1>;
> + clocks = <&osc_32k>, <&osc_24m>, <&rc_24m>;
> + clock-names = "osc-32k", "osc-24m", "rc-24m";
> + };
> +
> + clk_peri: clock-controller@300200 {
> + compatible = "zhihe,a210-peri-clk";
> + reg = <0x0 0x00300200 0x0 0x4>,
> + <0x0 0x02010200 0x0 0x8>,
> + <0x0 0x08400200 0x0 0x8>,
> + <0x0 0x00540200 0x0 0x4>,
> + <0x0 0x27420200 0x0 0x200>;
Same here, particularly things that are only a single word wide...
> + reg-names = "peri0-sysreg", "peri1-sysreg",
> + "peri2-sysreg", "peri3-sysreg", "tee-crg";
> + #clock-cells = <1>;
> + };
> + clk_aon: clock-controller@30844000 {
> + compatible = "zhihe,a210-aon-clk";
> + reg = <0 0x30844000 0 0x1c>;
0x1c is also suspiciously narrow, but believable. Is there a register
map for this device available somewhere (ideally in english, but I
suppose machine translation will do a sufficient job) so that I can try
to understand how this device should be modelled?
Thanks,
Conor.
> + #clock-cells = <1>;
> + clocks = <&aon_110m>, <&osc_24m>, <&aon_rc>, <&osc_32k>;
> + clock-names = "high", "osc", "rc", "rtc";
> + };
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 17/18] riscv: defconfig: enable A210 support
2026-10-21 19:53 ` [PATCH 17/18] riscv: defconfig: enable A210 support Han Gao via B4 Relay
@ 2026-10-22 18:50 ` Conor Dooley
0 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2026-10-22 18:50 UTC (permalink / raw)
To: gaohan
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini, devicetree, linux-kernel, linux-riscv, linux-clk,
linux-gpio, Paul Walmsley
[-- Attachment #1: Type: text/plain, Size: 1364 bytes --]
On Thu, Oct 22, 2026 at 03:53:37AM +0800, Han Gao via B4 Relay wrote:
> From: Han Gao <gaohan@iscas.ac.cn>
>
> Enable A210 platform drivers and reserve ten 8250 UART ports.
>
> Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
> ---
> arch/riscv/configs/defconfig | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
> index 04ae305d5511..b9b3bca12089 100644
> --- a/arch/riscv/configs/defconfig
> +++ b/arch/riscv/configs/defconfig
> @@ -33,6 +33,7 @@ CONFIG_SOC_STARFIVE=y
> CONFIG_ARCH_SUNXI=y
> CONFIG_ARCH_TENSTORRENT=y
> CONFIG_ARCH_THEAD=y
> +CONFIG_ARCH_ZHIHE=y
> CONFIG_ARCH_ULTRARISC=y
> CONFIG_ARCH_VIRT=y
> CONFIG_ARCH_CANAAN=y
> @@ -149,6 +150,8 @@ CONFIG_KEYBOARD_GPIO=y
> CONFIG_KEYBOARD_SUN4I_LRADC=m
> CONFIG_SERIAL_8250=y
> CONFIG_SERIAL_8250_CONSOLE=y
> +CONFIG_SERIAL_8250_NR_UARTS=10
> +CONFIG_SERIAL_8250_RUNTIME_UARTS=10
Why are these options needed?
> CONFIG_SERIAL_8250_DW=y
> CONFIG_SERIAL_OF_PLATFORM=y
> CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
> @@ -167,6 +170,7 @@ CONFIG_SPI_PL022=m
> CONFIG_SPI_SIFIVE=y
> CONFIG_SPI_SUN6I=y
> # CONFIG_PTP_1588_CLOCK is not set
> +CONFIG_PINCTRL_A210=y
> CONFIG_PINCTRL_TH1520=y
> CONFIG_PINCTRL_SOPHGO_CV1800B=y
> CONFIG_PINCTRL_SOPHGO_CV1812H=y
>
> --
> 2.55.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 03/18] dt-bindings: clock: add Zhihe A210 clock controllers
2026-10-21 19:53 ` [PATCH 03/18] dt-bindings: clock: add Zhihe A210 clock controllers Han Gao via B4 Relay
@ 2026-10-22 18:52 ` Conor Dooley
0 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2026-10-22 18:52 UTC (permalink / raw)
To: gaohan
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini, devicetree, linux-kernel, linux-riscv, linux-clk,
linux-gpio, Paul Walmsley
[-- Attachment #1: Type: text/plain, Size: 47453 bytes --]
On Thu, Oct 22, 2026 at 03:53:23AM +0800, Han Gao via B4 Relay wrote:
> From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
>
> Add bindings for the A210 clock controllers, including register ranges,
> input clocks and clock IDs.
>
> Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
> Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
I've left some comments on this device on the dts patch, but they
equally apply here. No point having two conversations, so I'm going to
mark this as changes requested.
pw-bot: changes-requested
Thanks,
Conor.
> ---
> .../devicetree/bindings/clock/zhihe,a210-clk.yaml | 231 ++++++++
> include/dt-bindings/clock/zhihe,a210-clk.h | 649 +++++++++++++++++++++
> 2 files changed, 880 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/zhihe,a210-clk.yaml b/Documentation/devicetree/bindings/clock/zhihe,a210-clk.yaml
> new file mode 100644
> index 000000000000..a3546d2f5977
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/zhihe,a210-clk.yaml
> @@ -0,0 +1,231 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/zhihe,a210-clk.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ZhiHe A210 Clock Controller
> +
> +maintainers:
> + - Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
> +
> +description:
> + The ZhiHe A210 SoC contains several clock controllers spread across
> + different subsystems. Each controller manages PLLs, dividers, gates and
> + muxes for its subsystem. The register regions consumed by a controller
> + depend on the specific compatible string.
> +
> +properties:
> + compatible:
> + enum:
> + - zhihe,a210-clk
> + - zhihe,a210-peri-clk
> + - zhihe,a210-gpu-clk
> + - zhihe,a210-pcie-clk
> + - zhihe,a210-usb-clk
> + - zhihe,a210-vi-clk
> + - zhihe,a210-vp-clk
> + - zhihe,a210-vo-clk
> + - zhihe,a210-npu-clk
> +
> + reg:
> + minItems: 1
> + maxItems: 9
> +
> + reg-names:
> + minItems: 1
> + maxItems: 9
> +
> + clocks:
> + description: Input reference oscillators.
> + minItems: 1
> + maxItems: 3
> +
> + clock-names:
> + minItems: 1
> + maxItems: 3
> + items:
> + enum:
> + - osc-32k
> + - osc-24m
> + - rc-24m
> +
> + power-domains:
> + maxItems: 1
> +
> + "#clock-cells":
> + const: 1
> + description:
> + The single cell is the clock ID defined in
> + include/dt-bindings/clock/zhihe,a210-clk.h.
> +
> +required:
> + - compatible
> + - reg
> + - reg-names
> + - "#clock-cells"
> +
> +allOf:
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-clk
> + then:
> + properties:
> + reg:
> + minItems: 9
> + reg-names:
> + items:
> + - const: pll-wrap
> + - const: top-crg
> + - const: cpu-ss-clk-sysreg
> + - const: cpu-ss-cpu-pll
> + - const: ddr0-sysreg
> + - const: ddr1-sysreg
> + - const: slc-dual-sysreg
> + - const: top-crg-t
> + - const: cpu-ss-ccu
> + clocks:
> + minItems: 3
> + clock-names:
> + items:
> + - const: osc-32k
> + - const: osc-24m
> + - const: rc-24m
> + required:
> + - clocks
> + - clock-names
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-peri-clk
> + then:
> + properties:
> + reg:
> + minItems: 5
> + maxItems: 5
> + reg-names:
> + items:
> + - const: peri0-sysreg
> + - const: peri1-sysreg
> + - const: peri2-sysreg
> + - const: peri3-sysreg
> + - const: tee-crg
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-gpu-clk
> + then:
> + properties:
> + reg:
> + minItems: 2
> + maxItems: 2
> + reg-names:
> + items:
> + - const: gpu-ss-pwrap-clk-en
> + - const: gpu-ss-top-clk-en
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-pcie-clk
> + then:
> + properties:
> + reg:
> + maxItems: 1
> + reg-names:
> + items:
> + - const: pcie-clk-en
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-usb-clk
> + then:
> + properties:
> + reg:
> + maxItems: 1
> + reg-names:
> + items:
> + - const: usb-clk-en
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-vi-clk
> + then:
> + properties:
> + reg:
> + minItems: 2
> + maxItems: 2
> + reg-names:
> + items:
> + - const: vi-clk
> + - const: vi-misc-ctrl
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-vp-clk
> + then:
> + properties:
> + reg:
> + maxItems: 1
> + reg-names:
> + items:
> + - const: vp-clk
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-vo-clk
> + then:
> + properties:
> + reg:
> + minItems: 2
> + maxItems: 2
> + reg-names:
> + items:
> + - const: vo-clk
> + - const: vo-path-ctrl
> +
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-npu-clk
> + then:
> + properties:
> + reg:
> + minItems: 2
> + maxItems: 2
> + reg-names:
> + items:
> + - const: npu-clk
> + - const: npu-top-clk
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/zhihe,a210-clk.h>
> +
> + clock-controller@260000 {
> + compatible = "zhihe,a210-clk";
> + reg = <0x00260000 0x1000>,
> + <0x00250000 0x1000>,
> + <0x10141600 0x100>,
> + <0x10141400 0x100>,
> + <0x04810000 0x1000>,
> + <0x05810000 0x1000>,
> + <0x04900000 0x1000>,
> + <0x20250000 0x1000>,
> + <0x10140000 0xe00>;
> + reg-names = "pll-wrap", "top-crg", "cpu-ss-clk-sysreg", "cpu-ss-cpu-pll",
> + "ddr0-sysreg", "ddr1-sysreg", "slc-dual-sysreg", "top-crg-t",
> + "cpu-ss-ccu";
> + #clock-cells = <1>;
> + clocks = <&osc_32k>, <&osc_24m>, <&rc_24m>;
> + clock-names = "osc-32k", "osc-24m", "rc-24m";
> + };
> diff --git a/include/dt-bindings/clock/zhihe,a210-clk.h b/include/dt-bindings/clock/zhihe,a210-clk.h
> new file mode 100644
> index 000000000000..aa59d91a9ad0
> --- /dev/null
> +++ b/include/dt-bindings/clock/zhihe,a210-clk.h
> @@ -0,0 +1,649 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +#ifndef _DT_BINDINGS_CLOCK_ZHIHE_A210_CLK_H
> +#define _DT_BINDINGS_CLOCK_ZHIHE_A210_CLK_H
> +
> +// PLL_WRAP
> +#define AUDIO0_PLL_FOUTVCO 0
> +#define AUDIO0_PLL_FOUTPOSTDIV 1
> +#define AUDIO0_PLL_FOUT2 2
> +#define AUDIO1_PLL_FOUTVCO 3
> +#define AUDIO1_PLL_FOUTPOSTDIV 4
> +#define AUDIO1_PLL_FOUT2 5
> +#define GMAC_PLL_FOUTVCO 6
> +#define GMAC_PLL_FOUTPOSTDIV 7
> +#define GMAC_PLL_FOUT1PH0 8
> +#define DVFS_PLL_FOUTVCO 9
> +#define DPU0_PLL_FOUTPOSTDIV 10
> +#define DPU1_PLL_FOUTVCO 11
> +#define DPU1_PLL_FOUTPOSTDIV 12
> +#define DPU2_PLL_FOUTVCO 13
> +#define DPU2_PLL_FOUTPOSTDIV 14
> +#define VIDEO_PLL_FOUTVCO 15
> +#define VIDEO_PLL_FOUTPOSTDIV 16
> +#define VIDEO_PLL_FOUT1PH0 17
> +#define VIDEO_PLL_FOUT3 18
> +#define TEE_PLL_FOUTVCO 19
> +
> +// TOP_CRG
> +#define IOMMU_PTW_ACLK_DIV 20
> +#define NOC_CCLK_DIV 21
> +#define NOC_CCLK_MUX 22
> +#define TOP_CFG_ACLK_DIV 23
> +#define TOP_PCLK_DIV 24
> +#define TOP_CPU_BAK_PLL0_CLK_DIV4 25
> +#define TOP_CPUSYS_PIC_CLK_DIV 26
> +#define TOP_CPU_DDR1_ACLK_MUX 27
> +#define TOP_CPU_DDR0_ACLK_MUX 28
> +#define TOP_CPU_BAK_PLL0_CLK_MUX0 29
> +#define TOP_CPU_BAK_PLL0_CLK_DIV0 30
> +#define TOP_CPU_BAK_PLL0_CLK_DIV1 31
> +#define TOP_CPU_BAK_PLL0_CLK_DIV3 32
> +#define TOP_CPUSYS_PIC_CLK_MUX 33
> +#define TOP_CPU_BAK_PLL0_CLK_MUX 34
> +#define TOP_CPU_BAK_PLL1_CLK_DIV1 35
> +#define TOP_CPUSYS_BUS_CLK_DIV 36
> +#define TOP_CPUSYS_BUS_CLK_MUX 37
> +#define TOP_CPU_BAK_PLL1_CLK_DIV0 38
> +#define TOP_CPU_BAK_PLL1_CLK_MUX0 39
> +#define TOP_CPU_BAK_PLL1_CLK_DIV3 40
> +#define TOP_CPU_BAK_PLL1_CLK_MUX 41
> +#define TOP_D2D_REF_CLK_MUX 42
> +#define TOP_D2D_SCAN_CLK0_DIV 43
> +#define TOP_D2D_SCAN_CLK1_DIV 44
> +#define TOP_D2D_ACLK_DIV 45
> +#define TOP_D2D_ACLK_MUX 46
> +#define AMUX_CLK_DIV 47
> +#define TOP_GPU_CORE_CLK_DIV 48
> +#define TOP_GPU_CORE_CLK_MUX 49
> +#define TOP_PCIE_SCAN_REF_CLK1_DIV 50
> +#define TOP_PCIE_SCAN_REF_CLK0_DIV 51
> +#define TOP_PCIE_AXI_M_ACLK_DIV 52
> +#define TOP_PCIE_AXI_M_ACLK_MUX 53
> +#define TOP_PERI_SPI_SSI_CLK0_DIV 54
> +#define TOP_PERI_MST_ACLK0_DIV 55
> +#define TOP_PERI_TIMER_CLK_MUX 56
> +#define TOP_PERI_I2S_8CH0_SRC_CLK_MUX 57
> +#define TOP_PERI_I2S_2CH0_SRC_CLK_MUX 58
> +#define TOP_PERI_QSPI_SSI_CLK_MUX0 59
> +#define TOP_PERI_QSPI0_SSI_CLK_DIV0 60
> +#define TOP_PERI_QSPI0_SSI_CLK_DIV1 61
> +#define TOP_PERI_SPI_SSI_CLK1_DIV 62
> +#define TOP_PERI_HIRES_CLK0_DIV 63
> +#define TOP_PERI_HIRES_CLK1_DIV 64
> +#define TOP_PERI_TDM_SRC_CLK_MUX 65
> +#define TOP_UART_SCLK_MUX 66
> +#define TOP_PERI_I2S_2CH1_SRC_CLK_MUX 67
> +#define TOP_PERI_PDM_MCLK_MUX 68
> +#define TOP_PERI_I2S_2CH2_SRC_CLK_MUX 69
> +#define TOP_PERI_QSPI_SSI_CLK_MUX1 70
> +#define TOP_PERI_QSPI1_SSI_CLK_DIV0 71
> +#define TOP_PERI_QSPI1_SSI_CLK_DIV1 72
> +#define TOP_PERI_MST_CLK1_DIV 73
> +#define TOP_PERI_EMMC_REF_CLK_DIV 74
> +#define TOP_PERI_PDM_MCLK_DIV 75
> +#define TOP_PERI_EMMC_REF_CLK_MUX 76
> +#define TOP_PAD_SENSOR_VCLK_MUX1 77
> +#define TOP_PAD_SENSOR_VCLK_MUX0 78
> +#define TOP_PAD_SENSOR_VCLK1_DIV 79
> +#define TOP_PAD_SENSOR_VCLK0_DIV 80
> +#define TOP_TEE_CLK_DIV 81
> +#define TOP_TEE_CLK_MUX 82
> +#define TOP_USB_BUS_ACLK_DIV 83
> +#define TOP_USB_DP_AUX_CLK_DIV 84
> +#define TOP_VP_ACLK_MUX 85
> +#define TOP_VP_ACLK_DIV 86
> +#define TOP_VP_G2D_CCLK_DIV 87
> +#define TOP_VP_G2D_CCLK_MUX 88
> +#define TOP_VP_VDEC_CCLK_DIV 89
> +#define TOP_VP_VDEC_CCLK_MUX 90
> +#define TOP_VP_VENC_CCLK_DIV 91
> +#define TOP_VP_VENC_CCLK_MUX 92
> +#define TOP_NPU_ACLK_DIV 93
> +#define TOP_NPU_ACLK_MUX 94
> +#define TOP_NPU_CCLK_DIV 95
> +#define TOP_NPU_CCLK_MUX 96
> +#define TOP_USB_USB20_SCAN_REF_CLK_DIV 97
> +#define TOP_USB_SCAN_REF_CLK3_DIV 98
> +#define TOP_USB_SCAN_REF_CLK2_DIV 99
> +#define TOP_USB_SCAN_REF_CLK1_DIV 100
> +#define TOP_USB_SCAN_REF_CLK0_DIV 101
> +#define TOP_CPU_BAK_PLL1_CLK_DIV4 102
> +#define SW_TOP_PAD_SENSOR_VCLK1_EN 103
> +#define SW_TOP_PAD_SENSOR_VCLK0_EN 104
> +#define SW_NOC_CCLK_EN 105
> +#define SW_TOP_OSC_CLK_LOGIC_EN 106
> +#define SW_IOMMU_PTW_330_ACLK_EN 107
> +#define SW_AMUX_660_CLK_EN 108
> +#define SW_NPU_SS_CLK_EN 109
> +#define SW_CPU_SS_CLK_EN 110
> +#define SW_DDR_SS_CLK_EN 111
> +#define SW_D2D_SS_CLK_EN 112
> +#define SW_VP_SS_CLK_EN 113
> +#define SW_VO_SS_CLK_EN 114
> +#define SW_VI_SS_CLK_EN 115
> +#define SW_PCIE_SS_CLK_EN 116
> +#define SW_USB_SS_CLK_EN 117
> +#define SW_PERI1_SS_CLK_EN 118
> +#define SW_PERI3_SS_CLK_EN 119
> +#define SW_GPU_SS_CLK_EN 120
> +
> +// CPU_SS_CLK_SYSREG
> +#define C908_CPU_TO_CDE_CLK_MUX 121
> +#define C920_CPU_TO_CDE_CLK_MUX 122
> +
> +// CPU_SS_CPU_PLL
> +#define C908_PLL_FOUTVCO 123
> +#define C920_PLL_FOUTVCO 124
> +
> +// GPU_SS_SYSREG
> +#define SW_PWR_WRAP_X2P_PCLK_EN 125
> +#define SW_PWR_WRAP_SYSREG_PCLK_EN 126
> +#define SW_PWR_WRAP_DFMU_PCLK_EN 127
> +#define SW_PWR_WRAP_X2P_ACLK_EN 128
> +#define SW_PWR_WRAP_CFG_ACLK_EN 129
> +#define SW_PWR_WRAP_CFG_AAB_MST_ACLK_EN 130
> +#define SW_PWR_WRAP_GPU_SYS_CLK_EN 131
> +#define SW_PWR_WRAP_MEMIF_AAB_SLV_CORE_CLK_EN 132
> +#define SW_PWR_WRAP_DFMU_CORE_CLK_EN 133
> +#define SW_PWR_WRAP_GPU_CORE_CLK_EN 134
> +
> +// GPU_SS_TOP_SYSREG
> +#define SW_TOP_CFG_AAB_SLV_ACLK_EN 135
> +#define SW_TOP_X2P_PCLK_EN 136
> +#define SW_TOP_SYSREG_PCLK_EN 137
> +#define SW_TOP_X2P_ACLK_EN 138
> +#define SW_TOP_CFG_ACLK_EN 139
> +#define SW_TOP_AFENCE_ACLK_EN 140
> +#define SW_MEMIF_AAB_MST_BUS_CLK_EN 141
> +
> +// NPU_CRG
> +#define NPU_CCLK_BUF_CDE_RATIO 142
> +#define NPU_CCLK_BUF_CDE_MUX 143
> +#define NPU_ACLK_BUF_CDE_RATIO 144
> +#define NPU_ACLK_BUF_CDE_MUX 145
> +#define SW_DROOP_PCLK_EN 146
> +#define SW_DROOP_CLK_EN 147
> +#define SW_DROOP_CCTRL_PCLK_EN 148
> +#define SW_DROOP_CCTRL_CLK_EN 149
> +#define SW_SEMA_PCLK_EN 150
> +#define SW_SEMA_ACLK_EN 151
> +#define SW_NPU_X2P_ACLK_EN 152
> +#define SW_NPU_X2H_ACLK_EN 153
> +#define SW_NPU_PTW_CCU_PCLK_EN 154
> +#define SW_NPU_PTW_CCU_CLK_EN 155
> +#define SW_NPU_PCTRL_PCLK_EN 156
> +#define SW_NPU_PCTRL_EN 157
> +#define SW_NPU_LPE_C_PCLK_EN 158
> +#define SW_NPU_LPE_C_CLK_EN 159
> +#define SW_NPU_LPC_C_CLK_EN 160
> +#define SW_NPU_IP_HCLK_EN 161
> +#define SW_NPU_IP_CCLK_EN 162
> +#define SW_NPU_IP_ACLK_EN 163
> +#define SW_NPU_DFMU_PTWCLK_EN 164
> +#define SW_NPU_DFMU_PCLK_EN 165
> +#define SW_NPU_CLK_CALC_EN 166
> +#define SW_NPU_AXI_M2S1_ACLK_EN 167
> +#define SW_NPU_AXI_CCU_PCLK_EN 168
> +#define SW_NPU_AXI_CCU_CLK_EN 169
> +#define SW_NPU_AXI_ACLK_EN 170
> +#define SW_NPU_AFENCE_EN 171
> +#define SW_NPU_AAB_MST_ACLK_EN 172
> +#define SW_DFMU_ACLK_EN 173
> +
> +// NPU_TOP_CRG
> +#define SW_NPUSS_AAB_SLV_CLK_EN 174
> +#define SW_NPUSS_FENCE_CLK_EN 175
> +
> +// DDR0_SYSREG
> +#define DDR0_PHY_DFICLK_EN 176
> +#define DDR0_DDRC_ACLK_EN 177
> +#define DDR0_DDRC_CCLK_EN 178
> +#define DDR0_SBR_CLK_EN 179
> +
> +// DDR1_SYSREG
> +#define DDR1_PHY_DFICLK_EN 180
> +#define DDR1_DDRC_ACLK_EN 181
> +#define DDR1_DDRC_CCLK_EN 182
> +#define DDR1_SBR_CLK_EN 183
> +
> +// SLC_DUAL_SYSREG
> +#define DDR_PLL_FOUTVCO 184
> +#define DDR_PLL_FOUTPOSTDIV 185
> +#define DDR_PLL_FOUT1PH0 186
> +#define DDR_PLL_FOUT2 187
> +#define DDR_PLL_FOUT4 188
> +#define DDR_PLL_CLK_SEL 189
> +#define DDR_PLL_CLK_EN 190
> +#define DDR_CBUS2DDR_ACLK0 191
> +#define DDR_CBUS2DDR_ACLK1 192
> +
> +// D2D_CRG_REG_T
> +#define D2D_SS_CTRL0_CLK_EN 193
> +#define D2D_SS_CTRL1_CLK_EN 194
> +
> +// PCIE_CPR
> +#define AXI4_PCIE_MST_PCLK_EN 195
> +#define AXI4_PCIE_MST_ACLK_EN 196
> +#define X2X_PERI3_MST_ACLK_EN 197
> +#define X2X_PERI3_SLV_ACLK_EN 198
> +#define PCIE_SS_DFMU_ACLK_EN 199
> +#define PCIE_SS_DFMU_IOMMU_PTW_ACLK_EN 200
> +#define PCIE_SS_DFMU_PCLK_EN 201
> +#define E16PHY_PCLK_EN 202
> +#define SATA_MST_AFENCE_ACLK_EN 203
> +#define SATA_SLV_AFENCE_ACLK_EN 204
> +#define SATA_GEN3X2_ACLK_EN 205
> +#define X2X_SATA_SLV_ACLK_EN 206
> +#define X2X_SATA_MST_ACLK_EN 207
> +#define SATA_RXOOB1_CLK_EN 208
> +#define SATA_RXOOB0_CLK_EN 209
> +#define SATA_PMALIVE_CLK_EN 210
> +#define PCIE_DM_MST_AFENCE_ACLK_EN 211
> +#define PCIE_DM_SLV_AFENCE_ACLK_EN 212
> +#define PCIE_DM_GEN3X4_AUX_CLK_EN 213
> +#define PCIE_DM_GEN3X4_MST_ACLK_EN 214
> +#define PCIE_DM_GEN3X4_PCLK_EN 215
> +#define PCIE_DM_GEN3X4_SLV_ACLK_EN 216
> +#define PCIE_RP_MST_AFENCE_ACLK_EN 217
> +#define PCIE_RP_SLV_AFENCE_ACLK_EN 218
> +#define PCIE_RP_GEN3X1_AUX_CLK_EN 219
> +#define PCIE_RP_GEN3X1_MST_ACLK_EN 220
> +#define PCIE_RP_GEN3X1_PCLK_EN 221
> +#define PCIE_RP_GEN3X1_SLV_ACLK_EN 222
> +
> +// USB_CPR
> +#define USB_SS_AXI_MST_PCLK_EN 223
> +#define USB_SS_AXI_MST_ACLK_EN 224
> +#define USB_SS_DFMU_IOMMU_PTW_ACLK_EN 225
> +#define USB_SS_DFMU_ACLK_EN 226
> +#define USB_SS_DFMU_PCLK_EN 227
> +#define DPTX_I2S_CLK_EN 228
> +#define DPTX_IPI_CLK_EN 229
> +#define DPTX_AUX_CLK_EN 230
> +#define DPTX_GTC_CLK_EN 231
> +#define DPTX_PCLK_EN 232
> +#define USB31_SLV_AFENCE_ACLK_EN 233
> +#define USB31_REF_CLK_EN 234
> +#define USB31_SUSPEND_CLK_EN 235
> +#define USB31_BUS_CLK_EN 236
> +#define USB31_PCLK_EN 237
> +#define C10PHY_SUSPEND_CLK_EN 238
> +#define C10PHY_PCLK_EN 239
> +#define USB2_SYSREG_PCLK_EN 240
> +#define USB2_AXI_MST_ACLK_EN 241
> +#define USB2_AHB_SLV_HCLK_EN 242
> +#define USB2_H2P_HCLK_EN 243
> +#define USB2_SLV_AFENCE_ACLK_EN 244
> +#define USB2_X2H_ACLK_EN 245
> +#define USB2_X2H_HCLK_EN 246
> +#define USB2_WRAP_A2X1_ACLK_EN 247
> +#define USB2_WRAP_A2X1_HCLK_EN 248
> +#define USB2_WRAP_A2X0_ACLK_EN 249
> +#define USB2_WRAP_A2X0_HCLK_EN 250
> +#define USB2_WRAP1_HCLK_EN 251
> +#define USB2_WRAP0_HCLK_EN 252
> +#define USB_SS_PERI2_SLV_AFENCE_ACLK_EN 253
> +#define USB_SS_PERI2_CFG_ACLK_EN 254
> +
> +// VI_SYSREG
> +#define VI_DW_SCLK_EN 255
> +#define VI_VSE_CLK_EN 256
> +#define VI_DWE_CLK_EN 257
> +#define VI_DW200_ACLK_EN 258
> +#define VI_DW200_HCLK_EN 259
> +#define VI_DECOMP_CLK_EN 260
> +#define VI_COMP1_CLK_EN 261
> +#define VI_COMP0_CLK_EN 262
> +#define VI_VSEOUT_CLK_EN 263
> +#define VI_DECOUT_CLK_EN 264
> +#define VI_ISPOUT_CLK_EN 265
> +#define VI_COMP_ACLK_EN 266
> +#define VI_COMP_PCLK_EN 267
> +#define VI_ISP_CLK_EN 268
> +#define VI_VIPRE_ACLK_EN 269
> +#define VI_VIPRE_SCLK_EN 270
> +#define VI_VIPRE_I1_PIXCLK_EN 271
> +#define VI_VIPRE_I0_PIXCLK_EN 272
> +#define VI_VIPRE_PCLK_EN 273
> +#define VI_MIPI1_CSI1_PIXCLK_EN 274
> +#define VI_MIPI1_CSI0_PIXCLK_EN 275
> +#define VI_MIPI1B_CFGCLK_EN 276
> +#define VI_MIPI1A_CFGCLK_EN 277
> +#define VI_MIPI1CSI1_PCLK_EN 278
> +#define VI_MIPI1CSI0_PCLK_EN 279
> +#define VI_MIPI0_CSI1_PIXCLK_EN 280
> +#define VI_MIPI0_CSI0_PIXCLK_EN 281
> +#define VI_MIPI0B_CFGCLK_EN 282
> +#define VI_MIPI0A_CFGCLK_EN 283
> +#define VI_MIPI0CSI1_PCLK_EN 284
> +#define VI_MIPI0CSI0_PCLK_EN 285
> +#define VI_REC_ACLK_EN 286
> +#define VI_REC_PCLK_EN 287
> +#define VI_FENCE_ACLK_EN 288
> +#define VI_MIPI1CSI1_FPCLK_EN 289
> +#define VI_MIPI1CSI0_FPCLK_EN 290
> +#define VI_MIPI0CSI1_FPCLK_EN 291
> +#define VI_MIPI0CSI0_FPCLK_EN 292
> +#define VI_X2H2_CLK_EN 293
> +#define VI_X2H1_CLK_EN 294
> +#define VI_X2H0_CLK_EN 295
> +#define VI_ARB_ACLK_EN 296
> +#define VI_ARB_PCLK_EN 297
> +#define VI_PTW_ACLK_EN 298
> +#define VI_DFMU_ACLK_EN 299
> +#define VI_DFMU_PCLK_EN 300
> +#define VI_PRE_ISP_CORE_CLK_DIV_EN 301
> +#define VI_PRE_ISP_IF_CLK_DIV_EN 302
> +#define VI_PRE_MIPI1_PIXCLK_DIV_EN 303
> +#define VI_PRE_MIPI0_PIXCLK_DIV_EN 304
> +#define VI_ISP_IF_REF_SWITCH_SEL 305
> +#define VI_MIPI1_PIX_REF_SWITCH_SEL 306
> +#define VI_MIPI0_PIX_REF_SWITCH_SEL 307
> +#define VI_PRE_ISP_CORE_CLK_DIV_NUM 308
> +#define VI_PRE_ISP_IF_CLK_DIV_NUM 309
> +#define VI_PRE_MIPI1_PIXCLK_DIV_NUM 310
> +#define VI_PRE_MIPI0_PIXCLK_DIV_NUM 311
> +#define VI_PRE_DECOMP_CLK_DIV_EN 312
> +#define VI_PRE_COMP_CLK_DIV_EN 313
> +#define VI_PRE_DWE_CLK_DIV_EN 314
> +#define VI_PRE_VSE_CLK_DIV_EN 315
> +#define VI_PRE_AXI_CLK_DIV_EN 316
> +#define VI_PRE_DECOMP_CLK_DIV_NUM 317
> +#define VI_PRE_COMP_CLK_DIV_NUM 318
> +#define VI_PRE_DWE_CLK_DIV_NUM 319
> +#define VI_PRE_VSE_CLK_DIV_NUM 320
> +#define VI_PRE_AXI_CLK_DIV_NUM 321
> +
> +// VO_SYSREG
> +#define VO_X2H1_CLK_EN 322
> +#define VO_X2H0_CLK_EN 323
> +#define VO_PTW_ACLK_EN 324
> +#define VO_DFMU_ACLK_EN 325
> +#define VO_DFMU_PCLK_EN 326
> +#define VO_ARB_ACLK_EN 327
> +#define VO_ARB_PCLK_EN 328
> +#define VO_DECOMP_ACLK_EN 329
> +#define VO_DECOMP1_CLK_EN 330
> +#define VO_DECOMP0_CLK_EN 331
> +#define VO_DECOMP_PCLK_EN 332
> +#define VO_MIPI_CFGCLK_EN 333
> +#define VO_MIPI_PCLK_EN 334
> +#define VO_HDMI_SFRCLK_EN 335
> +#define VO_CEC_CLK_EN 336
> +#define VO_I2S_CLK_EN 337
> +#define VO_HDMI_PCLK_EN 338
> +#define VO_AUXDISP_ACLK_EN 339
> +#define VO_AUXDISP_PCLK_EN 340
> +#define VO_CH2_PIXCLK_EN 341
> +#define VO_DPU_ACLK_EN 342
> +#define VO_DPUC_CLK_EN 343
> +#define VO_DPU_HCLK_EN 344
> +#define VO_CH1_PIXCLK_EN 345
> +#define VO_CH0_PIXCLK_EN 346
> +#define VO_PLL2_DIV_EN 347
> +#define VO_PLL2_DIV_NUM 348
> +#define VO_PLL1_DIV_EN 349
> +#define VO_PLL1_DIV_NUM 350
> +#define VO_PLL0_DIV_EN 351
> +#define VO_PLL0_DIV_NUM 352
> +#define VO_DECOMP_DIV_EN 353
> +#define VO_DECOMP_DIV_NUM 354
> +#define VO_DPUC_DIV_EN 355
> +#define VO_DPUC_DIV_NUM 356
> +#define VO_ACLK_DIV_EN 357
> +#define VO_ACLK_DIV_NUM 358
> +
> +// VP_SYSREG
> +#define VP_DECOMP_EXTPCLK_EN 359
> +#define VP_COMP_EXTPCLK_EN 360
> +#define VP_VENC_RS_ACLK_EN 361
> +#define VP_VDEC_RS_ACLK_EN 362
> +#define VP_ARB_ACLK_EN 363
> +#define VP_ARB_PCLK_EN 364
> +#define VP_PTW_ACLK_EN 365
> +#define VP_DFMU_ACLK_EN 366
> +#define VP_DFMU_PCLK_EN 367
> +#define VP_DECOMP_ACLK_EN 368
> +#define VP_DECOMP_CCLK_EN 369
> +#define VP_DECOMP_PCLK_EN 370
> +#define VP_COMP_ACLK_EN 371
> +#define VP_COMP_CCLK_EN 372
> +#define VP_COMP_PCLK_EN 373
> +#define VP_G2D_ACLK_EN 374
> +#define VP_G2D_CCLK_EN 375
> +#define VP_G2D_PCLK_EN 376
> +#define VP_VENC_ACLK_EN 377
> +#define VP_VENC_CCLK_EN 378
> +#define VP_VENC_PCLK_EN 379
> +#define VP_VDEC_ACLK_EN 380
> +#define VP_VDEC_CCLK_EN 381
> +#define VP_VDEC_PCLK_EN 382
> +#define VP_DECOMP_DIV_EN 383
> +#define VP_DECOMP_DIV_NUM 384
> +#define VP_COMP_DIV_EN 385
> +#define VP_COMP_DIV_NUM 386
> +
> +// PERI0_SYSREG
> +#define PERI0_MBOX1_PCLK_EN 387
> +#define PERI0_MBOX0_PCLK_EN 388
> +#define PERI0_WDT0_PCLK_EN 389
> +#define PERI0_TIMER1_PCLK_EN 390
> +#define PERI0_TIMER1_CCLK_EN 391
> +#define PERI0_TIMER0_PCLK_EN 392
> +#define PERI0_TIMER0_CCLK_EN 393
> +
> +// PERI1_SYSREG
> +#define PERI1_UART3_SCLK_EN 394
> +#define PERI1_UART3_PCLK_EN 395
> +#define PERI1_UART2_SCLK_EN 396
> +#define PERI1_UART2_PCLK_EN 397
> +#define PERI1_UART1_SCLK_EN 398
> +#define PERI1_UART1_PCLK_EN 399
> +#define PERI1_UART0_SCLK_EN 400
> +#define PERI1_UART0_PCLK_EN 401
> +#define PERI1_SPI0_SSI_CLK_EN 402
> +#define PERI1_SPI0_PCLK_EN 403
> +#define PERI1_QSPI0_SSI_CLK_EN 404
> +#define PERI1_QSPI0_PCLK_EN 405
> +#define PERI1_PWM0_PCLK_EN 406
> +#define PERI1_PWM0_CCLK_EN 407
> +#define PERI1_MST_BUS_PCLK_EN 408
> +#define PERI1_MST_BUS_ACLK_EN 409
> +#define PERI1_I2S0_SRC_CLK_EN 410
> +#define PERI1_I2S0_PCLK_EN 411
> +#define PERI1_I2C2_PCLK_EN 412
> +#define PERI1_I2C2_IC_CLK_EN 413
> +#define PERI1_I2C1_PCLK_EN 414
> +#define PERI1_I2C1_IC_CLK_EN 415
> +#define PERI1_I2C0_PCLK_EN 416
> +#define PERI1_I2C0_IC_CLK_EN 417
> +#define PERI1_GPIO1_PCLK_EN 418
> +#define PERI1_GPIO1_DBCLK_EN 419
> +#define PERI1_GPIO0_PCLK_EN 420
> +#define PERI1_GPIO0_DBCLK_EN 421
> +#define PERI1_GMAC1_HCLK_EN 422
> +#define PERI1_GMAC1_ACLK_EN 423
> +#define PERI1_GMAC0_HCLK_EN 424
> +#define PERI1_GMAC0_ACLK_EN 425
> +
> +// PERI2_SYSREG
> +#define PERI2_I2S3_PCLK_EN 426
> +#define PERI2_I2S3_SRC_CLK_EN 427
> +#define PERI2_I2S2_PCLK_EN 428
> +#define PERI2_I2S2_SRC_CLK_EN 429
> +#define PERI2_I2S1_PCLK_EN 430
> +#define PERI2_I2S1_SRC_CLK_EN 431
> +#define PERI2_I2C7_IC_CLK_EN 432
> +#define PERI2_I2C7_PCLK_EN 433
> +#define PERI2_I2C6_IC_CLK_EN 434
> +#define PERI2_I2C6_PCLK_EN 435
> +#define PERI2_I2C5_IC_CLK_EN 436
> +#define PERI2_I2C5_PCLK_EN 437
> +#define PERI2_I2C4_IC_CLK_EN 438
> +#define PERI2_I2C4_PCLK_EN 439
> +#define PERI2_I2C3_IC_CLK_EN 440
> +#define PERI2_I2C3_PCLK_EN 441
> +#define PERI2_GPIO3_DBCLK_EN 442
> +#define PERI2_GPIO3_PCLK_EN 443
> +#define PERI2_PAD_CTRL_PCLK_EN 444
> +#define PERI2_UART6_PCLK_EN 445
> +#define PERI2_UART5_PCLK_EN 446
> +#define PERI2_UART4_PCLK_EN 447
> +#define PERI2_SPI1_PCLK_EN 448
> +#define PERI2_GPIO2_PCLK_EN 449
> +#define PERI2_CAN2_PCLK_EN 450
> +#define PERI2_UART6_SCLK_EN 451
> +#define PERI2_UART5_SCLK_EN 452
> +#define PERI2_UART4_SCLK_EN 453
> +#define PERI2_SPI1_SSI_CLK_EN 454
> +#define PERI2_GPIO2_DBCLK_EN 455
> +#define PERI2_CAN2_OSC_CLK_EN 456
> +#define PERI2_CAN2_HIRES_CLK_EN 457
> +#define PERI2_QSPI1_PCLK_EN 458
> +#define PERI2_QSPI1_SSI_CLK_EN 459
> +#define PERI2_UART9_PCLK_EN 460
> +#define PERI2_UART9_SCLK_EN 461
> +#define PERI2_UART8_PCLK_EN 462
> +#define PERI2_UART8_SCLK_EN 463
> +#define PERI2_UART7_PCLK_EN 464
> +#define PERI2_UART7_SCLK_EN 465
> +#define PERI2_PWM2_PCLK_EN 466
> +#define PERI2_PWM2_CCLK_EN 467
> +#define PERI2_PWM1_PCLK_EN 468
> +#define PERI2_PWM1_CCLK_EN 469
> +
> +// PERI3_SYSREG
> +#define PERI3_PAD_CTRL_PCLK_EN 470
> +#define PERI3_GPIO4_PCLK_EN 471
> +#define PERI3_GPIO4_DBCLK_EN 472
> +#define CLKCTRL_PERI3_TEE_H2H_SHCLKEN 473
> +#define CLKCTRL_PERI3_TEE_H2H_MHCLKEN 474
> +#define PERI3_TEE_X2X_ACLK_S_EN 475
> +#define PERI3_ADC_PCLK_EN 476
> +#define AXI_PERI3_MST_PCLK_EN 477
> +#define AXI_PERI3_MST_ACLK_EN 478
> +#define PERI3_SDIO_X2X_ACLK_S_EN 479
> +#define PERI3_SDIO_X2X_ACLK_M_EN 480
> +#define PERI3_SDIO_OSC_CLK_EN 481
> +#define PERI3_SDIO_HCLK_EN 482
> +#define PERI3_EMMC_X2X_ACLK_S_EN 483
> +#define PERI3_EMMC_X2X_ACLK_M_EN 484
> +#define PERI3_EMMC_OSC_CLK_EN 485
> +#define PERI3_EMMC_HCLK_EN 486
> +#define PERI3_EMMC_ACLK_EN 487
> +#define PERI3_EMMC_SDIO_REF_CLK_CG_EN 488
> +#define PERI3_DMAC_HCLK_EN 489
> +#define PERI3_DMAC_ACLK_EN 490
> +
> +// TEE_CRG
> +#define TEE_PCLK_CDE_RATIO 491
> +#define TEE_AHB2_TEESYS_CLKEN 492
> +#define TEE_APB3_TEESYS_CLKEN 493
> +#define TEE_AXI4_TEESYS_CLKEN 494
> +#define TEE_X2P_TEESYS_CLKEN 495
> +#define TEE_EIP120SI_CLKEN 496
> +#define TEE_EIP120SII_CLKEN 497
> +#define TEE_EIP120SIII_CLKEN 498
> +#define TEE_EIP150B_CLKEN 499
> +#define TEE_DMAC_CLKEN 500
> +#define TEE_DS_CLKEN 501
> +#define TEE_OCRAM_CLKEN 502
> +#define TEE_EFUSE_CLKEN 503
> +#define TEE_KEYRAM_CLKEN 504
> +
> +#define CLK_DUMMY 505
> +#define OSC_32K 506
> +#define OSC_24M 507
> +#define RC_24M 508
> +
> +#define TOP_PLL_REF_CLK 509
> +#define AON_OSC_CLK_PHY 510
> +#define AON_OSC_CLK_LOGIC 511
> +#define PLL_OSC_CLK 512
> +#define D2D_PHY_REF_CLK_100M 513
> +#define D2D_PHY_SCAN_CLK2 514
> +#define TOP_PERI_TIMER_CLK_100M 515
> +#define PERI1_UART_SCLK 516
> +#define PERI2_UART_SCLK 517
> +#define UART_SCLK_100M 518
> +#define GPU_TOP_SYS_CLK 519
> +#define GPU_PCLK_CDT 520
> +#define PCIE_SS_APB_CLK 521
> +#define USB_SS_GTC_CLK 522
> +#define USB_SS_PAD_OSC_CLK_1M 523
> +#define USB20_BUS_CLK 524
> +#define USB20_CORE_CLK 525
> +#define VI_PCLK 526
> +#define VO_PCLK 527
> +#define AON_RTC_CLK 528
> +#define PERI1_PWM_CLK 529
> +#define PERI2_PWM_CLK 530
> +#define I2C_IC_CLK 531
> +#define PERI3_SDIO_ACLK_EN 532
> +
> +#define PERI1_ZGMAC_X2X_ACLK_EN 533
> +#define PERI1_GMAC2_HCLK_EN 534
> +#define PERI1_GMAC2_ACLK_EN 535
> +#define PERI1_X2H_GMAC2_HCLK_EN 536
> +#define PERI1_X2H_GMAC2_ACLK_EN 537
> +#define PERI1_CHIP_DBG_PCLK_EN 538
> +#define PERI1_CHIP_DBG_CCLK_EN 539
> +#define PERI1_CHIP_DBG_ACLK_EN 540
> +#define PERI1_TDM0_SCLK_EN 541
> +#define PERI1_TDM0_PCLK_EN 542
> +#define PERI1_PDM0_PCLK_EN 543
> +#define PERI1_PDM0_MCLK_EN 544
> +#define PERI1_CAN1_PCLK_EN 545
> +#define PERI1_CAN1_OSC_CLK_EN 546
> +#define PERI1_CAN1_HIRES_CLK_EN 547
> +#define PERI1_CAN0_PCLK_EN 548
> +#define PERI1_CAN0_OSC_CLK_EN 549
> +#define PERI1_CAN0_HIRES_CLK_EN 550
> +#define PERI1_PAD_CTRL_PCLK_EN 551
> +#define PERI1_DFMU_PTW_ACLK_EN 552
> +#define PERI1_DFMU_PCLK_EN 553
> +#define PERI1_DFMU_ACLK_EN 554
> +#define PERI1_X2H_GMAC1_HCLK_EN 555
> +#define PERI1_X2H_GMAC1_ACLK_EN 556
> +#define PERI1_X2H_GMAC0_HCLK_EN 557
> +#define PERI1_X2H_GMAC0_ACLK_EN 558
> +#define DPU0_PLL_FOUTVCO 559
> +
> +#define PERI3_EMMC_SDIO_REF_CLK 560
> +
> +#define VO_MIPI_PIXCLK 561
> +#define VO_HDMI_PIXCLK 562
> +#define VO_DPTX_PIXCLK 563
> +
> +#define TOP_CPUSYS_CFG_ACLK_DIV 564
> +#define TOP_CPUSYS_COM_APB_CLK_DIV 565
> +#define TOP_CPUSYS_APB_CLK_DIV 566
> +
> +#define VI_MISC_CTRL_H0CLK_CLK_EN 567
> +#define VI_MISC_CTRL_H1CLK_CLK_EN 568
> +#define VI_MISC_CTRL_ISP_ACLK_CLK_EN 569
> +#define VI_MISC_CTRL_ISP_SCLK_CLK0_EN 570
> +#define VI_MISC_CTRL_ISP_SCLK_CLK1_EN 571
> +#define VI_MISC_CTRL_ISP_SCLK_CLK2_EN 572
> +#define VI_MISC_CTRL_ISP_SCLK_CLK3_EN 573
> +#define VI_MISC_CTRL_ISP_CORE_CLK_EN 574
> +#define VI_MISC_CTRL_ISP_FLEXA_CLK_EN 575
> +#define VI_MISC_CTRL_ISP_MCM_CLK_EN 576
> +#define VI_MISC_CTRL_BUS_CLK_GT_DISABLE 577
> +
> +#define USB20_X2H_HCLK 578
> +#define USB20_X2H_ACLK 579
> +#define USB20_SLV_AFENCE_ACLK 580
> +#define USB20_H2P_HCLK 581
> +#define USB20_AHB_SLV_HCLK 582
> +#define USB20_SYSREG_PCLK 583
> +#define USB20_WRAP0_HCLK 584
> +#define USB20_WRAP1_HCLK 585
> +#define USB20_A2X0_HCLK 586
> +#define USB20_A2X0_ACLK 587
> +#define USB20_A2X1_HCLK 588
> +#define USB20_A2X1_ACLK 589
> +
> +#define CLK_END 590
> +
> +#endif
>
> --
> 2.55.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 08/18] dt-bindings: pinctrl: add Zhihe A210 pin controller
2026-10-21 19:53 ` [PATCH 08/18] dt-bindings: pinctrl: add Zhihe A210 pin controller Han Gao via B4 Relay
@ 2026-10-22 19:01 ` Conor Dooley
0 siblings, 0 replies; 26+ messages in thread
From: Conor Dooley @ 2026-10-22 19:01 UTC (permalink / raw)
To: gaohan
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini, devicetree, linux-kernel, linux-riscv, linux-clk,
linux-gpio, Paul Walmsley
[-- Attachment #1: Type: text/plain, Size: 7969 bytes --]
On Thu, Oct 22, 2026 at 03:53:28AM +0800, Han Gao via B4 Relay wrote:
> From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
>
> Add bindings for the four A210 pad controllers. Describe the shared
> PERI3 SDIO mux and per-pad bias controls.
>
> Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
> Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
> ---
> .../bindings/pinctrl/zhihe,a210-pinctrl.yaml | 206 +++++++++++++++++++++
> 1 file changed, 206 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml
> new file mode 100644
> index 000000000000..51cbb0189f47
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml
> @@ -0,0 +1,206 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/zhihe,a210-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ZhiHe A210 pin controller
> +
> +maintainers:
> + - Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
> +
> +description: |
> + Pinmux and pinconf controller of the ZhiHe A210 RISC-V SoC.
> +
> + The pads of the A210 are split into four groups, each managed by its
> + own pad controller with a separate register range:
> +
> + AON pad controller -> zhihe,a210-aon-pinctrl
> + PADCTRL0 (peripheral1) -> zhihe,a210-peri1-pinctrl
> + PADCTRL1 (peripheral2) -> zhihe,a210-peri2-pinctrl
> + PADCTRL2 (peripheral3) -> zhihe,a210-peri3-pinctrl
> +
> + Each pad can be muxed individually to up to 8 different functions,
> + though for most pads only a few of those configurations are valid.
> + A few pads in the AON group do not support muxing or configuration
> + at all.
> +
> + AON, PERI1 and PERI2 pads support configurable drive strength, bias,
> + input enable, Schmitt trigger and slew rate. PERI3 has a separate pad
> + layout: its six SDIO pads share one mux bit. Select their function with
> + the "sdio" group. Per-pad bias can be configured independently.
> +
> +properties:
> + compatible:
> + enum:
> + - zhihe,a210-aon-pinctrl
> + - zhihe,a210-peri1-pinctrl
> + - zhihe,a210-peri2-pinctrl
> + - zhihe,a210-peri3-pinctrl
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + clock-names:
> + const: pclk
> +
> +patternProperties:
> + '-[0-9]+$':
> + type: object
> +
> + description:
> + A pinmux group referenced by a consumer's pinctrl phandle. It
> + contains one subnode per set of pads sharing the same pinmux and
> + pinconf settings.
> +
> + additionalProperties: false
> +
> + patternProperties:
> + '-pins$':
> + type: object
> + $ref: /schemas/pinctrl/pincfg-node.yaml#
> +
> + description:
> + A pinctrl node describing the pinmux and pinconf settings of
> + one or more pads.
> +
> + properties:
> + pins:
> + $ref: /schemas/pinctrl/pinmux-node.yaml#/properties/pins
> + description: List of pads that properties in the node apply to.
> +
> + groups:
> + items:
> + - const: sdio
> +
> + function:
> + $ref: /schemas/pinctrl/pinmux-node.yaml#/properties/function
> + enum: [ aouart, aouart_ir, aogpio0, aogpio1, aoi2c0, aoi2c1,
> + aospi, jtag, reset, por, pmic, dvs, uart0, uart1,
> + uart2, uart3, uart4, uart5, uart6, uart7, uart8,
> + uart9, uart0_ir, uart1_ir, uart2_ir, uart3_ir,
> + uart4_ir, uart5_ir, uart6_ir, uart7_ir, uart8_ir,
> + uart9_ir, gpio0, gpio1, gpio2, gpio3, gpio4, gmac0,
> + gmac1, spi0, spi1, qspi0, qspi1, pwm0, pwm1, pwm2,
> + can0, can1, can2, i2s0, i2s1, i2s2, i2s3, i2c0, i2c1,
> + i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c7_smb, sdio,
> + isp0, dptx, usb31, sata_p0, sata_p1, hdmi, zmac,
> + bsel, dbgm, cdbg, pdm, tdm, pcie_x1, pcie_x4,
> + sen_vclk ]
These sorts of things always make me wonder: do uart4 and uart5 actually
need to be different functions, or can you just use a uart function
because no pin can potentially have more than one uart muxed to it?
Ditto for spi, i2c, gpio etc.
> + description: The mux function to select for the given pins.
> +
> + bias-disable: true
> +
> + bias-pull-up: true
> +
> + bias-pull-down: true
> +
> + drive-strength:
> + enum: [ 1, 2, 3, 5, 7, 8, 10, 12, 13, 15, 16, 18, 20, 21, 23,
> + 25 ]
> + description: Drive strength in mA.
> +
> + input-enable: true
> +
> + input-disable: true
> +
> + input-schmitt-enable: true
> +
> + input-schmitt-disable: true
> +
> + slew-rate:
> + maximum: 1
> +
> + oneOf:
> + - required: [pins]
> + - required: [groups]
> +
> + additionalProperties: false
> +
> +allOf:
> + - if:
> + properties:
> + compatible:
> + const: zhihe,a210-peri3-pinctrl
> + then:
> + patternProperties:
> + '-[0-9]+$':
> + patternProperties:
> + '-pins$':
> + properties:
> + pins:
> + items:
> + enum: [SDIO_CLK, SDIO_CMD, SDIO_DAT0, SDIO_DAT1,
> + SDIO_DAT2, SDIO_DAT3]
Where do these SDIO_CLK etc come from?
> + function:
> + enum: [sdio, gpio4]
> + drive-strength: false
> + input-enable: false
> + input-disable: false
> + input-schmitt-enable: false
> + input-schmitt-disable: false
> + slew-rate: false
> + if:
> + required: [function]
> + then:
> + required: [groups]
Can you please explain why this uses a group for sdio when the binding
would be more straightforward if you just used pins?
> + else:
> + patternProperties:
> + '-[0-9]+$':
> + patternProperties:
> + '-pins$':
> + properties:
> + groups: false
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + pinctrl@2026000 {
> + compatible = "zhihe,a210-peri1-pinctrl";
> + reg = <0x2026000 0x1000>;
> + clocks = <&clk 0>;
> + clock-names = "pclk";
> +
> + gmac0-0 {
> + gmac0-pins {
> + bias-disable;
> + drive-strength = <13>;
> + function = "gmac0";
> + input-disable;
> + input-schmitt-disable;
> + pins = "GPIO0_0", "GPIO0_12";
This is confusingly ordered. pins then function, followed by config
properties please.
> + slew-rate = <0>;
> + };
> + };
> + };
> +
> + - |
> + pinctrl@542000 {
> + compatible = "zhihe,a210-peri3-pinctrl";
> + reg = <0x542000 0x1000>;
> + clocks = <&clk 0>;
> + clock-names = "pclk";
> +
> + sdio-0 {
> + cmd-data-pins {
> + bias-pull-up;
> + pins = "SDIO_CMD", "SDIO_DAT0", "SDIO_DAT1",
> + "SDIO_DAT2", "SDIO_DAT3";
> + };
> +
> + sdio-pins {
> + function = "sdio";
> + groups = "sdio";
> + };
> + };
> + };
>
> --
> 2.55.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 13/18] riscv: dts: zhihe: add A210 core support
2026-10-21 19:48 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao
@ 2026-10-21 19:48 ` Han Gao
0 siblings, 0 replies; 26+ messages in thread
From: Han Gao @ 2026-10-21 19:48 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Zhiguo Zhu,
Stephen Boyd, Brian Masney, Jerome Brunet, Philipp Zabel,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Icenowy Zheng,
Drew Fustini
Cc: devicetree, linux-kernel, linux-riscv, linux-clk, linux-gpio,
Paul Walmsley, Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add the A210 CPU clusters, caches, interrupt controllers and control
blocks.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Co-developed-by: Han Gao <gaohan@iscas.ac.cn>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/boot/dts/zhihe/a210.dtsi | 495 ++++++++++++++++++++++++++++++++++++
1 file changed, 495 insertions(+)
diff --git a/arch/riscv/boot/dts/zhihe/a210.dtsi b/arch/riscv/boot/dts/zhihe/a210.dtsi
new file mode 100644
index 000000000000..bbad51a3edb0
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/a210.dtsi
@@ -0,0 +1,495 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ */
+
+#include <dt-bindings/clock/zhihe,a210-clk.h>
+#include <dt-bindings/clock/zhihe,a210-aon-clk.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset/zhihe,a210-resets.h>
+
+/ {
+ compatible = "zhihe,a210";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aon_rc: clock-aon-rc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ };
+
+ osc_24m: clock-osc-24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "osc-24m";
+ };
+
+ osc_32k: clock-osc-32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "osc-32k";
+ };
+
+ aon_110m: clock-osc-110m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <110000000>;
+ clock-output-names = "aon-110m";
+ };
+
+ rc_24m: clock-rc-24m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ clock-output-names = "rc-24m";
+ };
+
+ cpus: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <24000000>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&c908_0>;
+ };
+
+ core1 {
+ cpu = <&c908_1>;
+ };
+
+ core2 {
+ cpu = <&c908_2>;
+ };
+
+ core3 {
+ cpu = <&c908_3>;
+ };
+ };
+
+ cluster1 {
+ core0 {
+ cpu = <&c920_4>;
+ };
+
+ core1 {
+ cpu = <&c920_5>;
+ };
+
+ core2 {
+ cpu = <&c920_6>;
+ };
+
+ core3 {
+ cpu = <&c920_7>;
+ };
+ };
+ };
+
+ c0_l2_cache: l2-cache0 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-sets = <512>;
+ cache-size = <524288>;
+ cache-unified;
+ };
+
+ c1_l2_cache: l2-cache1 {
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-sets = <1024>;
+ cache-size = <1048576>;
+ cache-unified;
+ };
+
+ c908_0: cpu@0 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <0>;
+ clocks = <&clk C908_CPU_TO_CDE_CLK_MUX>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c908_1: cpu@1 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <1>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu1_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c908_2: cpu@2 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <2>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu2_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c908_3: cpu@3 {
+ device_type = "cpu";
+ compatible = "thead,c908", "riscv";
+ reg = <3>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <32768>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c0_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu3_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_4: cpu@4 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <4>;
+ clocks = <&clk C920_CPU_TO_CDE_CLK_MUX>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu4_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_5: cpu@5 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <5>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu5_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_6: cpu@6 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <6>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu6_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ c920_7: cpu@7 {
+ device_type = "cpu";
+ compatible = "thead,c920", "riscv";
+ reg = <7>;
+ d-cache-block-size = <64>;
+ d-cache-sets = <512>;
+ d-cache-size = <65536>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <512>;
+ i-cache-size = <65536>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&c1_l2_cache>;
+ riscv,cbom-block-size = <64>;
+ riscv,cbop-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
+ "b", "v", "sscofpmf", "sstc",
+ "svpbmt", "zba", "zbb", "zbc",
+ "zbs", "zicbom", "zicbop",
+ "zicboz", "zicntr", "zicsr",
+ "zifencei", "zihpm";
+
+ cpu7_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ dma-noncoherent;
+ #size-cells = <2>;
+
+ clk: clock-controller@260000 {
+ compatible = "zhihe,a210-clk";
+ reg = <0x0 0x00260000 0x0 0x1000>,
+ <0x0 0x00250000 0x0 0x1000>,
+ <0x0 0x10141600 0x0 0x100>,
+ <0x0 0x10141400 0x0 0x100>,
+ <0x0 0x04810000 0x0 0x1000>,
+ <0x0 0x05810000 0x0 0x1000>,
+ <0x0 0x04900000 0x0 0x1000>,
+ <0x0 0x20250000 0x0 0x1000>,
+ <0x0 0x10140000 0x0 0xe00>;
+ reg-names = "pll-wrap", "top-crg", "cpu-ss-clk-sysreg",
+ "cpu-ss-cpu-pll", "ddr0-sysreg",
+ "ddr1-sysreg", "slc-dual-sysreg",
+ "top-crg-t", "cpu-ss-ccu";
+ #clock-cells = <1>;
+ clocks = <&osc_32k>, <&osc_24m>, <&rc_24m>;
+ clock-names = "osc-32k", "osc-24m", "rc-24m";
+ };
+
+ clk_peri: clock-controller@300200 {
+ compatible = "zhihe,a210-peri-clk";
+ reg = <0x0 0x00300200 0x0 0x4>,
+ <0x0 0x02010200 0x0 0x8>,
+ <0x0 0x08400200 0x0 0x8>,
+ <0x0 0x00540200 0x0 0x4>,
+ <0x0 0x27420200 0x0 0x200>;
+ reg-names = "peri0-sysreg", "peri1-sysreg",
+ "peri2-sysreg", "peri3-sysreg", "tee-crg";
+ #clock-cells = <1>;
+ };
+
+ peri3_padctrl: pinctrl@542000 {
+ compatible = "zhihe,a210-peri3-pinctrl";
+ reg = <0x0 0x00542000 0x0 0x1000>;
+ clocks = <&clk_peri PERI3_PAD_CTRL_PCLK_EN>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ rst_peri1: reset-controller@2010400 {
+ compatible = "zhihe,a210-peri1-reset";
+ reg = <0x0 0x02010400 0x0 0x200>;
+ #reset-cells = <1>;
+ };
+
+ peri1_padctrl: pinctrl@2026000 {
+ compatible = "zhihe,a210-peri1-pinctrl";
+ reg = <0x0 0x02026000 0x0 0x1000>;
+ clocks = <&clk_peri PERI1_PAD_CTRL_PCLK_EN>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ rst_peri2: reset-controller@8400400 {
+ compatible = "zhihe,a210-peri2-reset";
+ reg = <0x0 0x08400400 0x0 0x200>;
+ #reset-cells = <1>;
+ };
+
+ peri2_padctrl: pinctrl@8411000 {
+ compatible = "zhihe,a210-peri2-pinctrl";
+ reg = <0x0 0x08411000 0x0 0x1000>;
+ clocks = <&clk_peri PERI2_PAD_CTRL_PCLK_EN>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ intc: interrupt-controller@18000000 {
+ compatible = "zhihe,a210-plic", "thead,c900-plic";
+ reg = <0x0 0x18000000 0x0 0x04000000>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ interrupts-extended = <&cpu0_intc 0xffffffff>,
+ <&cpu0_intc 9>,
+ <&cpu1_intc 0xffffffff>,
+ <&cpu1_intc 9>,
+ <&cpu2_intc 0xffffffff>,
+ <&cpu2_intc 9>,
+ <&cpu3_intc 0xffffffff>,
+ <&cpu3_intc 9>,
+ <&cpu4_intc 0xffffffff>,
+ <&cpu4_intc 9>,
+ <&cpu5_intc 0xffffffff>,
+ <&cpu5_intc 9>,
+ <&cpu6_intc 0xffffffff>,
+ <&cpu6_intc 9>,
+ <&cpu7_intc 0xffffffff>,
+ <&cpu7_intc 9>;
+ riscv,ndev = <351>;
+ };
+
+ clint0: clint@1c000000 {
+ compatible = "zhihe,a210-clint", "thead,c900-clint";
+ reg = <0x0 0x1c000000 0x0 0x0000d800>;
+ interrupts-extended = <&cpu0_intc 3>,
+ <&cpu0_intc 7>,
+ <&cpu1_intc 3>,
+ <&cpu1_intc 7>,
+ <&cpu2_intc 3>,
+ <&cpu2_intc 7>,
+ <&cpu3_intc 3>,
+ <&cpu3_intc 7>,
+ <&cpu4_intc 3>,
+ <&cpu4_intc 7>,
+ <&cpu5_intc 3>,
+ <&cpu5_intc 7>,
+ <&cpu6_intc 3>,
+ <&cpu6_intc 7>,
+ <&cpu7_intc 3>,
+ <&cpu7_intc 7>;
+ };
+
+ clk_aon: clock-controller@30844000 {
+ compatible = "zhihe,a210-aon-clk";
+ reg = <0 0x30844000 0 0x1c>;
+ #clock-cells = <1>;
+ clocks = <&aon_110m>, <&osc_24m>, <&aon_rc>, <&osc_32k>;
+ clock-names = "high", "osc", "rc", "rtc";
+ };
+
+ aon_padctrl: pinctrl@30848000 {
+ compatible = "zhihe,a210-aon-pinctrl";
+ reg = <0x0 0x30848000 0x0 0x2000>;
+ clocks = <&clk_aon A210_AON_SYS_CLK>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+ };
+};
--
2.55.0
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-10-22 19:01 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21 19:53 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 01/18] dt-bindings: vendor-prefixes: add Zhihe Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 02/18] riscv: add Zhihe A210 support Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 03/18] dt-bindings: clock: add Zhihe A210 clock controllers Han Gao via B4 Relay
2026-10-22 18:52 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 04/18] dt-bindings: clock: add Zhihe A210 AON clock controller Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 05/18] clk: zhihe: add A210 support Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 06/18] dt-bindings: reset: add Zhihe A210 reset controllers Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 07/18] reset: zhihe: add A210 support Han Gao via B4 Relay
2026-10-22 9:22 ` Philipp Zabel
2026-10-21 19:53 ` [PATCH 08/18] dt-bindings: pinctrl: add Zhihe A210 pin controller Han Gao via B4 Relay
2026-10-22 19:01 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 09/18] pinctrl: zhihe: add A210 support Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 10/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 11/18] dt-bindings: riscv: add Melon Pi V1 and V2 Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 12/18] dt-bindings: timer: add Zhihe A210 CLINT Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 13/18] riscv: dts: zhihe: add A210 core support Han Gao via B4 Relay
2026-10-22 18:48 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 14/18] riscv: dts: zhihe: add A210 UARTs Han Gao via B4 Relay
2026-10-22 9:22 ` Philipp Zabel
2026-10-21 19:53 ` [PATCH 15/18] riscv: dts: zhihe: add A210 module memory Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2 Han Gao via B4 Relay
2026-10-21 19:53 ` [PATCH 17/18] riscv: defconfig: enable A210 support Han Gao via B4 Relay
2026-10-22 18:50 ` Conor Dooley
2026-10-21 19:53 ` [PATCH 18/18] MAINTAINERS: add Zhihe A210 Han Gao via B4 Relay
-- strict thread matches above, loose matches on Subject: below --
2026-10-21 19:48 [PATCH 00/18] riscv: add initial support for Zhihe A210 and Melon Pi Han Gao
2026-10-21 19:48 ` [PATCH 13/18] riscv: dts: zhihe: add A210 core support Han Gao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®