* [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets
@ 2026-10-27 15:36 Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V Han Gao via B4 Relay
` (17 more replies)
0 siblings, 18 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
This adds initial support for the Zhihe A210 SoC and the Melon Pi V1
and V2 boards. It replaces the earlier series [1]. The way clocks and
resets are handled changed completely, so I am posting it as a new RFC
rather than as v2.
The A210 has eight RISC-V cores in two clusters, four C908 and four
C920, plus an E902 management core. In [1] Linux drove the clock and
reset registers directly. Review pointed out that those blocks were not
modelled properly, and they are also used by the E902 firmware, which
owns the power, PMIC and CPU DVFS sequencing. This series leaves those
registers to the firmware and uses the standard SCMI clock and reset
protocols instead.
I also looked at RPMI before settling on SCMI. The firmware has to
provide reset domains for the UARTs and pad controllers and sensors for
thermal management, and RPMI has no ratified protocol for either yet.
SCMI covers everything the firmware exposes today: clock, reset, power
domain, performance, voltage, sensor and system power. Linux, U-Boot
and EDK2 already have SCMI clients, so on the Linux side only the
mailbox transport is new. RPMI support in U-Boot is also still being
debated [8].
The SCMI related changes compared to [1]:
- The native clock and reset drivers and their bindings are gone.
- A new mailbox driver for the AP to E902 doorbell. One channel carries
SCMI requests, the other carries notifications from the firmware. The
shared memory lives in the AON SRAM.
- arm_scmi transports can be built on RISC-V.
- New dt-bindings headers for the SCMI clock and reset IDs exported by
the firmware. Only the IDs used here are defined for now. More will
be appended later without renumbering the existing ones.
- Each UART has separate APB and serial resets, so the UARTs get a
"zhihe,a210-uart" compatible with two resets, as Philipp suggested.
- The pin controllers take their pad resets from SCMI.
Other changes since [1]: the pinctrl binding explains the SDIO pad names
and the shared SDIO mux bit, pin nodes are ordered as pins, function,
then configuration, and the defconfig commit explains why ten 8250
ports are needed.
The series covers the mailbox, the pin controller, the UARTs and the
bindings and device trees around them. It is based on v7.3 and boots on
a Melon Pi V2 to a shell on the UART console with all eight CPUs online.
I would mostly like feedback on the SCMI approach and the ID headers
before sending the rest of the platform.
The E902 firmware is a Zephyr based SCMI server [2]. The rest of the
boot chain is coreboot [3], OpenSBI [4] and EDK2 [5][6]. The complete
Linux tree with the remaining peripherals is at [7].
[1] https://lore.kernel.org/r/20261022-a210-init-v1-0-5e438f972d24@iscas.ac.cn
[2] https://github.com/RevySR/zephyr/tree/xuantie/scmi
[3] https://github.com/revyos/coreboot/tree/a210/scmi
[4] https://github.com/revyos/opensbi/tree/a210/scmi
[5] https://github.com/revyos/edk2/tree/a210/scmi
[6] https://github.com/revyos/ruyiedk2/tree/a210/scmi
[7] https://github.com/RevySR/linux/tree/a210/scmi-bootchain-v7.3
[8] https://lists.u-boot-project.org/pipermail/u-boot/2026-October/635007.html
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
Han Gao (10):
firmware: arm_scmi: Allow SCMI transports on RISC-V
dt-bindings: mailbox: add the A210 AP to E902 doorbell
mailbox: add A210 AP to E902 doorbell support
dt-bindings: timer: add Zhihe A210 CLINT
dt-bindings: firmware: add A210 SCMI clock and reset IDs
dt-bindings: serial: snps-dw-apb-uart: add Zhihe A210 UART
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 (8):
dt-bindings: vendor-prefixes: add Zhihe
riscv: add Zhihe 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
.../interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
.../bindings/mailbox/zhihe,a210-ap-mailbox.yaml | 76 ++
.../bindings/pinctrl/zhihe,a210-pinctrl.yaml | 211 ++++
Documentation/devicetree/bindings/riscv/zhihe.yaml | 27 +
.../bindings/serial/snps-dw-apb-uart.yaml | 5 +-
.../devicetree/bindings/timer/sifive,clint.yaml | 1 +
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 14 +
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 | 619 ++++++++++
arch/riscv/configs/defconfig | 10 +
drivers/firmware/arm_scmi/Kconfig | 2 +-
drivers/mailbox/Kconfig | 9 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mailbox-a210.c | 205 ++++
drivers/pinctrl/Kconfig | 14 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-a210.c | 1212 ++++++++++++++++++++
include/dt-bindings/clock/zhihe,a210-scmi.h | 15 +
include/dt-bindings/reset/zhihe,a210-scmi.h | 13 +
26 files changed, 2534 insertions(+), 2 deletions(-)
---
base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222
change-id: 20261027-a210-scmi-ec32fdc246a6
Best regards,
--
Han Gao <gaohan@iscas.ac.cn>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:51 ` Michal Simek
2026-10-27 15:36 ` [PATCH RFC 02/18] dt-bindings: vendor-prefixes: add Zhihe Han Gao via B4 Relay
` (16 subsequent siblings)
17 siblings, 1 reply; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Mailbox and shared-memory SCMI transports do not require ARM execution.
Allow RISC-V platforms to use the existing SCMI core and protocol drivers;
architecture-specific transports retain their own dependencies.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
drivers/firmware/arm_scmi/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index 783c24a20e29..1cfe2b572d18 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -3,7 +3,7 @@ menu "ARM System Control and Management Interface Protocol"
config ARM_SCMI_PROTOCOL
tristate "ARM System Control and Management Interface (SCMI) Message Protocol"
- depends on ARM || ARM64 || COMPILE_TEST
+ depends on ARM || ARM64 || RISCV || COMPILE_TEST
help
ARM System Control and Management Interface (SCMI) protocol is a
set of operating system-independent software interfaces that are
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 02/18] dt-bindings: vendor-prefixes: add Zhihe
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 03/18] riscv: add Zhihe A210 support Han Gao via B4 Relay
` (15 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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] 21+ messages in thread
* [PATCH RFC 03/18] riscv: add Zhihe A210 support
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 02/18] dt-bindings: vendor-prefixes: add Zhihe Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 04/18] dt-bindings: mailbox: add the A210 AP to E902 doorbell Han Gao via B4 Relay
` (14 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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] 21+ messages in thread
* [PATCH RFC 04/18] dt-bindings: mailbox: add the A210 AP to E902 doorbell
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (2 preceding siblings ...)
2026-10-27 15:36 ` [PATCH RFC 03/18] riscv: add Zhihe A210 support Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 05/18] mailbox: add A210 AP to E902 doorbell support Han Gao via B4 Relay
` (13 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Describe the AP doorbell and optional endpoint clocks. Firmware may keep
the clocks enabled before the SCMI transport is available. An optional
E902 to AP data bank identifies a second, receive-only notification
channel sharing the doorbell interrupt.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
.../bindings/mailbox/zhihe,a210-ap-mailbox.yaml | 76 ++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/Documentation/devicetree/bindings/mailbox/zhihe,a210-ap-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/zhihe,a210-ap-mailbox.yaml
new file mode 100644
index 000000000000..4541750223eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/zhihe,a210-ap-mailbox.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/zhihe,a210-ap-mailbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Zhihe A210 application processor to E902 doorbell
+
+maintainers:
+ - Han Gao <gaohan@iscas.ac.cn>
+
+description: |
+ The A210 exposes a bidirectional notification channel between the
+ application processors and E902 firmware. Payloads and transaction
+ completion are managed by the client using shared memory. The firmware
+ initializes the remote endpoint before the application processor binds.
+ When firmware manages the endpoint clocks and keeps them running, omit
+ clocks and clock-names to avoid a dependency on services using this mailbox.
+
+properties:
+ compatible:
+ const: zhihe,a210-ap-mailbox
+ reg:
+ minItems: 2
+ items:
+ - description: Application processor interrupt status and control
+ - description: Remote E902 notification channel
+ - description:
+ E902 to application processor channel data, which identifies the
+ channel that raised the shared interrupt
+ reg-names:
+ minItems: 2
+ items:
+ - const: interrupt
+ - const: tx
+ - const: rx
+ interrupts:
+ maxItems: 1
+ clocks:
+ items:
+ - description: Application processor mailbox clock
+ - description: E902 mailbox clock
+ clock-names:
+ items:
+ - const: local
+ - const: remote
+ '#mbox-cells':
+ const: 1
+ description: |
+ Channel index. Channel 0 carries requests to E902 and their completion.
+ Channel 1 receives E902 notifications and requires the rx region.
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - interrupts
+ - '#mbox-cells'
+
+additionalProperties: false
+
+dependentRequired:
+ clocks: [clock-names]
+ clock-names: [clocks]
+
+examples:
+ - |
+ mailbox@321000 {
+ compatible = "zhihe,a210-ap-mailbox";
+ reg = <0x321000 0x1000>, <0x311000 0x1000>, <0x320000 0x1000>;
+ reg-names = "interrupt", "tx", "rx";
+ clocks = <&clk 0>, <&clk 1>;
+ clock-names = "local", "remote";
+ #mbox-cells = <1>;
+ interrupts = <336 4>;
+ };
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 05/18] mailbox: add A210 AP to E902 doorbell support
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (3 preceding siblings ...)
2026-10-27 15:36 ` [PATCH RFC 04/18] dt-bindings: mailbox: add the A210 AP to E902 doorbell Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 06/18] dt-bindings: pinctrl: add Zhihe A210 pin controller Han Gao via B4 Relay
` (12 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Add the AP doorbell transport. Allow firmware to retain endpoint clocks
so that SCMI can provide clocks without depending on itself.
E902 completions and notifications share one interrupt. When the E902
to AP data bank is described, firmware tags each doorbell in INFO0 or
INFO1 and the driver exposes notifications as receive-only channel 1.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
drivers/mailbox/Kconfig | 9 ++
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mailbox-a210.c | 205 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 216 insertions(+)
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index ab869769e278..e48f40000851 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -409,4 +409,13 @@ config AXIADO_MAILBOX
Axiado SoCs.
If unsure, say N.
+config ZHIHE_A210_MBOX
+ bool "Zhihe A210 AP to E902 mailbox"
+ depends on OF && (ARCH_ZHIHE || COMPILE_TEST)
+ help
+ Enable the AP doorbell channel to running E902 firmware on A210.
+ Clients exchange their payloads through shared memory and signal
+ completion themselves. The controller does not carry vendor RPCs.
+ Enable this for an SCMI server running on the A210 E902 processor.
+
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 45dc59bb3e7f..f537ebb8aaff 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -86,3 +86,5 @@ obj-$(CONFIG_BCM74110_MAILBOX) += bcm74110-mailbox.o
obj-$(CONFIG_RISCV_SBI_MPXY_MBOX) += riscv-sbi-mpxy-mbox.o
obj-$(CONFIG_AXIADO_MAILBOX) += axiado-mailbox.o
+
+obj-$(CONFIG_ZHIHE_A210_MBOX) += mailbox-a210.o
diff --git a/drivers/mailbox/mailbox-a210.c b/drivers/mailbox/mailbox-a210.c
new file mode 100644
index 000000000000..767bb4fe7b40
--- /dev/null
+++ b/drivers/mailbox/mailbox-a210.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* AP and E902 doorbell channels on the Zhihe A210. */
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#define A210_MBOX_STATUS 0x00
+#define A210_MBOX_CLEAR 0x04
+#define A210_MBOX_MASK 0x0c
+#define A210_MBOX_GENERATE 0x10
+#define A210_MBOX_INFO(n) (0x14 + 4 * (n))
+#define A210_MBOX_E902_PENDING BIT(0)
+#define A210_MBOX_NOTIFY BIT(6)
+
+/* Channel 0 carries AP requests and completions, channel 1 E902 notifications. */
+#define A210_MBOX_CHANS 2
+
+struct a210_mbox {
+ struct mbox_controller controller;
+ struct mbox_chan channels[A210_MBOX_CHANS];
+ void __iomem *local;
+ void __iomem *remote;
+ void __iomem *rx;
+ struct clk_bulk_data clocks[2];
+ /* Protects the shared interrupt mask and the set of started channels. */
+ spinlock_t lock;
+ unsigned long started;
+ int irq;
+};
+
+static void a210_mbox_mask(struct a210_mbox *mbox, unsigned int index, bool enable)
+{
+ unsigned long flags;
+ u32 value;
+
+ spin_lock_irqsave(&mbox->lock, flags);
+ if (enable)
+ __set_bit(index, &mbox->started);
+ else
+ __clear_bit(index, &mbox->started);
+ value = readl(mbox->local + A210_MBOX_MASK);
+ if (mbox->started)
+ value |= A210_MBOX_E902_PENDING;
+ else
+ value &= ~A210_MBOX_E902_PENDING;
+ writel(value, mbox->local + A210_MBOX_MASK);
+ spin_unlock_irqrestore(&mbox->lock, flags);
+}
+
+static irqreturn_t a210_mbox_irq(int irq, void *data)
+{
+ struct a210_mbox *mbox = data;
+
+ if (!(readl(mbox->local + A210_MBOX_MASK) & A210_MBOX_E902_PENDING))
+ return IRQ_NONE;
+ if (!(readl(mbox->local + A210_MBOX_STATUS) & A210_MBOX_E902_PENDING))
+ return IRQ_NONE;
+
+ writel(A210_MBOX_E902_PENDING, mbox->local + A210_MBOX_CLEAR);
+ if (!mbox->rx) {
+ mbox_chan_received_data(&mbox->channels[0], NULL);
+ return IRQ_HANDLED;
+ }
+
+ /* E902 sets INFO<n> before ringing the shared doorbell for channel n. */
+ for (unsigned int i = 0; i < A210_MBOX_CHANS; i++) {
+ if (!readl(mbox->rx + A210_MBOX_INFO(i)))
+ continue;
+ writel(0, mbox->rx + A210_MBOX_INFO(i));
+ if (test_bit(i, &mbox->started))
+ mbox_chan_received_data(&mbox->channels[i], NULL);
+ }
+ return IRQ_HANDLED;
+}
+
+static unsigned int a210_mbox_index(struct a210_mbox *mbox, struct mbox_chan *channel)
+{
+ return channel - mbox->channels;
+}
+
+static int a210_mbox_send(struct mbox_chan *channel, void *data)
+{
+ struct a210_mbox *mbox = channel->con_priv;
+
+ /* E902 notifications are receive-only. */
+ if (a210_mbox_index(mbox, channel))
+ return -EINVAL;
+
+ /* Payload and completion ownership belong to the shared-memory client. */
+ writel(A210_MBOX_NOTIFY, mbox->remote + A210_MBOX_GENERATE);
+ return 0;
+}
+
+static int a210_mbox_startup(struct mbox_chan *channel)
+{
+ struct a210_mbox *mbox = channel->con_priv;
+ unsigned int index = a210_mbox_index(mbox, channel);
+
+ if (mbox->rx)
+ writel(0, mbox->rx + A210_MBOX_INFO(index));
+ else
+ writel(A210_MBOX_E902_PENDING, mbox->local + A210_MBOX_CLEAR);
+ a210_mbox_mask(mbox, index, true);
+ return 0;
+}
+
+static void a210_mbox_shutdown(struct mbox_chan *channel)
+{
+ struct a210_mbox *mbox = channel->con_priv;
+
+ a210_mbox_mask(mbox, a210_mbox_index(mbox, channel), false);
+ synchronize_irq(mbox->irq);
+}
+
+static const struct mbox_chan_ops a210_mbox_ops = {
+ .send_data = a210_mbox_send,
+ .startup = a210_mbox_startup,
+ .shutdown = a210_mbox_shutdown,
+};
+
+static void a210_mbox_disable_clocks(void *data)
+{
+ struct a210_mbox *mbox = data;
+
+ clk_bulk_disable_unprepare(ARRAY_SIZE(mbox->clocks), mbox->clocks);
+}
+
+static int a210_mbox_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct a210_mbox *mbox;
+ int ret;
+
+ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+ if (!mbox)
+ return -ENOMEM;
+
+ mbox->local = devm_platform_ioremap_resource_byname(pdev, "interrupt");
+ if (IS_ERR(mbox->local))
+ return PTR_ERR(mbox->local);
+ mbox->remote = devm_platform_ioremap_resource_byname(pdev, "tx");
+ if (IS_ERR(mbox->remote))
+ return PTR_ERR(mbox->remote);
+ if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rx")) {
+ mbox->rx = devm_platform_ioremap_resource_byname(pdev, "rx");
+ if (IS_ERR(mbox->rx))
+ return PTR_ERR(mbox->rx);
+ }
+ mbox->irq = platform_get_irq(pdev, 0);
+ if (mbox->irq < 0)
+ return mbox->irq;
+
+ mbox->clocks[0].id = "local";
+ mbox->clocks[1].id = "remote";
+ ret = devm_clk_bulk_get_optional(dev, ARRAY_SIZE(mbox->clocks), mbox->clocks);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get mailbox clocks\n");
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(mbox->clocks), mbox->clocks);
+ if (ret)
+ return ret;
+ ret = devm_add_action_or_reset(dev, a210_mbox_disable_clocks, mbox);
+ if (ret)
+ return ret;
+
+ spin_lock_init(&mbox->lock);
+ a210_mbox_mask(mbox, 0, false);
+ for (unsigned int i = 0; i < A210_MBOX_CHANS; i++)
+ mbox->channels[i].con_priv = mbox;
+ mbox->controller.dev = dev;
+ mbox->controller.chans = mbox->channels;
+ mbox->controller.num_chans = mbox->rx ? A210_MBOX_CHANS : 1;
+ mbox->controller.ops = &a210_mbox_ops;
+ /* The client acknowledges completion after consuming shared memory. */
+ ret = devm_request_irq(dev, mbox->irq, a210_mbox_irq, IRQF_SHARED,
+ dev_name(dev), mbox);
+ if (ret)
+ return ret;
+
+ return devm_mbox_controller_register(dev, &mbox->controller);
+}
+
+static const struct of_device_id a210_mbox_match[] = {
+ { .compatible = "zhihe,a210-ap-mailbox" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, a210_mbox_match);
+
+static struct platform_driver a210_mbox_driver = {
+ .probe = a210_mbox_probe,
+ .driver = {
+ .name = "a210-mailbox",
+ .of_match_table = a210_mbox_match,
+ /* Running E902 firmware continuously accesses the remote bank. */
+ .suppress_bind_attrs = true,
+ },
+};
+module_platform_driver(a210_mbox_driver);
+
+MODULE_AUTHOR("Han Gao <gaohan@iscas.ac.cn>");
+MODULE_DESCRIPTION("Zhihe A210 AP to E902 doorbell");
+MODULE_LICENSE("GPL");
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 06/18] dt-bindings: pinctrl: add Zhihe A210 pin controller
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (4 preceding siblings ...)
2026-10-27 15:36 ` [PATCH RFC 05/18] mailbox: add A210 AP to E902 doorbell support Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 07/18] pinctrl: zhihe: add A210 support Han Gao via B4 Relay
` (11 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Add bindings for the four A210 pad controllers. Describe the shared
PERI3 SDIO mux, the per-pad bias controls and the optional pad
controller reset.
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 | 211 +++++++++++++++++++++
1 file changed, 211 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..ae8eebbb0be2
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml
@@ -0,0 +1,211 @@
+# 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 dedicated SDIO pads, named SDIO_CLK, SDIO_CMD and
+ SDIO_DAT0..3 in the SoC pin list, share one mux bit that selects SDIO or
+ GPIO4 for all of them. 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
+
+ resets:
+ maxItems: 1
+
+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 {
+ pins = "GPIO0_0", "GPIO0_12";
+ function = "gmac0";
+ bias-disable;
+ drive-strength = <13>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+ };
+
+ - |
+ pinctrl@542000 {
+ compatible = "zhihe,a210-peri3-pinctrl";
+ reg = <0x542000 0x1000>;
+ clocks = <&clk 0>;
+ clock-names = "pclk";
+
+ sdio-0 {
+ cmd-data-pins {
+ pins = "SDIO_CMD", "SDIO_DAT0", "SDIO_DAT1",
+ "SDIO_DAT2", "SDIO_DAT3";
+ bias-pull-up;
+ };
+
+ sdio-pins {
+ groups = "sdio";
+ function = "sdio";
+ };
+ };
+ };
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 07/18] pinctrl: zhihe: add A210 support
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (5 preceding siblings ...)
2026-10-27 15:36 ` [PATCH RFC 06/18] dt-bindings: pinctrl: add Zhihe A210 pin controller Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 08/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC Han Gao via B4 Relay
` (10 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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.
Release the optional pad controller reset at probe.
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 | 1212 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 1227 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..d067c7021d7d
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-a210.c
@@ -0,0 +1,1212 @@
+// 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/reset.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;
+ struct reset_control *rst;
+ 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;
+
+ rst = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL);
+ if (IS_ERR(rst))
+ return dev_err_probe(dev, PTR_ERR(rst), "could not release padctrl reset\n");
+
+ 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] 21+ messages in thread
* [PATCH RFC 08/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (6 preceding siblings ...)
2026-10-27 15:36 ` [PATCH RFC 07/18] pinctrl: zhihe: add A210 support Han Gao via B4 Relay
@ 2026-10-27 15:36 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 09/18] dt-bindings: riscv: add Melon Pi V1 and V2 Han Gao via B4 Relay
` (9 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:36 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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] 21+ messages in thread
* [PATCH RFC 09/18] dt-bindings: riscv: add Melon Pi V1 and V2
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (7 preceding siblings ...)
2026-10-27 15:36 ` [PATCH RFC 08/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 10/18] dt-bindings: timer: add Zhihe A210 CLINT Han Gao via B4 Relay
` (8 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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] 21+ messages in thread
* [PATCH RFC 10/18] dt-bindings: timer: add Zhihe A210 CLINT
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (8 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 09/18] dt-bindings: riscv: add Melon Pi V1 and V2 Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 11/18] dt-bindings: firmware: add A210 SCMI clock and reset IDs Han Gao via B4 Relay
` (7 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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] 21+ messages in thread
* [PATCH RFC 11/18] dt-bindings: firmware: add A210 SCMI clock and reset IDs
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (9 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 10/18] dt-bindings: timer: add Zhihe A210 CLINT Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 12/18] dt-bindings: serial: snps-dw-apb-uart: add Zhihe A210 UART Han Gao via B4 Relay
` (6 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Define the SCMI clock and reset IDs for the A210 UARTs, pad controllers
and AON I2C1. Each UART has separate serial and APB reset lines, so
they get separate reset IDs, numbered like the matching clocks.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
include/dt-bindings/clock/zhihe,a210-scmi.h | 15 +++++++++++++++
include/dt-bindings/reset/zhihe,a210-scmi.h | 13 +++++++++++++
2 files changed, 28 insertions(+)
diff --git a/include/dt-bindings/clock/zhihe,a210-scmi.h b/include/dt-bindings/clock/zhihe,a210-scmi.h
new file mode 100644
index 000000000000..b8f6441ac650
--- /dev/null
+++ b/include/dt-bindings/clock/zhihe,a210-scmi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+#ifndef _DT_BINDINGS_CLOCK_ZHIHE_A210_SCMI_H_
+#define _DT_BINDINGS_CLOCK_ZHIHE_A210_SCMI_H_
+
+/* SCMI clock IDs; existing entries must not be renumbered. */
+#define A210_CLK_UART_SCLK(n) (n)
+#define A210_CLK_UART_PCLK(n) (10 + (n))
+#define A210_CLK_PERI1_PAD 20
+#define A210_CLK_PERI2_PAD 21
+#define A210_CLK_PERI3_PAD 22
+#define A210_CLK_AON_SYS 23
+#define A210_CLK_AON_I2C1_IC 24
+#define A210_CLK_AON_I2C1_PCLK 25
+
+#endif
diff --git a/include/dt-bindings/reset/zhihe,a210-scmi.h b/include/dt-bindings/reset/zhihe,a210-scmi.h
new file mode 100644
index 000000000000..53e108c15407
--- /dev/null
+++ b/include/dt-bindings/reset/zhihe,a210-scmi.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+#ifndef _DT_BINDINGS_RESET_ZHIHE_A210_SCMI_H_
+#define _DT_BINDINGS_RESET_ZHIHE_A210_SCMI_H_
+
+/* SCMI reset IDs; existing entries must not be renumbered. */
+#define A210_RESET_UART_SRST(n) (n)
+#define A210_RESET_UART_PRST(n) (10 + (n))
+#define A210_RESET_PERI1_PAD 20
+#define A210_RESET_PERI2_PAD 21
+#define A210_RESET_PERI3_PAD 22
+#define A210_RESET_AON_I2C1 23
+
+#endif
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 12/18] dt-bindings: serial: snps-dw-apb-uart: add Zhihe A210 UART
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (10 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 11/18] dt-bindings: firmware: add A210 SCMI clock and reset IDs Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 13/18] riscv: dts: zhihe: add A210 core support Han Gao via B4 Relay
` (5 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
The Zhihe A210 UARTs have separate APB and serial clock domain resets.
Add an SoC-specific compatible that, like the StarFive JH7110 one,
allows both resets.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
index 664305de4986..907f8dab2c4f 100644
--- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
@@ -29,7 +29,9 @@ allOf:
properties:
compatible:
contains:
- const: starfive,jh7110-uart
+ enum:
+ - starfive,jh7110-uart
+ - zhihe,a210-uart
then:
properties:
resets:
@@ -81,6 +83,7 @@ properties:
- starfive,jh7100-uart
- starfive,jh7110-uart
- ultrarisc,dp1000-uart
+ - zhihe,a210-uart
- const: snps,dw-apb-uart
- const: snps,dw-apb-uart
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 13/18] riscv: dts: zhihe: add A210 core support
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (11 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 12/18] dt-bindings: serial: snps-dw-apb-uart: add Zhihe A210 UART Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 14/18] riscv: dts: zhihe: add A210 UARTs Han Gao via B4 Relay
` (4 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Describe the CPU clusters, interrupt controllers and pad controllers.
Use SCMI clock and reset services through the E902 mailbox, with a
second mailbox channel for firmware notifications.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/boot/dts/zhihe/a210.dtsi | 458 ++++++++++++++++++++++++++++++++++++
1 file changed, 458 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..c7b623800aa7
--- /dev/null
+++ b/arch/riscv/boot/dts/zhihe/a210.dtsi
@@ -0,0 +1,458 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2021 Alibaba Group Holding Limited.
+ */
+
+#include <dt-bindings/clock/zhihe,a210-scmi.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset/zhihe,a210-scmi.h>
+
+/ {
+ compatible = "zhihe,a210";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ 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>;
+ 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>;
+ 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;
+ };
+ };
+ };
+
+ firmware {
+ scmi {
+ compatible = "arm,scmi";
+ mboxes = <&mbox_e902 0>, <&mbox_e902 1>;
+ mbox-names = "tx", "rx";
+ shmem = <&scmi_shmem>, <&scmi_notification_shmem>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ scmi_clk: protocol@14 {
+ reg = <0x14>;
+ #clock-cells = <1>;
+ };
+
+ scmi_reset: protocol@16 {
+ reg = <0x16>;
+ #reset-cells = <1>;
+ };
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ dma-noncoherent;
+ #size-cells = <2>;
+
+ mbox_e902: mailbox@321000 {
+ compatible = "zhihe,a210-ap-mailbox";
+ reg = <0 0x00321000 0 0x1000>,
+ <0 0x00311000 0 0x1000>,
+ <0 0x00320000 0 0x1000>;
+ reg-names = "interrupt", "tx", "rx";
+ interrupt-parent = <&intc>;
+ interrupts = <336 IRQ_TYPE_LEVEL_HIGH>;
+ #mbox-cells = <1>;
+ };
+
+ peri3_padctrl: pinctrl@542000 {
+ compatible = "zhihe,a210-peri3-pinctrl";
+ reg = <0x0 0x00542000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_PERI3_PAD>;
+ clock-names = "pclk";
+ resets = <&scmi_reset A210_RESET_PERI3_PAD>;
+
+ status = "disabled";
+ };
+
+ peri1_padctrl: pinctrl@2026000 {
+ compatible = "zhihe,a210-peri1-pinctrl";
+ reg = <0x0 0x02026000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_PERI1_PAD>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ peri2_padctrl: pinctrl@8411000 {
+ compatible = "zhihe,a210-peri2-pinctrl";
+ reg = <0x0 0x08411000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_PERI2_PAD>;
+ clock-names = "pclk";
+ resets = <&scmi_reset A210_RESET_PERI2_PAD>;
+
+ 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>;
+ };
+
+ aon_padctrl: pinctrl@30848000 {
+ compatible = "zhihe,a210-aon-pinctrl";
+ reg = <0x0 0x30848000 0x0 0x2000>;
+ clocks = <&scmi_clk A210_CLK_AON_SYS>;
+ clock-names = "pclk";
+
+ status = "disabled";
+ };
+
+ sram@30907c00 {
+ compatible = "mmio-sram";
+ reg = <0 0x30907c00 0 0x200>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0x30907c00 0x200>;
+
+ scmi_shmem: scp-sram@0 {
+ compatible = "arm,scmi-shmem";
+ reg = <0 0x100>;
+ };
+
+ scmi_notification_shmem: scp-sram@100 {
+ compatible = "arm,scmi-shmem";
+ reg = <0x100 0x100>;
+ };
+ };
+ };
+};
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 14/18] riscv: dts: zhihe: add A210 UARTs
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (12 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 13/18] riscv: dts: zhihe: add A210 core support Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 15/18] riscv: dts: zhihe: add A210 module memory Han Gao via B4 Relay
` (3 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Describe the ten DW APB UARTs with SCMI clocks and their separate APB
and serial resets.
Signed-off-by: Zhiguo Zhu <zhiguo.zhu@linux.alibaba.com>
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/boot/dts/zhihe/a210.dtsi | 161 ++++++++++++++++++++++++++++++++++++
1 file changed, 161 insertions(+)
diff --git a/arch/riscv/boot/dts/zhihe/a210.dtsi b/arch/riscv/boot/dts/zhihe/a210.dtsi
index c7b623800aa7..a23f59394659 100644
--- a/arch/riscv/boot/dts/zhihe/a210.dtsi
+++ b/arch/riscv/boot/dts/zhihe/a210.dtsi
@@ -363,11 +363,172 @@ peri3_padctrl: pinctrl@542000 {
status = "disabled";
};
+ uart0: serial@2014000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x02014000 0x0 0x400>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(0)>,
+ <&scmi_clk A210_CLK_UART_PCLK(0)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <321 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(0)>,
+ <&scmi_reset A210_RESET_UART_SRST(0)>;
+
+ status = "disabled";
+ };
+
+ uart1: serial@2015000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x02015000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(1)>,
+ <&scmi_clk A210_CLK_UART_PCLK(1)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <322 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(1)>,
+ <&scmi_reset A210_RESET_UART_SRST(1)>;
+
+ status = "disabled";
+ };
+
+ uart2: serial@2016000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x02016000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(2)>,
+ <&scmi_clk A210_CLK_UART_PCLK(2)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <323 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(2)>,
+ <&scmi_reset A210_RESET_UART_SRST(2)>;
+
+ status = "disabled";
+ };
+
+ uart3: serial@2017000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x02017000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(3)>,
+ <&scmi_clk A210_CLK_UART_PCLK(3)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <324 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(3)>,
+ <&scmi_reset A210_RESET_UART_SRST(3)>;
+
+ status = "disabled";
+ };
+
peri1_padctrl: pinctrl@2026000 {
compatible = "zhihe,a210-peri1-pinctrl";
reg = <0x0 0x02026000 0x0 0x1000>;
clocks = <&scmi_clk A210_CLK_PERI1_PAD>;
clock-names = "pclk";
+ resets = <&scmi_reset A210_RESET_PERI1_PAD>;
+
+ status = "disabled";
+ };
+
+ uart4: serial@8401000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x08401000 0x0 0x400>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(4)>,
+ <&scmi_clk A210_CLK_UART_PCLK(4)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <325 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(4)>,
+ <&scmi_reset A210_RESET_UART_SRST(4)>;
+
+ status = "disabled";
+ };
+
+ uart5: serial@8402000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x08402000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(5)>,
+ <&scmi_clk A210_CLK_UART_PCLK(5)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <326 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(5)>,
+ <&scmi_reset A210_RESET_UART_SRST(5)>;
+
+ status = "disabled";
+ };
+
+ uart6: serial@8403000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x08403000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(6)>,
+ <&scmi_clk A210_CLK_UART_PCLK(6)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <327 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(6)>,
+ <&scmi_reset A210_RESET_UART_SRST(6)>;
+
+ status = "disabled";
+ };
+
+ uart7: serial@8404000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x08404000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(7)>,
+ <&scmi_clk A210_CLK_UART_PCLK(7)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <328 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(7)>,
+ <&scmi_reset A210_RESET_UART_SRST(7)>;
+
+ status = "disabled";
+ };
+
+ uart8: serial@8405000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x08405000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(8)>,
+ <&scmi_clk A210_CLK_UART_PCLK(8)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <329 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(8)>,
+ <&scmi_reset A210_RESET_UART_SRST(8)>;
+
+ status = "disabled";
+ };
+
+ uart9: serial@8406000 {
+ compatible = "zhihe,a210-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x08406000 0x0 0x1000>;
+ clocks = <&scmi_clk A210_CLK_UART_SCLK(9)>,
+ <&scmi_clk A210_CLK_UART_PCLK(9)>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupt-parent = <&intc>;
+ interrupts = <330 IRQ_TYPE_LEVEL_HIGH>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ resets = <&scmi_reset A210_RESET_UART_PRST(9)>,
+ <&scmi_reset A210_RESET_UART_SRST(9)>;
status = "disabled";
};
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 15/18] riscv: dts: zhihe: add A210 module memory
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (13 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 14/18] riscv: dts: zhihe: add A210 UARTs Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2 Han Gao via B4 Relay
` (2 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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] 21+ messages in thread
* [PATCH RFC 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (14 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 15/18] riscv: dts: zhihe: add A210 module memory Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 17/18] riscv: defconfig: enable A210 support Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 18/18] MAINTAINERS: add Zhihe A210 Han Gao via B4 Relay
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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..52015f6de5f8
--- /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 {
+ pins = "GPIO2_1";
+ function = "uart4";
+ bias-disable;
+ drive-strength = <1>;
+ input-enable;
+ input-schmitt-enable;
+ slew-rate = <0>;
+ };
+
+ tx-pins {
+ pins = "GPIO2_0";
+ function = "uart4";
+ bias-disable;
+ drive-strength = <3>;
+ input-disable;
+ input-schmitt-disable;
+ 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] 21+ messages in thread
* [PATCH RFC 17/18] riscv: defconfig: enable A210 support
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (15 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2 Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 18/18] MAINTAINERS: add Zhihe A210 Han Gao via B4 Relay
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
Han Gao
From: Han Gao <gaohan@iscas.ac.cn>
Enable A210 pinctrl, mailbox and standard SCMI clock/reset drivers.
The A210 has ten UARTs, and Melon Pi numbers them through serial0..9
aliases with the console on serial4. With the default four 8250 ports,
the ports beyond serial3 fall back to other line numbers and no longer
match their aliases. Reserve ten ports.
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
arch/riscv/configs/defconfig | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index 04ae305d5511..b4c4aea6eabe 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
@@ -108,6 +109,8 @@ CONFIG_PCI_HOST_GENERIC=y
CONFIG_PCIE_XILINX=y
CONFIG_PCIE_FU740=y
CONFIG_PCIE_STARFIVE_HOST=m
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCMI_TRANSPORT_MAILBOX=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_SIFIVE_CCACHE=y
@@ -119,6 +122,7 @@ CONFIG_MTD_SPI_NOR=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_NVME=m
+CONFIG_SRAM=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y
CONFIG_SCSI_VIRTIO=y
@@ -149,6 +153,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 +173,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
@@ -255,6 +262,7 @@ CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
+CONFIG_COMMON_CLK_SCMI=y
CONFIG_CLK_SOPHGO_CV1800=y
CONFIG_CLK_SOPHGO_SG2042_PLL=y
CONFIG_CLK_SOPHGO_SG2042_CLKGEN=y
@@ -263,11 +271,13 @@ CONFIG_SPACEMIT_K1_CCU=y
CONFIG_SPACEMIT_K3_CCU=y
CONFIG_SUN8I_DE2_CCU=m
CONFIG_SUN50I_IOMMU=y
+CONFIG_ZHIHE_A210_MBOX=y
CONFIG_RPMSG_CHAR=y
CONFIG_RPMSG_CTRL=y
CONFIG_RPMSG_VIRTIO=y
CONFIG_PM_DEVFREQ=y
CONFIG_IIO=y
+CONFIG_RESET_SCMI=y
CONFIG_PWM=y
CONFIG_PWM_PXA=m
CONFIG_THEAD_C900_ACLINT_SSWI=y
--
2.55.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH RFC 18/18] MAINTAINERS: add Zhihe A210
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
` (16 preceding siblings ...)
2026-10-27 15:37 ` [PATCH RFC 17/18] riscv: defconfig: enable A210 support Han Gao via B4 Relay
@ 2026-10-27 15:37 ` Han Gao via B4 Relay
17 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-10-27 15:37 UTC (permalink / raw)
To: Sudeep Holla, Cristian Marussi, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Zhiguo Zhu, Jassi Brar, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Thomas Gleixner, Radu Rendec,
Samuel Holland, Daniel Lezcano, Anup Patel, Stephen Boyd,
Brian Masney, Jerome Brunet, Greg Kroah-Hartman, Jiri Slaby,
Drew Fustini, Icenowy Zheng, Inochi Amaoto, Vivian Wang, Yao Zi,
Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial,
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 | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 782389bd5cd3..c6cdd9bb0864 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -30115,6 +30115,20 @@ 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/mailbox/zhihe,a210-ap-mailbox.yaml
+F: Documentation/devicetree/bindings/pinctrl/zhihe,a210-pinctrl.yaml
+F: Documentation/devicetree/bindings/riscv/zhihe.yaml
+F: arch/riscv/boot/dts/zhihe/
+F: drivers/mailbox/mailbox-a210.c
+F: drivers/pinctrl/pinctrl-a210.c
+F: include/dt-bindings/clock/zhihe,a210-scmi.h
+F: include/dt-bindings/reset/zhihe,a210-scmi.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] 21+ messages in thread
* Re: [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V
2026-10-27 15:36 ` [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V Han Gao via B4 Relay
@ 2026-10-27 15:51 ` Michal Simek
2026-10-27 16:18 ` Sudeep Holla
0 siblings, 1 reply; 21+ messages in thread
From: Michal Simek @ 2026-10-27 15:51 UTC (permalink / raw)
To: gaohan, Sudeep Holla, Cristian Marussi, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Zhiguo Zhu, Jassi Brar,
Linus Walleij, Bartosz Golaszewski, Philipp Zabel,
Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
Anup Patel, Stephen Boyd, Brian Masney, Jerome Brunet,
Greg Kroah-Hartman, Jiri Slaby, Drew Fustini, Icenowy Zheng,
Inochi Amaoto, Vivian Wang, Yao Zi, Jiaxun Yang
Cc: arm-scmi, linux-arm-kernel, linux-kernel, devicetree,
linux-riscv, linux-gpio, Paul Walmsley, linux-clk, linux-serial
On 10/27/26 16:36, Han Gao via B4 Relay wrote:
> From: Han Gao <gaohan@iscas.ac.cn>
>
> Mailbox and shared-memory SCMI transports do not require ARM execution.
> Allow RISC-V platforms to use the existing SCMI core and protocol drivers;
> architecture-specific transports retain their own dependencies.
>
> Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
> ---
> drivers/firmware/arm_scmi/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> index 783c24a20e29..1cfe2b572d18 100644
> --- a/drivers/firmware/arm_scmi/Kconfig
> +++ b/drivers/firmware/arm_scmi/Kconfig
> @@ -3,7 +3,7 @@ menu "ARM System Control and Management Interface Protocol"
>
> config ARM_SCMI_PROTOCOL
> tristate "ARM System Control and Management Interface (SCMI) Message Protocol"
> - depends on ARM || ARM64 || COMPILE_TEST
> + depends on ARM || ARM64 || RISCV || COMPILE_TEST
I would prefer to remove ARM || ARM64 dependencies completely that you don't
need to add RISCV there.
Thanks,
Michal
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V
2026-10-27 15:51 ` Michal Simek
@ 2026-10-27 16:18 ` Sudeep Holla
0 siblings, 0 replies; 21+ messages in thread
From: Sudeep Holla @ 2026-10-27 16:18 UTC (permalink / raw)
To: Michal Simek
Cc: gaohan, Cristian Marussi, Rob Herring, Sudeep Holla,
Krzysztof Kozlowski, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Zhiguo Zhu, Jassi Brar,
Linus Walleij, Bartosz Golaszewski, Philipp Zabel,
Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
Anup Patel, Stephen Boyd, Brian Masney, Jerome Brunet,
Greg Kroah-Hartman, Jiri Slaby, Drew Fustini, Icenowy Zheng,
Inochi Amaoto, Vivian Wang, Yao Zi, Jiaxun Yang, arm-scmi,
linux-arm-kernel, linux-kernel, devicetree, linux-riscv,
linux-gpio, Paul Walmsley, linux-clk, linux-serial
On Tue, Oct 27, 2026 at 04:51:36PM +0100, Michal Simek wrote:
>
>
> On 10/27/26 16:36, Han Gao via B4 Relay wrote:
> > From: Han Gao <gaohan@iscas.ac.cn>
> >
> > Mailbox and shared-memory SCMI transports do not require ARM execution.
> > Allow RISC-V platforms to use the existing SCMI core and protocol drivers;
> > architecture-specific transports retain their own dependencies.
> >
> > Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
> > ---
> > drivers/firmware/arm_scmi/Kconfig | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> > index 783c24a20e29..1cfe2b572d18 100644
> > --- a/drivers/firmware/arm_scmi/Kconfig
> > +++ b/drivers/firmware/arm_scmi/Kconfig
> > @@ -3,7 +3,7 @@ menu "ARM System Control and Management Interface Protocol"
> > config ARM_SCMI_PROTOCOL
> > tristate "ARM System Control and Management Interface (SCMI) Message Protocol"
> > - depends on ARM || ARM64 || COMPILE_TEST
> > + depends on ARM || ARM64 || RISCV || COMPILE_TEST
>
>
> I would prefer to remove ARM || ARM64 dependencies completely that you don't
> need to add RISCV there.
>
Agreed. Before merging, we should trigger exploratory builds across multiple
architectures. This will help us catch any hardware-specific dependencies,
such as arch-exclusive IO accessors, that I might be overlooking right now.
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-10-27 16:18 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-27 15:36 [PATCH RFC 00/18] riscv: add initial Zhihe A210 support using SCMI clocks and resets Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 01/18] firmware: arm_scmi: Allow SCMI transports on RISC-V Han Gao via B4 Relay
2026-10-27 15:51 ` Michal Simek
2026-10-27 16:18 ` Sudeep Holla
2026-10-27 15:36 ` [PATCH RFC 02/18] dt-bindings: vendor-prefixes: add Zhihe Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 03/18] riscv: add Zhihe A210 support Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 04/18] dt-bindings: mailbox: add the A210 AP to E902 doorbell Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 05/18] mailbox: add A210 AP to E902 doorbell support Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 06/18] dt-bindings: pinctrl: add Zhihe A210 pin controller Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 07/18] pinctrl: zhihe: add A210 support Han Gao via B4 Relay
2026-10-27 15:36 ` [PATCH RFC 08/18] dt-bindings: interrupt-controller: add Zhihe A210 PLIC Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 09/18] dt-bindings: riscv: add Melon Pi V1 and V2 Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 10/18] dt-bindings: timer: add Zhihe A210 CLINT Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 11/18] dt-bindings: firmware: add A210 SCMI clock and reset IDs Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 12/18] dt-bindings: serial: snps-dw-apb-uart: add Zhihe A210 UART Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 13/18] riscv: dts: zhihe: add A210 core support Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 14/18] riscv: dts: zhihe: add A210 UARTs Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 15/18] riscv: dts: zhihe: add A210 module memory Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 16/18] riscv: dts: zhihe: add Melon Pi V1 and V2 Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 17/18] riscv: defconfig: enable A210 support Han Gao via B4 Relay
2026-10-27 15:37 ` [PATCH RFC 18/18] MAINTAINERS: add Zhihe A210 Han Gao via B4 Relay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®