* [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
@ 2026-05-15 1:17 ` Jia Wang via B4 Relay
2026-05-15 1:17 ` [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible Jia Wang via B4 Relay
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:17 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Add Shenzhen Rongda Computer Co., Ltd. to the vendor prefixes.
Link: http://www.shenrongda.com/
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
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 28784d66ae7b..04e593c66c7c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1407,6 +1407,8 @@ patternProperties:
description: Rockchip Electronics Co., Ltd.
"^rocktech,.*":
description: ROCKTECH DISPLAYS LIMITED
+ "^rongda,.*":
+ description: Shenzhen Rongda Computer Co., Ltd.
"^rohm,.*":
description: ROHM Semiconductor Co., Ltd
"^ronbo,.*":
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
2026-05-15 1:17 ` [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda Jia Wang via B4 Relay
@ 2026-05-15 1:17 ` Jia Wang via B4 Relay
2026-05-15 10:06 ` Conor Dooley
2026-05-15 1:17 ` [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings Jia Wang via B4 Relay
` (7 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:17 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Update Documentation for supporting UltraRISC CP100 based CPU.
CP100 is used in UltraRISC DP1000 SoC.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
Documentation/devicetree/bindings/riscv/cpus.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
index 5feeb2203050..9f5226717701 100644
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
@@ -67,6 +67,7 @@ properties:
- thead,c908
- thead,c910
- thead,c920
+ - ultrarisc,cp100
- const: riscv
- items:
- enum:
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
2026-05-15 1:17 ` [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible Jia Wang via B4 Relay
@ 2026-05-15 10:06 ` Conor Dooley
0 siblings, 0 replies; 16+ messages in thread
From: Conor Dooley @ 2026-05-15 10:06 UTC (permalink / raw)
To: Jia Wang
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland, Paul Walmsley,
Palmer Dabbelt, Conor Dooley, devicetree, linux-riscv,
linux-kernel, linux-gpio
[-- Attachment #1.1: Type: text/plain, Size: 52 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
2026-05-15 1:17 ` [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda Jia Wang via B4 Relay
2026-05-15 1:17 ` [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible Jia Wang via B4 Relay
@ 2026-05-15 1:17 ` Jia Wang via B4 Relay
2026-05-15 10:08 ` Conor Dooley
2026-05-15 1:18 ` [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings Jia Wang via B4 Relay
` (6 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:17 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Add DT binding documentation for the UltraRISC DP1000 SoC.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
.../devicetree/bindings/riscv/ultrarisc.yaml | 27 ++++++++++++++++++++++
MAINTAINERS | 6 +++++
2 files changed, 33 insertions(+)
diff --git a/Documentation/devicetree/bindings/riscv/ultrarisc.yaml b/Documentation/devicetree/bindings/riscv/ultrarisc.yaml
new file mode 100644
index 000000000000..d4421c2ef945
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/ultrarisc.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/ultrarisc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: UltraRISC SoC-based boards
+
+maintainers:
+ - Jia Wang <wangjia@ultrarisc.com>
+
+description:
+ UltraRISC DP1000 SoC-based boards
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - rongda,m0
+ - milkv,titan
+ - const: ultrarisc,dp1000
+
+additionalProperties: true
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index b2040011a386..5bf971ff48b2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23082,6 +23082,12 @@ F: include/dt-bindings/power/thead,th1520-power.h
F: include/dt-bindings/reset/thead,th1520-reset.h
F: include/linux/firmware/thead/thead,th1520-aon.h
+RISC-V ULTRARISC SoC SUPPORT
+M: Jia Wang <wangjia@ultrarisc.com>
+L: linux-riscv@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/riscv/ultrarisc.yaml
+
RNBD BLOCK DRIVERS
M: Md. Haris Iqbal <haris.iqbal@ionos.com>
M: Jack Wang <jinpu.wang@ionos.com>
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings
2026-05-15 1:17 ` [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings Jia Wang via B4 Relay
@ 2026-05-15 10:08 ` Conor Dooley
0 siblings, 0 replies; 16+ messages in thread
From: Conor Dooley @ 2026-05-15 10:08 UTC (permalink / raw)
To: Jia Wang
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland, Paul Walmsley,
Palmer Dabbelt, Conor Dooley, devicetree, linux-riscv,
linux-kernel, linux-gpio
[-- Attachment #1.1: Type: text/plain, Size: 2211 bytes --]
On Fri, May 15, 2026 at 09:17:59AM +0800, Jia Wang wrote:
> Add DT binding documentation for the UltraRISC DP1000 SoC.
>
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---
> .../devicetree/bindings/riscv/ultrarisc.yaml | 27 ++++++++++++++++++++++
> MAINTAINERS | 6 +++++
> 2 files changed, 33 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/riscv/ultrarisc.yaml b/Documentation/devicetree/bindings/riscv/ultrarisc.yaml
> new file mode 100644
> index 000000000000..d4421c2ef945
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/riscv/ultrarisc.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/ultrarisc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: UltraRISC SoC-based boards
> +
> +maintainers:
> + - Jia Wang <wangjia@ultrarisc.com>
> +
> +description:
> + UltraRISC DP1000 SoC-based boards
> +
> +properties:
> + $nodename:
> + const: '/'
> + compatible:
> + oneOf:
> + - items:
> + - enum:
> + - rongda,m0
> + - milkv,titan
> + - const: ultrarisc,dp1000
> +
> +additionalProperties: true
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b2040011a386..5bf971ff48b2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -23082,6 +23082,12 @@ F: include/dt-bindings/power/thead,th1520-power.h
> F: include/dt-bindings/reset/thead,th1520-reset.h
> F: include/linux/firmware/thead/thead,th1520-aon.h
>
> +RISC-V ULTRARISC SoC SUPPORT
> +M: Jia Wang <wangjia@ultrarisc.com>
> +L: linux-riscv@lists.infradead.org
> +S: Maintained
You work for ultrasoc, probably this should be "Supported".
> +F: Documentation/devicetree/bindings/riscv/ultrarisc.yaml
There's no git tree here where patches for the platform will be applied
before sending them on to the SoC maintainers. Are you expecting me to
apply patches for this platform?
> +
> RNBD BLOCK DRIVERS
> M: Md. Haris Iqbal <haris.iqbal@ionos.com>
> M: Jack Wang <jinpu.wang@ionos.com>
>
> --
> 2.34.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
` (2 preceding siblings ...)
2026-05-15 1:17 ` [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings Jia Wang via B4 Relay
@ 2026-05-15 1:18 ` Jia Wang via B4 Relay
2026-05-15 10:12 ` Conor Dooley
2026-05-15 1:18 ` [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000 Jia Wang via B4 Relay
` (5 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Add bindings for the pin controllers on the UltraRISC DP1000 RISC-V SoC.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
.../bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml | 168 +++++++++++++++++++++
MAINTAINERS | 7 +
.../dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h | 65 ++++++++
3 files changed, 240 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
new file mode 100644
index 000000000000..c7ed1f96382a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
@@ -0,0 +1,168 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/ultrarisc,dp1000-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: UltraRISC DP1000 Pin Controller
+maintainers:
+ - Jia Wang <wangjia@ultrarisc.com>
+
+description: |
+ UltraRISC RISC-V SoC DP1000 pin controller.
+
+ The binding supports two child node styles under the same controller
+ compatible:
+
+ - legacy DP1000-specific nodes using phandle-array properties
+ `pinctrl-pins` and `pinconf-pins`
+ - generic pinctrl nodes using `pins`, `function` and generic pin
+ configuration properties
+
+properties:
+ compatible:
+ const: ultrarisc,dp1000-pinctrl
+
+ reg:
+ maxItems: 1
+
+ "#pinctrl-cells":
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+patternProperties:
+ '.*-pins$':
+ type: object
+ allOf:
+ - $ref: /schemas/pinctrl/pincfg-node.yaml#
+ - $ref: /schemas/pinctrl/pinmux-node.yaml#
+ additionalProperties: false
+ properties:
+ pinctrl-pins:
+ description: |
+ The list of pins and their mux settings that properties in the node
+ apply to. The format: `PORT PIN FUNCTION`.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 1
+ maxItems: 32
+ pinconf-pins:
+ description: |
+ The list of pins and their pad configuration that properties in the
+ node apply to. The format: `PORT PIN CONF`.
+ CONF is a DP1000-specific encoding of pull and drive strength as
+ defined in dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 1
+ maxItems: 32
+ pins:
+ description: List of pins affected by this state node.
+ minItems: 1
+ uniqueItems: true
+ items:
+ type: string
+ pattern: '^(PA([0-9]|1[0-5])|P[BCD][0-7]|LPC([0-9]|1[0-2]))$'
+
+ function:
+ description: |
+ Mux function to select for the listed pins.
+ gpio maps to the hardware default mode. The default mode is
+ GPIO for PA/PB/PC/PD pins and LPC for LPC pins.
+ func1 is not supported on LPC pins.
+ enum:
+ - gpio
+ - func0
+ - func1
+
+ bias-disable: true
+ bias-high-impedance: true
+ bias-pull-up: true
+ bias-pull-down: true
+
+ drive-strength:
+ description: Output drive strength in mA.
+ enum: [20, 27, 33, 40]
+
+ oneOf:
+ - allOf:
+ - anyOf:
+ - required: [pinctrl-pins]
+ - required: [pinconf-pins]
+ - not:
+ required: [pins]
+ - allOf:
+ - required: [pins]
+ - not:
+ anyOf:
+ - required: [pinctrl-pins]
+ - required: [pinconf-pins]
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pinmux@11081000 {
+ compatible = "ultrarisc,dp1000-pinctrl";
+ reg = <0x0 0x11081000 0x0 0x1000>;
+ #pinctrl-cells = <2>;
+
+ i2c0-pins {
+ pins = "PA12", "PA13";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart0-pins {
+ pins = "PA8", "PA9";
+ function = "func1";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+ };
+ };
+
+ - |
+ /* Legacy example */
+ #include <dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pinmux@11081000 {
+ compatible = "ultrarisc,dp1000-pinctrl";
+ reg = <0x0 0x11081000 0x0 0x1000>;
+ #pinctrl-cells = <2>;
+
+ i2c0-pins {
+ pinctrl-pins = <
+ UR_DP1000_IOMUX_A 12 UR_DP1000_FUNC0
+ UR_DP1000_IOMUX_A 13 UR_DP1000_FUNC0
+ >;
+
+ pinconf-pins = <
+ UR_DP1000_IOMUX_A 12 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
+ UR_DP1000_DRIVE_DEF)
+ UR_DP1000_IOMUX_A 13 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
+ UR_DP1000_DRIVE_DEF)
+ >;
+ };
+
+ uart0-pins {
+ pinctrl-pins = <
+ UR_DP1000_IOMUX_A 8 UR_DP1000_FUNC1
+ UR_DP1000_IOMUX_A 9 UR_DP1000_FUNC1
+ >;
+
+ pinconf-pins = <
+ UR_DP1000_IOMUX_A 8 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
+ UR_DP1000_DRIVE_DEF)
+ UR_DP1000_IOMUX_A 9 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
+ UR_DP1000_DRIVE_DEF)
+ >;
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 5bf971ff48b2..baaaa46b1a56 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27358,6 +27358,13 @@ S: Maintained
F: drivers/usb/common/ulpi.c
F: include/linux/ulpi/
+ULTRARISC DP1000 PINCTRL DRIVER
+M: Jia Wang <wangjia@ultrarisc.com>
+L: linux-gpio@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
+F: include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
+
ULTRATRONIK BOARD SUPPORT
M: Goran Rađenović <goran.radni@gmail.com>
M: Börge Strümpfel <boerge.struempfel@gmail.com>
diff --git a/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h b/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
new file mode 100644
index 000000000000..bef28115898d
--- /dev/null
+++ b/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * UltraRISC DP1000 pinctrl header.
+ *
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_PINCTRL_H
+#define _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_PINCTRL_H
+
+/**
+ * UltraRISC DP1000 IO pad configuration
+ * port: A, B, C, D, LPC
+ * Pin in the port
+ * pin:
+ * PA: 0 - 15
+ * PB-PD: 0 - 7
+ * LPC: 0 - 12
+ * func:
+ * UR_DP1000_FUNC_DEF: default
+ * UR_DP1000_FUNC0: func0
+ * UR_DP1000_FUNC1: func1
+ */
+#define UR_DP1000_IOMUX_A 0x0
+#define UR_DP1000_IOMUX_B 0x1
+#define UR_DP1000_IOMUX_C 0x2
+#define UR_DP1000_IOMUX_D 0x3
+#define UR_DP1000_IOMUX_LPC 0x4
+
+#define UR_DP1000_FUNC_DEF 0
+#define UR_DP1000_FUNC0 1
+#define UR_DP1000_FUNC1 0x10000
+
+/**
+ * Configure pull up/down resistor of the IO pin
+ * UR_DP1000_PULL_DIS: disable pull-up and pull-down
+ * UR_DP1000_PULL_UP: enable pull-up
+ * UR_DP1000_PULL_DOWN: enable pull-down
+ */
+#define UR_DP1000_PULL_DIS 0
+#define UR_DP1000_PULL_UP 1
+#define UR_DP1000_PULL_DOWN 2
+/**
+ * Configure drive strength of the IO pin
+ * UR_DP1000_DRIVE_DEF: default value, reset value is 2
+ * UR_DP1000_DRIVE_0: 20mA
+ * UR_DP1000_DRIVE_1: 27mA
+ * UR_DP1000_DRIVE_2: 33mA
+ * UR_DP1000_DRIVE_3: 40mA
+ */
+#define UR_DP1000_DRIVE_DEF 2
+#define UR_DP1000_DRIVE_0 0
+#define UR_DP1000_DRIVE_1 1
+#define UR_DP1000_DRIVE_2 2
+#define UR_DP1000_DRIVE_3 3
+
+/**
+ * Combine the pull-up/down resistor and drive strength
+ * pull: UR_DP1000_PULL_DIS, UR_DP1000_PULL_UP, UR_DP1000_PULL_DOWN
+ * drive: UR_DP1000_DRIVE_DEF, UR_DP1000_DRIVE_0, UR_DP1000_DRIVE_1,
+ * UR_DP1000_DRIVE_2, UR_DP1000_DRIVE_3
+ */
+#define UR_DP1000_BIAS(pull, drive) (((pull) << 2) | (drive))
+
+#endif /* _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_PINCTRL_H */
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
2026-05-15 1:18 ` [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings Jia Wang via B4 Relay
@ 2026-05-15 10:12 ` Conor Dooley
0 siblings, 0 replies; 16+ messages in thread
From: Conor Dooley @ 2026-05-15 10:12 UTC (permalink / raw)
To: Jia Wang
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland, Paul Walmsley,
Palmer Dabbelt, Conor Dooley, devicetree, linux-riscv,
linux-kernel, linux-gpio
[-- Attachment #1.1: Type: text/plain, Size: 9830 bytes --]
On Fri, May 15, 2026 at 09:18:00AM +0800, Jia Wang wrote:
> Add bindings for the pin controllers on the UltraRISC DP1000 RISC-V SoC.
>
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---
> .../bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml | 168 +++++++++++++++++++++
> MAINTAINERS | 7 +
> .../dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h | 65 ++++++++
> 3 files changed, 240 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
> new file mode 100644
> index 000000000000..c7ed1f96382a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
> @@ -0,0 +1,168 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/ultrarisc,dp1000-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: UltraRISC DP1000 Pin Controller
> +maintainers:
> + - Jia Wang <wangjia@ultrarisc.com>
> +
> +description: |
> + UltraRISC RISC-V SoC DP1000 pin controller.
> +
> + The binding supports two child node styles under the same controller
> + compatible:
> +
> + - legacy DP1000-specific nodes using phandle-array properties
> + `pinctrl-pins` and `pinconf-pins`
> + - generic pinctrl nodes using `pins`, `function` and generic pin
> + configuration properties
> +
> +properties:
> + compatible:
> + const: ultrarisc,dp1000-pinctrl
> +
> + reg:
> + maxItems: 1
> +
> + "#pinctrl-cells":
> + $ref: /schemas/types.yaml#/definitions/uint32
> +
> +patternProperties:
> + '.*-pins$':
> + type: object
> + allOf:
> + - $ref: /schemas/pinctrl/pincfg-node.yaml#
> + - $ref: /schemas/pinctrl/pinmux-node.yaml#
> + additionalProperties: false
> + properties:
> + pinctrl-pins:
> + description: |
> + The list of pins and their mux settings that properties in the node
> + apply to. The format: `PORT PIN FUNCTION`.
> + $ref: /schemas/types.yaml#/definitions/uint32-array
> + minItems: 1
> + maxItems: 32
> + pinconf-pins:
> + description: |
> + The list of pins and their pad configuration that properties in the
> + node apply to. The format: `PORT PIN CONF`.
> + CONF is a DP1000-specific encoding of pull and drive strength as
> + defined in dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h.
> + $ref: /schemas/types.yaml#/definitions/uint32-array
> + minItems: 1
> + maxItems: 32
These two "legacy" properties are not acceptable, sorry.
> + pins:
> + description: List of pins affected by this state node.
> + minItems: 1
> + uniqueItems: true
> + items:
> + type: string
> + pattern: '^(PA([0-9]|1[0-5])|P[BCD][0-7]|LPC([0-9]|1[0-2]))$'
The regex might be neat, but I don't think that it is very
user-friendly. It's hard to read this and understand what the pin
namings actually are. Could you break this down into multiple patterns,
one for each type of pin?
I think that would make reading it much simpler.
> +
> + function:
> + description: |
> + Mux function to select for the listed pins.
> + gpio maps to the hardware default mode. The default mode is
> + GPIO for PA/PB/PC/PD pins and LPC for LPC pins.
> + func1 is not supported on LPC pins.
> + enum:
> + - gpio
> + - func0
> + - func1
These two do no seem to be very useful to people writing devicetrees.
What do func0 and func1 represent? I assume that they represent
something different for different pins? For example, maybe qspi for LPC
or i2c for PC?
pw-bot: changes-requested
Cheers,
Conor.
> +
> + bias-disable: true
> + bias-high-impedance: true
> + bias-pull-up: true
> + bias-pull-down: true
> +
> + drive-strength:
> + description: Output drive strength in mA.
> + enum: [20, 27, 33, 40]
> +
> + oneOf:
> + - allOf:
> + - anyOf:
> + - required: [pinctrl-pins]
> + - required: [pinconf-pins]
> + - not:
> + required: [pins]
> + - allOf:
> + - required: [pins]
> + - not:
> + anyOf:
> + - required: [pinctrl-pins]
> + - required: [pinconf-pins]
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + pinmux@11081000 {
> + compatible = "ultrarisc,dp1000-pinctrl";
> + reg = <0x0 0x11081000 0x0 0x1000>;
> + #pinctrl-cells = <2>;
> +
> + i2c0-pins {
> + pins = "PA12", "PA13";
> + function = "func0";
> + bias-pull-up;
> + drive-strength = <33>;
> + };
> +
> + uart0-pins {
> + pins = "PA8", "PA9";
> + function = "func1";
> + bias-pull-up;
> + drive-strength = <33>;
> + };
> + };
> + };
> +
> + - |
> + /* Legacy example */
> + #include <dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h>
> +
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + pinmux@11081000 {
> + compatible = "ultrarisc,dp1000-pinctrl";
> + reg = <0x0 0x11081000 0x0 0x1000>;
> + #pinctrl-cells = <2>;
> +
> + i2c0-pins {
> + pinctrl-pins = <
> + UR_DP1000_IOMUX_A 12 UR_DP1000_FUNC0
> + UR_DP1000_IOMUX_A 13 UR_DP1000_FUNC0
> + >;
> +
> + pinconf-pins = <
> + UR_DP1000_IOMUX_A 12 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
> + UR_DP1000_DRIVE_DEF)
> + UR_DP1000_IOMUX_A 13 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
> + UR_DP1000_DRIVE_DEF)
> + >;
> + };
> +
> + uart0-pins {
> + pinctrl-pins = <
> + UR_DP1000_IOMUX_A 8 UR_DP1000_FUNC1
> + UR_DP1000_IOMUX_A 9 UR_DP1000_FUNC1
> + >;
> +
> + pinconf-pins = <
> + UR_DP1000_IOMUX_A 8 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
> + UR_DP1000_DRIVE_DEF)
> + UR_DP1000_IOMUX_A 9 UR_DP1000_BIAS(UR_DP1000_PULL_UP,
> + UR_DP1000_DRIVE_DEF)
> + >;
> + };
> + };
> + };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5bf971ff48b2..baaaa46b1a56 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -27358,6 +27358,13 @@ S: Maintained
> F: drivers/usb/common/ulpi.c
> F: include/linux/ulpi/
>
> +ULTRARISC DP1000 PINCTRL DRIVER
> +M: Jia Wang <wangjia@ultrarisc.com>
> +L: linux-gpio@vger.kernel.org
> +S: Maintained
> +F: Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
> +F: include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
> +
> ULTRATRONIK BOARD SUPPORT
> M: Goran Rađenović <goran.radni@gmail.com>
> M: Börge Strümpfel <boerge.struempfel@gmail.com>
> diff --git a/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h b/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
> new file mode 100644
> index 000000000000..bef28115898d
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
> @@ -0,0 +1,65 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * UltraRISC DP1000 pinctrl header.
> + *
> + * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
> + */
> +
> +#ifndef _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_PINCTRL_H
> +#define _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_PINCTRL_H
> +
> +/**
> + * UltraRISC DP1000 IO pad configuration
> + * port: A, B, C, D, LPC
> + * Pin in the port
> + * pin:
> + * PA: 0 - 15
> + * PB-PD: 0 - 7
> + * LPC: 0 - 12
> + * func:
> + * UR_DP1000_FUNC_DEF: default
> + * UR_DP1000_FUNC0: func0
> + * UR_DP1000_FUNC1: func1
> + */
> +#define UR_DP1000_IOMUX_A 0x0
> +#define UR_DP1000_IOMUX_B 0x1
> +#define UR_DP1000_IOMUX_C 0x2
> +#define UR_DP1000_IOMUX_D 0x3
> +#define UR_DP1000_IOMUX_LPC 0x4
> +
> +#define UR_DP1000_FUNC_DEF 0
> +#define UR_DP1000_FUNC0 1
> +#define UR_DP1000_FUNC1 0x10000
> +
> +/**
> + * Configure pull up/down resistor of the IO pin
> + * UR_DP1000_PULL_DIS: disable pull-up and pull-down
> + * UR_DP1000_PULL_UP: enable pull-up
> + * UR_DP1000_PULL_DOWN: enable pull-down
> + */
> +#define UR_DP1000_PULL_DIS 0
> +#define UR_DP1000_PULL_UP 1
> +#define UR_DP1000_PULL_DOWN 2
> +/**
> + * Configure drive strength of the IO pin
> + * UR_DP1000_DRIVE_DEF: default value, reset value is 2
> + * UR_DP1000_DRIVE_0: 20mA
> + * UR_DP1000_DRIVE_1: 27mA
> + * UR_DP1000_DRIVE_2: 33mA
> + * UR_DP1000_DRIVE_3: 40mA
> + */
> +#define UR_DP1000_DRIVE_DEF 2
> +#define UR_DP1000_DRIVE_0 0
> +#define UR_DP1000_DRIVE_1 1
> +#define UR_DP1000_DRIVE_2 2
> +#define UR_DP1000_DRIVE_3 3
> +
> +/**
> + * Combine the pull-up/down resistor and drive strength
> + * pull: UR_DP1000_PULL_DIS, UR_DP1000_PULL_UP, UR_DP1000_PULL_DOWN
> + * drive: UR_DP1000_DRIVE_DEF, UR_DP1000_DRIVE_0, UR_DP1000_DRIVE_1,
> + * UR_DP1000_DRIVE_2, UR_DP1000_DRIVE_3
> + */
> +#define UR_DP1000_BIAS(pull, drive) (((pull) << 2) | (drive))
> +
> +#endif /* _DT_BINDINGS_PINCTRL_ULTRARISC_DP1000_PINCTRL_H */
>
> --
> 2.34.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
` (3 preceding siblings ...)
2026-05-15 1:18 ` [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings Jia Wang via B4 Relay
@ 2026-05-15 1:18 ` Jia Wang via B4 Relay
2026-05-15 10:26 ` Conor Dooley
2026-05-15 1:18 ` [PATCH 6/9] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver Jia Wang via B4 Relay
` (4 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Add the base device tree for the UltraRISC DP1000 SoC. It describes the
8×CP100 CPU cores and essential SoC peripherals including the interrupt
controller, pinctrl, GPIO, UART, SPI, I2C, PCIe, GMAC and the DMA
controller.
Link: https://lore.kernel.org/lkml/20260427-ultrarisc-pcie-v4-2-98935f6cdfb5@ultrarisc.com/
Link: https://lore.kernel.org/lkml/20260429-ultrarisc-serial-v7-3-e475cce9e274@ultrarisc.com/
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
MAINTAINERS | 1 +
arch/riscv/boot/dts/ultrarisc/dp1000.dtsi | 851 ++++++++++++++++++++++++++++++
2 files changed, 852 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index baaaa46b1a56..832e01898ae5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23087,6 +23087,7 @@ M: Jia Wang <wangjia@ultrarisc.com>
L: linux-riscv@lists.infradead.org
S: Maintained
F: Documentation/devicetree/bindings/riscv/ultrarisc.yaml
+F: arch/riscv/boot/dts/ultrarisc/
RNBD BLOCK DRIVERS
M: Md. Haris Iqbal <haris.iqbal@ionos.com>
diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi b/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi
new file mode 100644
index 000000000000..1aae53fc1a2b
--- /dev/null
+++ b/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi
@@ -0,0 +1,851 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "ultrarisc,dp1000";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ timebase-frequency = <10000000>;
+
+ cpu0: cpu@0 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x0>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache0>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu0_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache0: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster0_l3>;
+ };
+ };
+
+ cpu1: cpu@1 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x1>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache1>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu1_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache1: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster0_l3>;
+ };
+ };
+
+ cpu2: cpu@2 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x2>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache2>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu2_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache2: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster0_l3>;
+ };
+ };
+
+ cpu3: cpu@3 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x3>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache3>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu3_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache3: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster0_l3>;
+ };
+ };
+
+ cpu4: cpu@4 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x10>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache4>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu4_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache4: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster1_l3>;
+ };
+ };
+ cpu5: cpu@5 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x11>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache5>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu5_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache5: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster1_l3>;
+ };
+ };
+ cpu6: cpu@6 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x12>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache6>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu6_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache6: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster1_l3>;
+ };
+ };
+
+ cpu7: cpu@7 {
+ compatible = "ultrarisc,cp100", "riscv";
+ reg = <0x13>;
+ device_type = "cpu";
+ riscv,isa = "rv64imafdcbh";
+ riscv,isa-base = "rv64i";
+ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
+ "zba", "zbb", "zbc", "zbs", "zicntr",
+ "zicsr", "zifencei", "zihpm", "ziccif",
+ "ziccrse", "ziccamoa", "za64rs", "zicbom",
+ "zicbop", "zicboz", "zkt", "svade",
+ "ssccptr", "sstvecd", "sscounterenw",
+ "shcounterenw", "shtvala", "shvstvecd",
+ "shvsatpa", "svvptc";
+ mmu-type = "riscv,sv48";
+ clock-frequency = <2000000000>;
+ /* L1 I-cache and D-cache:
+ * block-size 64B
+ * 4-way set associative, size 64KB
+ * per-core.
+ */
+ d-cache-block-size = <64>;
+ d-cache-sets = <256>;
+ d-cache-size = <0x10000>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <0x10000>;
+ next-level-cache = <&l2_cache7>;
+ riscv,cbom-block-size = <64>;
+ riscv,cboz-block-size = <64>;
+
+ cpu7_intc: interrupt-controller {
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ #interrupt-cells = <0x01>;
+ };
+
+ l2_cache7: l2-cache {
+ /* L2 cache:
+ * cache-unified, block-size 64B
+ * 8-way set associative, size 512KB
+ * per-core.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-size = <0x80000>;
+ cache-sets = <1024>;
+ cache-unified;
+ next-level-cache = <&cluster1_l3>;
+ };
+ };
+
+ cpu-map {
+ cluster0: cluster0 {
+ core0 {
+ cpu = <&cpu0>;
+ };
+
+ core1 {
+ cpu = <&cpu1>;
+ };
+
+ core2 {
+ cpu = <&cpu2>;
+ };
+
+ core3 {
+ cpu = <&cpu3>;
+ };
+ };
+
+ cluster1: cluster1 {
+ core0 {
+ cpu = <&cpu4>;
+ };
+
+ core1 {
+ cpu = <&cpu5>;
+ };
+
+ core2 {
+ cpu = <&cpu6>;
+ };
+
+ core3 {
+ cpu = <&cpu7>;
+ };
+ };
+ };
+
+ cluster0_l3: l3-cache0 {
+ /* L3 cache:
+ * cache-unified, block-size 64B
+ * 16-way set associative, size 4MB
+ * per-cluster.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <3>;
+ cache-size = <0x400000>;
+ cache-sets = <0x1000>;
+ cache-unified;
+ next-level-cache = <&l4_cache>;
+ };
+
+ cluster1_l3: l3-cache1 {
+ /* L3 cache:
+ * cache-unified, block-size 64B
+ * 16-way set associative, size 4MB
+ * per-cluster.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <3>;
+ cache-size = <0x400000>;
+ cache-sets = <0x1000>;
+ cache-unified;
+ next-level-cache = <&l4_cache>;
+ };
+ };
+
+ clocks {
+ device_clk: device_clk {
+ compatible = "fixed-clock";
+ clock-frequency = <62500000>;
+ #clock-cells = <0>;
+ };
+
+ timer_clk: timer_clk {
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ #clock-cells = <0>;
+ };
+
+ csr_clk: csr_clk {
+ compatible = "fixed-clock";
+ clock-frequency = <250000000>;
+ #clock-cells = <0>;
+ };
+ };
+
+ l4_cache: l4-cache {
+ /* L4 cache:
+ * cache-unified, block-size 64B
+ * 16-way set associative, size 16MB
+ * shared by the SoC.
+ */
+ compatible = "cache";
+ cache-block-size = <64>;
+ cache-level = <4>;
+ cache-size = <0x1000000>;
+ cache-sets = <0x4000>;
+ cache-unified;
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x00 0x80000000 0x4 0x00000000>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <0x02>;
+ #size-cells = <0x02>;
+
+ clint: clint@8000000 {
+ compatible = "sifive,clint0", "riscv,clint0";
+ reg = <0x00 0x8000000 0x00 0x100000>;
+ interrupts-extended = <&cpu0_intc 0x03>, <&cpu0_intc 0x07>,
+ <&cpu1_intc 0x03>, <&cpu1_intc 0x07>,
+ <&cpu2_intc 0x03>, <&cpu2_intc 0x07>,
+ <&cpu3_intc 0x03>, <&cpu3_intc 0x07>,
+ <&cpu4_intc 0x03>, <&cpu4_intc 0x07>,
+ <&cpu5_intc 0x03>, <&cpu5_intc 0x07>,
+ <&cpu6_intc 0x03>, <&cpu6_intc 0x07>,
+ <&cpu7_intc 0x03>, <&cpu7_intc 0x07>;
+ };
+
+ plic: plic@9000000 {
+ compatible = "ultrarisc,dp1000-plic", "ultrarisc,cp100-plic";
+ reg = <0x00 0x9000000 0x00 0x4000000>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ interrupt-controller;
+ interrupts-extended = <&cpu0_intc 0xb>, <&cpu0_intc 0x9>, <&cpu0_intc 0xa>,
+ <&cpu1_intc 0xb>, <&cpu1_intc 0x9>, <&cpu1_intc 0xa>,
+ <&cpu2_intc 0xb>, <&cpu2_intc 0x9>, <&cpu2_intc 0xa>,
+ <&cpu3_intc 0xb>, <&cpu3_intc 0x9>, <&cpu3_intc 0xa>,
+ <&cpu4_intc 0xb>, <&cpu4_intc 0x9>, <&cpu4_intc 0xa>,
+ <&cpu5_intc 0xb>, <&cpu5_intc 0x9>, <&cpu5_intc 0xa>,
+ <&cpu6_intc 0xb>, <&cpu6_intc 0x9>, <&cpu6_intc 0xa>,
+ <&cpu7_intc 0xb>, <&cpu7_intc 0x9>, <&cpu7_intc 0xa>;
+ riscv,ndev = <160>;
+ };
+
+ pmx0: pinmux@11081000 {
+ compatible = "ultrarisc,dp1000-pinctrl";
+ reg = <0x0 0x11081000 0x0 0x1000>;
+ #pinctrl-cells = <2>;
+ };
+
+ gpio: gpio@20200000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x0 0x20200000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "bus", "db";
+ clocks = <&csr_clk>, <&device_clk>;
+
+ gpio_a: gpio-port@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ reg = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <16>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&plic>;
+ interrupts = <34>;
+ gpio-ranges = <&pmx0 0 0 16>;
+ };
+
+ gpio_b: gpio-port@1 {
+ compatible = "snps,dw-apb-gpio-port";
+ reg = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ gpio-ranges = <&pmx0 16 0 8>;
+ };
+
+ gpio_c: gpio-port@2 {
+ compatible = "snps,dw-apb-gpio-port";
+ reg = <2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ gpio-ranges = <&pmx0 24 0 8>;
+ };
+
+ gpio_d: gpio-port@3 {
+ compatible = "snps,dw-apb-gpio-port";
+ reg = <3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <8>;
+ gpio-ranges = <&pmx0 32 0 8>;
+ };
+ };
+
+ uart0: serial@20300000 {
+ compatible = "ultrarisc,dp1000-uart", "snps,dw-apb-uart";
+ reg = <0x00 0x20300000 0x00 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <17>;
+ clock-frequency = <62500000>;
+ reg-io-width = <0x04>;
+ reg-shift = <0x02>;
+ };
+
+ uart1: serial@20310000 {
+ compatible = "ultrarisc,dp1000-uart", "snps,dw-apb-uart";
+ reg = <0x00 0x20310000 0x00 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <18>;
+ clock-frequency = <62500000>;
+ reg-io-width = <0x04>;
+ reg-shift = <0x02>;
+ };
+
+ uart2: serial@20400000 {
+ compatible = "ultrarisc,dp1000-uart", "snps,dw-apb-uart";
+ reg = <0x00 0x20400000 0x00 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <25>;
+ clock-frequency = <62500000>;
+ reg-io-width = <0x04>;
+ reg-shift = <0x02>;
+ };
+
+ uart3: serial@20410000 {
+ compatible = "ultrarisc,dp1000-uart", "snps,dw-apb-uart";
+ reg = <0x00 0x20410000 0x00 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <26>;
+ clock-frequency = <62500000>;
+ reg-io-width = <0x04>;
+ reg-shift = <0x02>;
+ };
+
+ spi0: spi@20320000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x0 0x20320000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&device_clk>;
+ interrupt-parent = <&plic>;
+ interrupts = <19>;
+ num-cs = <3>;
+ };
+
+ spi1: spi@20420000 {
+ compatible = "snps,dw-apb-ssi";
+ reg = <0x0 0x20420000 0x0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&device_clk>;
+ interrupt-parent = <&plic>;
+ interrupts = <27>;
+ num-cs = <3>;
+ };
+
+ i2c0: i2c@20330000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x20330000 0x0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ clocks = <&device_clk>;
+ interrupt-parent = <&plic>;
+ interrupts = <20>;
+ };
+
+ i2c1: i2c@20340000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x20340000 0x0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ clocks = <&device_clk>;
+ interrupt-parent = <&plic>;
+ interrupts = <21>;
+ };
+
+ i2c2: i2c@20430000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x20430000 0x0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ clocks = <&device_clk>;
+ interrupt-parent = <&plic>;
+ interrupts = <28>;
+ };
+
+ i2c3: i2c@20440000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x20440000 0x0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <400000>;
+ clocks = <&device_clk>;
+ interrupt-parent = <&plic>;
+ interrupts = <29>;
+ };
+
+ pcie_x16: pcie@21000000 {
+ compatible = "ultrarisc,dp1000-pcie";
+ reg = <0x0 0x21000000 0x0 0x01000000>,
+ <0x0 0x4fff0000 0x0 0x00010000>;
+ reg-names = "dbi", "config";
+ ranges = <0x81000000 0x0 0x4fbf0000 0x0 0x4fbf0000 0x0 0x00400000>,
+ <0x82000000 0x0 0x40000000 0x0 0x40000000 0x0 0x0fbf0000>,
+ <0xc3000000 0x40 0x00000000 0x40 0x00000000 0xd 0x00000000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ bus-range = <0x0 0xff>;
+ num-lanes = <16>;
+ interrupt-parent = <&plic>;
+ interrupts = <43>, <44>, <45>, <46>, <47>;
+ interrupt-names = "msi", "inta", "intb", "intc", "intd";
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &plic 44>,
+ <0x0 0x0 0x0 0x2 &plic 45>,
+ <0x0 0x0 0x0 0x3 &plic 46>,
+ <0x0 0x0 0x0 0x4 &plic 47>;
+ };
+
+ pcie_x4a: pcie@23000000 {
+ compatible = "ultrarisc,dp1000-pcie";
+ reg = <0x0 0x23000000 0x0 0x01000000>,
+ <0x0 0x6fff0000 0x0 0x00010000>;
+ reg-names = "dbi", "config";
+ ranges = <0x81000000 0x0 0x6fbf0000 0x0 0x6fbf0000 0x0 0x00400000>,
+ <0x82000000 0x0 0x60000000 0x0 0x60000000 0x0 0x0fbf0000>,
+ <0xc3000000 0x80 0x00000000 0x80 0x00000000 0xd 0x00000000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ bus-range = <0x0 0xff>;
+ num-lanes = <4>;
+ interrupt-parent = <&plic>;
+ interrupts = <63>, <64>, <65>, <66>, <67>;
+ interrupt-names = "msi", "inta", "intb", "intc", "intd";
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &plic 64>,
+ <0x0 0x0 0x0 0x2 &plic 65>,
+ <0x0 0x0 0x0 0x3 &plic 66>,
+ <0x0 0x0 0x0 0x4 &plic 67>;
+ };
+
+ pcie_x4b: pcie@24000000 {
+ compatible = "ultrarisc,dp1000-pcie";
+ reg = <0x0 0x24000000 0x0 0x01000000>,
+ <0x0 0x7fff0000 0x0 0x00010000>;
+ reg-names = "dbi", "config";
+ ranges = <0x81000000 0x0 0x7fbf0000 0x0 0x7fbf0000 0x0 0x00400000>,
+ <0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x0fbf0000>,
+ <0xc3000000 0xc0 0x00000000 0xc0 0x00000000 0xd 0x00000000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ dma-coherent;
+ bus-range = <0x0 0xff>;
+ num-lanes = <4>;
+ interrupt-parent = <&plic>;
+ interrupts = <73>, <74>, <75>, <76>, <77>;
+ interrupt-names = "msi", "inta", "intb", "intc", "intd";
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+ interrupt-map = <0x0 0x0 0x0 0x1 &plic 74>,
+ <0x0 0x0 0x0 0x2 &plic 75>,
+ <0x0 0x0 0x0 0x3 &plic 76>,
+ <0x0 0x0 0x0 0x4 &plic 77>;
+ };
+
+ ethernet: ethernet@38000000 {
+ compatible = "snps,dwmac", "snps,dwmac-5.10a";
+ reg = <0x00 0x38000000 0x00 0x1000000>;
+ clocks = <&csr_clk>;
+ clock-names = "stmmaceth";
+ interrupt-parent = <&plic>;
+ interrupts = <84>;
+ interrupt-names = "macirq";
+ local-mac-address = [ff ff ff ff ff ff];
+ max-speed = <1000>;
+ phy-mode = "rgmii-id";
+ snps,txpbl = <8>;
+ snps,rxpbl = <8>;
+ };
+
+ dmac: dma-controller@39000000 {
+ compatible = "snps,axi-dma-1.01a";
+ reg = <0x0 0x39000000 0x0 0x400>;
+ clocks = <&device_clk>, <&device_clk>;
+ clock-names = "core-clk", "cfgr-clk";
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ interrupt-parent = <&plic>;
+ interrupts = <152>;
+ snps,dma-masters = <1>;
+ snps,data-width = <4>;
+ snps,block-size = <512 512 512 512 512 512 512 512>;
+ snps,priority = <0 1 2 3 4 5 6 7>;
+ snps,axi-max-burst-len = <256>;
+ };
+ };
+};
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
2026-05-15 1:18 ` [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000 Jia Wang via B4 Relay
@ 2026-05-15 10:26 ` Conor Dooley
0 siblings, 0 replies; 16+ messages in thread
From: Conor Dooley @ 2026-05-15 10:26 UTC (permalink / raw)
To: Jia Wang
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland, Paul Walmsley,
Palmer Dabbelt, Conor Dooley, devicetree, linux-riscv,
linux-kernel, linux-gpio
[-- Attachment #1.1: Type: text/plain, Size: 8799 bytes --]
On Fri, May 15, 2026 at 09:18:01AM +0800, Jia Wang wrote:
> Add the base device tree for the UltraRISC DP1000 SoC. It describes the
> 8×CP100 CPU cores and essential SoC peripherals including the interrupt
> controller, pinctrl, GPIO, UART, SPI, I2C, PCIe, GMAC and the DMA
> controller.
>
> Link: https://lore.kernel.org/lkml/20260427-ultrarisc-pcie-v4-2-98935f6cdfb5@ultrarisc.com/
> Link: https://lore.kernel.org/lkml/20260429-ultrarisc-serial-v7-3-e475cce9e274@ultrarisc.com/
>
No blank line here FYI.
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---
> MAINTAINERS | 1 +
> arch/riscv/boot/dts/ultrarisc/dp1000.dtsi | 851 ++++++++++++++++++++++++++++++
> 2 files changed, 852 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index baaaa46b1a56..832e01898ae5 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -23087,6 +23087,7 @@ M: Jia Wang <wangjia@ultrarisc.com>
> L: linux-riscv@lists.infradead.org
> S: Maintained
> F: Documentation/devicetree/bindings/riscv/ultrarisc.yaml
> +F: arch/riscv/boot/dts/ultrarisc/
>
> RNBD BLOCK DRIVERS
> M: Md. Haris Iqbal <haris.iqbal@ionos.com>
> diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi b/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi
> new file mode 100644
> index 000000000000..1aae53fc1a2b
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi
> @@ -0,0 +1,851 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
> + */
> +
> +/dts-v1/;
> +
> +/ {
> + compatible = "ultrarisc,dp1000";
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + timebase-frequency = <10000000>;
> +
> + cpu0: cpu@0 {
> + compatible = "ultrarisc,cp100", "riscv";
> + reg = <0x0>;
> + device_type = "cpu";
> + riscv,isa = "rv64imafdcbh";
Drop this property, its replacements (below) should be supported by all
users.
> + riscv,isa-base = "rv64i";
> + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "h",
> + "zba", "zbb", "zbc", "zbs", "zicntr",
> + "zicsr", "zifencei", "zihpm", "ziccif",
> + "ziccrse", "ziccamoa", "za64rs", "zicbom",
> + "zicbop", "zicboz", "zkt", "svade",
> + "ssccptr", "sstvecd", "sscounterenw",
> + "shcounterenw", "shtvala", "shvstvecd",
> + "shvsatpa", "svvptc";
> + mmu-type = "riscv,sv48";
> + clock-frequency = <2000000000>;
> + /* L1 I-cache and D-cache:
FYI, the comment format outside of drivers/net/ has a newline after /*.
> + * block-size 64B
> + * 4-way set associative, size 64KB
> + * per-core.
> + */
> + d-cache-block-size = <64>;
> + d-cache-sets = <256>;
> + d-cache-size = <0x10000>;
> + i-cache-block-size = <64>;
> + i-cache-sets = <256>;
> + i-cache-size = <0x10000>;
> + next-level-cache = <&l2_cache0>;
> + riscv,cbom-block-size = <64>;
> + riscv,cboz-block-size = <64>;
> +
> + cpu0_intc: interrupt-controller {
> + compatible = "riscv,cpu-intc";
> + interrupt-controller;
> + #interrupt-cells = <0x01>;
> + };
> +
> + l2_cache0: l2-cache {
> + /* L2 cache:
> + * cache-unified, block-size 64B
> + * 8-way set associative, size 512KB
> + * per-core.
> + */
> + compatible = "cache";
> + cache-block-size = <64>;
> + cache-level = <2>;
> + cache-size = <0x80000>;
> + cache-sets = <1024>;
> + cache-unified;
> + next-level-cache = <&cluster0_l3>;
> + };
> + };
> + cpu4: cpu@4 {
> + compatible = "ultrarisc,cp100", "riscv";
> + reg = <0x10>;
Sashiko correctly pointed out that this is wrong.
> + cpu5: cpu@5 {
> + compatible = "ultrarisc,cp100", "riscv";
> + reg = <0x11>;
And so is this.
> + cpu6: cpu@6 {
> + compatible = "ultrarisc,cp100", "riscv";
> + reg = <0x12>;
And this.
> + cpu7: cpu@7 {
> + compatible = "ultrarisc,cp100", "riscv";
> + reg = <0x13>;
And this.
> + clocks {
I've commented on this in the cover letter.
> + device_clk: device_clk {
> + compatible = "fixed-clock";
> + clock-frequency = <62500000>;
> + #clock-cells = <0>;
> + };
> +
> + timer_clk: timer_clk {
> + compatible = "fixed-clock";
> + clock-frequency = <50000000>;
> + #clock-cells = <0>;
> + };
> +
> + csr_clk: csr_clk {
> + compatible = "fixed-clock";
> + clock-frequency = <250000000>;
> + #clock-cells = <0>;
> + };
> + };
> + memory@80000000 {
> + device_type = "memory";
> + reg = <0x00 0x80000000 0x4 0x00000000>;
> + };
This looks incorrectly placed, memory should be in the board dts unless
it is actually a part of the chip.
> +
> + soc {
> + compatible = "simple-bus";
> + ranges;
> + #address-cells = <0x02>;
> + #size-cells = <0x02>;
> +
> + clint: clint@8000000 {
> + compatible = "sifive,clint0", "riscv,clint0";
Missing a device-specific clint compatible.
> + reg = <0x00 0x8000000 0x00 0x100000>;
> + interrupts-extended = <&cpu0_intc 0x03>, <&cpu0_intc 0x07>,
> + <&cpu1_intc 0x03>, <&cpu1_intc 0x07>,
> + <&cpu2_intc 0x03>, <&cpu2_intc 0x07>,
> + <&cpu3_intc 0x03>, <&cpu3_intc 0x07>,
> + <&cpu4_intc 0x03>, <&cpu4_intc 0x07>,
> + <&cpu5_intc 0x03>, <&cpu5_intc 0x07>,
> + <&cpu6_intc 0x03>, <&cpu6_intc 0x07>,
> + <&cpu7_intc 0x03>, <&cpu7_intc 0x07>;
> + };
> +
> + plic: plic@9000000 {
> + compatible = "ultrarisc,dp1000-plic", "ultrarisc,cp100-plic";
> + reg = <0x00 0x9000000 0x00 0x4000000>;
> + #interrupt-cells = <1>;
> + #address-cells = <0>;
> + interrupt-controller;
> + interrupts-extended = <&cpu0_intc 0xb>, <&cpu0_intc 0x9>, <&cpu0_intc 0xa>,
> + <&cpu1_intc 0xb>, <&cpu1_intc 0x9>, <&cpu1_intc 0xa>,
> + <&cpu2_intc 0xb>, <&cpu2_intc 0x9>, <&cpu2_intc 0xa>,
> + <&cpu3_intc 0xb>, <&cpu3_intc 0x9>, <&cpu3_intc 0xa>,
> + <&cpu4_intc 0xb>, <&cpu4_intc 0x9>, <&cpu4_intc 0xa>,
> + <&cpu5_intc 0xb>, <&cpu5_intc 0x9>, <&cpu5_intc 0xa>,
> + <&cpu6_intc 0xb>, <&cpu6_intc 0x9>, <&cpu6_intc 0xa>,
> + <&cpu7_intc 0xb>, <&cpu7_intc 0x9>, <&cpu7_intc 0xa>;
> + riscv,ndev = <160>;
> + };
> +
> + pmx0: pinmux@11081000 {
> + compatible = "ultrarisc,dp1000-pinctrl";
> + reg = <0x0 0x11081000 0x0 0x1000>;
^^ extra space here btw
> + #pinctrl-cells = <2>;
> + };
> +
> + spi0: spi@20320000 {
> + compatible = "snps,dw-apb-ssi";
Missing a device-specific compatible here, can just fall abck to the
dw-apb-ssi one, so no need to make driver changes.
> + reg = <0x0 0x20320000 0x0 0x1000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + clocks = <&device_clk>;
> + interrupt-parent = <&plic>;
> + interrupts = <19>;
> + num-cs = <3>;
> + };
> +
> + i2c0: i2c@20330000 {
> + compatible = "snps,designware-i2c";
Same applies here.
> + reg = <0x0 0x20330000 0x0 0x100>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + clock-frequency = <400000>;
> + clocks = <&device_clk>;
> + interrupt-parent = <&plic>;
> + interrupts = <20>;
> + };
> +
> + ethernet: ethernet@38000000 {
> + compatible = "snps,dwmac", "snps,dwmac-5.10a";
Surprised this passes dtbs_check. Same here, you need a specific
compatible.
> + reg = <0x00 0x38000000 0x00 0x1000000>;
> + clocks = <&csr_clk>;
> + clock-names = "stmmaceth";
> + interrupt-parent = <&plic>;
> + interrupts = <84>;
> + interrupt-names = "macirq";
> + local-mac-address = [ff ff ff ff ff ff];
> + max-speed = <1000>;
> + phy-mode = "rgmii-id";
> + snps,txpbl = <8>;
> + snps,rxpbl = <8>;
> + };
> +
> + dmac: dma-controller@39000000 {
> + compatible = "snps,axi-dma-1.01a";
Same thing here, I'd like to see a device specific compatible too.
> + reg = <0x0 0x39000000 0x0 0x400>;
> + clocks = <&device_clk>, <&device_clk>;
This kind of thing is what makes me think that you're over simplifying
your clock tree. Sure, maybe you do use the same clock here for both
ports, but it's suspect.
Cheers,
Conor.
> + clock-names = "core-clk", "cfgr-clk";
> + #dma-cells = <1>;
> + dma-channels = <8>;
> + interrupt-parent = <&plic>;
> + interrupts = <152>;
> + snps,dma-masters = <1>;
> + snps,data-width = <4>;
> + snps,block-size = <512 512 512 512 512 512 512 512>;
> + snps,priority = <0 1 2 3 4 5 6 7>;
> + snps,axi-max-burst-len = <256>;
> + };
> + };
> +};
>
> --
> 2.34.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 6/9] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
` (4 preceding siblings ...)
2026-05-15 1:18 ` [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000 Jia Wang via B4 Relay
@ 2026-05-15 1:18 ` Jia Wang via B4 Relay
2026-05-15 1:18 ` [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree Jia Wang via B4 Relay
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Add pinctrl driver for UltraRISC DP1000 pinctrl controller.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
MAINTAINERS | 1 +
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/ultrarisc/Kconfig | 23 +
drivers/pinctrl/ultrarisc/Makefile | 4 +
drivers/pinctrl/ultrarisc/pinctrl-dp1000.c | 112 ++++
drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c | 746 ++++++++++++++++++++++++++
drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h | 71 +++
8 files changed, 959 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 832e01898ae5..ecd87d58f28c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -27364,6 +27364,7 @@ M: Jia Wang <wangjia@ultrarisc.com>
L: linux-gpio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml
+F: drivers/pinctrl/ultrarisc/*
F: include/dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h
ULTRATRONIK BOARD SUPPORT
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 03f2e3ee065f..76105be8b395 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -711,5 +711,6 @@ source "drivers/pinctrl/ti/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
source "drivers/pinctrl/visconti/Kconfig"
source "drivers/pinctrl/vt8500/Kconfig"
+source "drivers/pinctrl/ultrarisc/Kconfig"
endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f7d5d5f76d0c..4df3e52518ea 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -98,3 +98,4 @@ obj-y += ti/
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_PINCTRL_VISCONTI) += visconti/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
+obj-$(CONFIG_ARCH_ULTRARISC) += ultrarisc/
diff --git a/drivers/pinctrl/ultrarisc/Kconfig b/drivers/pinctrl/ultrarisc/Kconfig
new file mode 100644
index 000000000000..ba8747b90127
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/Kconfig
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config PINCTRL_ULTRARISC
+ tristate
+ depends on OF
+ select PINMUX
+ select GENERIC_PINCTRL_GROUPS
+ select GENERIC_PINCONF
+ select GENERIC_PINMUX_FUNCTIONS
+ select GPIOLIB
+ select IRQ_DOMAIN_HIERARCHY
+ select MFD_SYSCON
+
+config PINCTRL_ULTRARISC_DP1000
+ tristate "UltraRISC DP1000 SoC Pinctrl driver"
+ select PINCTRL_ULTRARISC
+ depends on OF && HAS_IOMEM
+ default ARCH_ULTRARISC
+ help
+ Say Y to select the pinctrl driver for UltraRISC DP1000 SoC.
+ This pin controller allows selecting the mux function for
+ each pin. This driver can also be built as a module called
+ pinctrl-dp1000.
diff --git a/drivers/pinctrl/ultrarisc/Makefile b/drivers/pinctrl/ultrarisc/Makefile
new file mode 100644
index 000000000000..5d49ce1c0af9
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_PINCTRL_ULTRARISC) += pinctrl-ultrarisc.o
+obj-$(CONFIG_PINCTRL_ULTRARISC_DP1000) += pinctrl-dp1000.o
diff --git a/drivers/pinctrl/ultrarisc/pinctrl-dp1000.c b/drivers/pinctrl/ultrarisc/pinctrl-dp1000.c
new file mode 100644
index 000000000000..23b6cc512031
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/pinctrl-dp1000.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ *
+ * Author: Jia Wang <wangjia@ultrarisc.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-ultrarisc.h"
+
+static const struct pinctrl_pin_desc ur_dp1000_pins[] = {
+ PINCTRL_PIN(0, "PA0"),
+ PINCTRL_PIN(1, "PA1"),
+ PINCTRL_PIN(2, "PA2"),
+ PINCTRL_PIN(3, "PA3"),
+ PINCTRL_PIN(4, "PA4"),
+ PINCTRL_PIN(5, "PA5"),
+ PINCTRL_PIN(6, "PA6"),
+ PINCTRL_PIN(7, "PA7"),
+ PINCTRL_PIN(8, "PA8"),
+ PINCTRL_PIN(9, "PA9"),
+ PINCTRL_PIN(10, "PA10"),
+ PINCTRL_PIN(11, "PA11"),
+ PINCTRL_PIN(12, "PA12"),
+ PINCTRL_PIN(13, "PA13"),
+ PINCTRL_PIN(14, "PA14"),
+ PINCTRL_PIN(15, "PA15"),
+ PINCTRL_PIN(16, "PB0"),
+ PINCTRL_PIN(17, "PB1"),
+ PINCTRL_PIN(18, "PB2"),
+ PINCTRL_PIN(19, "PB3"),
+ PINCTRL_PIN(20, "PB4"),
+ PINCTRL_PIN(21, "PB5"),
+ PINCTRL_PIN(22, "PB6"),
+ PINCTRL_PIN(23, "PB7"),
+ PINCTRL_PIN(24, "PC0"),
+ PINCTRL_PIN(25, "PC1"),
+ PINCTRL_PIN(26, "PC2"),
+ PINCTRL_PIN(27, "PC3"),
+ PINCTRL_PIN(28, "PC4"),
+ PINCTRL_PIN(29, "PC5"),
+ PINCTRL_PIN(30, "PC6"),
+ PINCTRL_PIN(31, "PC7"),
+ PINCTRL_PIN(32, "PD0"),
+ PINCTRL_PIN(33, "PD1"),
+ PINCTRL_PIN(34, "PD2"),
+ PINCTRL_PIN(35, "PD3"),
+ PINCTRL_PIN(36, "PD4"),
+ PINCTRL_PIN(37, "PD5"),
+ PINCTRL_PIN(38, "PD6"),
+ PINCTRL_PIN(39, "PD7"),
+ PINCTRL_PIN(40, "LPC0"),
+ PINCTRL_PIN(41, "LPC1"),
+ PINCTRL_PIN(42, "LPC2"),
+ PINCTRL_PIN(43, "LPC3"),
+ PINCTRL_PIN(44, "LPC4"),
+ PINCTRL_PIN(45, "LPC5"),
+ PINCTRL_PIN(46, "LPC6"),
+ PINCTRL_PIN(47, "LPC7"),
+ PINCTRL_PIN(48, "LPC8"),
+ PINCTRL_PIN(49, "LPC9"),
+ PINCTRL_PIN(50, "LPC10"),
+ PINCTRL_PIN(51, "LPC11"),
+ PINCTRL_PIN(52, "LPC12"),
+};
+
+static const struct ur_function_desc ur_dp1000_functions[] = {
+ { "gpio", UR_FUNC_DEF, true },
+ { "func0", UR_FUNC0, false },
+ { "func1", UR_FUNC1, false },
+};
+
+#define UR_DP1000_PORT(_name, _npins, _func, _conf, _modes) \
+ { .name = (_name), .npins = (_npins), .func_offset = (_func), \
+ .conf_offset = (_conf), .supported_modes = (_modes) }
+
+static const struct ur_pinctrl_match_data ur_dp1000_match_data = {
+ .pins = ur_dp1000_pins,
+ .npins = ARRAY_SIZE(ur_dp1000_pins),
+ .functions = ur_dp1000_functions,
+ .num_functions = ARRAY_SIZE(ur_dp1000_functions),
+ .num_ports = 5,
+ .ports = {
+ UR_DP1000_PORT("A", 16, 0x2c0, 0x310, UR_FUNC0 | UR_FUNC1),
+ UR_DP1000_PORT("B", 8, 0x2c4, 0x318, UR_FUNC0 | UR_FUNC1),
+ UR_DP1000_PORT("C", 8, 0x2c8, 0x31c, UR_FUNC0 | UR_FUNC1),
+ UR_DP1000_PORT("D", 8, 0x2cc, 0x320, UR_FUNC0 | UR_FUNC1),
+ UR_DP1000_PORT("LPC", 13, 0x2d0, 0x324, UR_FUNC0),
+ },
+};
+
+static const struct of_device_id ur_pinctrl_of_match[] = {
+ { .compatible = "ultrarisc,dp1000-pinctrl", .data = &ur_dp1000_match_data, },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ur_pinctrl_of_match);
+
+static struct platform_driver ur_pinctrl_driver = {
+ .driver = {
+ .name = "ultrarisc-pinctrl-dp1000",
+ .of_match_table = ur_pinctrl_of_match,
+ },
+ .probe = ur_pinctrl_probe,
+};
+
+module_platform_driver(ur_pinctrl_driver);
+
+MODULE_DESCRIPTION("UltraRISC DP1000 pinctrl driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c
new file mode 100644
index 000000000000..774746943e28
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c
@@ -0,0 +1,746 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ *
+ * Author: Jia Wang <wangjia@ultrarisc.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../devicetree.h"
+#include "../pinconf.h"
+#include "../pinctrl-utils.h"
+#include "../pinmux.h"
+
+#include "pinctrl-ultrarisc.h"
+
+#define UR_CONF_BIT_PER_PIN 4
+#define UR_CONF_PIN_PER_REG (32 / UR_CONF_BIT_PER_PIN)
+static const int ur_drive_strengths[] = { 20, 27, 33, 40 };
+
+static int ur_pin_num_to_port_pin(const struct ur_pinctrl_match_data *match_data,
+ struct ur_pin_val *pin_val, u32 pin_num)
+{
+ for (u32 i = 0; i < match_data->num_ports; i++) {
+ if (pin_num < match_data->ports[i].npins) {
+ pin_val->port = i;
+ pin_val->pin = pin_num;
+ return 0;
+ }
+ pin_num -= match_data->ports[i].npins;
+ }
+
+ return -EINVAL;
+}
+
+static int ur_pin_to_desc(struct pinctrl_dev *pctldev, struct ur_pin_val *pin_val)
+{
+ struct ur_pinctrl *ur_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+ int index = 0;
+
+ for (u32 i = 0; i < pin_val->port; i++)
+ index += ur_pinctrl->match_data->ports[i].npins;
+
+ return index + pin_val->pin;
+}
+
+static u32 ur_get_pin_conf_offset(const struct ur_port_desc *port_desc, u32 pin)
+{
+ return port_desc->conf_offset +
+ (pin / UR_CONF_PIN_PER_REG) * sizeof(u32);
+}
+
+static u32 ur_read_pin_conf(struct ur_pinctrl *pctldata, unsigned int pin)
+{
+ const struct ur_port_desc *port_desc;
+ struct ur_pin_val pin_val;
+ u32 reg_offset;
+ u32 shift;
+ u32 conf;
+ u32 mask;
+
+ if (ur_pin_num_to_port_pin(pctldata->match_data, &pin_val, pin))
+ return 0;
+
+ port_desc = &pctldata->match_data->ports[pin_val.port];
+ reg_offset = ur_get_pin_conf_offset(port_desc, pin_val.pin);
+ shift = (pin_val.pin % UR_CONF_PIN_PER_REG) * UR_CONF_BIT_PER_PIN;
+ mask = GENMASK(UR_CONF_BIT_PER_PIN - 1, 0) << shift;
+ conf = field_get(mask, readl_relaxed(pctldata->base + reg_offset));
+
+ return conf;
+}
+
+static int ur_write_pin_conf(struct ur_pinctrl *pctldata, unsigned int pin, u32 conf)
+{
+ const struct ur_port_desc *port_desc;
+ struct ur_pin_val pin_val;
+ unsigned long flags;
+ void __iomem *reg;
+ u32 reg_offset;
+ u32 val;
+ u32 shift;
+ u32 mask;
+
+ if (ur_pin_num_to_port_pin(pctldata->match_data, &pin_val, pin))
+ return -EINVAL;
+
+ port_desc = &pctldata->match_data->ports[pin_val.port];
+ reg_offset = ur_get_pin_conf_offset(port_desc, pin_val.pin);
+ reg = pctldata->base + reg_offset;
+ shift = (pin_val.pin % UR_CONF_PIN_PER_REG) * UR_CONF_BIT_PER_PIN;
+ mask = GENMASK(UR_CONF_BIT_PER_PIN - 1, 0) << shift;
+
+ raw_spin_lock_irqsave(&pctldata->lock, flags);
+ val = readl_relaxed(reg);
+ val = (val & ~mask) | field_prep(mask, conf);
+ writel_relaxed(val, reg);
+ raw_spin_unlock_irqrestore(&pctldata->lock, flags);
+
+ return 0;
+}
+
+static int ur_set_pin_mux(struct ur_pinctrl *pctldata, struct ur_pin_val *pin_val)
+{
+ const struct ur_port_desc *port_desc = &pctldata->match_data->ports[pin_val->port];
+ void __iomem *reg = pctldata->base + port_desc->func_offset;
+ unsigned long flags;
+ u32 val;
+
+ raw_spin_lock_irqsave(&pctldata->lock, flags);
+ val = readl_relaxed(reg);
+ val &= ~((UR_FUNC0 | UR_FUNC1) << pin_val->pin);
+ val |= pin_val->mode << pin_val->pin;
+ writel_relaxed(val, reg);
+ raw_spin_unlock_irqrestore(&pctldata->lock, flags);
+
+ return 0;
+}
+
+static int ur_set_pin_mux_by_num(struct ur_pinctrl *pctldata, unsigned int pin, u32 mode)
+{
+ struct ur_pin_val pin_val = { .mode = mode };
+ const struct ur_port_desc *port_desc;
+ int ret;
+
+ ret = ur_pin_num_to_port_pin(pctldata->match_data, &pin_val, pin);
+ if (ret)
+ return ret;
+
+ port_desc = &pctldata->match_data->ports[pin_val.port];
+ if (mode != UR_FUNC_DEF && !(port_desc->supported_modes & mode))
+ return -EINVAL;
+
+ return ur_set_pin_mux(pctldata, &pin_val);
+}
+
+static int ur_hw_to_config(unsigned long *config, u32 conf)
+{
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 drive = FIELD_GET(UR_DRIVE_MASK, conf);
+ u32 pull = FIELD_GET(UR_PULL_MASK, conf);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+ if (pull != UR_PULL_DIS)
+ return -EINVAL;
+ *config = pinconf_to_config_packed(param, 1);
+ return 0;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (pull != UR_PULL_UP)
+ return -EINVAL;
+ *config = pinconf_to_config_packed(param, 1);
+ return 0;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+ if (pull != UR_PULL_DOWN)
+ return -EINVAL;
+ *config = pinconf_to_config_packed(param, 1);
+ return 0;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ if (drive >= ARRAY_SIZE(ur_drive_strengths))
+ return -EINVAL;
+ *config = pinconf_to_config_packed(param, ur_drive_strengths[drive]);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ur_config_to_hw(unsigned long config, u32 *conf)
+{
+ enum pin_config_param param = pinconf_to_config_param(config);
+ u32 arg = pinconf_to_config_argument(config);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+ FIELD_MODIFY(UR_PULL_MASK, conf, UR_PULL_DIS);
+ return 0;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ FIELD_MODIFY(UR_PULL_MASK, conf, UR_PULL_UP);
+ return 0;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+ FIELD_MODIFY(UR_PULL_MASK, conf, UR_PULL_DOWN);
+ return 0;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ for (u32 i = 0; i < ARRAY_SIZE(ur_drive_strengths); i++) {
+ if (ur_drive_strengths[i] != arg)
+ continue;
+ FIELD_MODIFY(UR_DRIVE_MASK, conf, i);
+ return 0;
+ }
+ return -EINVAL;
+ case PIN_CONFIG_DRIVE_PUSH_PULL:
+ case PIN_CONFIG_INPUT_ENABLE:
+ case PIN_CONFIG_OUTPUT_ENABLE:
+ case PIN_CONFIG_PERSIST_STATE:
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+struct ur_legacy_prop_data {
+ struct ur_pin_val *pin_vals;
+ unsigned int *group_pins;
+ unsigned int num_pins;
+};
+
+static int ur_legacy_parse_prop(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ const char *propname,
+ struct ur_legacy_prop_data *prop)
+{
+ struct ur_pinctrl *pctldata = pinctrl_dev_get_drvdata(pctldev);
+ int rows;
+
+ rows = pinctrl_count_index_with_args(np, propname);
+ if (rows < 0)
+ return dev_err_probe(pctldev->dev, rows, "%pOF: invalid %s count\n",
+ np, propname);
+
+ prop->pin_vals = devm_kcalloc(pctldev->dev, rows, sizeof(*prop->pin_vals),
+ GFP_KERNEL);
+ if (!prop->pin_vals)
+ return -ENOMEM;
+
+ prop->group_pins = devm_kcalloc(pctldev->dev, rows, sizeof(*prop->group_pins),
+ GFP_KERNEL);
+ if (!prop->group_pins)
+ return -ENOMEM;
+
+ prop->num_pins = rows;
+
+ for (int i = 0; i < rows; i++) {
+ struct of_phandle_args pin_args;
+ int ret;
+
+ ret = pinctrl_parse_index_with_args(np, propname, i, &pin_args);
+ if (ret)
+ return dev_err_probe(pctldev->dev, ret,
+ "%pOF: failed to parse %s[%d]\n",
+ np, propname, i);
+
+ if (pin_args.args_count != 3)
+ return dev_err_probe(pctldev->dev, -EINVAL,
+ "%pOF: invalid %s[%d] args_count=%d\n",
+ np, propname, i, pin_args.args_count);
+
+ prop->pin_vals[i].port = pin_args.args[0];
+ prop->pin_vals[i].pin = pin_args.args[1];
+ prop->pin_vals[i].mode = pin_args.args[2];
+
+ if (prop->pin_vals[i].port >= pctldata->match_data->num_ports)
+ return dev_err_probe(pctldev->dev, -EINVAL,
+ "%pOF: invalid %s[%d] port=%u\n",
+ np, propname, i, prop->pin_vals[i].port);
+
+ if (prop->pin_vals[i].pin >=
+ pctldata->match_data->ports[prop->pin_vals[i].port].npins)
+ return dev_err_probe(pctldev->dev, -EINVAL,
+ "%pOF: invalid %s[%d] pin=%u\n",
+ np, propname, i, prop->pin_vals[i].pin);
+
+ prop->group_pins[i] = ur_pin_to_desc(pctldev, &prop->pin_vals[i]);
+ }
+
+ return 0;
+}
+
+static const char *ur_legacy_get_function_name(const struct ur_pinctrl_match_data *match_data,
+ u32 mode)
+{
+ for (u32 i = 0; i < match_data->num_functions; i++) {
+ if (match_data->functions[i].mode == mode)
+ return match_data->functions[i].name;
+ }
+
+ return NULL;
+}
+
+static int ur_legacy_conf_to_configs(struct pinctrl_dev *pctldev, u32 conf,
+ unsigned long **configs,
+ unsigned int *num_configs)
+{
+ u32 drive = FIELD_GET(UR_DRIVE_MASK, conf);
+ u32 pull = FIELD_GET(UR_PULL_MASK, conf);
+ unsigned long config;
+ int ret;
+
+ switch (pull) {
+ case UR_PULL_DIS:
+ config = pinconf_to_config_packed(PIN_CONFIG_BIAS_DISABLE, 1);
+ break;
+ case UR_PULL_UP:
+ config = pinconf_to_config_packed(PIN_CONFIG_BIAS_PULL_UP, 1);
+ break;
+ case UR_PULL_DOWN:
+ config = pinconf_to_config_packed(PIN_CONFIG_BIAS_PULL_DOWN, 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = pinctrl_utils_add_config(pctldev, configs, num_configs, config);
+ if (ret)
+ return ret;
+
+ if (drive >= ARRAY_SIZE(ur_drive_strengths))
+ return -EINVAL;
+
+ config = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
+ ur_drive_strengths[drive]);
+
+ return pinctrl_utils_add_config(pctldev, configs, num_configs, config);
+}
+
+static int ur_legacy_add_mux_maps(struct pinctrl_dev *pctldev,
+ struct pinctrl_map **map,
+ unsigned int *reserved_maps,
+ unsigned int *num_maps,
+ const struct ur_legacy_prop_data *prop)
+{
+ struct ur_pinctrl *pctldata = pinctrl_dev_get_drvdata(pctldev);
+
+ for (u32 i = 0; i < prop->num_pins; i++) {
+ const char *function;
+ const char *group;
+ int ret;
+
+ function = ur_legacy_get_function_name(pctldata->match_data,
+ prop->pin_vals[i].mode);
+ if (!function)
+ return -EINVAL;
+
+ group = pctldata->match_data->pins[prop->group_pins[i]].name;
+ if (!group)
+ return -EINVAL;
+
+ ret = pinctrl_utils_add_map_mux(pctldev, map, reserved_maps,
+ num_maps, group, function);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ur_legacy_add_pinconf_maps(struct pinctrl_dev *pctldev,
+ struct pinctrl_map **map,
+ unsigned int *reserved_maps,
+ unsigned int *num_maps,
+ const struct ur_legacy_prop_data *prop)
+{
+ struct ur_pinctrl *pctldata = pinctrl_dev_get_drvdata(pctldev);
+
+ for (u32 i = 0; i < prop->num_pins; i++) {
+ unsigned long *configs = NULL;
+ unsigned int num_configs = 0;
+ const char *group;
+ int ret;
+
+ ret = ur_legacy_conf_to_configs(pctldev, prop->pin_vals[i].conf,
+ &configs, &num_configs);
+ if (ret)
+ goto err;
+
+ group = pctldata->match_data->pins[prop->group_pins[i]].name;
+ if (!group) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ ret = pinctrl_utils_add_map_configs(pctldev, map, reserved_maps,
+ num_maps, group, configs,
+ num_configs,
+ PIN_MAP_TYPE_CONFIGS_PIN);
+err:
+ kfree(configs);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ur_legacy_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ struct pinctrl_map **map,
+ unsigned int *num_maps)
+{
+ struct ur_legacy_prop_data conf_prop = {};
+ struct ur_legacy_prop_data mux_prop = {};
+ struct pinctrl_map *new_map = NULL;
+ unsigned int reserved_maps = 0;
+ unsigned int total_maps = 0;
+ bool conf_present = false;
+ bool mux_present = false;
+ unsigned int map_num = 0;
+ int ret;
+
+ if (of_property_present(np, "pinctrl-pins"))
+ mux_present = true;
+ if (of_property_present(np, "pinconf-pins"))
+ conf_present = true;
+ if (!mux_present && !conf_present)
+ return -EINVAL;
+
+ if (mux_present) {
+ ret = ur_legacy_parse_prop(pctldev, np, "pinctrl-pins", &mux_prop);
+ if (ret)
+ goto err;
+ total_maps += mux_prop.num_pins;
+ }
+
+ if (conf_present) {
+ ret = ur_legacy_parse_prop(pctldev, np, "pinconf-pins", &conf_prop);
+ if (ret)
+ goto err;
+ total_maps += conf_prop.num_pins;
+ }
+
+ ret = pinctrl_utils_reserve_map(pctldev, &new_map, &reserved_maps,
+ &map_num, total_maps);
+ if (ret)
+ goto err;
+
+ if (mux_present) {
+ ret = ur_legacy_add_mux_maps(pctldev, &new_map, &reserved_maps,
+ &map_num, &mux_prop);
+ if (ret)
+ goto err;
+ }
+
+ if (conf_present) {
+ ret = ur_legacy_add_pinconf_maps(pctldev, &new_map, &reserved_maps,
+ &map_num, &conf_prop);
+ if (ret)
+ goto err;
+ }
+
+ *map = new_map;
+ *num_maps = map_num;
+
+ return 0;
+
+err:
+ pinctrl_utils_free_map(pctldev, new_map, map_num);
+ return ret;
+}
+
+static int ur_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map,
+ unsigned int *num_maps)
+{
+ return pinconf_generic_dt_node_to_map(pctldev, np_config, map, num_maps,
+ PIN_MAP_TYPE_INVALID);
+}
+
+static int ur_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np,
+ struct pinctrl_map **map,
+ unsigned int *num_maps)
+{
+ bool legacy = of_property_present(np, "pinctrl-pins") ||
+ of_property_present(np, "pinconf-pins");
+ bool generic = of_property_present(np, "pins");
+
+ if (legacy && generic) {
+ dev_err(pctldev->dev,
+ "%pOF: mixed legacy and generic pinctrl properties are not supported\n",
+ np);
+ return -EINVAL;
+ }
+
+ if (generic)
+ return ur_generic_dt_node_to_map(pctldev, np, map, num_maps);
+
+ if (legacy)
+ return ur_legacy_dt_node_to_map(pctldev, np, map, num_maps);
+
+ return -EINVAL;
+}
+
+static void ur_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map,
+ unsigned int num_maps)
+{
+ pinctrl_utils_free_map(pctldev, map, num_maps);
+}
+
+static void ur_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned int offset)
+{
+ seq_printf(s, "%s", dev_name(pctldev->dev));
+}
+
+static const struct pinctrl_ops ur_pinctrl_ops = {
+ .get_groups_count = pinctrl_generic_get_group_count,
+ .get_group_name = pinctrl_generic_get_group_name,
+ .get_group_pins = pinctrl_generic_get_group_pins,
+ .dt_node_to_map = ur_dt_node_to_map,
+ .dt_free_map = ur_dt_free_map,
+ .pin_dbg_show = ur_pin_dbg_show,
+};
+
+static int ur_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int offset)
+{
+ struct ur_pinctrl *pctldata = pinctrl_dev_get_drvdata(pctldev);
+
+ (void)range;
+
+ return ur_set_pin_mux_by_num(pctldata, offset, UR_FUNC_DEF);
+}
+
+static int ur_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
+ unsigned int group_selector)
+{
+ struct ur_pinctrl *pctldata = pinctrl_dev_get_drvdata(pctldev);
+ const struct ur_function_desc *desc;
+ const struct function_desc *func;
+ const unsigned int *pins;
+ unsigned int npins;
+ int ret;
+
+ func = pinmux_generic_get_function(pctldev, func_selector);
+ if (!func || !func->data)
+ return -EINVAL;
+
+ desc = func->data;
+ ret = pinctrl_generic_get_group_pins(pctldev, group_selector, &pins, &npins);
+ if (ret)
+ return ret;
+
+ for (u32 i = 0; i < npins; i++) {
+ ret = ur_set_pin_mux_by_num(pctldata, pins[i], desc->mode);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct pinmux_ops ur_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 = ur_set_mux,
+ .gpio_request_enable = ur_gpio_request_enable,
+ .strict = true,
+};
+
+static int ur_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *config)
+{
+ struct ur_pinctrl *pctldata = pinctrl_dev_get_drvdata(pctldev);
+
+ return ur_hw_to_config(config, ur_read_pin_conf(pctldata, pin));
+}
+
+static int ur_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct ur_pinctrl *pctldata = pinctrl_dev_get_drvdata(pctldev);
+ u32 conf = ur_read_pin_conf(pctldata, pin);
+ int ret;
+
+ for (u32 i = 0; i < num_configs; i++) {
+ ret = ur_config_to_hw(configs[i], &conf);
+ if (ret)
+ return ret;
+ }
+
+ return ur_write_pin_conf(pctldata, pin, conf);
+}
+
+static int ur_pin_config_group_get(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *config)
+{
+ const unsigned int *pins;
+ unsigned int npins;
+ int ret;
+
+ ret = pinctrl_generic_get_group_pins(pctldev, selector, &pins, &npins);
+ if (ret || !npins)
+ return ret ?: -EINVAL;
+
+ return ur_pin_config_get(pctldev, pins[0], config);
+}
+
+static int ur_pin_config_group_set(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ const unsigned int *pins;
+ unsigned int npins;
+ int ret;
+
+ ret = pinctrl_generic_get_group_pins(pctldev, selector, &pins, &npins);
+ if (ret)
+ return ret;
+
+ for (u32 i = 0; i < npins; i++) {
+ ret = ur_pin_config_set(pctldev, pins[i], configs, num_configs);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct pinconf_ops ur_pinconf_ops = {
+ .pin_config_get = ur_pin_config_get,
+ .pin_config_set = ur_pin_config_set,
+ .pin_config_group_get = ur_pin_config_group_get,
+ .pin_config_group_set = ur_pin_config_group_set,
+#ifdef CONFIG_GENERIC_PINCONF
+ .is_generic = true,
+#endif
+};
+
+static int ur_add_pin_groups(struct ur_pinctrl *pctldata)
+{
+ for (u32 i = 0; i < pctldata->match_data->npins; i++) {
+ int ret;
+
+ pctldata->group_names[i] = pctldata->match_data->pins[i].name;
+ pctldata->group_pins[i] = pctldata->match_data->pins[i].number;
+
+ ret = pinctrl_generic_add_group(pctldata->pctl_dev, pctldata->group_names[i],
+ &pctldata->group_pins[i], 1, NULL);
+ if (ret < 0)
+ return dev_err_probe(pctldata->dev, ret,
+ "failed to add pin group %s\n",
+ pctldata->group_names[i]);
+ }
+
+ return 0;
+}
+
+static int ur_add_functions(struct ur_pinctrl *pctldata)
+{
+ for (u32 i = 0; i < pctldata->match_data->num_functions; i++) {
+ const struct ur_function_desc *desc = &pctldata->match_data->functions[i];
+ struct pinfunction func = desc->gpio ?
+ PINCTRL_GPIO_PINFUNCTION(desc->name, pctldata->group_names,
+ pctldata->match_data->npins) :
+ PINCTRL_PINFUNCTION(desc->name, pctldata->group_names,
+ pctldata->match_data->npins);
+ int ret;
+
+ ret = pinmux_generic_add_pinfunction(pctldata->pctl_dev, &func, (void *)desc);
+ if (ret < 0)
+ return dev_err_probe(pctldata->dev, ret,
+ "failed to add function %s\n",
+ desc->name);
+ }
+
+ return 0;
+}
+
+int ur_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct ur_pinctrl_match_data *match_data;
+ struct ur_pinctrl *pctldata;
+ struct pinctrl_desc *desc;
+ int ret;
+
+ match_data = of_device_get_match_data(&pdev->dev);
+ if (!match_data)
+ return -ENODEV;
+
+ desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ pctldata = devm_kzalloc(&pdev->dev, sizeof(*pctldata), GFP_KERNEL);
+ if (!pctldata)
+ return -ENOMEM;
+
+ pctldata->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pctldata->base))
+ return PTR_ERR(pctldata->base);
+ pctldata->dev = &pdev->dev;
+ pctldata->match_data = match_data;
+ pctldata->group_names = devm_kcalloc(&pdev->dev, match_data->npins,
+ sizeof(*pctldata->group_names), GFP_KERNEL);
+ if (!pctldata->group_names)
+ return -ENOMEM;
+
+ pctldata->group_pins = devm_kcalloc(&pdev->dev, match_data->npins,
+ sizeof(*pctldata->group_pins), GFP_KERNEL);
+ if (!pctldata->group_pins)
+ return -ENOMEM;
+
+ raw_spin_lock_init(&pctldata->lock);
+
+ desc->name = dev_name(&pdev->dev);
+ desc->owner = THIS_MODULE;
+ desc->pins = match_data->pins;
+ desc->npins = match_data->npins;
+ desc->pctlops = &ur_pinctrl_ops;
+ desc->pmxops = &ur_pinmux_ops;
+ desc->confops = &ur_pinconf_ops;
+
+ ret = devm_pinctrl_register_and_init(&pdev->dev, desc, pctldata, &pctldata->pctl_dev);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "failed to register pinctrl\n");
+
+ ret = ur_add_pin_groups(pctldata);
+ if (ret)
+ return ret;
+
+ ret = ur_add_functions(pctldata);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, pctldata);
+
+ return pinctrl_enable(pctldata->pctl_dev);
+}
+EXPORT_SYMBOL_GPL(ur_pinctrl_probe);
+
+MODULE_DESCRIPTION("UltraRISC pinctrl core driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h
new file mode 100644
index 000000000000..25291f18c950
--- /dev/null
+++ b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ *
+ * Author: Jia Wang <wangjia@ultrarisc.com>
+ */
+
+#ifndef __PINCTRL_ULTRARISC_H__
+#define __PINCTRL_ULTRARISC_H__
+
+#include <linux/io.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/spinlock.h>
+
+struct platform_device;
+
+struct ur_pin_val {
+ u32 port;
+ u32 pin;
+ union {
+ u32 mode;
+ u32 conf;
+ };
+#define UR_FUNC_DEF 0
+#define UR_FUNC0 1
+#define UR_FUNC1 0x10000
+
+#define UR_BIAS_MASK 0x0000000F
+#define UR_PULL_MASK 0x0C
+#define UR_PULL_DIS 0
+#define UR_PULL_UP 1
+#define UR_PULL_DOWN 2
+#define UR_DRIVE_MASK 0x03
+};
+
+struct ur_port_desc {
+ const char *name;
+ u32 npins;
+ u32 func_offset;
+ u32 conf_offset;
+ u32 supported_modes;
+};
+
+struct ur_function_desc {
+ const char *name;
+ u32 mode;
+ bool gpio;
+};
+
+struct ur_pinctrl_match_data {
+ const struct pinctrl_pin_desc *pins;
+ u32 npins;
+ const struct ur_function_desc *functions;
+ u32 num_functions;
+ u32 num_ports;
+ struct ur_port_desc ports[];
+};
+
+struct ur_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctl_dev;
+ void __iomem *base;
+ const struct ur_pinctrl_match_data *match_data;
+ raw_spinlock_t lock;
+ const char **group_names;
+ unsigned int *group_pins;
+};
+
+int ur_pinctrl_probe(struct platform_device *pdev);
+
+#endif
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
` (5 preceding siblings ...)
2026-05-15 1:18 ` [PATCH 6/9] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver Jia Wang via B4 Relay
@ 2026-05-15 1:18 ` Jia Wang via B4 Relay
2026-05-15 10:28 ` Conor Dooley
2026-05-15 1:18 ` [PATCH 8/9] riscv: dts: ultrarisc: add Milk-V Titan " Jia Wang via B4 Relay
` (2 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Rongda M0 is an mATX motherboard based on the UltraRISC DP1000 SoC.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
arch/riscv/boot/dts/Makefile | 1 +
arch/riscv/boot/dts/ultrarisc/Makefile | 2 +
.../dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi | 85 ++++++++++++++++
arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts | 111 +++++++++++++++++++++
4 files changed, 199 insertions(+)
diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index 69d8751fb17c..702882974251 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 += ultrarisc
diff --git a/arch/riscv/boot/dts/ultrarisc/Makefile b/arch/riscv/boot/dts/ultrarisc/Makefile
new file mode 100644
index 000000000000..d01a770d3cba
--- /dev/null
+++ b/arch/riscv/boot/dts/ultrarisc/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_ULTRARISC) += dp1000-rongda-m0.dtb
diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi
new file mode 100644
index 000000000000..101b416b1079
--- /dev/null
+++ b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ */
+
+#include "dp1000.dtsi"
+
+&pmx0 {
+ i2c0_pins: i2c0-pins {
+ pins = "PA12", "PA13";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ i2c1_pins: i2c1-pins {
+ pins = "PB6", "PB7";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ i2c2_pins: i2c2-pins {
+ pins = "PC0", "PC1";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ i2c3_pins: i2c3-pins {
+ pins = "PC2", "PC3";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ pciex4a_link_pins: pciex4a-link-pins {
+ pins = "PC0";
+ function = "func1";
+ bias-pull-down;
+ drive-strength = <33>;
+ };
+
+ pciex4b_link_pins: pciex4b-link-pins {
+ pins = "PC1";
+ function = "func1";
+ bias-pull-down;
+ drive-strength = <33>;
+ };
+
+ spi0_pins: spi0-pins {
+ pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7";
+ function = "func1";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ spi1_pins: spi1-pins {
+ pins = "PA0", "PA1", "PA2", "PA3";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart0_pins: uart0-pins {
+ pins = "PA8", "PA9";
+ function = "func1";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart1_pins: uart1-pins {
+ pins = "PB4", "PB5";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart2_pins: uart2-pins {
+ pins = "PC4", "PC5";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+};
diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts
new file mode 100644
index 000000000000..6f72d60ad55e
--- /dev/null
+++ b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ */
+
+#include "dp1000-rongda-m0-pinctrl.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Rongda M0 Board";
+ compatible = "rongda,m0", "ultrarisc,dp1000";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio_b 0 GPIO_ACTIVE_HIGH>;
+ active-delay-ms = <100>;
+
+ status = "disabled";
+ };
+
+ gpio-restart {
+ compatible = "gpio-restart";
+ gpios = <&gpio_b 1 GPIO_ACTIVE_HIGH>;
+ active-delay = <100>;
+
+ status = "disabled";
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ rtc@32 {
+ compatible = "whwave,sd3078";
+ reg = <0x32>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+};
+
+&spi1 {
+ num-cs = <1>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+ðernet {
+ phy-handle = <&phy0>;
+ /*
+ * YT8531 RGMII timing on this board requires no PHY internal delays.
+ * Using "rgmii-id" together with rx/tx-internal-delay-ps results in RX CRC
+ * errors and no usable traffic, so keep plain "rgmii" here.
+ */
+ phy-mode = "rgmii";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: phy@0 {
+ reg = <0x00>;
+ };
+ };
+};
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
2026-05-15 1:18 ` [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree Jia Wang via B4 Relay
@ 2026-05-15 10:28 ` Conor Dooley
0 siblings, 0 replies; 16+ messages in thread
From: Conor Dooley @ 2026-05-15 10:28 UTC (permalink / raw)
To: Jia Wang
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland, Paul Walmsley,
Palmer Dabbelt, Conor Dooley, devicetree, linux-riscv,
linux-kernel, linux-gpio
[-- Attachment #1.1: Type: text/plain, Size: 4498 bytes --]
On Fri, May 15, 2026 at 09:18:03AM +0800, Jia Wang wrote:
> Rongda M0 is an mATX motherboard based on the UltraRISC DP1000 SoC.
>
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---
> arch/riscv/boot/dts/Makefile | 1 +
> arch/riscv/boot/dts/ultrarisc/Makefile | 2 +
> .../dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi | 85 ++++++++++++++++
> arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts | 111 +++++++++++++++++++++
> 4 files changed, 199 insertions(+)
>
> diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
> index 69d8751fb17c..702882974251 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 += ultrarisc
> diff --git a/arch/riscv/boot/dts/ultrarisc/Makefile b/arch/riscv/boot/dts/ultrarisc/Makefile
> new file mode 100644
> index 000000000000..d01a770d3cba
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_ARCH_ULTRARISC) += dp1000-rongda-m0.dtb
> diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi
> new file mode 100644
> index 000000000000..101b416b1079
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi
> @@ -0,0 +1,85 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
> + */
> +
> +#include "dp1000.dtsi"
> +
> +&pmx0 {
> + i2c0_pins: i2c0-pins {
> + pins = "PA12", "PA13";
> + function = "func0";
This is what I meant about func0 btw, and having this be "i2c" etc instead.
> diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts
> new file mode 100644
> index 000000000000..6f72d60ad55e
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts
> @@ -0,0 +1,111 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
> + */
> +
> +#include "dp1000-rongda-m0-pinctrl.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +
> +/ {
> + model = "Rongda M0 Board";
> + compatible = "rongda,m0", "ultrarisc,dp1000";
> +
> + aliases {
> + serial0 = &uart0;
> + serial1 = &uart1;
> + serial2 = &uart2;
> + serial3 = &uart3;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +
> + gpio-poweroff {
> + compatible = "gpio-poweroff";
> + gpios = <&gpio_b 0 GPIO_ACTIVE_HIGH>;
> + active-delay-ms = <100>;
> +
> + status = "disabled";
Why bother adding the nodes if they are disabled? What enables them?
> + };
> +
> + gpio-restart {
> + compatible = "gpio-restart";
> + gpios = <&gpio_b 1 GPIO_ACTIVE_HIGH>;
> + active-delay = <100>;
> +
> + status = "disabled";
> + };
> +};
> +
> +&i2c0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c0_pins>;
> +};
> +
> +&i2c1 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c1_pins>;
> +};
> +
> +&i2c2 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c2_pins>;
> +
> + rtc@32 {
> + compatible = "whwave,sd3078";
> + reg = <0x32>;
> + };
> +};
> +
> +&i2c3 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&i2c3_pins>;
> +};
> +
> +&spi0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&spi0_pins>;
> +};
> +
> +&spi1 {
> + num-cs = <1>;
Why is num-cs set at the board level here?
> +
> + pinctrl-names = "default";
> + pinctrl-0 = <&spi1_pins>;
> +};
> +
> +&uart0 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart0_pins>;
> +};
> +
> +&uart1 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart1_pins>;
> +};
> +
> +&uart2 {
> + pinctrl-names = "default";
> + pinctrl-0 = <&uart2_pins>;
> +};
> +
> +ðernet {
> + phy-handle = <&phy0>;
> + /*
> + * YT8531 RGMII timing on this board requires no PHY internal delays.
> + * Using "rgmii-id" together with rx/tx-internal-delay-ps results in RX CRC
> + * errors and no usable traffic, so keep plain "rgmii" here.
> + */
> + phy-mode = "rgmii";
> +
> + mdio {
> + compatible = "snps,dwmac-mdio";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + phy0: phy@0 {
> + reg = <0x00>;
> + };
> + };
> +};
>
> --
> 2.34.1
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 8/9] riscv: dts: ultrarisc: add Milk-V Titan board device tree
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
` (6 preceding siblings ...)
2026-05-15 1:18 ` [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree Jia Wang via B4 Relay
@ 2026-05-15 1:18 ` Jia Wang via B4 Relay
2026-05-15 1:18 ` [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC Jia Wang via B4 Relay
2026-05-15 10:05 ` [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Conor Dooley
9 siblings, 0 replies; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Milk-V Titan is an ITX motherboard based on the UltraRISC DP1000 SoC.
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
arch/riscv/boot/dts/ultrarisc/Makefile | 1 +
.../dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi | 107 ++++++++++++
.../boot/dts/ultrarisc/dp1000-milkv-titan.dts | 182 +++++++++++++++++++++
3 files changed, 290 insertions(+)
diff --git a/arch/riscv/boot/dts/ultrarisc/Makefile b/arch/riscv/boot/dts/ultrarisc/Makefile
index d01a770d3cba..9c27256a2f67 100644
--- a/arch/riscv/boot/dts/ultrarisc/Makefile
+++ b/arch/riscv/boot/dts/ultrarisc/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_ULTRARISC) += dp1000-milkv-titan.dtb
dtb-$(CONFIG_ARCH_ULTRARISC) += dp1000-rongda-m0.dtb
diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi
new file mode 100644
index 000000000000..053206190ec7
--- /dev/null
+++ b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ */
+
+#include "dp1000.dtsi"
+
+&pmx0 {
+ i2c0_pins: i2c0-pins {
+ pins = "PA12", "PA13";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ i2c1_pins: i2c1-pins {
+ pins = "PB6", "PB7";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ i2c2_pins: i2c2-pins {
+ pins = "PC0", "PC1";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ i2c3_pins: i2c3-pins {
+ pins = "PC2", "PC3";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ io_pins: io-pins {
+ pins = "PA10", "PA15", "PB0", "PB1", "PB2", "PD6", "PD7";
+ function = "gpio";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ gpio_keys_pins: gpio-keys-pins {
+ pins = "PA4", "PA11", "PA14";
+ function = "gpio";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ mux_dcdc_pins: mux-dcdc-pins {
+ pins = "PA5";
+ function = "gpio";
+ };
+
+ mux_i2c3_pins: mux-i2c3-pins {
+ pins = "PA6";
+ function = "gpio";
+ };
+
+ mux_uart0_pins: mux-uart0-pins {
+ pins = "PA7";
+ function = "gpio";
+ };
+
+ spi0_pins: spi0-pins {
+ pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5";
+ function = "func1";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ spi1_pins: spi1-pins {
+ pins = "PA0", "PA1", "PA2", "PA3";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart0_pins: uart0-pins {
+ pins = "PA8", "PA9";
+ function = "func1";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart1_pins: uart1-pins {
+ pins = "PB4", "PB5";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart2_pins: uart2-pins {
+ pins = "PC4", "PC5";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+
+ uart3_pins: uart3-pins {
+ pins = "PC6", "PC7";
+ function = "func0";
+ bias-pull-up;
+ drive-strength = <33>;
+ };
+};
diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan.dts b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan.dts
new file mode 100644
index 000000000000..21d85c03abe1
--- /dev/null
+++ b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan.dts
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
+ */
+
+#include "dp1000-milkv-titan-pinctrl.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Milk-V Titan";
+ compatible = "milkv,titan", "ultrarisc,dp1000";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio_b 0 GPIO_ACTIVE_LOW>;
+ active-delay-ms = <100>;
+
+ status = "disabled";
+ };
+
+ gpio-restart {
+ compatible = "gpio-restart";
+ gpios = <&gpio_b 1 GPIO_ACTIVE_LOW>;
+ active-delay = <100>;
+
+ status = "disabled";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pins>;
+
+ key-wakeup-0 {
+ label = "Wake-Up";
+ gpios = <&gpio_a 14 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WAKEUP>;
+ linux,input-type = <EV_KEY>;
+ debounce-interval = <10>;
+ wakeup-source;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ };
+
+ key-wakeup-1 {
+ label = "Power";
+ gpios = <&gpio_a 11 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ linux,input-type = <EV_KEY>;
+ debounce-interval = <10>;
+ wakeup-source;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ };
+
+ key-wakeup-2 {
+ label = "Wake-Up-by-USB";
+ gpios = <&gpio_a 4 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WAKEUP>;
+ linux,input-type = <EV_KEY>;
+ debounce-interval = <10>;
+ wakeup-source;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ };
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ rtc@68 {
+ compatible = "st,m41t11";
+ reg = <0x68>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+};
+
+&spi1 {
+ num-cs = <1>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&gpio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&io_pins &mux_dcdc_pins &mux_i2c3_pins &mux_uart0_pins>;
+};
+
+ðernet {
+ phy-handle = <&phy0>;
+ /*
+ * RTL8211F: board timing uses PHY strap delays; keep plain "rgmii".
+ * Enabling PHY internal delays via "rgmii-id" breaks Ethernet traffic.
+ */
+ phy-mode = "rgmii";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: phy@0 {
+ reg = <0x00>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ label = "eth-link";
+ reg = <0x01>;
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_INDICATOR;
+ default-state = "keep";
+ linux,default-trigger = "netdev";
+ };
+
+ led@2 {
+ label = "eth-activity";
+ reg = <0x02>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_ACTIVITY;
+ default-state = "keep";
+ linux,default-trigger = "netdev";
+ };
+ };
+ };
+ };
+};
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
` (7 preceding siblings ...)
2026-05-15 1:18 ` [PATCH 8/9] riscv: dts: ultrarisc: add Milk-V Titan " Jia Wang via B4 Relay
@ 2026-05-15 1:18 ` Jia Wang via B4 Relay
2026-05-15 10:05 ` [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Conor Dooley
9 siblings, 0 replies; 16+ messages in thread
From: Jia Wang via B4 Relay @ 2026-05-15 1:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland
Cc: Paul Walmsley, Palmer Dabbelt, Conor Dooley, devicetree,
linux-riscv, linux-kernel, linux-gpio, Jia Wang
From: Jia Wang <wangjia@ultrarisc.com>
Enable `ARCH_ULTRARISC` in the default RISC-V defconfig.
Link: https://lore.kernel.org/lkml/20260427-ultrarisc-pcie-v4-1-98935f6cdfb5@ultrarisc.com/
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
arch/riscv/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index c2c37327b987..9fdc4d1831ed 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -32,6 +32,7 @@ CONFIG_SOC_STARFIVE=y
CONFIG_ARCH_SUNXI=y
CONFIG_ARCH_TENSTORRENT=y
CONFIG_ARCH_THEAD=y
+CONFIG_ARCH_ULTRARISC=y
CONFIG_ARCH_VIRT=y
CONFIG_ARCH_CANAAN=y
CONFIG_SMP=y
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support
2026-05-15 1:17 [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Jia Wang via B4 Relay
` (8 preceding siblings ...)
2026-05-15 1:18 ` [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC Jia Wang via B4 Relay
@ 2026-05-15 10:05 ` Conor Dooley
9 siblings, 0 replies; 16+ messages in thread
From: Conor Dooley @ 2026-05-15 10:05 UTC (permalink / raw)
To: Jia Wang
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Linus Walleij,
Bartosz Golaszewski, Samuel Holland, Paul Walmsley,
Palmer Dabbelt, Conor Dooley, devicetree, linux-riscv,
linux-kernel, linux-gpio
[-- Attachment #1.1: Type: text/plain, Size: 5172 bytes --]
Hey,
On Fri, May 15, 2026 at 09:17:56AM +0800, Jia Wang wrote:
> This series adds initial Devicetree support for the UltraRISC DP1000 RISC-V
> SoC and two DP1000-based boards (Milk-V Titan and Rongda M0).
>
> The series introduces the required DT bindings, adds the DP1000 pinctrl
> driver, and provides the initial SoC/board DTS files.
>
> Notes:
> - Clocks are configured and enabled by firmware before Linux boots. Linux
> does not manage clock rates or gating at runtime on this platform.
> Therefore the initial DT only models the fixed clocks required by
> standard drivers, and no clock controller/driver is provided.
I really disagree with this approach. In my experience it never ends up
working out and ends up being disruptive, because it is either an over
simplification of the clock tree and condenses multiple different clocks
into one where rates are similar or because firmware changes mean clock
rate changes down the line. I would much rather you modelled the clocks
accurately, even if that just means that a read-only clock controller is
implemented. Alternatively, if firmware does all of your clock control,
you can implement this using rpmi/mpoxy using clk-rpmi.c
> - The DP1000 pinctrl binding supports two child node styles under the same
> controller compatible:
> * legacy DP1000-specific nodes using phandle-array properties
> "pinctrl-pins" and "pinconf-pins"
> * generic pinctrl nodes using "pins", "function" and generic pin
> configuration properties
> The legacy form is kept for compatibility with existing vendor DTs.
Why would we want "legacy" stuff in mainline when this is a brand new
platform? "legacy" vendor devicetrees are not something that mainline
cares about, sorry.
Additionally, these pinctrl patches should be sent standalone to the
pinctrl maintainers, they're likely to go through lots of revisions and
a different maintainer applies them.
> - The bindings for "ultrarisc,dp1000-uart" and "ultrarisc,dp1000-pcie" are
> being reviewed in separate series, since the DP1000 SoC DTS introduced
> here uses those compatibles:
> * Link: https://lore.kernel.org/lkml/20260429-ultrarisc-serial-v7-3-e475cce9e274@ultrarisc.com/
> * Link: https://lore.kernel.org/lkml/20260427-ultrarisc-pcie-v4-2-98935f6cdfb5@ultrarisc.com/
> - ARCH_ULTRARISC support is being reviewed separately:
> * Link: https://lore.kernel.org/lkml/20260427-ultrarisc-pcie-v4-1-98935f6cdfb5@ultrarisc.com/
IMO, this patch needs to be in this series so that it compiles.
Cheers,
Conor.
>
> Testing:
> - dt_binding_check and yamllint (all new/modified binding YAMLs)
> - dtbs_check and dtbs (RISC-V, including dp1000-milkv-titan.dtb and
> dp1000-rongda-m0.dtb)
> - Kernel build for RISC-V and boot-tested on DP1000 (Milk-V Titan and
> Rongda M0)
>
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---
> Jia Wang (9):
> dt-bindings: vendor-prefixes: add Rongda
> dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
> dt-bindings: riscv: Add UltraRISC DP1000 bindings
> dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
> riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
> pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver
> riscv: dts: ultrarisc: add Rongda M0 board device tree
> riscv: dts: ultrarisc: add Milk-V Titan board device tree
> riscv: defconfig: enable ARCH_ULTRARISC
>
> .../bindings/pinctrl/ultrarisc,dp1000-pinctrl.yaml | 168 ++++
> Documentation/devicetree/bindings/riscv/cpus.yaml | 1 +
> .../devicetree/bindings/riscv/ultrarisc.yaml | 27 +
> .../devicetree/bindings/vendor-prefixes.yaml | 2 +
> MAINTAINERS | 15 +
> arch/riscv/boot/dts/Makefile | 1 +
> arch/riscv/boot/dts/ultrarisc/Makefile | 3 +
> .../dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi | 107 +++
> .../boot/dts/ultrarisc/dp1000-milkv-titan.dts | 182 +++++
> .../dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi | 85 ++
> arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts | 111 +++
> arch/riscv/boot/dts/ultrarisc/dp1000.dtsi | 851 +++++++++++++++++++++
> arch/riscv/configs/defconfig | 1 +
> drivers/pinctrl/Kconfig | 1 +
> drivers/pinctrl/Makefile | 1 +
> drivers/pinctrl/ultrarisc/Kconfig | 23 +
> drivers/pinctrl/ultrarisc/Makefile | 4 +
> drivers/pinctrl/ultrarisc/pinctrl-dp1000.c | 112 +++
> drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c | 746 ++++++++++++++++++
> drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.h | 71 ++
> .../dt-bindings/pinctrl/ultrarisc,dp1000-pinctrl.h | 65 ++
> 21 files changed, 2577 insertions(+)
> ---
> base-commit: 50897c955902c93ae71c38698abb910525ebdc89
> change-id: 20260316-ultrarisc-pinctrl-efa6e24c4803
>
> Best regards,
> --
> Jia Wang <wangjia@ultrarisc.com>
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 161 bytes --]
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 16+ messages in thread