All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support
@ 2026-05-15  1:17 ` Jia Wang
  0 siblings, 0 replies; 51+ 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

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

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>



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

* [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support
@ 2026-05-15  1:17 ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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

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>


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

* [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support
@ 2026-05-15  1:17 ` Jia Wang
  0 siblings, 0 replies; 51+ 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

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

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>



_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:17   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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



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

* [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda
@ 2026-05-15  1:17   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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


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

* [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda
@ 2026-05-15  1:17   ` Jia Wang
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:17   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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



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

* [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
@ 2026-05-15  1:17   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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


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

* [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
@ 2026-05-15  1:17   ` Jia Wang
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:17   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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



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

* [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings
@ 2026-05-15  1:17   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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


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

* [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings
@ 2026-05-15  1:17   ` Jia Wang
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:18   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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



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

* [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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


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

* [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:18   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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



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

* [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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


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

* [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* [PATCH 6/9] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:18   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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



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

* [PATCH 6/9] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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


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

* [PATCH 6/9] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:18   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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>;
+};
+
+&ethernet {
+	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



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

* [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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>;
+};
+
+&ethernet {
+	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


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

* [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ 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>;
+};
+
+&ethernet {
+	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] 51+ messages in thread

* [PATCH 8/9] riscv: dts: ultrarisc: add Milk-V Titan board device tree
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:18   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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>;
+};
+
+&ethernet {
+	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



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

* [PATCH 8/9] riscv: dts: ultrarisc: add Milk-V Titan board device tree
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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>;
+};
+
+&ethernet {
+	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


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

* [PATCH 8/9] riscv: dts: ultrarisc: add Milk-V Titan board device tree
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ 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>;
+};
+
+&ethernet {
+	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] 51+ messages in thread

* [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC
  2026-05-15  1:17 ` Jia Wang
  (?)
@ 2026-05-15  1:18   ` Jia Wang
  -1 siblings, 0 replies; 51+ 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



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

* [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 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

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


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

* [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC
@ 2026-05-15  1:18   ` Jia Wang
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* Re: [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda
  2026-05-15  1:17   ` Jia Wang
  (?)
  (?)
@ 2026-05-15  1:20   ` sashiko-bot
  2026-05-15  1:25     ` Jia Wang
  -1 siblings, 1 reply; 51+ messages in thread
From: sashiko-bot @ 2026-05-15  1:20 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: krzk+dt, devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The new vendor prefix '^rongda,.*' is inserted in the wrong alphabetical order in `vendor-prefixes.yaml`.
--

commit dca4b6c39a857922a831a430a56bddfea711476c
Author: Jia Wang <wangjia@ultrarisc.com>

dt-bindings: vendor-prefixes: add Rongda

This commit adds Shenzhen Rongda Computer Co., Ltd. to the devicetree vendor
prefixes list.

Link: http://www.shenrongda.com/

> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 28784d66ae7ba..04e593c66c7c4 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,.*":

This isn't a bug, but is this entry inserted in the correct alphabetical
order? Alphabetically, "rohm" and "ronbo" should appear before "rongda".

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=1

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

* Re: [PATCH 1/9] dt-bindings: vendor-prefixes: add Rongda
  2026-05-15  1:20   ` sashiko-bot
@ 2026-05-15  1:25     ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 2026-05-15  1:25 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: Jia Wang via B4 Relay, krzk+dt, devicetree, robh, conor+dt

On 2026-05-15 01:20 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Low] The new vendor prefix '^rongda,.*' is inserted in the wrong alphabetical order in `vendor-prefixes.yaml`.
> --
> 
> commit dca4b6c39a857922a831a430a56bddfea711476c
> Author: Jia Wang <wangjia@ultrarisc.com>
> 
> dt-bindings: vendor-prefixes: add Rongda
> 
> This commit adds Shenzhen Rongda Computer Co., Ltd. to the devicetree vendor
> prefixes list.
> 
> Link: http://www.shenrongda.com/
> 
> > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > index 28784d66ae7ba..04e593c66c7c4 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,.*":
> 
> This isn't a bug, but is this entry inserted in the correct alphabetical
> order? Alphabetically, "rohm" and "ronbo" should appear before "rongda".
>

Thanks for pointing this out. I’ll fix the ordering in the next version.
 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=1
> 

Best Regards,
Jia Wang



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

* Re: [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
  2026-05-15  1:18   ` Jia Wang
  (?)
  (?)
@ 2026-05-15  1:49   ` sashiko-bot
  2026-05-15  8:43     ` Jia Wang
  -1 siblings, 1 reply; 51+ messages in thread
From: sashiko-bot @ 2026-05-15  1:49 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: robh, krzk+dt, devicetree, conor+dt

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] The schema lacks a top-level `required` block for mandatory controller properties.
- [Medium] The binding introduces custom legacy vendor properties and magic macros instead of using generic pinctrl properties.
- [Medium] The `maxItems: 32` constraint on the legacy array properties allows structurally incomplete configuration tuples.
- [Medium] The schema incorrectly uses `additionalProperties: false` alongside `$ref` inclusions, forcing redundant property definitions.
- [Low] The documentation incorrectly describes the legacy properties as a `phandle-array`.
- [Low] The schema fails to enforce the hardware limitation that `func1` is unsupported on `LPC` pins.
--

commit 20f50ac043d77ef903b805d0902034551c955519
Author: Jia Wang <wangjia@ultrarisc.com>

dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
    
Add bindings for the pin controllers on the UltraRISC DP1000 RISC-V SoC.

> 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 0000000000000..c7ed1f96382af
> --- /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`

Is "phandle-array" accurate here? The schema defines these as flat uint32
arrays, and the examples show raw integer arrays without any phandles.

> +  - 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

Should there be a top-level required block for compatible and reg?
Without it, a device tree node omitting the reg property or left entirely
empty could silently pass schema validation.

> +patternProperties:
> +  '.*-pins$':
> +    type: object
> +    allOf:
> +      - $ref: /schemas/pinctrl/pincfg-node.yaml#
> +      - $ref: /schemas/pinctrl/pinmux-node.yaml#
> +    additionalProperties: false

Should this use unevaluatedProperties: false instead? Using
additionalProperties: false alongside $ref ignores properties imported by
the references and forces redundantly redefining generic properties locally
in this file.

> +    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

Since the format requires 3 integers per tuple, does a maxItems: 32
constraint allow structurally incomplete configuration tuples? 32 is not a
multiple of 3, so it rejects a valid 11-pin configuration (33 integers) while
permitting an invalid array ending with a partial tuple.

> +      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

Is it appropriate to encode distinct physical characteristics like bias and
drive strength into a single integer using a macro? The pinctrl subsystem's
architectural design typically models these as individual, human-readable DT
properties.

For a new upstream driver, shouldn't it rely exclusively on the standard
generic pinctrl framework rather than introducing new custom vendor properties?

[ ... ]

> +      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

Could the schema enforce the hardware limitation that func1 is unsupported
on LPC pins? Adding an allOf with an if/then block would prevent this
invalid combination from passing schema validation.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=4

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

* Re: [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
  2026-05-15  1:18   ` Jia Wang
  (?)
  (?)
@ 2026-05-15  2:02   ` sashiko-bot
  -1 siblings, 0 replies; 51+ messages in thread
From: sashiko-bot @ 2026-05-15  2:02 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: krzk+dt, robh, devicetree, conor+dt

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] The `gpio-ranges` property values in `gpio_b`, `gpio_c`, and `gpio_d` incorrectly specify a local GPIO base that exceeds the available pins.
- [High] PCI I/O space is incorrectly mapped 1:1 to a high CPU address, breaking legacy PCI endpoints.
- [High] The Ethernet node incorrectly defines a broadcast MAC address as its local unicast MAC address.
- [Medium] Mismatch between CPU node unit addresses and their `reg` properties.
- [Medium] Ethernet compatible strings are listed in the wrong order.
- [Low] Clock node names contain underscores instead of hyphens.
--

commit f5aec289ca4daa2ae7f4c27bac4b1694ece4043b
Author: Jia Wang <wangjia@ultrarisc.com>

riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000

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/

> diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi b/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi
> new file mode 100644
> index 0000000000000..1aae53fc1a2b1
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000.dtsi
> @@ -0,0 +1,851 @@
[ ... ]
> +		cpu4: cpu@4 {
> +			compatible = "ultrarisc,cp100", "riscv";
> +			reg = <0x10>;

Does the unit address in the node name here correctly match the first
address specified in its reg property?

The Devicetree Specification mandates that the hexadecimal value after the @
must exactly match the reg value to avoid parser errors and dtc compiler
warnings. Should these be renamed to cpu@10, cpu@11, cpu@12, and cpu@13?

[ ... ]
> +	clocks {
> +		device_clk: device_clk {

Is it intended to use underscores in these clock node names?

Device tree naming conventions generally require node names to use hyphens
instead of underscores (e.g., device-clk) to avoid triggering strict
character warnings.

[ ... ]
> +			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>;

Will operations on local GPIOs 0-7 have a valid pinmux mapping with this
configuration?

The gpio-ranges property uses the format <pinctrl_phandle gpio_base
pinctrl_base count>. By specifying a local gpio_base of 16 for a port with
only 8 pins, it seems gpiolib will fail to configure pins 0-7 correctly.

Should this be inverted to <&pmx0 0 16 8> to map local GPIOs 0-7 to
pinctrl pins 16-23? This appears to be similarly configured for gpio_c and
gpio_d as well.

[ ... ]
> +		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>,

Can legacy PCI endpoints and HBAs that only decode 16-bit I/O addresses
successfully initialize with this mapping?

The ranges property maps the CPU MMIO address 0x4fbf0000 directly to the
PCI bus I/O address 0x4fbf0000 (indicated by the 0x81000000 bitfield).
Would it be better to map the CPU MMIO region to a PCI bus I/O address of 0
instead?

[ ... ]
> +		ethernet: ethernet@38000000 {
> +			compatible = "snps,dwmac", "snps,dwmac-5.10a";

Could the OS prematurely bind to the generic driver before applying
hardware-specific driver quirks with this ordering? Device tree bindings
typically require the compatible array to be ordered from most specific to
least specific.

> +			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];

Will the network driver initialize with an invalid broadcast MAC address if
the bootloader does not dynamically overwrite this value?

Using a broadcast address as a source MAC violates IEEE 802.3 standards,
and upstream network switches may drop packets sent by this interface.
Should this be omitted or zeroed out as a placeholder?

> +			max-speed = <1000>;
> +			phy-mode = "rgmii-id";
> +			snps,txpbl = <8>;
> +			snps,rxpbl = <8>;
> +		};

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=5

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

* Re: [PATCH 6/9] pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver
  2026-05-15  1:18   ` Jia Wang
  (?)
  (?)
@ 2026-05-15  2:28   ` sashiko-bot
  -1 siblings, 0 replies; 51+ messages in thread
From: sashiko-bot @ 2026-05-15  2:28 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: conor+dt, robh, devicetree, krzk+dt

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Memory leak of temporary DT parsing arrays on consumer probe paths
- [Medium] Silent ignoring of unsupported pin configurations
- [Low] Build failure due to dynamic mask in `field_prep()`
- [Low] Signed integer overflow during pin mux configuration
- [Low] Unnecessary Kconfig dependencies selected
--

commit 03445610d24a54757505c7f2def35cc4894dd19f
Author: Jia Wang <wangjia@ultrarisc.com>

pinctrl: ultrarisc: Add UltraRISC DP1000 pinctrl driver

This commit adds the pinctrl driver for the UltraRISC DP1000 pinctrl
controller.

> diff --git a/drivers/pinctrl/ultrarisc/Kconfig b/drivers/pinctrl/ultrarisc/Kconfig
> new file mode 100644
> index 0000000000000..ba8747b90127d
> --- /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

This isn't a bug, but is it necessary to select IRQ_DOMAIN_HIERARCHY and
MFD_SYSCON here? The driver code doesn't seem to include the corresponding
headers or use their APIs.

[ ... ]
> diff --git a/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c
> new file mode 100644
> index 0000000000000..774746943e283
> --- /dev/null
> +++ b/drivers/pinctrl/ultrarisc/pinctrl-ultrarisc.c
[ ... ]
> @@ -0,0 +1,746 @@
[ ... ]
> +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);

Does this cause a build failure? The field_prep() macro strictly enforces
that its mask argument must be a compile-time constant. Because mask is
calculated dynamically based on pin_val.pin, the driver will fail to compile.

> +	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);

Could this shift result in a signed integer overflow?

UR_FUNC0 is 1 and UR_FUNC1 is 0x10000, so their bitwise OR is 0x10001. If
pin_val->pin is 15, left-shifting 0x10001 by 15 results in 0x80008000.
This shifts a bit into the sign bit of a 32-bit signed integer.

Should these macros be defined with unsigned literals, such as 1U and
0x10000U?

> +	val |= pin_val->mode << pin_val->pin;
> +	writel_relaxed(val, reg);
> +	raw_spin_unlock_irqrestore(&pctldata->lock, flags);
> +
> +	return 0;
> +}
[ ... ]
> +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;

Does this code silently ignore unsupported configurations?

Returning 0 here tells the pinctrl framework that the configurations were
successfully applied, even though no hardware state was modified. Should
this return -ENOTSUPP for configurations the hardware doesn't support?

> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +}
[ ... ]
> +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);

Will this leak memory when consumer devices defer probe?

The devm_kcalloc() allocations are tied to pctldev->dev, which is the pinctrl
provider device. Since ur_legacy_parse_prop() is called from dt_node_to_map
during the consumer's probe sequence, these allocations will remain on the
provider's devres list and accumulate each time the consumer defers probe.

Should standard kcalloc() be used here instead and explicitly freed at the
end of ur_legacy_dt_node_to_map()?

> +	if (!prop->group_pins)
> +		return -ENOMEM;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=6

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

* Re: [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
  2026-05-15  1:18   ` Jia Wang
  (?)
  (?)
@ 2026-05-15  2:37   ` sashiko-bot
  -1 siblings, 0 replies; 51+ messages in thread
From: sashiko-bot @ 2026-05-15  2:37 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: conor+dt, robh, krzk+dt, devicetree

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] Unused hardware blocks (PCIe controllers and UART3) are left enabled without proper configuration.
- [Low] Board-specific power management features (`gpio-poweroff` and `gpio-restart`) are explicitly disabled.
- [Low] Unused PCIe link pin configurations conflict with actively used I2C2 pins.
--

commit 024b81fdfc4200deef00a8435cf80efa58aed943
Author: Jia Wang <wangjia@ultrarisc.com>

riscv: dts: ultrarisc: add Rongda M0 board device tree

This commit adds the device tree for the Rongda M0 mATX motherboard based
on the UltraRISC DP1000 SoC. It configures pin controls, aliases, and
active peripherals like I2C, SPI, UART, and Ethernet.

> 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 0000000000000..101b416b10792
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0-pinctrl.dtsi
> @@ -0,0 +1,85 @@
[ ... ]
> +	i2c2_pins: i2c2-pins {
> +		pins = "PC0", "PC1";
> +		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>;
> +	};

Are these pciex4a_link_pins and pciex4b_link_pins configurations needed?
They appear to use pins PC0 and PC1, which are also mapped to i2c2_pins and
actively assigned to i2c2 below.

Since these PCIe link pin configurations are unused in the board device tree
and conflict with the active I2C pins, could they be removed?

> 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 0000000000000..6f72d60ad55e4
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000-rongda-m0.dts
> @@ -0,0 +1,111 @@
[ ... ]
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +		serial3 = &uart3;
> +	};

Is uart3 intended to be active on this board? It is aliased here but does
not appear to be configured with pins or explicitly disabled.

If unused hardware blocks like uart3 or the PCIe controllers are left enabled
in the generic SoC device tree without being explicitly disabled in the board
device tree, could probing them waste resources or expose dangling interfaces?

Should unused IP blocks be explicitly marked with status = "disabled" in
this board-level device tree?

> +
> +	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";
> +	};

Should these gpio-poweroff and gpio-restart nodes be included if they are
explicitly disabled?

If the board is physically wired to support these features, could they be
enabled by removing the status lines? If not, does it make sense to omit
these nodes from the board file entirely?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=7

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

* Re: [PATCH 8/9] riscv: dts: ultrarisc: add Milk-V Titan board device tree
  2026-05-15  1:18   ` Jia Wang
  (?)
  (?)
@ 2026-05-15  2:50   ` sashiko-bot
  -1 siblings, 0 replies; 51+ messages in thread
From: sashiko-bot @ 2026-05-15  2:50 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: conor+dt, krzk+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The GPIO pins used for board-level multiplexers (`PA5`, `PA6`, `PA7`) are configured with the `gpio` pinmux function but are not driven to any defined state.
- [Low] The `gpio-poweroff` and `gpio-restart` nodes are explicitly defined in the board device tree but are left with `status = "disabled";`.
--

commit f0b973e0e230934a238fa1f5d39b91d61efc3d7b
Author: Jia Wang <wangjia@ultrarisc.com>

riscv: dts: ultrarisc: add Milk-V Titan board device tree

This commit adds the device tree for the Milk-V Titan motherboard based on
the dp1000 soc.

> diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi
> index 0000000000000..053206190ec75
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan-pinctrl.dtsi
[ ... ]
> +	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";
> +	};

[ ... ]

> diff --git a/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan.dts b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan.dts
> index 0000000000000..21d85c03abe12
> --- /dev/null
> +++ b/arch/riscv/boot/dts/ultrarisc/dp1000-milkv-titan.dts
[ ... ]
> +	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";
> +	};

Is it intended to leave these nodes disabled in a final board device tree?

Defining board-level features only to disable them might leave functionality
unexpectedly unavailable or litter the tree with dead code. If the hardware
supports these features, should they be enabled to provide power-off and
restart functionality?

[ ... ]
> +&gpio {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&io_pins &mux_dcdc_pins &mux_i2c3_pins &mux_uart0_pins>;
> +};

Does this configuration leave the multiplexer pins in a floating state?

The mux_dcdc_pins, mux_i2c3_pins, and mux_uart0_pins configure the PA5, PA6,
and PA7 pins to act as gpios and are applied to the default state of the gpio
controller here. However, configuring a pin to gpio mode only routes it to
the gpio controller without configuring the direction or output level.

Without a driver or gpio-hog nodes explicitly setting these pins as outputs
and driving them high or low, they will default to inputs. This might lead to
unpredictable hardware behavior, potentially disabling the dcdc converter,
i2c bus, or the system console. Could this be addressed by adding gpio-hog
configurations?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=8

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

* Re: [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC
  2026-05-15  1:18   ` Jia Wang
  (?)
  (?)
@ 2026-05-15  2:59   ` sashiko-bot
  -1 siblings, 0 replies; 51+ messages in thread
From: sashiko-bot @ 2026-05-15  2:59 UTC (permalink / raw)
  To: Jia Wang via B4 Relay; +Cc: robh, krzk+dt, devicetree, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The Kconfig symbol `ARCH_ULTRARISC` is not defined anywhere in the kernel tree.
--

commit c77ace3a44699f903221665a56d7714a8cd6cf21
Author: Jia Wang <wangjia@ultrarisc.com>

riscv: defconfig: enable ARCH_ULTRARISC

This commit adds the CONFIG_ARCH_ULTRARISC symbol to the default RISC-V
defconfig file.

Link: https://lore.kernel.org/lkml/20260427-ultrarisc-pcie-v4-1-98935f6cdfb5@ultrarisc.com/

> diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
> index c2c37327b9877..9fdc4d1831ed9 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

Is ARCH_ULTRARISC defined anywhere in the kernel tree?

It appears that the Kconfig entry for ARCH_ULTRARISC is missing. Adding an
undefined symbol to a defconfig has no effect because the Kconfig system will
silently discard it during .config generation, which would prevent the
intended components from being built.

Was a prerequisite patch that adds the ARCH_ULTRARISC definition accidentally
left out of this patch series?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=9

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

* Re: [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
  2026-05-15  1:49   ` sashiko-bot
@ 2026-05-15  8:43     ` Jia Wang
  0 siblings, 0 replies; 51+ messages in thread
From: Jia Wang @ 2026-05-15  8:43 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: Jia Wang via B4 Relay, robh, krzk+dt, devicetree, conor+dt

On 2026-05-15 01:49 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
> - [High] The schema lacks a top-level `required` block for mandatory controller properties.
> - [Medium] The binding introduces custom legacy vendor properties and magic macros instead of using generic pinctrl properties.
> - [Medium] The `maxItems: 32` constraint on the legacy array properties allows structurally incomplete configuration tuples.
> - [Medium] The schema incorrectly uses `additionalProperties: false` alongside `$ref` inclusions, forcing redundant property definitions.
> - [Low] The documentation incorrectly describes the legacy properties as a `phandle-array`.
> - [Low] The schema fails to enforce the hardware limitation that `func1` is unsupported on `LPC` pins.
> --
> 
> commit 20f50ac043d77ef903b805d0902034551c955519
> Author: Jia Wang <wangjia@ultrarisc.com>
> 
> dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
>     
> Add bindings for the pin controllers on the UltraRISC DP1000 RISC-V SoC.
> 
> > 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 0000000000000..c7ed1f96382af
> > --- /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`
> 
> Is "phandle-array" accurate here? The schema defines these as flat uint32
> arrays, and the examples show raw integer arrays without any phandles.
>

Thanks for spotting that. The term "phandle-array" is indeed inaccurate
here, but since these legacy properties will be removed entirely in v2,
this description will be dropped along with them.
 
> > +  - 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
> 
> Should there be a top-level required block for compatible and reg?
> Without it, a device tree node omitting the reg property or left entirely
> empty could silently pass schema validation.
>

Yes, I’ll added the top-level required block for compatible and reg.
 
> > +patternProperties:
> > +  '.*-pins$':
> > +    type: object
> > +    allOf:
> > +      - $ref: /schemas/pinctrl/pincfg-node.yaml#
> > +      - $ref: /schemas/pinctrl/pinmux-node.yaml#
> > +    additionalProperties: false
> 
> Should this use unevaluatedProperties: false instead? Using
> additionalProperties: false alongside $ref ignores properties imported by
> the references and forces redundantly redefining generic properties locally
> in this file.
> 

I’ll switch to unevaluatedProperties: false and verify the behavior.

> > +    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
> 
> Since the format requires 3 integers per tuple, does a maxItems: 32
> constraint allow structurally incomplete configuration tuples? 32 is not a
> multiple of 3, so it rejects a valid 11-pin configuration (33 integers) while
> permitting an invalid array ending with a partial tuple.
> 

This legacy property will be removed in v2.

> > +      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
> 
> Is it appropriate to encode distinct physical characteristics like bias and
> drive strength into a single integer using a macro? The pinctrl subsystem's
> architectural design typically models these as individual, human-readable DT
> properties.
> 
> For a new upstream driver, shouldn't it rely exclusively on the standard
> generic pinctrl framework rather than introducing new custom vendor properties?
> 

In v2, I’ll remove the legacy vendor-specific pinconf-pins/pinctrl-pins
properties from the binding schema. They were previously included for
compatibility.

The legacy format is kept only as a driver implementation detail for
existing DTs and is not part of the binding.

New device trees must use the generic pinctrl binding.

> [ ... ]
> 
> > +      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
> 
> Could the schema enforce the hardware limitation that func1 is unsupported
> on LPC pins? Adding an allOf with an if/then block would prevent this
> invalid combination from passing schema validation.
>

Thanks, will add an allOf with if/then in v2 to reject func1 on LPC pins.
 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260515-ultrarisc-pinctrl-v1-0-bf559589ea8a@ultrarisc.com?part=4
> 

Best Regards,
Jia Wang



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

* Re: [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support
  2026-05-15  1:17 ` Jia Wang
@ 2026-05-15 10:05   ` Conor Dooley
  -1 siblings, 0 replies; 51+ 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: 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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support
@ 2026-05-15 10:05   ` Conor Dooley
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* Re: [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
  2026-05-15  1:17   ` Jia Wang
@ 2026-05-15 10:06     ` Conor Dooley
  -1 siblings, 0 replies; 51+ 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: Type: text/plain, Size: 52 bytes --]

Acked-by: Conor Dooley <conor.dooley@microchip.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 2/9] dt-bindings: riscv: cpus: Add UltraRISC CP100 compatible
@ 2026-05-15 10:06     ` Conor Dooley
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* Re: [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings
  2026-05-15  1:17   ` Jia Wang
@ 2026-05-15 10:08     ` Conor Dooley
  -1 siblings, 0 replies; 51+ 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: 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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 3/9] dt-bindings: riscv: Add UltraRISC DP1000 bindings
@ 2026-05-15 10:08     ` Conor Dooley
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* Re: [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
  2026-05-15  1:18   ` Jia Wang
@ 2026-05-15 10:12     ` Conor Dooley
  -1 siblings, 0 replies; 51+ 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] 51+ messages in thread

* Re: [PATCH 4/9] dt-bindings: pinctrl: Add UltraRISC DP1000 pinctrl bindings
@ 2026-05-15 10:12     ` Conor Dooley
  0 siblings, 0 replies; 51+ 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: 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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
  2026-05-15  1:18   ` Jia Wang
@ 2026-05-15 10:26     ` Conor Dooley
  -1 siblings, 0 replies; 51+ 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: 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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 5/9] riscv: dts: ultrarisc: Add initial device tree for UltraRISC DP1000
@ 2026-05-15 10:26     ` Conor Dooley
  0 siblings, 0 replies; 51+ 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] 51+ messages in thread

* Re: [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
  2026-05-15  1:18   ` Jia Wang
@ 2026-05-15 10:28     ` Conor Dooley
  -1 siblings, 0 replies; 51+ 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: 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>;
> +};
> +
> +&ethernet {
> +	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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH 7/9] riscv: dts: ultrarisc: add Rongda M0 board device tree
@ 2026-05-15 10:28     ` Conor Dooley
  0 siblings, 0 replies; 51+ 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>;
> +};
> +
> +&ethernet {
> +	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] 51+ messages in thread

end of thread, other threads:[~2026-05-15 10:29 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` Jia Wang
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  1:17   ` Jia Wang
2026-05-15  1:20   ` sashiko-bot
2026-05-15  1:25     ` Jia Wang
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  1:17   ` Jia Wang
2026-05-15 10:06   ` Conor Dooley
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
2026-05-15  1:17   ` Jia Wang via B4 Relay
2026-05-15  1:17   ` Jia Wang
2026-05-15 10:08   ` Conor Dooley
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
2026-05-15  1:18   ` Jia Wang via B4 Relay
2026-05-15  1:18   ` Jia Wang
2026-05-15  1:49   ` sashiko-bot
2026-05-15  8:43     ` Jia Wang
2026-05-15 10:12   ` Conor Dooley
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
2026-05-15  1:18   ` Jia Wang via B4 Relay
2026-05-15  1:18   ` Jia Wang
2026-05-15  2:02   ` sashiko-bot
2026-05-15 10:26   ` Conor Dooley
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
2026-05-15  1:18   ` Jia Wang via B4 Relay
2026-05-15  1:18   ` Jia Wang
2026-05-15  2:28   ` sashiko-bot
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   ` Jia Wang
2026-05-15  2:37   ` sashiko-bot
2026-05-15 10:28   ` Conor Dooley
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
2026-05-15  1:18   ` Jia Wang via B4 Relay
2026-05-15  1:18   ` Jia Wang
2026-05-15  2:50   ` sashiko-bot
2026-05-15  1:18 ` [PATCH 9/9] riscv: defconfig: enable ARCH_ULTRARISC Jia Wang via B4 Relay
2026-05-15  1:18   ` Jia Wang via B4 Relay
2026-05-15  1:18   ` Jia Wang
2026-05-15  2:59   ` sashiko-bot
2026-05-15 10:05 ` [PATCH 0/9] riscv: ultrarisc: add DP1000 SoC DT and pinctrl support Conor Dooley
2026-05-15 10:05   ` Conor Dooley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.