Linux clock framework development
 help / color / mirror / Atom feed
* [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2
@ 2026-11-13 22:33 Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 01/19] riscv: sunxi: describe the wider Allwinner SoC family Han Gao via B4 Relay
                   ` (18 more replies)
  0 siblings, 19 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

The Allwinner V861 is a camera SoC with two XuanTie C907 harts. This
series adds the clock and pin controllers, the RTC clocks and the
device trees needed to boot the YuzukiHD Avaota F2 board to a serial
console.

Tested on the Avaota F2.

---
Han Gao (19):
      riscv: sunxi: describe the wider Allwinner SoC family
      dt-bindings: riscv: cpus: add the XuanTie C907
      dt-bindings: interrupt-controller: add the Allwinner V861 PLIC
      dt-bindings: timer: add the Allwinner V861 CLINT
      dt-bindings: clock: sunxi-ng: document the Allwinner V861 CCUs
      clk: sunxi-ng: add support for the Allwinner V861 CCU
      clk: sunxi-ng: add support for the Allwinner V861 PRCM CCU
      dt-bindings: rtc: sun6i: add the Allwinner V861 RTC
      clk: sunxi-ng: sun6i-rtc: allow variants without a 32k fanout mux
      clk: sunxi-ng: sun6i-rtc: allow another 24 MHz to 32k divider ratio
      clk: sunxi-ng: sun6i-rtc: add Allwinner V861 support
      dt-bindings: pinctrl: add the Allwinner V861 pin controllers
      pinctrl: sunxi: allow a per-controller IRQ register base
      pinctrl: sunxi: add support for the Allwinner V861 PIO
      pinctrl: sunxi: add support for the Allwinner V861 R-PIO
      riscv: dts: allwinner: add the Allwinner V861 SoC
      dt-bindings: riscv: sunxi: add the YuzukiHD Avaota F2
      riscv: dts: allwinner: add the YuzukiHD Avaota F2 board
      MAINTAINERS: add an entry for the Allwinner V861 SoC

 .../bindings/clock/allwinner,sun252i-v861-ccu.yaml |   99 ++
 .../interrupt-controller/sifive,plic-1.0.0.yaml    |    1 +
 .../pinctrl/allwinner,sun55i-a523-pinctrl.yaml     |   31 +-
 Documentation/devicetree/bindings/riscv/cpus.yaml  |    1 +
 Documentation/devicetree/bindings/riscv/sunxi.yaml |    5 +
 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      |    1 +
 .../devicetree/bindings/timer/sifive,clint.yaml    |    1 +
 MAINTAINERS                                        |   12 +
 arch/riscv/Kconfig.socs                            |    6 +-
 arch/riscv/boot/dts/allwinner/Makefile             |    1 +
 .../boot/dts/allwinner/sun252i-v861-avaota-f2.dts  |   43 +
 arch/riscv/boot/dts/allwinner/sun252i-v861.dtsi    |  272 +++++
 drivers/clk/sunxi-ng/Kconfig                       |   20 +
 drivers/clk/sunxi-ng/Makefile                      |    4 +
 drivers/clk/sunxi-ng/ccu-sun252i-v861-r.c          |  110 ++
 drivers/clk/sunxi-ng/ccu-sun252i-v861.c            | 1117 ++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun6i-rtc.c               |   31 +-
 drivers/pinctrl/sunxi/Kconfig                      |   20 +
 drivers/pinctrl/sunxi/Makefile                     |    2 +
 drivers/pinctrl/sunxi/pinctrl-sun252i-v861-r.c     |   48 +
 drivers/pinctrl/sunxi/pinctrl-sun252i-v861.c       |   49 +
 drivers/pinctrl/sunxi/pinctrl-sunxi.h              |    7 +-
 include/dt-bindings/clock/sun252i-v861-ccu.h       |  127 +++
 include/dt-bindings/clock/sun252i-v861-r-ccu.h     |   14 +
 include/dt-bindings/reset/sun252i-v861-ccu.h       |   55 +
 include/dt-bindings/reset/sun252i-v861-r-ccu.h     |   12 +
 26 files changed, 2080 insertions(+), 9 deletions(-)
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261114-v861-01f7c38f9d0e

Best regards,
--  
Han Gao <gaohan@iscas.ac.cn>



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

* [PATCH 01/19] riscv: sunxi: describe the wider Allwinner SoC family
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 02/19] dt-bindings: riscv: cpus: add the XuanTie C907 Han Gao via B4 Relay
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

ARCH_SUNXI is about to cover the V861 as well. Update its prompt and
help text instead of adding another option.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 arch/riscv/Kconfig.socs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index cecbce0c4983..4cf3b24467e8 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -61,13 +61,13 @@ config SOC_STARFIVE
 	  This enables support for StarFive SoC platform hardware.
 
 config ARCH_SUNXI
-	bool "Allwinner sun20i SoCs"
+	bool "Allwinner SoCs"
 	depends on MMU
 	select ERRATA_THEAD
 	select SUN4I_TIMER
 	help
-	  This enables support for Allwinner sun20i platform hardware,
-	  including boards based on the D1 and D1s SoCs.
+	  This enables support for Allwinner SoC platform hardware,
+	  including boards based on the D1, D1s and V861 SoCs.
 
 config ARCH_TENSTORRENT
 	bool "Tenstorrent SoCs"

-- 
2.55.0



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

* [PATCH 02/19] dt-bindings: riscv: cpus: add the XuanTie C907
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 01/19] riscv: sunxi: describe the wider Allwinner SoC family Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 03/19] dt-bindings: interrupt-controller: add the Allwinner V861 PLIC Han Gao via B4 Relay
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add the XuanTie C907, used in the Allwinner V861.

XuanTie is a brand of C-SKY Microsystems [1], whose JEP106 ID 0x5b7 [2]
is what the C907 reports in mvendorid, so use the csky prefix rather
than thead.

[1] https://www.xrvm.com/declaration
[2] https://www.jedec.org/standards-documents/docs/jep-106ab

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 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 0da219ae6769..bdb119ab8ee0 100644
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
@@ -48,6 +48,7 @@ properties:
               - amd,mbv64
               - andestech,ax45mp
               - canaan,k210
+              - csky,c907
               - nuclei,ux900
               - sifive,bullet0
               - sifive,e5

-- 
2.55.0



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

* [PATCH 03/19] dt-bindings: interrupt-controller: add the Allwinner V861 PLIC
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 01/19] riscv: sunxi: describe the wider Allwinner SoC family Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 02/19] dt-bindings: riscv: cpus: add the XuanTie C907 Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 04/19] dt-bindings: timer: add the Allwinner V861 CLINT Han Gao via B4 Relay
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The V861 uses the XuanTie C900 PLIC implementation, like the D1. Add an
SoC-specific compatible with "thead,c900-plic" as the fallback.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 .../devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml      | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
index cde4bb691897..6178fea9bbdc 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
@@ -72,6 +72,7 @@ properties:
       - items:
           - enum:
               - allwinner,sun20i-d1-plic
+              - allwinner,sun252i-v861-plic
               - canaan,k230-plic
               - sophgo,cv1800b-plic
               - sophgo,cv1812h-plic

-- 
2.55.0



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

* [PATCH 04/19] dt-bindings: timer: add the Allwinner V861 CLINT
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (2 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 03/19] dt-bindings: interrupt-controller: add the Allwinner V861 PLIC Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 05/19] dt-bindings: clock: sunxi-ng: document the Allwinner V861 CCUs Han Gao via B4 Relay
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The V861 uses the XuanTie C900 CLINT implementation, like the D1. Add an
SoC-specific compatible with "thead,c900-clint" as the fallback.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
index d53f52e80d88..313fb39bd453 100644
--- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
+++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
@@ -49,6 +49,7 @@ properties:
       - items:
           - enum:
               - allwinner,sun20i-d1-clint
+              - allwinner,sun252i-v861-clint
               - canaan,k230-clint
               - sophgo,cv1800b-clint
               - sophgo,cv1812h-clint

-- 
2.55.0



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

* [PATCH 05/19] dt-bindings: clock: sunxi-ng: document the Allwinner V861 CCUs
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (3 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 04/19] dt-bindings: timer: add the Allwinner V861 CLINT Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 06/19] clk: sunxi-ng: add support for the Allwinner V861 CCU Han Gao via B4 Relay
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The V861 has a main CCU and a PRCM CCU. Add the binding and the clock
and reset indices for both.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 .../bindings/clock/allwinner,sun252i-v861-ccu.yaml |  99 ++++++++++++++++
 include/dt-bindings/clock/sun252i-v861-ccu.h       | 127 +++++++++++++++++++++
 include/dt-bindings/clock/sun252i-v861-r-ccu.h     |  14 +++
 include/dt-bindings/reset/sun252i-v861-ccu.h       |  55 +++++++++
 include/dt-bindings/reset/sun252i-v861-r-ccu.h     |  12 ++
 5 files changed, 307 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun252i-v861-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun252i-v861-ccu.yaml
new file mode 100644
index 000000000000..29fc23ab2401
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/allwinner,sun252i-v861-ccu.yaml
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/allwinner,sun252i-v861-ccu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner V861 Clock Control Unit
+
+maintainers:
+  - Han Gao <gaohan@iscas.ac.cn>
+
+properties:
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  compatible:
+    enum:
+      - allwinner,sun252i-v861-ccu
+      - allwinner,sun252i-v861-r-ccu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 3
+    maxItems: 4
+
+  clock-names:
+    minItems: 3
+    maxItems: 4
+
+required:
+  - "#clock-cells"
+  - "#reset-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          enum:
+            - allwinner,sun252i-v861-ccu
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: High Frequency Oscillator (usually at 24MHz)
+            - description: Low Frequency Oscillator (usually at 32kHz)
+            - description: Internal Oscillator
+
+        clock-names:
+          items:
+            - const: hosc
+            - const: losc
+            - const: iosc
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - allwinner,sun252i-v861-r-ccu
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: High Frequency Oscillator (usually at 24MHz)
+            - description: Low Frequency Oscillator (usually at 32kHz)
+            - description: Internal Oscillator
+            - description: Peripherals PLL (200 MHz output)
+
+        clock-names:
+          items:
+            - const: hosc
+            - const: losc
+            - const: iosc
+            - const: pll-periph
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@2001000 {
+        compatible = "allwinner,sun252i-v861-ccu";
+        reg = <0x02001000 0x1000>;
+        clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
+        clock-names = "hosc", "losc", "iosc";
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
+
+...
diff --git a/include/dt-bindings/clock/sun252i-v861-ccu.h b/include/dt-bindings/clock/sun252i-v861-ccu.h
new file mode 100644
index 000000000000..1123b894a493
--- /dev/null
+++ b/include/dt-bindings/clock/sun252i-v861-ccu.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN252I_V861_CCU_H_
+#define _DT_BINDINGS_CLK_SUN252I_V861_CCU_H_
+
+#define CLK_PLL_DDR		0
+#define CLK_PLL_PERIPH0_4X	1
+#define CLK_PLL_PERIPH0_2X	2
+#define CLK_PLL_PERIPH0_800M	3
+#define CLK_PLL_PERIPH0_480M	4
+#define CLK_PLL_PERIPH0_600M	5
+#define CLK_PLL_PERIPH0_400M	6
+#define CLK_PLL_PERIPH0_300M	7
+#define CLK_PLL_PERIPH0_200M	8
+#define CLK_PLL_PERIPH0_160M	9
+#define CLK_PLL_PERIPH0_150M	10
+#define CLK_PLL_VIDEO_8X	11
+#define CLK_PLL_VIDEO_4X	12
+#define CLK_PLL_VIDEO_2X	13
+#define CLK_PLL_VIDEO_1X	14
+#define CLK_PLL_CSI_8X		15
+#define CLK_PLL_CSI_4X		16
+#define CLK_PLL_CSI_2X		17
+#define CLK_PLL_CSI_1X		18
+#define CLK_PLL_AUDIO		19
+#define CLK_PLL_AUDIO_DIV2	20
+#define CLK_PLL_AUDIO_DIV3	21
+#define CLK_PLL_AUDIO_DIV5	22
+#define CLK_PLL_AUDIO_4X	23
+#define CLK_PLL_AUDIO_1X	24
+#define CLK_PLL_NPU_8X		25
+#define CLK_PLL_NPU_4X		26
+#define CLK_PLL_NPU_2X		27
+#define CLK_PLL_NPU_1X		28
+#define CLK_AHB			29
+#define CLK_APB0		30
+#define CLK_APB1		31
+#define CLK_APB_UART		32
+#define CLK_DE			33
+#define CLK_BUS_DE		34
+#define CLK_G2D			35
+#define CLK_BUS_G2D		36
+#define CLK_CE			37
+#define CLK_BUS_CE		38
+#define CLK_BUS_CE_SYS		39
+#define CLK_VE			40
+#define CLK_BUS_VE		41
+#define CLK_NPU			42
+#define CLK_BUS_NPU		43
+#define CLK_BUS_SGDMA		44
+#define CLK_BUS_NDMA		45
+#define CLK_BUS_MSGBOX0		46
+#define CLK_BUS_MSGBOX1		47
+#define CLK_BUS_SPINLOCK	48
+#define CLK_BUS_HSTIMER		49
+#define CLK_AVS			50
+#define CLK_BUS_TIMER		51
+#define CLK_BUS_DBG		52
+#define CLK_BUS_PWM		53
+#define CLK_DRAM		54
+#define CLK_MBUS		55
+#define CLK_MBUS_DMA		56
+#define CLK_MBUS_VE		57
+#define CLK_MBUS_CE		58
+#define CLK_MBUS_CSI		59
+#define CLK_MBUS_ISP		60
+#define CLK_MBUS_G2D		61
+#define CLK_BUS_DRAM		62
+#define CLK_MMC0		63
+#define CLK_MMC1		64
+#define CLK_MMC2		65
+#define CLK_BUS_MMC0		66
+#define CLK_BUS_MMC1		67
+#define CLK_BUS_MMC2		68
+#define CLK_PSRAM		69
+#define CLK_BUS_PSRAM		70
+#define CLK_BUS_UART0		71
+#define CLK_BUS_UART1		72
+#define CLK_BUS_UART2		73
+#define CLK_BUS_UART3		74
+#define CLK_BUS_I2C0		75
+#define CLK_BUS_I2C1		76
+#define CLK_BUS_I2C2		77
+#define CLK_BUS_I2C3		78
+#define CLK_SPI0		79
+#define CLK_SPI1		80
+#define CLK_SPI2		81
+#define CLK_SPIF		82
+#define CLK_BUS_SPI0		83
+#define CLK_BUS_SPI1		84
+#define CLK_BUS_SPI2		85
+#define CLK_BUS_SPIF		86
+#define CLK_GMAC_25M		87
+#define CLK_BUS_GMAC		88
+#define CLK_BUS_GPADC		89
+#define CLK_BUS_THS		90
+#define CLK_I2S0		91
+#define CLK_BUS_I2S0		92
+#define CLK_AUDIO_CODEC_DAC	93
+#define CLK_AUDIO_CODEC_ADC	94
+#define CLK_BUS_AUDIO_CODEC	95
+#define CLK_USB_OHCI0		96
+#define CLK_BUS_OHCI0		97
+#define CLK_BUS_EHCI0		98
+#define CLK_BUS_OTG		99
+#define CLK_BUS_DPSS_TOP	100
+#define CLK_TCON_LCD		101
+#define CLK_BUS_TCON_LCD	102
+#define CLK_CSI			103
+#define CLK_CSI_MCLK0		104
+#define CLK_CSI_MCLK1		105
+#define CLK_CSI_MCLK2		106
+#define CLK_BUS_CSI		107
+#define CLK_FANOUT_24M		108
+#define CLK_FANOUT_12M		109
+#define CLK_FANOUT_16M		110
+#define CLK_FANOUT_25M		111
+#define CLK_FANOUT_27M		112
+#define CLK_FANOUT_PCLK		113
+#define CLK_FANOUT0		114
+#define CLK_FANOUT1		115
+#define CLK_FANOUT2		116
+
+#endif /* _DT_BINDINGS_CLK_SUN252I_V861_CCU_H_ */
diff --git a/include/dt-bindings/clock/sun252i-v861-r-ccu.h b/include/dt-bindings/clock/sun252i-v861-r-ccu.h
new file mode 100644
index 000000000000..41eaf8aab2c0
--- /dev/null
+++ b/include/dt-bindings/clock/sun252i-v861-r-ccu.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN252I_V861_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN252I_V861_R_CCU_H_
+
+#define CLK_R_AHB		0
+#define CLK_R_APB0		1
+#define CLK_BUS_R_PPU		2
+#define CLK_BUS_R_RTC		3
+
+#endif /* _DT_BINDINGS_CLK_SUN252I_V861_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun252i-v861-ccu.h b/include/dt-bindings/reset/sun252i-v861-ccu.h
new file mode 100644
index 000000000000..4e0245c6c99a
--- /dev/null
+++ b/include/dt-bindings/reset/sun252i-v861-ccu.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN252I_V861_CCU_H_
+#define _DT_BINDINGS_RST_SUN252I_V861_CCU_H_
+
+#define RST_MBUS		0
+#define RST_BUS_DE		1
+#define RST_BUS_G2D		2
+#define RST_BUS_CE		3
+#define RST_BUS_CE_SYS		4
+#define RST_BUS_VE		5
+#define RST_BUS_NPU		6
+#define RST_BUS_SGDMA		7
+#define RST_BUS_NDMA		8
+#define RST_BUS_MSGBOX0		9
+#define RST_BUS_MSGBOX1		10
+#define RST_BUS_SPINLOCK	11
+#define RST_BUS_HSTIMER		12
+#define RST_BUS_TIMER		13
+#define RST_BUS_DBG		14
+#define RST_BUS_PWM		15
+#define RST_BUS_DRAM		16
+#define RST_BUS_MMC0		17
+#define RST_BUS_MMC1		18
+#define RST_BUS_MMC2		19
+#define RST_BUS_PSRAM		20
+#define RST_BUS_UART0		21
+#define RST_BUS_UART1		22
+#define RST_BUS_UART2		23
+#define RST_BUS_UART3		24
+#define RST_BUS_I2C0		25
+#define RST_BUS_I2C1		26
+#define RST_BUS_I2C2		27
+#define RST_BUS_I2C3		28
+#define RST_BUS_SPI0		29
+#define RST_BUS_SPI1		30
+#define RST_BUS_SPI2		31
+#define RST_BUS_SPIF		32
+#define RST_BUS_GMAC		33
+#define RST_BUS_GPADC		34
+#define RST_BUS_THS		35
+#define RST_BUS_I2S0		36
+#define RST_BUS_AUDIO_CODEC	37
+#define RST_USB_PHY0		38
+#define RST_BUS_OHCI0		39
+#define RST_BUS_EHCI0		40
+#define RST_BUS_OTG		41
+#define RST_BUS_DPSS_TOP	42
+#define RST_BUS_TCON_LCD	43
+#define RST_BUS_CSI		44
+
+#endif /* _DT_BINDINGS_RST_SUN252I_V861_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun252i-v861-r-ccu.h b/include/dt-bindings/reset/sun252i-v861-r-ccu.h
new file mode 100644
index 000000000000..ed0f3063df49
--- /dev/null
+++ b/include/dt-bindings/reset/sun252i-v861-r-ccu.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN252I_V861_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN252I_V861_R_CCU_H_
+
+#define RST_BUS_R_PPU		0
+#define RST_BUS_R_RTC		1
+
+#endif /* _DT_BINDINGS_RST_SUN252I_V861_R_CCU_H_ */

-- 
2.55.0



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

* [PATCH 06/19] clk: sunxi-ng: add support for the Allwinner V861 CCU
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (4 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 05/19] dt-bindings: clock: sunxi-ng: document the Allwinner V861 CCUs Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:46   ` sashiko-bot
  2026-11-13 22:33 ` [PATCH 07/19] clk: sunxi-ng: add support for the Allwinner V861 PRCM CCU Han Gao via B4 Relay
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add the main CCU driver for the V861, based on the A523 one. The CPU
PLL, the CPU subsystem clocks and the E907 clocks are left to the
firmware.

Unlike on the A523, the second divider of the 27 MHz output is a power
of two. pll-audio-4x does not pass rate changes up, as its parent also
feeds the UART clock mux.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/clk/sunxi-ng/Kconfig            |   10 +
 drivers/clk/sunxi-ng/Makefile           |    2 +
 drivers/clk/sunxi-ng/ccu-sun252i-v861.c | 1117 +++++++++++++++++++++++++++++++
 3 files changed, 1129 insertions(+)

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 6af2d020e03e..890a0cbb45b6 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -22,6 +22,16 @@ config SUN20I_D1_R_CCU
 	default ARCH_SUNXI
 	depends on MACH_SUN8I || RISCV || COMPILE_TEST
 
+config SUN252I_V861_CCU
+	tristate "Support for the Allwinner V861 CCU"
+	default ARCH_SUNXI
+	depends on RISCV || COMPILE_TEST
+	help
+	  Support for the main clock control unit of the Allwinner V861
+	  SoC. It provides the PLLs, the bus and module clocks and the
+	  reset lines of most peripherals, so it is required on boards
+	  based on this SoC.
+
 config SUN50I_A64_CCU
 	tristate "Support for the Allwinner A64 CCU"
 	default ARCH_SUNXI
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index a1c4087d7241..01869330dc4e 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -27,6 +27,7 @@ sunxi-ccu-y			+= ccu_mp.o
 obj-$(CONFIG_SUNIV_F1C100S_CCU)	+= suniv-f1c100s-ccu.o
 obj-$(CONFIG_SUN20I_D1_CCU)	+= sun20i-d1-ccu.o
 obj-$(CONFIG_SUN20I_D1_R_CCU)	+= sun20i-d1-r-ccu.o
+obj-$(CONFIG_SUN252I_V861_CCU)	+= sun252i-v861-ccu.o
 obj-$(CONFIG_SUN50I_A64_CCU)	+= sun50i-a64-ccu.o
 obj-$(CONFIG_SUN50I_A100_CCU)	+= sun50i-a100-ccu.o
 obj-$(CONFIG_SUN50I_A100_R_CCU)	+= sun50i-a100-r-ccu.o
@@ -55,6 +56,7 @@ obj-$(CONFIG_SUN9I_A80_CCU)	+= sun9i-a80-usb-ccu.o
 suniv-f1c100s-ccu-y		+= ccu-suniv-f1c100s.o
 sun20i-d1-ccu-y			+= ccu-sun20i-d1.o
 sun20i-d1-r-ccu-y		+= ccu-sun20i-d1-r.o
+sun252i-v861-ccu-y		+= ccu-sun252i-v861.o
 sun50i-a64-ccu-y		+= ccu-sun50i-a64.o
 sun50i-a100-ccu-y		+= ccu-sun50i-a100.o
 sun50i-a100-r-ccu-y		+= ccu-sun50i-a100-r.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun252i-v861.c b/drivers/clk/sunxi-ng/ccu-sun252i-v861.c
new file mode 100644
index 000000000000..af84c49fbaf1
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun252i-v861.c
@@ -0,0 +1,1117 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ *
+ * Based on the A523 CCU driver:
+ *   Copyright (C) 2023-2024 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/sun252i-v861-ccu.h>
+#include <dt-bindings/reset/sun252i-v861-ccu.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mux.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+static const struct clk_parent_data osc24M[] = {
+	{ .fw_name = "hosc" }
+};
+
+/**************************************************************************
+ *                              PLLs                                      *
+ **************************************************************************/
+
+/* The CPU PLL at 0x000 is left to the firmware. */
+
+#define SUN252I_V861_PLL_DDR_REG	0x010
+static struct ccu_nkmp pll_ddr_clk = {
+	.enable		= BIT(27),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 11),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.p		= _SUNXI_CCU_DIV(0, 1), /* output divider */
+	.common		= {
+		.reg		= SUN252I_V861_PLL_DDR_REG,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-ddr", osc24M,
+							   &ccu_nkmp_ops,
+							   CLK_SET_RATE_GATE |
+							   CLK_IS_CRITICAL),
+	},
+};
+
+/*
+ * There is no clock output at the VCO rate (2.4 GHz). The outputs have their
+ * own dividers, so model them as divider clocks of the VCO.
+ */
+#define SUN252I_V861_PLL_PERIPH0_REG	0x020
+static struct ccu_nm pll_periph0_4x_clk = {
+	.enable		= BIT(27),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 11),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.common		= {
+		.reg		= SUN252I_V861_PLL_PERIPH0_REG,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-periph0-4x",
+							   osc24M, &ccu_nm_ops,
+							   CLK_SET_RATE_GATE),
+	},
+};
+
+static const struct clk_hw *pll_periph0_4x_hws[] = {
+	&pll_periph0_4x_clk.common.hw
+};
+
+static SUNXI_CCU_M_HWS(pll_periph0_2x_clk, "pll-periph0-2x",
+		       pll_periph0_4x_hws, 0x020, 16, 3, 0);
+static const struct clk_hw *pll_periph0_2x_hws[] = {
+	&pll_periph0_2x_clk.common.hw
+};
+
+static SUNXI_CCU_M_HWS(pll_periph0_800M_clk, "pll-periph0-800M",
+		       pll_periph0_4x_hws, 0x020, 20, 3, 0);
+static SUNXI_CCU_M_HWS(pll_periph0_480M_clk, "pll-periph0-480M",
+		       pll_periph0_4x_hws, 0x020, 2, 3, 0);
+static const struct clk_hw *pll_periph0_480M_hws[] = {
+	&pll_periph0_480M_clk.common.hw
+};
+
+static CLK_FIXED_FACTOR_HWS(pll_periph0_600M_clk, "pll-periph0-600M",
+			    pll_periph0_2x_hws, 2, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_periph0_400M_clk, "pll-periph0-400M",
+			    pll_periph0_2x_hws, 3, 1, 0);
+static const struct clk_hw *pll_periph0_400M_hws[] = {
+	&pll_periph0_400M_clk.hw
+};
+
+static CLK_FIXED_FACTOR_HWS(pll_periph0_300M_clk, "pll-periph0-300M",
+			    pll_periph0_2x_hws, 4, 1, 0);
+static const struct clk_hw *pll_periph0_300M_hws[] = {
+	&pll_periph0_300M_clk.hw
+};
+
+static CLK_FIXED_FACTOR_HWS(pll_periph0_200M_clk, "pll-periph0-200M",
+			    pll_periph0_400M_hws, 2, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_periph0_150M_clk, "pll-periph0-150M",
+			    pll_periph0_300M_hws, 2, 1, 0);
+static const struct clk_hw *pll_periph0_150M_hws[] = {
+	&pll_periph0_150M_clk.hw
+};
+
+static CLK_FIXED_FACTOR_HWS(pll_periph0_160M_clk, "pll-periph0-160M",
+			    pll_periph0_480M_hws, 3, 1, 0);
+static const struct clk_hw *pll_periph0_160M_hws[] = {
+	&pll_periph0_160M_clk.hw
+};
+
+/*
+ * The video, CSI and NPU PLLs share one layout: the 4x output divides the
+ * VCO by one or two, while the 2x and 1x outputs divide it by two and four.
+ */
+#define SUN252I_V861_PLL_VIDEO_REG	0x040
+static struct ccu_nm pll_video_8x_clk = {
+	.enable		= BIT(27),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 11),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.common		= {
+		.reg		= SUN252I_V861_PLL_VIDEO_REG,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-video-8x",
+							   osc24M, &ccu_nm_ops,
+							   CLK_SET_RATE_GATE),
+	},
+};
+
+static const struct clk_hw *pll_video_8x_hws[] = {
+	&pll_video_8x_clk.common.hw
+};
+
+static SUNXI_CCU_M_HWS(pll_video_4x_clk, "pll-video-4x",
+		       pll_video_8x_hws, 0x040, 0, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_video_2x_clk, "pll-video-2x",
+			    pll_video_8x_hws, 2, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_video_1x_clk, "pll-video-1x",
+			    pll_video_8x_hws, 4, 1, 0);
+
+#define SUN252I_V861_PLL_CSI_REG	0x048
+static struct ccu_nm pll_csi_8x_clk = {
+	.enable		= BIT(27),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 11),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.common		= {
+		.reg		= SUN252I_V861_PLL_CSI_REG,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-csi-8x",
+							   osc24M, &ccu_nm_ops,
+							   CLK_SET_RATE_GATE),
+	},
+};
+
+static const struct clk_hw *pll_csi_8x_hws[] = {
+	&pll_csi_8x_clk.common.hw
+};
+
+static SUNXI_CCU_M_HWS(pll_csi_4x_clk, "pll-csi-4x",
+		       pll_csi_8x_hws, 0x048, 0, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_csi_2x_clk, "pll-csi-2x",
+			    pll_csi_8x_hws, 2, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_csi_1x_clk, "pll-csi-1x",
+			    pll_csi_8x_hws, 4, 1, 0);
+
+/*
+ * The audio PLL VCO feeds three output dividers. Two further dividers, in
+ * the pre-divider register at 0xe00, derive the 4x and 1x audio clocks.
+ * Their alternative fractional dividers are not used, see the probe function.
+ */
+#define SUN252I_V861_PLL_AUDIO_REG	0x078
+static struct ccu_nm pll_audio_clk = {
+	.enable		= BIT(27),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 11),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.common		= {
+		.reg		= SUN252I_V861_PLL_AUDIO_REG,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-audio",
+							   osc24M, &ccu_nm_ops,
+							   CLK_SET_RATE_GATE),
+	},
+};
+
+static const struct clk_hw *pll_audio_hws[] = {
+	&pll_audio_clk.common.hw
+};
+
+static SUNXI_CCU_M_HWS(pll_audio_div2_clk, "pll-audio-div2",
+		       pll_audio_hws, 0x078, 16, 3, 0);
+static SUNXI_CCU_M_HWS(pll_audio_div3_clk, "pll-audio-div3",
+		       pll_audio_hws, 0x078, 20, 3, 0);
+static SUNXI_CCU_M_HWS(pll_audio_div5_clk, "pll-audio-div5",
+		       pll_audio_hws, 0x078, 2, 3, 0);
+static const struct clk_hw *pll_audio_div2_hws[] = {
+	&pll_audio_div2_clk.common.hw
+};
+
+static const struct clk_hw *pll_audio_div5_hws[] = {
+	&pll_audio_div5_clk.common.hw
+};
+
+/*
+ * The audio PLL P0 divider also feeds the UART bus clock mux, so keep audio
+ * rate changes from propagating to it.
+ */
+#define SUN252I_V861_PLL_AUDIO_PRE_DIV_REG	0xe00
+static SUNXI_CCU_M_HWS(pll_audio_4x_clk, "pll-audio-4x",
+		       pll_audio_div2_hws, 0xe00, 5, 5, 0);
+static SUNXI_CCU_M_HWS(pll_audio_1x_clk, "pll-audio-1x",
+		       pll_audio_div5_hws, 0xe00, 0, 5, CLK_SET_RATE_PARENT);
+
+#define SUN252I_V861_PLL_NPU_REG	0x080
+static struct ccu_nm pll_npu_8x_clk = {
+	.enable		= BIT(27),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 11),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.common		= {
+		.reg		= SUN252I_V861_PLL_NPU_REG,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("pll-npu-8x",
+							   osc24M, &ccu_nm_ops,
+							   CLK_SET_RATE_GATE),
+	},
+};
+
+static const struct clk_hw *pll_npu_8x_hws[] = {
+	&pll_npu_8x_clk.common.hw
+};
+
+static SUNXI_CCU_M_HWS(pll_npu_4x_clk, "pll-npu-4x",
+		       pll_npu_8x_hws, 0x080, 0, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_npu_2x_clk, "pll-npu-2x",
+			    pll_npu_8x_hws, 2, 1, 0);
+static CLK_FIXED_FACTOR_HWS(pll_npu_1x_clk, "pll-npu-1x",
+			    pll_npu_8x_hws, 4, 1, 0);
+
+/**************************************************************************
+ *                           bus clocks                                   *
+ **************************************************************************/
+
+/*
+ * The CPU subsystem clocks between 0x4fc and 0x50c, including the IPMC used
+ * for CPU power management, are left to the firmware.
+ */
+
+static const struct clk_parent_data ahb_apb_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .fw_name = "losc" },
+	{ .fw_name = "iosc" },
+	{ .hw = &pll_periph0_600M_clk.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(ahb_clk, "ahb", ahb_apb_parents, 0x510,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  CLK_IS_CRITICAL);
+static const struct clk_hw *ahb_hws[] = { &ahb_clk.common.hw };
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(apb0_clk, "apb0", ahb_apb_parents, 0x520,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  0);
+static const struct clk_hw *apb0_hws[] = { &apb0_clk.common.hw };
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(apb1_clk, "apb1", ahb_apb_parents, 0x524,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  0);
+static const struct clk_hw *apb1_hws[] = { &apb1_clk.common.hw };
+
+static const struct clk_parent_data apb_uart_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .fw_name = "losc" },
+	{ .fw_name = "iosc" },
+	{ .hw = &pll_periph0_600M_clk.hw },
+	{ .hw = &pll_audio_div2_clk.common.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(apb_uart_clk, "apb-uart", apb_uart_parents,
+				  0x528,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  0);
+static const struct clk_hw *apb_uart_hws[] = { &apb_uart_clk.common.hw };
+
+/**************************************************************************
+ *                          mod clocks with gates                         *
+ **************************************************************************/
+
+static const struct clk_hw *de_g2d_parents[] = {
+	&pll_periph0_300M_clk.hw,
+	&pll_video_1x_clk.hw,
+};
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(de_clk, "de", de_g2d_parents, 0x600,
+				    0, 5,	/* M */
+				    24, 1,	/* mux */
+				    BIT(31),	/* gate */
+				    0);
+
+static SUNXI_CCU_GATE_HWS(bus_de_clk, "bus-de", ahb_hws, 0x60c, BIT(0), 0);
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(g2d_clk, "g2d", de_g2d_parents, 0x630,
+				    0, 5,	/* M */
+				    24, 1,	/* mux */
+				    BIT(31),	/* gate */
+				    0);
+
+static SUNXI_CCU_GATE_HWS(bus_g2d_clk, "bus-g2d", ahb_hws, 0x63c, BIT(0), 0);
+
+static const struct clk_parent_data ce_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_periph0_400M_clk.hw },
+	{ .hw = &pll_periph0_300M_clk.hw },
+};
+
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
+				      0, 4,	/* M */
+				      24, 3,	/* mux */
+				      BIT(31),	/* gate */
+				      0);
+
+static SUNXI_CCU_GATE_HWS(bus_ce_clk, "bus-ce", ahb_hws, 0x68c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ce_sys_clk, "bus-ce-sys", ahb_hws, 0x68c,
+			  BIT(1), 0);
+
+static const struct clk_hw *ve_parents[] = {
+	&pll_periph0_300M_clk.hw,
+	&pll_periph0_400M_clk.hw,
+	&pll_periph0_480M_clk.common.hw,
+	&pll_periph0_600M_clk.hw,
+	&pll_video_4x_clk.common.hw,
+	&pll_csi_4x_clk.common.hw,
+	&pll_audio_div3_clk.common.hw,
+};
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
+				    0, 5,	/* M */
+				    24, 3,	/* mux */
+				    BIT(31),	/* gate */
+				    0);
+
+static SUNXI_CCU_GATE_HWS(bus_ve_clk, "bus-ve", ahb_hws, 0x69c, BIT(0), 0);
+
+static const struct clk_hw *npu_parents[] = {
+	&pll_periph0_800M_clk.common.hw,
+	&pll_periph0_600M_clk.hw,
+	&pll_npu_4x_clk.common.hw,
+};
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(npu_clk, "npu", npu_parents, 0x6e0,
+				    0, 5,	/* M */
+				    24, 2,	/* mux */
+				    BIT(31),	/* gate */
+				    0);
+
+static SUNXI_CCU_GATE_HWS(bus_npu_clk, "bus-npu", ahb_hws, 0x6ec, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_sgdma_clk, "bus-sgdma", ahb_hws, 0x70c,
+			  BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ndma_clk, "bus-ndma", ahb_hws, 0x70c,
+			  BIT(1), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_msgbox0_clk, "bus-msgbox0", ahb_hws, 0x71c,
+			  BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_msgbox1_clk, "bus-msgbox1", ahb_hws, 0x71c,
+			  BIT(1), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_spinlock_clk, "bus-spinlock", ahb_hws, 0x72c,
+			  BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_hstimer_clk, "bus-hstimer", ahb_hws, 0x73c,
+			  BIT(0), 0);
+
+static SUNXI_CCU_GATE_DATA(avs_clk, "avs", osc24M, 0x740, BIT(31), 0);
+
+/* The timer bus clock gate has its own register, apart from the reset. */
+static SUNXI_CCU_GATE_HWS(bus_timer_clk, "bus-timer", apb0_hws, 0x744,
+			  BIT(31), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dbg_clk, "bus-dbg", ahb_hws, 0x78c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_pwm_clk, "bus-pwm", apb0_hws, 0x7ac, BIT(0), 0);
+
+static const struct clk_parent_data dram_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_ddr_clk.common.hw },
+	{ .hw = &pll_periph0_2x_clk.common.hw },
+	{ .hw = &pll_periph0_800M_clk.common.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(dram_clk, "dram", dram_parents,
+					    0x800,
+					    0, 5,	/* M */
+					    8, 2,	/* P */
+					    24, 3,	/* mux */
+					    BIT(31),	/* gate */
+					    CLK_IS_CRITICAL,
+					    CCU_FEATURE_UPDATE_BIT);
+
+/* MBUS runs at a quarter of the DRAM clock. */
+static CLK_FIXED_FACTOR_HW(mbus_clk, "mbus", &dram_clk.common.hw, 4, 1, 0);
+static const struct clk_hw *mbus_hws[] = { &mbus_clk.hw };
+
+static SUNXI_CCU_GATE_HWS(mbus_dma_clk, "mbus-dma", mbus_hws,
+			  0x804, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ve_clk, "mbus-ve", mbus_hws,
+			  0x804, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
+			  0x804, BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
+			  0x804, BIT(8), 0);
+static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
+			  0x804, BIT(9), 0);
+static SUNXI_CCU_GATE_HWS(mbus_g2d_clk, "mbus-g2d", mbus_hws,
+			  0x804, BIT(10), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dram_clk, "bus-dram", ahb_hws, 0x80c,
+			  BIT(0), CLK_IS_CRITICAL);
+
+/*
+ * The MMC controllers use timing mode 1, in which the card clock is half
+ * of the module clock, so model that with a fixed post-divider.
+ */
+static const struct clk_parent_data mmc0_mmc1_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_periph0_400M_clk.hw },
+	{ .hw = &pll_periph0_300M_clk.hw },
+	{ .hw = &pll_video_4x_clk.common.hw },
+	{ .hw = &pll_ddr_clk.common.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0",
+					       mmc0_mmc1_parents, 0x830,
+					       0, 4,	/* M */
+					       8, 2,	/* P */
+					       24, 3,	/* mux */
+					       BIT(31),	/* gate */
+					       2,	/* post-div */
+					       0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1",
+					       mmc0_mmc1_parents, 0x834,
+					       0, 4,	/* M */
+					       8, 2,	/* P */
+					       24, 3,	/* mux */
+					       BIT(31),	/* gate */
+					       2,	/* post-div */
+					       0);
+
+static const struct clk_parent_data mmc2_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_periph0_600M_clk.hw },
+	{ .hw = &pll_periph0_800M_clk.common.hw },
+	{ .hw = &pll_video_4x_clk.common.hw },
+	{ .hw = &pll_ddr_clk.common.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2",
+					       mmc2_parents, 0x838,
+					       0, 4,	/* M */
+					       8, 2,	/* P */
+					       24, 3,	/* mux */
+					       BIT(31),	/* gate */
+					       2,	/* post-div */
+					       0);
+
+static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", ahb_hws, 0x84c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_mmc1_clk, "bus-mmc1", ahb_hws, 0x84c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_mmc2_clk, "bus-mmc2", ahb_hws, 0x84c, BIT(2), 0);
+
+static const struct clk_parent_data psram_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_periph0_480M_clk.common.hw },
+	{ .hw = &pll_periph0_400M_clk.hw },
+	{ .hw = &pll_periph0_300M_clk.hw },
+};
+
+static SUNXI_CCU_M_DATA_WITH_MUX_GATE(psram_clk, "psram", psram_parents, 0x850,
+				      0, 5,	/* M */
+				      24, 3,	/* mux */
+				      BIT(31),	/* gate */
+				      0);
+
+static SUNXI_CCU_GATE_HWS(bus_psram_clk, "bus-psram", ahb_hws, 0x85c,
+			  BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_uart0_clk, "bus-uart0", apb_uart_hws, 0x90c,
+			  BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart1_clk, "bus-uart1", apb_uart_hws, 0x90c,
+			  BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart2_clk, "bus-uart2", apb_uart_hws, 0x90c,
+			  BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart3_clk, "bus-uart3", apb_uart_hws, 0x90c,
+			  BIT(3), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_i2c0_clk, "bus-i2c0", apb1_hws, 0x91c,
+			  BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c1_clk, "bus-i2c1", apb1_hws, 0x91c,
+			  BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c2_clk, "bus-i2c2", apb1_hws, 0x91c,
+			  BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c3_clk, "bus-i2c3", apb1_hws, 0x91c,
+			  BIT(3), 0);
+
+static const struct clk_parent_data spi_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_periph0_300M_clk.hw },
+	{ .hw = &pll_periph0_200M_clk.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
+				       0, 4,	/* M */
+				       8, 2,	/* P */
+				       24, 3,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
+				       0, 4,	/* M */
+				       8, 2,	/* P */
+				       24, 3,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi2_clk, "spi2", spi_parents, 0x948,
+				       0, 4,	/* M */
+				       8, 2,	/* P */
+				       24, 3,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+
+static const struct clk_parent_data spif_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_periph0_400M_clk.hw },
+	{ .hw = &pll_periph0_300M_clk.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spif_clk, "spif", spif_parents, 0x950,
+				       0, 4,	/* M */
+				       8, 2,	/* P */
+				       24, 3,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+
+static SUNXI_CCU_GATE_HWS(bus_spi0_clk, "bus-spi0", ahb_hws, 0x96c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_spi1_clk, "bus-spi1", ahb_hws, 0x96c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(bus_spi2_clk, "bus-spi2", ahb_hws, 0x96c, BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(bus_spif_clk, "bus-spif", ahb_hws, 0x96c, BIT(4), 0);
+
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(gmac_25M_clk, "gmac-25M",
+				      pll_periph0_150M_hws,
+				      0x970, BIT(31) | BIT(30), 6, 0);
+static SUNXI_CCU_GATE_HWS(bus_gmac_clk, "bus-gmac", ahb_hws, 0x97c,
+			  BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_gpadc_clk, "bus-gpadc", apb0_hws, 0x9ec,
+			  BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_ths_clk, "bus-ths", apb0_hws, 0x9fc, BIT(0), 0);
+
+static const struct clk_hw *audio_parents[] = {
+	&pll_audio_1x_clk.common.hw,
+	&pll_audio_4x_clk.common.hw,
+};
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(i2s0_clk, "i2s0", audio_parents, 0xa10,
+				    0, 4,	/* M */
+				    24, 1,	/* mux */
+				    BIT(31),	/* gate */
+				    CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_i2s0_clk, "bus-i2s0", apb0_hws, 0xa2c,
+			  BIT(0), 0);
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(audio_codec_dac_clk, "audio-codec-dac",
+				    audio_parents, 0xa50,
+				    0, 4,	/* M */
+				    24, 1,	/* mux */
+				    BIT(31),	/* gate */
+				    CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(audio_codec_adc_clk, "audio-codec-adc",
+				    audio_parents, 0xa54,
+				    0, 4,	/* M */
+				    24, 1,	/* mux */
+				    BIT(31),	/* gate */
+				    CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_audio_codec_clk, "bus-audio-codec", apb0_hws,
+			  0xa5c, BIT(0), 0);
+
+/*
+ * The first two parents provide 12 MHz, from a 48 MHz clock synchronized by
+ * pll-periph0 and from the 24 MHz oscillator.
+ */
+static const struct clk_parent_data usb_ohci_parents[] = {
+	{ .hw = &pll_periph0_4x_clk.common.hw },
+	{ .fw_name = "hosc" },
+	{ .fw_name = "losc" },
+	{ .fw_name = "iosc" },
+};
+
+static const struct ccu_mux_fixed_prediv usb_ohci_predivs[] = {
+	{ .index = 0, .div = 200 },
+	{ .index = 1, .div = 2 },
+};
+
+static struct ccu_mux usb_ohci0_clk = {
+	.enable		= BIT(31),
+	.mux		= {
+		.shift		= 24,
+		.width		= 2,
+		.fixed_predivs	= usb_ohci_predivs,
+		.n_predivs	= ARRAY_SIZE(usb_ohci_predivs),
+	},
+	.common		= {
+		.reg		= 0xa70,
+		.features	= CCU_FEATURE_FIXED_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("usb-ohci0",
+							   usb_ohci_parents,
+							   &ccu_mux_ops,
+							   0),
+	},
+};
+
+static SUNXI_CCU_GATE_HWS(bus_ohci0_clk, "bus-ohci0", ahb_hws, 0xa8c,
+			  BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ehci0_clk, "bus-ehci0", ahb_hws, 0xa8c,
+			  BIT(4), 0);
+static SUNXI_CCU_GATE_HWS(bus_otg_clk, "bus-otg", ahb_hws, 0xa8c, BIT(8), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dpss_top_clk, "bus-dpss-top", ahb_hws, 0xabc,
+			  BIT(0), 0);
+
+static const struct clk_hw *tcon_lcd_parents[] = {
+	&pll_video_4x_clk.common.hw,
+	&pll_periph0_2x_clk.common.hw,
+	&pll_csi_4x_clk.common.hw,
+};
+
+static SUNXI_CCU_MP_HW_WITH_MUX_GATE(tcon_lcd_clk, "tcon-lcd",
+				     tcon_lcd_parents, 0xb60,
+				     0, 4,	/* M */
+				     8, 2,	/* P */
+				     24, 3,	/* mux */
+				     BIT(31),	/* gate */
+				     CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE_HWS(bus_tcon_lcd_clk, "bus-tcon-lcd", ahb_hws, 0xb7c,
+			  BIT(0), 0);
+
+static const struct clk_hw *csi_parents[] = {
+	&pll_periph0_300M_clk.hw,
+	&pll_periph0_400M_clk.hw,
+	&pll_video_4x_clk.common.hw,
+	&pll_csi_4x_clk.common.hw,
+};
+
+static SUNXI_CCU_M_HW_WITH_MUX_GATE(csi_clk, "csi", csi_parents, 0xc04,
+				    0, 5,	/* M */
+				    24, 3,	/* mux */
+				    BIT(31),	/* gate */
+				    0);
+
+static const struct clk_parent_data csi_mclk_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .hw = &pll_csi_4x_clk.common.hw },
+	{ .hw = &pll_video_4x_clk.common.hw },
+	{ .hw = &pll_periph0_2x_clk.common.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(csi_mclk0_clk, "csi-mclk0",
+				       csi_mclk_parents, 0xc08,
+				       0, 5,	/* M */
+				       8, 2,	/* P */
+				       24, 3,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(csi_mclk1_clk, "csi-mclk1",
+				       csi_mclk_parents, 0xc0c,
+				       0, 5,	/* M */
+				       8, 2,	/* P */
+				       24, 3,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(csi_mclk2_clk, "csi-mclk2",
+				       csi_mclk_parents, 0xc10,
+				       0, 5,	/* M */
+				       8, 2,	/* P */
+				       24, 3,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+
+static SUNXI_CCU_GATE_HWS(bus_csi_clk, "bus-csi", ahb_hws, 0xc2c, BIT(0), 0);
+
+/* The E907 clocks between 0xd00 and 0xd0c are left to the firmware. */
+
+static SUNXI_CCU_GATE_DATA(fanout_24M_clk, "fanout-24M", osc24M,
+			   0xf30, BIT(0), 0);
+static SUNXI_CCU_GATE_DATA_WITH_PREDIV(fanout_12M_clk, "fanout-12M", osc24M,
+				       0xf30, BIT(1), 2, 0);
+
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_16M_clk, "fanout-16M",
+				      pll_periph0_160M_hws,
+				      0xf30, BIT(2), 10, 0);
+static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_25M_clk, "fanout-25M",
+				      pll_periph0_150M_hws,
+				      0xf30, BIT(3), 6, 0);
+
+static const struct clk_parent_data fanout_27M_parents[] = {
+	{ .hw = &pll_video_1x_clk.hw },
+	{ .hw = &pll_csi_1x_clk.hw },
+	{ .hw = &pll_periph0_300M_clk.hw },
+};
+
+/* Unlike in the A523, the second divider is a power of two. */
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(fanout_27M_clk, "fanout-27M",
+				       fanout_27M_parents, 0xf34,
+				       0, 5,	/* M */
+				       8, 2,	/* P */
+				       24, 2,	/* mux */
+				       BIT(31),	/* gate */
+				       0);
+
+static const struct clk_parent_data fanout_pclk_parents[] = {
+	{ .hw = &apb0_clk.common.hw }
+};
+
+static SUNXI_CCU_DUALDIV_MUX_GATE(fanout_pclk_clk, "fanout-pclk",
+				  fanout_pclk_parents, 0xf38,
+				  0, 5,		/* div0 */
+				  5, 5,		/* div1 */
+				  0, 0,		/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static const struct clk_parent_data fanout_parents[] = {
+	{ .fw_name = "losc" },
+	{ .hw = &fanout_12M_clk.common.hw, },
+	{ .hw = &fanout_16M_clk.common.hw, },
+	{ .hw = &fanout_24M_clk.common.hw, },
+	{ .hw = &fanout_25M_clk.common.hw, },
+	{ .hw = &fanout_27M_clk.common.hw, },
+	{ .hw = &fanout_pclk_clk.common.hw, },
+};
+
+static SUNXI_CCU_MUX_DATA_WITH_GATE(fanout0_clk, "fanout0", fanout_parents,
+				    0xf3c,
+				    0, 3,	/* mux */
+				    BIT(21),	/* gate */
+				    0);
+static SUNXI_CCU_MUX_DATA_WITH_GATE(fanout1_clk, "fanout1", fanout_parents,
+				    0xf3c,
+				    3, 3,	/* mux */
+				    BIT(22),	/* gate */
+				    0);
+static SUNXI_CCU_MUX_DATA_WITH_GATE(fanout2_clk, "fanout2", fanout_parents,
+				    0xf3c,
+				    6, 3,	/* mux */
+				    BIT(23),	/* gate */
+				    0);
+
+static struct ccu_common *sun252i_v861_ccu_clks[] = {
+	&pll_ddr_clk.common,
+	&pll_periph0_4x_clk.common,
+	&pll_periph0_2x_clk.common,
+	&pll_periph0_800M_clk.common,
+	&pll_periph0_480M_clk.common,
+	&pll_video_8x_clk.common,
+	&pll_video_4x_clk.common,
+	&pll_csi_8x_clk.common,
+	&pll_csi_4x_clk.common,
+	&pll_audio_clk.common,
+	&pll_audio_div2_clk.common,
+	&pll_audio_div3_clk.common,
+	&pll_audio_div5_clk.common,
+	&pll_audio_4x_clk.common,
+	&pll_audio_1x_clk.common,
+	&pll_npu_8x_clk.common,
+	&pll_npu_4x_clk.common,
+	&ahb_clk.common,
+	&apb0_clk.common,
+	&apb1_clk.common,
+	&apb_uart_clk.common,
+	&de_clk.common,
+	&bus_de_clk.common,
+	&g2d_clk.common,
+	&bus_g2d_clk.common,
+	&ce_clk.common,
+	&bus_ce_clk.common,
+	&bus_ce_sys_clk.common,
+	&ve_clk.common,
+	&bus_ve_clk.common,
+	&npu_clk.common,
+	&bus_npu_clk.common,
+	&bus_sgdma_clk.common,
+	&bus_ndma_clk.common,
+	&bus_msgbox0_clk.common,
+	&bus_msgbox1_clk.common,
+	&bus_spinlock_clk.common,
+	&bus_hstimer_clk.common,
+	&avs_clk.common,
+	&bus_timer_clk.common,
+	&bus_dbg_clk.common,
+	&bus_pwm_clk.common,
+	&dram_clk.common,
+	&mbus_dma_clk.common,
+	&mbus_ve_clk.common,
+	&mbus_ce_clk.common,
+	&mbus_csi_clk.common,
+	&mbus_isp_clk.common,
+	&mbus_g2d_clk.common,
+	&bus_dram_clk.common,
+	&mmc0_clk.common,
+	&mmc1_clk.common,
+	&mmc2_clk.common,
+	&bus_mmc0_clk.common,
+	&bus_mmc1_clk.common,
+	&bus_mmc2_clk.common,
+	&psram_clk.common,
+	&bus_psram_clk.common,
+	&bus_uart0_clk.common,
+	&bus_uart1_clk.common,
+	&bus_uart2_clk.common,
+	&bus_uart3_clk.common,
+	&bus_i2c0_clk.common,
+	&bus_i2c1_clk.common,
+	&bus_i2c2_clk.common,
+	&bus_i2c3_clk.common,
+	&spi0_clk.common,
+	&spi1_clk.common,
+	&spi2_clk.common,
+	&spif_clk.common,
+	&bus_spi0_clk.common,
+	&bus_spi1_clk.common,
+	&bus_spi2_clk.common,
+	&bus_spif_clk.common,
+	&gmac_25M_clk.common,
+	&bus_gmac_clk.common,
+	&bus_gpadc_clk.common,
+	&bus_ths_clk.common,
+	&i2s0_clk.common,
+	&bus_i2s0_clk.common,
+	&audio_codec_dac_clk.common,
+	&audio_codec_adc_clk.common,
+	&bus_audio_codec_clk.common,
+	&usb_ohci0_clk.common,
+	&bus_ohci0_clk.common,
+	&bus_ehci0_clk.common,
+	&bus_otg_clk.common,
+	&bus_dpss_top_clk.common,
+	&tcon_lcd_clk.common,
+	&bus_tcon_lcd_clk.common,
+	&csi_clk.common,
+	&csi_mclk0_clk.common,
+	&csi_mclk1_clk.common,
+	&csi_mclk2_clk.common,
+	&bus_csi_clk.common,
+	&fanout_24M_clk.common,
+	&fanout_12M_clk.common,
+	&fanout_16M_clk.common,
+	&fanout_25M_clk.common,
+	&fanout_27M_clk.common,
+	&fanout_pclk_clk.common,
+	&fanout0_clk.common,
+	&fanout1_clk.common,
+	&fanout2_clk.common,
+};
+
+static struct clk_hw_onecell_data sun252i_v861_hw_clks = {
+	.num	= CLK_FANOUT2 + 1,
+	.hws	= {
+		[CLK_PLL_DDR]		= &pll_ddr_clk.common.hw,
+		[CLK_PLL_PERIPH0_4X]	= &pll_periph0_4x_clk.common.hw,
+		[CLK_PLL_PERIPH0_2X]	= &pll_periph0_2x_clk.common.hw,
+		[CLK_PLL_PERIPH0_800M]	= &pll_periph0_800M_clk.common.hw,
+		[CLK_PLL_PERIPH0_480M]	= &pll_periph0_480M_clk.common.hw,
+		[CLK_PLL_PERIPH0_600M]	= &pll_periph0_600M_clk.hw,
+		[CLK_PLL_PERIPH0_400M]	= &pll_periph0_400M_clk.hw,
+		[CLK_PLL_PERIPH0_300M]	= &pll_periph0_300M_clk.hw,
+		[CLK_PLL_PERIPH0_200M]	= &pll_periph0_200M_clk.hw,
+		[CLK_PLL_PERIPH0_160M]	= &pll_periph0_160M_clk.hw,
+		[CLK_PLL_PERIPH0_150M]	= &pll_periph0_150M_clk.hw,
+		[CLK_PLL_VIDEO_8X]	= &pll_video_8x_clk.common.hw,
+		[CLK_PLL_VIDEO_4X]	= &pll_video_4x_clk.common.hw,
+		[CLK_PLL_VIDEO_2X]	= &pll_video_2x_clk.hw,
+		[CLK_PLL_VIDEO_1X]	= &pll_video_1x_clk.hw,
+		[CLK_PLL_CSI_8X]	= &pll_csi_8x_clk.common.hw,
+		[CLK_PLL_CSI_4X]	= &pll_csi_4x_clk.common.hw,
+		[CLK_PLL_CSI_2X]	= &pll_csi_2x_clk.hw,
+		[CLK_PLL_CSI_1X]	= &pll_csi_1x_clk.hw,
+		[CLK_PLL_AUDIO]		= &pll_audio_clk.common.hw,
+		[CLK_PLL_AUDIO_DIV2]	= &pll_audio_div2_clk.common.hw,
+		[CLK_PLL_AUDIO_DIV3]	= &pll_audio_div3_clk.common.hw,
+		[CLK_PLL_AUDIO_DIV5]	= &pll_audio_div5_clk.common.hw,
+		[CLK_PLL_AUDIO_4X]	= &pll_audio_4x_clk.common.hw,
+		[CLK_PLL_AUDIO_1X]	= &pll_audio_1x_clk.common.hw,
+		[CLK_PLL_NPU_8X]	= &pll_npu_8x_clk.common.hw,
+		[CLK_PLL_NPU_4X]	= &pll_npu_4x_clk.common.hw,
+		[CLK_PLL_NPU_2X]	= &pll_npu_2x_clk.hw,
+		[CLK_PLL_NPU_1X]	= &pll_npu_1x_clk.hw,
+		[CLK_AHB]		= &ahb_clk.common.hw,
+		[CLK_APB0]		= &apb0_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_APB_UART]		= &apb_uart_clk.common.hw,
+		[CLK_DE]		= &de_clk.common.hw,
+		[CLK_BUS_DE]		= &bus_de_clk.common.hw,
+		[CLK_G2D]		= &g2d_clk.common.hw,
+		[CLK_BUS_G2D]		= &bus_g2d_clk.common.hw,
+		[CLK_CE]		= &ce_clk.common.hw,
+		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
+		[CLK_BUS_CE_SYS]	= &bus_ce_sys_clk.common.hw,
+		[CLK_VE]		= &ve_clk.common.hw,
+		[CLK_BUS_VE]		= &bus_ve_clk.common.hw,
+		[CLK_NPU]		= &npu_clk.common.hw,
+		[CLK_BUS_NPU]		= &bus_npu_clk.common.hw,
+		[CLK_BUS_SGDMA]		= &bus_sgdma_clk.common.hw,
+		[CLK_BUS_NDMA]		= &bus_ndma_clk.common.hw,
+		[CLK_BUS_MSGBOX0]	= &bus_msgbox0_clk.common.hw,
+		[CLK_BUS_MSGBOX1]	= &bus_msgbox1_clk.common.hw,
+		[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common.hw,
+		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_BUS_TIMER]		= &bus_timer_clk.common.hw,
+		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
+		[CLK_BUS_PWM]		= &bus_pwm_clk.common.hw,
+		[CLK_DRAM]		= &dram_clk.common.hw,
+		[CLK_MBUS]		= &mbus_clk.hw,
+		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
+		[CLK_MBUS_VE]		= &mbus_ve_clk.common.hw,
+		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
+		[CLK_MBUS_CSI]		= &mbus_csi_clk.common.hw,
+		[CLK_MBUS_ISP]		= &mbus_isp_clk.common.hw,
+		[CLK_MBUS_G2D]		= &mbus_g2d_clk.common.hw,
+		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_MMC2]		= &mmc2_clk.common.hw,
+		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
+		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
+		[CLK_BUS_MMC2]		= &bus_mmc2_clk.common.hw,
+		[CLK_PSRAM]		= &psram_clk.common.hw,
+		[CLK_BUS_PSRAM]		= &bus_psram_clk.common.hw,
+		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
+		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
+		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
+		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
+		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
+		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
+		[CLK_BUS_I2C2]		= &bus_i2c2_clk.common.hw,
+		[CLK_BUS_I2C3]		= &bus_i2c3_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_SPI2]		= &spi2_clk.common.hw,
+		[CLK_SPIF]		= &spif_clk.common.hw,
+		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
+		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
+		[CLK_BUS_SPI2]		= &bus_spi2_clk.common.hw,
+		[CLK_BUS_SPIF]		= &bus_spif_clk.common.hw,
+		[CLK_GMAC_25M]		= &gmac_25M_clk.common.hw,
+		[CLK_BUS_GMAC]		= &bus_gmac_clk.common.hw,
+		[CLK_BUS_GPADC]		= &bus_gpadc_clk.common.hw,
+		[CLK_BUS_THS]		= &bus_ths_clk.common.hw,
+		[CLK_I2S0]		= &i2s0_clk.common.hw,
+		[CLK_BUS_I2S0]		= &bus_i2s0_clk.common.hw,
+		[CLK_AUDIO_CODEC_DAC]	= &audio_codec_dac_clk.common.hw,
+		[CLK_AUDIO_CODEC_ADC]	= &audio_codec_adc_clk.common.hw,
+		[CLK_BUS_AUDIO_CODEC]	= &bus_audio_codec_clk.common.hw,
+		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
+		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
+		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
+		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
+		[CLK_BUS_DPSS_TOP]	= &bus_dpss_top_clk.common.hw,
+		[CLK_TCON_LCD]		= &tcon_lcd_clk.common.hw,
+		[CLK_BUS_TCON_LCD]	= &bus_tcon_lcd_clk.common.hw,
+		[CLK_CSI]		= &csi_clk.common.hw,
+		[CLK_CSI_MCLK0]		= &csi_mclk0_clk.common.hw,
+		[CLK_CSI_MCLK1]		= &csi_mclk1_clk.common.hw,
+		[CLK_CSI_MCLK2]		= &csi_mclk2_clk.common.hw,
+		[CLK_BUS_CSI]		= &bus_csi_clk.common.hw,
+		[CLK_FANOUT_24M]	= &fanout_24M_clk.common.hw,
+		[CLK_FANOUT_12M]	= &fanout_12M_clk.common.hw,
+		[CLK_FANOUT_16M]	= &fanout_16M_clk.common.hw,
+		[CLK_FANOUT_25M]	= &fanout_25M_clk.common.hw,
+		[CLK_FANOUT_27M]	= &fanout_27M_clk.common.hw,
+		[CLK_FANOUT_PCLK]	= &fanout_pclk_clk.common.hw,
+		[CLK_FANOUT0]		= &fanout0_clk.common.hw,
+		[CLK_FANOUT1]		= &fanout1_clk.common.hw,
+		[CLK_FANOUT2]		= &fanout2_clk.common.hw,
+	},
+};
+
+static const struct ccu_reset_map sun252i_v861_ccu_resets[] = {
+	[RST_MBUS]		= { 0x540, BIT(30) },
+	[RST_BUS_DE]		= { 0x60c, BIT(16) },
+	[RST_BUS_G2D]		= { 0x63c, BIT(16) },
+	[RST_BUS_CE]		= { 0x68c, BIT(16) },
+	[RST_BUS_CE_SYS]	= { 0x68c, BIT(17) },
+	[RST_BUS_VE]		= { 0x69c, BIT(16) },
+	[RST_BUS_NPU]		= { 0x6ec, BIT(16) },
+	[RST_BUS_SGDMA]		= { 0x70c, BIT(16) },
+	[RST_BUS_NDMA]		= { 0x70c, BIT(17) },
+	[RST_BUS_MSGBOX0]	= { 0x71c, BIT(16) },
+	[RST_BUS_MSGBOX1]	= { 0x71c, BIT(17) },
+	[RST_BUS_SPINLOCK]	= { 0x72c, BIT(16) },
+	[RST_BUS_HSTIMER]	= { 0x73c, BIT(16) },
+	[RST_BUS_TIMER]		= { 0x74c, BIT(16) },
+	[RST_BUS_DBG]		= { 0x78c, BIT(16) },
+	[RST_BUS_PWM]		= { 0x7ac, BIT(16) },
+	[RST_BUS_DRAM]		= { 0x80c, BIT(16) },
+	[RST_BUS_MMC0]		= { 0x84c, BIT(16) },
+	[RST_BUS_MMC1]		= { 0x84c, BIT(17) },
+	[RST_BUS_MMC2]		= { 0x84c, BIT(18) },
+	[RST_BUS_PSRAM]		= { 0x85c, BIT(16) },
+	[RST_BUS_UART0]		= { 0x90c, BIT(16) },
+	[RST_BUS_UART1]		= { 0x90c, BIT(17) },
+	[RST_BUS_UART2]		= { 0x90c, BIT(18) },
+	[RST_BUS_UART3]		= { 0x90c, BIT(19) },
+	[RST_BUS_I2C0]		= { 0x91c, BIT(16) },
+	[RST_BUS_I2C1]		= { 0x91c, BIT(17) },
+	[RST_BUS_I2C2]		= { 0x91c, BIT(18) },
+	[RST_BUS_I2C3]		= { 0x91c, BIT(19) },
+	[RST_BUS_SPI0]		= { 0x96c, BIT(16) },
+	[RST_BUS_SPI1]		= { 0x96c, BIT(17) },
+	[RST_BUS_SPI2]		= { 0x96c, BIT(18) },
+	[RST_BUS_SPIF]		= { 0x96c, BIT(20) },
+	[RST_BUS_GMAC]		= { 0x97c, BIT(16) },
+	[RST_BUS_GPADC]		= { 0x9ec, BIT(16) },
+	[RST_BUS_THS]		= { 0x9fc, BIT(16) },
+	[RST_BUS_I2S0]		= { 0xa2c, BIT(16) },
+	[RST_BUS_AUDIO_CODEC]	= { 0xa5c, BIT(16) },
+	[RST_USB_PHY0]		= { 0xa70, BIT(30) },
+	[RST_BUS_OHCI0]		= { 0xa8c, BIT(16) },
+	[RST_BUS_EHCI0]		= { 0xa8c, BIT(20) },
+	[RST_BUS_OTG]		= { 0xa8c, BIT(24) },
+	[RST_BUS_DPSS_TOP]	= { 0xabc, BIT(16) },
+	[RST_BUS_TCON_LCD]	= { 0xb7c, BIT(16) },
+	[RST_BUS_CSI]		= { 0xc2c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun252i_v861_ccu_desc = {
+	.ccu_clks	= sun252i_v861_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun252i_v861_ccu_clks),
+
+	.hw_clks	= &sun252i_v861_hw_clks,
+
+	.resets		= sun252i_v861_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun252i_v861_ccu_resets),
+};
+
+static const u32 pll_regs[] = {
+	SUN252I_V861_PLL_DDR_REG,
+	SUN252I_V861_PLL_PERIPH0_REG,
+	SUN252I_V861_PLL_VIDEO_REG,
+	SUN252I_V861_PLL_CSI_REG,
+	SUN252I_V861_PLL_AUDIO_REG,
+	SUN252I_V861_PLL_NPU_REG,
+};
+
+static int sun252i_v861_ccu_probe(struct platform_device *pdev)
+{
+	void __iomem *reg;
+	u32 val;
+	int i;
+
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	/*
+	 * The PLL clock code does not model all bits, for instance it does
+	 * not support a separate enable and gate bit. We present the
+	 * gate bit(27) as the enable bit, but then have to set the
+	 * PLL Enable, LDO Enable, and Lock Enable bits on all PLLs here.
+	 */
+	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
+		val = readl(reg + pll_regs[i]);
+		val |= BIT(31) | BIT(30) | BIT(29);
+		writel(val, reg + pll_regs[i]);
+	}
+
+	/* Derive the 4x and 1x audio clocks from the integer PLL outputs. */
+	val = readl(reg + SUN252I_V861_PLL_AUDIO_PRE_DIV_REG);
+	val &= ~(BIT(28) | BIT(24));
+	writel(val, reg + SUN252I_V861_PLL_AUDIO_PRE_DIV_REG);
+
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun252i_v861_ccu_desc);
+}
+
+static const struct of_device_id sun252i_v861_ccu_ids[] = {
+	{ .compatible = "allwinner,sun252i-v861-ccu" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sun252i_v861_ccu_ids);
+
+static struct platform_driver sun252i_v861_ccu_driver = {
+	.probe	= sun252i_v861_ccu_probe,
+	.driver	= {
+		.name			= "sun252i-v861-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun252i_v861_ccu_ids,
+	},
+};
+module_platform_driver(sun252i_v861_ccu_driver);
+
+MODULE_IMPORT_NS("SUNXI_CCU");
+MODULE_DESCRIPTION("Support for the Allwinner V861 CCU");
+MODULE_LICENSE("GPL");

-- 
2.55.0



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

* [PATCH 07/19] clk: sunxi-ng: add support for the Allwinner V861 PRCM CCU
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (5 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 06/19] clk: sunxi-ng: add support for the Allwinner V861 CCU Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 08/19] dt-bindings: rtc: sun6i: add the Allwinner V861 RTC Han Gao via B4 Relay
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add the PRCM CCU driver for the V861. It provides the R-AHB and R-APB0
bus clocks and the PPU and RTC gates and resets.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/clk/sunxi-ng/Kconfig              |  10 +++
 drivers/clk/sunxi-ng/Makefile             |   2 +
 drivers/clk/sunxi-ng/ccu-sun252i-v861-r.c | 110 ++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+)

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 890a0cbb45b6..0c591b24f085 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -32,6 +32,16 @@ config SUN252I_V861_CCU
 	  reset lines of most peripherals, so it is required on boards
 	  based on this SoC.
 
+config SUN252I_V861_R_CCU
+	tristate "Support for the Allwinner V861 PRCM CCU"
+	default ARCH_SUNXI
+	depends on RISCV || COMPILE_TEST
+	help
+	  Support for the PRCM clock control unit of the Allwinner V861
+	  SoC. It provides the bus clocks and reset lines of the always-on
+	  blocks, such as the RTC and the power management unit, so it is
+	  required on boards based on this SoC.
+
 config SUN50I_A64_CCU
 	tristate "Support for the Allwinner A64 CCU"
 	default ARCH_SUNXI
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 01869330dc4e..851c5ae6dc21 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUNIV_F1C100S_CCU)	+= suniv-f1c100s-ccu.o
 obj-$(CONFIG_SUN20I_D1_CCU)	+= sun20i-d1-ccu.o
 obj-$(CONFIG_SUN20I_D1_R_CCU)	+= sun20i-d1-r-ccu.o
 obj-$(CONFIG_SUN252I_V861_CCU)	+= sun252i-v861-ccu.o
+obj-$(CONFIG_SUN252I_V861_R_CCU)	+= sun252i-v861-r-ccu.o
 obj-$(CONFIG_SUN50I_A64_CCU)	+= sun50i-a64-ccu.o
 obj-$(CONFIG_SUN50I_A100_CCU)	+= sun50i-a100-ccu.o
 obj-$(CONFIG_SUN50I_A100_R_CCU)	+= sun50i-a100-r-ccu.o
@@ -57,6 +58,7 @@ suniv-f1c100s-ccu-y		+= ccu-suniv-f1c100s.o
 sun20i-d1-ccu-y			+= ccu-sun20i-d1.o
 sun20i-d1-r-ccu-y		+= ccu-sun20i-d1-r.o
 sun252i-v861-ccu-y		+= ccu-sun252i-v861.o
+sun252i-v861-r-ccu-y		+= ccu-sun252i-v861-r.o
 sun50i-a64-ccu-y		+= ccu-sun50i-a64.o
 sun50i-a100-ccu-y		+= ccu-sun50i-a100.o
 sun50i-a100-r-ccu-y		+= ccu-sun50i-a100-r.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun252i-v861-r.c b/drivers/clk/sunxi-ng/ccu-sun252i-v861-r.c
new file mode 100644
index 000000000000..9c8de9643722
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun252i-v861-r.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ *
+ * Based on the A523 PRCM CCU driver:
+ *   Copyright (C) 2024 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/sun252i-v861-r-ccu.h>
+#include <dt-bindings/reset/sun252i-v861-r-ccu.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+
+static const struct clk_parent_data r_ahb_apb_parents[] = {
+	{ .fw_name = "hosc" },
+	{ .fw_name = "losc" },
+	{ .fw_name = "iosc" },
+	{ .fw_name = "pll-periph" },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(r_ahb_clk, "r-ahb", r_ahb_apb_parents, 0x000,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  0);
+static const struct clk_hw *r_ahb_hws[] = { &r_ahb_clk.common.hw };
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(r_apb0_clk, "r-apb0", r_ahb_apb_parents,
+				  0x00c,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  0);
+static const struct clk_hw *r_apb0_hws[] = { &r_apb0_clk.common.hw };
+
+static SUNXI_CCU_GATE_HWS(bus_r_ppu_clk, "bus-r-ppu", r_apb0_hws, 0x1ac,
+			  BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_r_rtc_clk, "bus-r-rtc", r_ahb_hws, 0x20c,
+			  BIT(0), 0);
+
+static struct ccu_common *sun252i_v861_r_ccu_clks[] = {
+	&r_ahb_clk.common,
+	&r_apb0_clk.common,
+	&bus_r_ppu_clk.common,
+	&bus_r_rtc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun252i_v861_r_hw_clks = {
+	.num	= CLK_BUS_R_RTC + 1,
+	.hws	= {
+		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
+		[CLK_R_APB0]		= &r_apb0_clk.common.hw,
+		[CLK_BUS_R_PPU]		= &bus_r_ppu_clk.common.hw,
+		[CLK_BUS_R_RTC]		= &bus_r_rtc_clk.common.hw,
+	},
+};
+
+static const struct ccu_reset_map sun252i_v861_r_ccu_resets[] = {
+	[RST_BUS_R_PPU]		= { 0x1ac, BIT(16) },
+	[RST_BUS_R_RTC]		= { 0x20c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun252i_v861_r_ccu_desc = {
+	.ccu_clks	= sun252i_v861_r_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun252i_v861_r_ccu_clks),
+
+	.hw_clks	= &sun252i_v861_r_hw_clks,
+
+	.resets		= sun252i_v861_r_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun252i_v861_r_ccu_resets),
+};
+
+static int sun252i_v861_r_ccu_probe(struct platform_device *pdev)
+{
+	void __iomem *reg;
+
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun252i_v861_r_ccu_desc);
+}
+
+static const struct of_device_id sun252i_v861_r_ccu_ids[] = {
+	{ .compatible = "allwinner,sun252i-v861-r-ccu" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sun252i_v861_r_ccu_ids);
+
+static struct platform_driver sun252i_v861_r_ccu_driver = {
+	.probe	= sun252i_v861_r_ccu_probe,
+	.driver	= {
+		.name			= "sun252i-v861-r-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun252i_v861_r_ccu_ids,
+	},
+};
+module_platform_driver(sun252i_v861_r_ccu_driver);
+
+MODULE_IMPORT_NS("SUNXI_CCU");
+MODULE_DESCRIPTION("Support for the Allwinner V861 PRCM CCU");
+MODULE_LICENSE("GPL");

-- 
2.55.0



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

* [PATCH 08/19] dt-bindings: rtc: sun6i: add the Allwinner V861 RTC
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (6 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 07/19] clk: sunxi-ng: add support for the Allwinner V861 PRCM CCU Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 09/19] clk: sunxi-ng: sun6i-rtc: allow variants without a 32k fanout mux Han Gao via B4 Relay
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The V861 RTC is compatible with the R329 one. Add a compatible with the
R329 one as fallback.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
index ebe35f893f8c..9d05b61acedd 100644
--- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
@@ -33,6 +33,7 @@ properties:
       - items:
           - enum:
               - allwinner,sun20i-d1-rtc
+              - allwinner,sun252i-v861-rtc
               - allwinner,sun55i-a523-rtc
               - allwinner,sun60i-a733-rtc
           - const: allwinner,sun50i-r329-rtc

-- 
2.55.0



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

* [PATCH 09/19] clk: sunxi-ng: sun6i-rtc: allow variants without a 32k fanout mux
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (7 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 08/19] dt-bindings: rtc: sun6i: add the Allwinner V861 RTC Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 10/19] clk: sunxi-ng: sun6i-rtc: allow another 24 MHz to 32k divider ratio Han Gao via B4 Relay
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Some RTC clock blocks have no 32 kHz fanout mux. Do not register the
fanout clock for variants whose match data lists no fanout parents.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index 98ae10307f43..0e40fd5fa624 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -436,8 +436,12 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
 	if (data->rtc_32k_single_parent)
 		rtc_32k_init_data.num_parents = 1;
 
-	osc32k_fanout_init_data.parent_data = data->osc32k_fanout_parents;
-	osc32k_fanout_init_data.num_parents = data->osc32k_fanout_nparents;
+	if (data->osc32k_fanout_nparents) {
+		osc32k_fanout_init_data.parent_data = data->osc32k_fanout_parents;
+		osc32k_fanout_init_data.num_parents = data->osc32k_fanout_nparents;
+	} else {
+		sun6i_rtc_ccu_hw_clks.hws[CLK_OSC32K_FANOUT] = NULL;
+	}
 
 	if (data->have_dcxo_status)
 		sun6i_rtc_ccu_hw_clks.hws[CLK_OSC24M_32K_DIV] =

-- 
2.55.0



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

* [PATCH 10/19] clk: sunxi-ng: sun6i-rtc: allow another 24 MHz to 32k divider ratio
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (8 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 09/19] clk: sunxi-ng: sun6i-rtc: allow variants without a 32k fanout mux Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 11/19] clk: sunxi-ng: sun6i-rtc: add Allwinner V861 support Han Gao via B4 Relay
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The fixed 24 MHz to 32 kHz divider does not divide by 750 on all
variants. Allow the match data to override its multiplier and divider.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index 0e40fd5fa624..b3619222fef0 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -54,6 +54,8 @@ struct sun6i_rtc_match_data {
 	bool				have_dcxo_status	: 1;
 	bool				have_phy_ref_gates	: 1;
 	bool				rtc_32k_single_parent	: 1;
+	unsigned int			osc24M_32k_mult;
+	unsigned int			osc24M_32k_div;
 	const struct clk_parent_data	*osc32k_fanout_parents;
 	u8				osc32k_fanout_nparents;
 };
@@ -436,6 +438,11 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
 	if (data->rtc_32k_single_parent)
 		rtc_32k_init_data.num_parents = 1;
 
+	if (data->osc24M_32k_div) {
+		osc24M_32k_div_clk.mult = data->osc24M_32k_mult;
+		osc24M_32k_div_clk.div = data->osc24M_32k_div;
+	}
+
 	if (data->osc32k_fanout_nparents) {
 		osc32k_fanout_init_data.parent_data = data->osc32k_fanout_parents;
 		osc32k_fanout_init_data.num_parents = data->osc32k_fanout_nparents;

-- 
2.55.0



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

* [PATCH 11/19] clk: sunxi-ng: sun6i-rtc: add Allwinner V861 support
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (9 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 10/19] clk: sunxi-ng: sun6i-rtc: allow another 24 MHz to 32k divider ratio Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 12/19] dt-bindings: pinctrl: add the Allwinner V861 pin controllers Han Gao via B4 Relay
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The V861 RTC clocks are like the A523 ones, without the 32k fanout mux.

The 24 MHz to 32k divider ratio is not documented. With the RTC running
from it, the RTC kept time with the architectural timer, which uses the
same oscillator, to within 5 ppm over 15 minutes. So the divider
outputs 32768 Hz, not 24 MHz / 750.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index b3619222fef0..1abee85271a9 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -392,6 +392,18 @@ static const struct sun6i_rtc_match_data sun60i_a733_rtc_ccu_data = {
 	.osc32k_fanout_nparents	= ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents),
 };
 
+/*
+ * The V861 has no 32k fanout mux. Its 24 MHz to 32k divider ratio is not
+ * documented; measured against the architectural timer, it generates
+ * 32768 Hz.
+ */
+static const struct sun6i_rtc_match_data sun252i_v861_rtc_ccu_data = {
+	.have_ext_osc32k	= true,
+	.have_iosc_calibration	= true,
+	.osc24M_32k_mult	= 128,
+	.osc24M_32k_div		= 93750,
+};
+
 static const struct of_device_id sun6i_rtc_ccu_match[] = {
 	{
 		.compatible	= "allwinner,sun50i-h616-rtc",
@@ -401,6 +413,10 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = {
 		.compatible	= "allwinner,sun50i-r329-rtc",
 		.data		= &sun50i_r329_rtc_ccu_data,
 	},
+	{
+		.compatible	= "allwinner,sun252i-v861-rtc",
+		.data		= &sun252i_v861_rtc_ccu_data,
+	},
 	{
 		.compatible	= "allwinner,sun55i-a523-rtc",
 		.data		= &sun55i_a523_rtc_ccu_data,

-- 
2.55.0



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

* [PATCH 12/19] dt-bindings: pinctrl: add the Allwinner V861 pin controllers
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (10 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 11/19] clk: sunxi-ng: sun6i-rtc: add Allwinner V861 support Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 13/19] pinctrl: sunxi: allow a per-controller IRQ register base Han Gao via B4 Relay
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The V861 main and always-on pin controllers follow the A523 binding.
The always-on one has a single interrupt bank, so also allow a single
debounce value.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 .../pinctrl/allwinner,sun55i-a523-pinctrl.yaml     | 31 +++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun55i-a523-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun55i-a523-pinctrl.yaml
index d7d0ba32ced4..3c2924df17b9 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun55i-a523-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun55i-a523-pinctrl.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/pinctrl/allwinner,sun55i-a523-pinctrl.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Allwinner A523 & A733 Pin Controller
+title: Allwinner A523, A733 & V861 Pin Controller
 
 maintainers:
   - Andre Przywara <andre.przywara@arm.com>
@@ -26,6 +26,8 @@ properties:
 
   compatible:
     enum:
+      - allwinner,sun252i-v861-pinctrl
+      - allwinner,sun252i-v861-r-pinctrl
       - allwinner,sun55i-a523-pinctrl
       - allwinner,sun55i-a523-r-pinctrl
       - allwinner,sun60i-a733-pinctrl
@@ -35,7 +37,7 @@ properties:
     maxItems: 1
 
   interrupts:
-    minItems: 2
+    minItems: 1
     maxItems: 11
     description:
       One interrupt per external interrupt bank supported on the
@@ -62,7 +64,7 @@ properties:
       Debouncing periods in microseconds, one period per interrupt
       bank found in the controller
     $ref: /schemas/types.yaml#/definitions/uint32-array
-    minItems: 2
+    minItems: 1
     maxItems: 11
 
 patternProperties:
@@ -149,6 +151,29 @@ allOf:
           minItems: 2
           maxItems: 2
 
+  - if:
+      properties:
+        compatible:
+          const: allwinner,sun252i-v861-pinctrl
+    then:
+      properties:
+        interrupts:
+          minItems: 7
+          maxItems: 7
+        input-debounce:
+          maxItems: 7
+
+  - if:
+      properties:
+        compatible:
+          const: allwinner,sun252i-v861-r-pinctrl
+    then:
+      properties:
+        interrupts:
+          maxItems: 1
+        input-debounce:
+          maxItems: 1
+
 additionalProperties: false
 
 examples:

-- 
2.55.0



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

* [PATCH 13/19] pinctrl: sunxi: allow a per-controller IRQ register base
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (11 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 12/19] dt-bindings: pinctrl: add the Allwinner V861 pin controllers Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 14/19] pinctrl: sunxi: add support for the Allwinner V861 PIO Han Gao via B4 Relay
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

The V861 always-on pin controller has its interrupt registers at 0x40
instead of 0x200. Let the descriptor override the base.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/pinctrl/sunxi/pinctrl-sunxi.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index 7c2f29e75519..a0f5eac5c914 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -152,6 +152,11 @@ struct sunxi_pinctrl_desc {
 	unsigned			pin_base;
 	unsigned			irq_banks;
 	const unsigned int		*irq_bank_map;
+	/*
+	 * Interrupt register base, where zero selects the traditional 0x200.
+	 * Not used with the NCAT3 register layout.
+	 */
+	u32				irq_reg_base;
 	bool				irq_read_needs_mux;
 	bool				disable_strict_mode;
 	enum sunxi_desc_bias_voltage	io_bias_cfg_variant;
@@ -261,7 +266,7 @@ static inline u32 sunxi_irq_base_reg(const struct sunxi_pinctrl *pctl, u16 bank)
 		return pctl->bank_offset + bank * pctl->bank_mem_size +
 		       A733_IRQ_REGS_OFFSET;
 
-	return IRQ_REGS_OFFSET +
+	return (pctl->desc->irq_reg_base ?: IRQ_REGS_OFFSET) +
 	       sunxi_irq_hw_bank_num(pctl->desc, bank) * IRQ_MEM_SIZE;
 }
 

-- 
2.55.0



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

* [PATCH 14/19] pinctrl: sunxi: add support for the Allwinner V861 PIO
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (12 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 13/19] pinctrl: sunxi: allow a per-controller IRQ register base Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 15/19] pinctrl: sunxi: add support for the Allwinner V861 R-PIO Han Gao via B4 Relay
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add the V861 main pin controller driver, using the DT based function
tables.

The 1.8 V mode of bank PF is not supported, as none of the existing I/O
bias variants handles its control register.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/pinctrl/sunxi/Kconfig                | 10 ++++++
 drivers/pinctrl/sunxi/Makefile               |  1 +
 drivers/pinctrl/sunxi/pinctrl-sun252i-v861.c | 49 ++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+)

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 831bb1dc9373..2d5ace1e5f5f 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -86,6 +86,16 @@ config PINCTRL_SUN20I_D1
 	default MACH_SUN8I || (RISCV && ARCH_SUNXI)
 	select PINCTRL_SUNXI
 
+config PINCTRL_SUN252I_V861
+	bool "Support for the Allwinner V861 PIO"
+	default RISCV && ARCH_SUNXI
+	select PINCTRL_SUNXI
+	help
+	  Support for the main pin controller of the Allwinner V861 SoC.
+	  It provides pin multiplexing, GPIOs and GPIO interrupts for the
+	  PA and PC to PH banks, and is required on boards based on this
+	  SoC.
+
 config PINCTRL_SUN50I_A64
 	bool "Support for the Allwinner A64 PIO"
 	default ARM64 && ARCH_SUNXI
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index 3658c9d06b49..dc7559e260e1 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_PINCTRL_SUN8I_H3)		+= pinctrl-sun8i-h3.o
 obj-$(CONFIG_PINCTRL_SUN8I_H3_R)	+= pinctrl-sun8i-h3-r.o
 obj-$(CONFIG_PINCTRL_SUN8I_V3S)		+= pinctrl-sun8i-v3s.o
 obj-$(CONFIG_PINCTRL_SUN20I_D1)		+= pinctrl-sun20i-d1.o
+obj-$(CONFIG_PINCTRL_SUN252I_V861)	+= pinctrl-sun252i-v861.o
 obj-$(CONFIG_PINCTRL_SUN50I_H5)		+= pinctrl-sun50i-h5.o
 obj-$(CONFIG_PINCTRL_SUN50I_H6)		+= pinctrl-sun50i-h6.o
 obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun252i-v861.c b/drivers/pinctrl/sunxi/pinctrl-sun252i-v861.c
new file mode 100644
index 000000000000..742465076d86
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun252i-v861.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Allwinner V861 SoC pinctrl driver.
+ *
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const u8 v861_nr_bank_pins[SUNXI_PINCTRL_MAX_BANKS] =
+/*	  PA  PB  PC  PD  PE  PF  PG  PH */
+	{ 22,  0, 12, 23, 18,  7,  8, 16 };
+
+static const unsigned int v861_irq_bank_map[] = { 0, 2, 3, 4, 5, 6, 7 };
+
+static const u8 v861_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =
+/*	  PA  PB  PC  PD  PE  PF  PG  PH */
+	{ 14,  0, 14, 14, 14, 14, 14, 14 };
+
+static struct sunxi_pinctrl_desc v861_pinctrl_data = {
+	.irq_banks = ARRAY_SIZE(v861_irq_bank_map),
+	.irq_bank_map = v861_irq_bank_map,
+};
+
+static int v861_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_dt_table_init(pdev, v861_nr_bank_pins,
+					   v861_irq_bank_muxes,
+					   &v861_pinctrl_data,
+					   SUNXI_PINCTRL_NCAT2_REG_LAYOUT);
+}
+
+static const struct of_device_id v861_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun252i-v861-pinctrl", },
+	{}
+};
+
+static struct platform_driver v861_pinctrl_driver = {
+	.probe	= v861_pinctrl_probe,
+	.driver	= {
+		.name		= "sun252i-v861-pinctrl",
+		.of_match_table	= v861_pinctrl_match,
+	},
+};
+builtin_platform_driver(v861_pinctrl_driver);

-- 
2.55.0



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

* [PATCH 15/19] pinctrl: sunxi: add support for the Allwinner V861 R-PIO
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (13 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 14/19] pinctrl: sunxi: add support for the Allwinner V861 PIO Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 16/19] riscv: dts: allwinner: add the Allwinner V861 SoC Han Gao via B4 Relay
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add the V861 always-on pin controller driver, using the DT based
function tables. The manual calls it RTC_GPIO.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 drivers/pinctrl/sunxi/Kconfig                  | 10 ++++++
 drivers/pinctrl/sunxi/Makefile                 |  1 +
 drivers/pinctrl/sunxi/pinctrl-sun252i-v861-r.c | 48 ++++++++++++++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 2d5ace1e5f5f..80a53d3619d4 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -96,6 +96,16 @@ config PINCTRL_SUN252I_V861
 	  PA and PC to PH banks, and is required on boards based on this
 	  SoC.
 
+config PINCTRL_SUN252I_V861_R
+	bool "Support for the Allwinner V861 R-PIO"
+	default RISCV && ARCH_SUNXI
+	select PINCTRL_SUNXI
+	help
+	  Support for the always-on pin controller of the Allwinner V861
+	  SoC. It provides pin multiplexing, GPIOs and GPIO interrupts for
+	  the PL bank, and is required on boards based on this SoC.
+	  Say Y here if you are building a kernel for such a board.
+
 config PINCTRL_SUN50I_A64
 	bool "Support for the Allwinner A64 PIO"
 	default ARM64 && ARCH_SUNXI
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index dc7559e260e1..f3e601f61ce3 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_PINCTRL_SUN8I_H3_R)	+= pinctrl-sun8i-h3-r.o
 obj-$(CONFIG_PINCTRL_SUN8I_V3S)		+= pinctrl-sun8i-v3s.o
 obj-$(CONFIG_PINCTRL_SUN20I_D1)		+= pinctrl-sun20i-d1.o
 obj-$(CONFIG_PINCTRL_SUN252I_V861)	+= pinctrl-sun252i-v861.o
+obj-$(CONFIG_PINCTRL_SUN252I_V861_R)	+= pinctrl-sun252i-v861-r.o
 obj-$(CONFIG_PINCTRL_SUN50I_H5)		+= pinctrl-sun50i-h5.o
 obj-$(CONFIG_PINCTRL_SUN50I_H6)		+= pinctrl-sun50i-h6.o
 obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun252i-v861-r.c b/drivers/pinctrl/sunxi/pinctrl-sun252i-v861-r.c
new file mode 100644
index 000000000000..fef0ed2e2684
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun252i-v861-r.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Allwinner V861 SoC r-pinctrl driver.
+ *
+ * Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn>
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const u8 v861_r_nr_bank_pins[SUNXI_PINCTRL_MAX_BANKS] =
+/*	  PL */
+	{  7 };
+
+static const u8 v861_r_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =
+/*	  PL */
+	{ 14 };
+
+static struct sunxi_pinctrl_desc v861_r_pinctrl_data = {
+	.irq_banks = 1,
+	.irq_reg_base = 0x40,	/* PL_INT_CFG0 */
+	.pin_base = PL_BASE,
+};
+
+static int v861_r_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_dt_table_init(pdev, v861_r_nr_bank_pins,
+					   v861_r_irq_bank_muxes,
+					   &v861_r_pinctrl_data,
+					   SUNXI_PINCTRL_NCAT2_REG_LAYOUT);
+}
+
+static const struct of_device_id v861_r_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun252i-v861-r-pinctrl", },
+	{}
+};
+
+static struct platform_driver v861_r_pinctrl_driver = {
+	.probe	= v861_r_pinctrl_probe,
+	.driver	= {
+		.name		= "sun252i-v861-r-pinctrl",
+		.of_match_table	= v861_r_pinctrl_match,
+	},
+};
+builtin_platform_driver(v861_r_pinctrl_driver);

-- 
2.55.0



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

* [PATCH 16/19] riscv: dts: allwinner: add the Allwinner V861 SoC
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (14 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 15/19] pinctrl: sunxi: add support for the Allwinner V861 R-PIO Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 17/19] dt-bindings: riscv: sunxi: add the YuzukiHD Avaota F2 Han Gao via B4 Relay
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add the V861 SoC with its two C907 harts, PLIC, CLINT, clock
controllers, RTC, pin controllers and UART0.

The cache geometry and PMU events come from the V861 and C907 manuals.
Zcb, Zbkc and Zvfh were also checked to work on the hardware.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 arch/riscv/boot/dts/allwinner/sun252i-v861.dtsi | 272 ++++++++++++++++++++++++
 1 file changed, 272 insertions(+)

diff --git a/arch/riscv/boot/dts/allwinner/sun252i-v861.dtsi b/arch/riscv/boot/dts/allwinner/sun252i-v861.dtsi
new file mode 100644
index 000000000000..7a18b973ee32
--- /dev/null
+++ b/arch/riscv/boot/dts/allwinner/sun252i-v861.dtsi
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/* Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn> */
+
+#include <dt-bindings/clock/sun252i-v861-ccu.h>
+#include <dt-bindings/clock/sun252i-v861-r-ccu.h>
+#include <dt-bindings/clock/sun6i-rtc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset/sun252i-v861-ccu.h>
+#include <dt-bindings/reset/sun252i-v861-r-ccu.h>
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <24000000>;
+
+		cpu0: cpu@0 {
+			compatible = "csky,c907", "riscv";
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <16384>;
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <16384>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&l2_cache>;
+			riscv,isa-base = "rv64i";
+			riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v",
+				"zicbom", "zicbop", "zicboz", "zicntr", "zicond",
+				"zicsr", "zifencei", "zihintntl", "zihintpause",
+				"zihpm", "zawrs", "zfa", "zfbfmin", "zfh",
+				"zca", "zcb", "zcd", "zba", "zbb", "zbc", "zbkc",
+				"zbs", "zkt", "zvfbfmin", "zvfbfwma", "zvfh",
+				"sscofpmf", "sstc", "svinval", "svnapot", "svpbmt";
+			riscv,cbom-block-size = <64>;
+			riscv,cbop-block-size = <64>;
+			riscv,cboz-block-size = <64>;
+
+			cpu0_intc: interrupt-controller {
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+			};
+		};
+
+		cpu1: cpu@1 {
+			compatible = "csky,c907", "riscv";
+			device_type = "cpu";
+			reg = <1>;
+			d-cache-block-size = <64>;
+			d-cache-sets = <64>;
+			d-cache-size = <16384>;
+			i-cache-block-size = <64>;
+			i-cache-sets = <64>;
+			i-cache-size = <16384>;
+			mmu-type = "riscv,sv39";
+			next-level-cache = <&l2_cache>;
+			riscv,isa-base = "rv64i";
+			riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "b", "v",
+				"zicbom", "zicbop", "zicboz", "zicntr", "zicond",
+				"zicsr", "zifencei", "zihintntl", "zihintpause",
+				"zihpm", "zawrs", "zfa", "zfbfmin", "zfh",
+				"zca", "zcb", "zcd", "zba", "zbb", "zbc", "zbkc",
+				"zbs", "zkt", "zvfbfmin", "zvfbfwma", "zvfh",
+				"sscofpmf", "sstc", "svinval", "svnapot", "svpbmt";
+			riscv,cbom-block-size = <64>;
+			riscv,cbop-block-size = <64>;
+			riscv,cboz-block-size = <64>;
+
+			cpu1_intc: interrupt-controller {
+				compatible = "riscv,cpu-intc";
+				interrupt-controller;
+				#interrupt-cells = <1>;
+			};
+		};
+
+		l2_cache: l2-cache {
+			compatible = "cache";
+			cache-block-size = <64>;
+			cache-level = <2>;
+			cache-sets = <128>;
+			cache-size = <131072>;
+			cache-unified;
+		};
+	};
+
+	osc24M: osc24M-clk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "osc24M";
+	};
+
+	pmu {
+		compatible = "riscv,pmu";
+		riscv,event-to-mhpmcounters =
+			<0x00003 0x00006 0x0007fff8>,
+			<0x00008 0x00009 0x0007fff8>,
+			<0x10000 0x10003 0x0007fff8>,
+			<0x10008 0x10009 0x0007fff8>,
+			<0x10019 0x10019 0x0007fff8>,
+			<0x1001b 0x1001b 0x0007fff8>,
+			<0x10021 0x10021 0x0007fff8>,
+			<0x10028 0x10029 0x0007fff8>;
+		riscv,event-to-mhpmevent =
+			<0x00003 0x00000000 0x000000a5>,
+			<0x00004 0x00000000 0x000000a6>,
+			<0x00005 0x00000000 0x00000036>,
+			<0x00006 0x00000000 0x00000038>,
+			<0x00008 0x00000000 0x00000027>,
+			<0x00009 0x00000000 0x00000028>,
+			<0x10000 0x00000000 0x0000000c>,
+			<0x10001 0x00000000 0x0000000d>,
+			<0x10002 0x00000000 0x0000000e>,
+			<0x10003 0x00000000 0x0000000f>,
+			<0x10008 0x00000000 0x00000001>,
+			<0x10009 0x00000000 0x00000002>,
+			<0x10019 0x00000000 0x000000a4>,
+			<0x1001b 0x00000000 0x000000a3>,
+			<0x10021 0x00000000 0x00000003>,
+			<0x10028 0x00000000 0x00000036>,
+			<0x10029 0x00000000 0x00000038>;
+		riscv,raw-event-to-mhpmcounters =
+			<0x00000000 0x00000001 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000002 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000003 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000005 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000006 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000007 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000008 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000009 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000000b 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000000c 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000000d 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000000e 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000000f 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000016 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000001b 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000001c 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000001d 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000001f 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000020 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000021 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000023 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000025 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000027 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000028 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000029 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000002a 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000030 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000036 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x00000038 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000009b 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000009c 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x0000009e 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000a3 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000a4 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000a5 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000a6 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000a7 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000a8 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000a9 0xffffffff 0xffffffff 0x0007fff8>,
+			<0x00000000 0x000000aa 0xffffffff 0xffffffff 0x0007fff8>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		interrupt-parent = <&plic>;
+		ranges;
+		dma-noncoherent;
+
+		pio: pinctrl@2000000 {
+			compatible = "allwinner,sun252i-v861-pinctrl";
+			reg = <0 0x02000000 0 0x400>;
+			interrupts = <67 IRQ_TYPE_LEVEL_HIGH>, <71 IRQ_TYPE_LEVEL_HIGH>,
+				     <73 IRQ_TYPE_LEVEL_HIGH>, <75 IRQ_TYPE_LEVEL_HIGH>,
+				     <77 IRQ_TYPE_LEVEL_HIGH>, <79 IRQ_TYPE_LEVEL_HIGH>,
+				     <81 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_APB0>, <&osc24M>, <&rtc CLK_OSC32K>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+
+			uart0_ph_pins: uart0-ph-pins {
+				pins = "PH9", "PH10";
+				function = "uart0";
+				allwinner,pinmux = <5>;
+				bias-pull-up;
+			};
+		};
+
+		r_pio: pinctrl@2000540 {
+			compatible = "allwinner,sun252i-v861-r-pinctrl";
+			reg = <0 0x02000540 0 0x60>;
+			interrupts = <85 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_APB0>, <&osc24M>, <&rtc CLK_OSC32K>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		ccu: clock-controller@2001000 {
+			compatible = "allwinner,sun252i-v861-ccu";
+			reg = <0 0x02001000 0 0x1000>;
+			clocks = <&osc24M>, <&rtc CLK_OSC32K>, <&rtc CLK_IOSC>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		uart0: serial@2500000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0 0x02500000 0 0x400>;
+			interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
+			status = "disabled";
+		};
+
+		r_ccu: clock-controller@7010000 {
+			compatible = "allwinner,sun252i-v861-r-ccu";
+			reg = <0 0x07010000 0 0x400>;
+			clocks = <&osc24M>, <&rtc CLK_OSC32K>, <&rtc CLK_IOSC>,
+				 <&ccu CLK_PLL_PERIPH0_200M>;
+			clock-names = "hosc", "losc", "iosc", "pll-periph";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		rtc: rtc@7090000 {
+			compatible = "allwinner,sun252i-v861-rtc",
+				     "allwinner,sun50i-r329-rtc";
+			reg = <0 0x07090000 0 0x400>;
+			interrupts = <138 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&r_ccu CLK_BUS_R_RTC>, <&osc24M>,
+				 <&r_ccu CLK_R_AHB>;
+			clock-names = "bus", "hosc", "ahb";
+			#clock-cells = <1>;
+		};
+
+		plic: interrupt-controller@30000000 {
+			compatible = "allwinner,sun252i-v861-plic", "thead,c900-plic";
+			reg = <0 0x30000000 0 0x4000000>;
+			interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
+					      <&cpu1_intc 11>, <&cpu1_intc 9>;
+			riscv,ndev = <150>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			#address-cells = <0>;
+		};
+
+		clint: timer@34000000 {
+			compatible = "allwinner,sun252i-v861-clint", "thead,c900-clint";
+			reg = <0 0x34000000 0 0x10000>;
+			interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
+					      <&cpu1_intc 3>, <&cpu1_intc 7>;
+		};
+	};
+};

-- 
2.55.0



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

* [PATCH 17/19] dt-bindings: riscv: sunxi: add the YuzukiHD Avaota F2
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (15 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 16/19] riscv: dts: allwinner: add the Allwinner V861 SoC Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 18/19] riscv: dts: allwinner: add the YuzukiHD Avaota F2 board Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 19/19] MAINTAINERS: add an entry for the Allwinner V861 SoC Han Gao via B4 Relay
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Document the YuzukiHD Avaota F2 board, which is based on the Allwinner
V861 SoC.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 Documentation/devicetree/bindings/riscv/sunxi.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/riscv/sunxi.yaml b/Documentation/devicetree/bindings/riscv/sunxi.yaml
index b36e313e13a6..9e993a5752e4 100644
--- a/Documentation/devicetree/bindings/riscv/sunxi.yaml
+++ b/Documentation/devicetree/bindings/riscv/sunxi.yaml
@@ -69,6 +69,11 @@ properties:
           - const: widora,mangopi-mq-r-f133
           - const: allwinner,sun20i-d1s
 
+      - description: YuzukiHD Avaota F2
+        items:
+          - const: yuzukihd,avaota-f2
+          - const: allwinner,sun252i-v861
+
 additionalProperties: true
 
 ...

-- 
2.55.0



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

* [PATCH 18/19] riscv: dts: allwinner: add the YuzukiHD Avaota F2 board
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (16 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 17/19] dt-bindings: riscv: sunxi: add the YuzukiHD Avaota F2 Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  2026-11-13 22:33 ` [PATCH 19/19] MAINTAINERS: add an entry for the Allwinner V861 SoC Han Gao via B4 Relay
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add the YuzukiHD Avaota F2, a V861 board, with its memory and serial
console.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 arch/riscv/boot/dts/allwinner/Makefile             |  1 +
 .../boot/dts/allwinner/sun252i-v861-avaota-f2.dts  | 43 ++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/arch/riscv/boot/dts/allwinner/Makefile b/arch/riscv/boot/dts/allwinner/Makefile
index 1c91be38ea16..725919d9a4af 100644
--- a/arch/riscv/boot/dts/allwinner/Makefile
+++ b/arch/riscv/boot/dts/allwinner/Makefile
@@ -9,3 +9,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-lichee-rv.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-mangopi-mq-pro.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1-nezha.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun20i-d1s-mangopi-mq.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun252i-v861-avaota-f2.dtb
diff --git a/arch/riscv/boot/dts/allwinner/sun252i-v861-avaota-f2.dts b/arch/riscv/boot/dts/allwinner/sun252i-v861-avaota-f2.dts
new file mode 100644
index 000000000000..e3f5e6c8d350
--- /dev/null
+++ b/arch/riscv/boot/dts/allwinner/sun252i-v861-avaota-f2.dts
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/* Copyright (c) 2026 Han Gao <gaohan@iscas.ac.cn> */
+
+/dts-v1/;
+
+#include "sun252i-v861.dtsi"
+
+/ {
+	model = "Avaota F2";
+	compatible = "yuzukihd,avaota-f2", "allwinner,sun252i-v861";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	/* U-Boot updates this node with the detected DRAM capacity. */
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x08000000>;
+	};
+
+	reg_vcc3v3: regulator-vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+};
+
+&pio {
+	vcc-ph-supply = <&reg_vcc3v3>;
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};

-- 
2.55.0



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

* [PATCH 19/19] MAINTAINERS: add an entry for the Allwinner V861 SoC
  2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
                   ` (17 preceding siblings ...)
  2026-11-13 22:33 ` [PATCH 18/19] riscv: dts: allwinner: add the YuzukiHD Avaota F2 board Han Gao via B4 Relay
@ 2026-11-13 22:33 ` Han Gao via B4 Relay
  18 siblings, 0 replies; 21+ messages in thread
From: Han Gao via B4 Relay @ 2026-11-13 22:33 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Guo Ren,
	Thomas Gleixner, Radu Rendec, Samuel Holland, Daniel Lezcano,
	Anup Patel, Han Gao, Stephen Boyd, Brian Masney, Jerome Brunet,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Philipp Zabel,
	Alexandre Belloni, Maxime Ripard, Linus Walleij, Andre Przywara
  Cc: Han Gao, linux-riscv, linux-kernel, Paul Walmsley, Palmer Dabbelt,
	Conor Dooley, devicetree, linux-csky, linux-sunxi, linux-clk,
	linux-arm-kernel, linux-rtc, linux-gpio

From: Han Gao <gaohan@iscas.ac.cn>

Add myself as maintainer for the V861 bindings, clock and pin control
drivers and device trees.

Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 93abbb315065..dfc300dc1eb2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -24031,6 +24031,18 @@ F:	drivers/irqchip/irq-riscv-intc.c
 F:	include/linux/irqchip/riscv-aplic.h
 F:	include/linux/irqchip/riscv-imsic.h
 
+RISC-V ALLWINNER V861 SoC SUPPORT
+M:	Han Gao <gaohan@iscas.ac.cn>
+L:	linux-riscv@lists.infradead.org
+L:	linux-sunxi@lists.linux.dev
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/allwinner,sun252i-v861-ccu.yaml
+F:	arch/riscv/boot/dts/allwinner/sun252i-v861*
+F:	drivers/clk/sunxi-ng/ccu-sun252i-v861*.c
+F:	drivers/pinctrl/sunxi/pinctrl-sun252i-v861*.c
+F:	include/dt-bindings/clock/sun252i-v861*.h
+F:	include/dt-bindings/reset/sun252i-v861*.h
+
 RISC-V ANDES SoC Support
 M:	Ben Zong-You Xie <ben717@andestech.com>
 S:	Maintained

-- 
2.55.0



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

* Re: [PATCH 06/19] clk: sunxi-ng: add support for the Allwinner V861 CCU
  2026-11-13 22:33 ` [PATCH 06/19] clk: sunxi-ng: add support for the Allwinner V861 CCU Han Gao via B4 Relay
@ 2026-11-13 22:46   ` sashiko-bot
  0 siblings, 0 replies; 21+ messages in thread
From: sashiko-bot @ 2026-11-13 22:46 UTC (permalink / raw)
  To: Han Gao
  Cc: devicetree, linux-sunxi, linux-clk, linux-rtc, linux-gpio, robh,
	conor+dt, Alexandre Belloni

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] clk: sunxi-ng: ccu_mp_set_rate() ignores
  CCU_FEATURE_UPDATE_BIT for dram_clk
--

commit 4dcfa888826dc579312b5e254290daa03aed3f59
Author: Han Gao <gaohan@iscas.ac.cn>

clk: sunxi-ng: add support for the Allwinner V861 CCU

This commit adds the main CCU clock and reset driver for the Allwinner
V861 SoC.

> diff --git a/drivers/clk/sunxi-ng/ccu-sun252i-v861.c b/drivers/clk/sunxi-ng/ccu-sun252i-v861.c
> new file mode 100644
> index 0000000000000..af84c49fbaf16
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun252i-v861.c
[ ... ]
> +static const struct clk_parent_data dram_parents[] = {
> +	{ .fw_name = "hosc" },
> +	{ .hw = &pll_ddr_clk.common.hw },
> +	{ .hw = &pll_periph0_2x_clk.common.hw },
> +	{ .hw = &pll_periph0_800M_clk.common.hw },
> +};
> +
> +static SUNXI_CCU_MP_DATA_WITH_MUX_GATE_FEAT(dram_clk, "dram", dram_parents,
> +					    0x800,
> +					    0, 5,	/* M */
> +					    8, 2,	/* P */
> +					    24, 3,	/* mux */
> +					    BIT(31),	/* gate */
> +					    CLK_IS_CRITICAL,
> +					    CCU_FEATURE_UPDATE_BIT);

[Severity: Medium]
Does changing the rate of dram_clk actually latch the new dividers in
hardware?

dram_clk uses ccu_mp_ops with CCU_FEATURE_UPDATE_BIT, but unlike
ccu_div_set_rate(), ccu_mp_set_rate() never checks CCU_FEATURE_UPDATE_BIT
or sets CCU_SUNXI_UPDATE_BIT before writing the register:

drivers/clk/sunxi-ng/ccu_mp.c:ccu_mp_set_rate() {
    ...
	if (shift)
		reg |= ilog2(p) << cmp->p.shift;
	else
		reg |= (p - cmp->p.offset) << cmp->p.shift;

	writel(reg, cmp->common.base + cmp->common.reg);
    ...
}

When clk_set_rate() updates the M or P dividers without a parent mux or
gate change, the hardware ignores the unlatched divider update while
ccu_mp_recalc_rate() reads back the new register fields and reports the
wrong rate to the clock framework and child clocks such as mbus_clk.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261114-v861-v1-0-eb71ec3ee523@iscas.ac.cn?part=6

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

end of thread, other threads:[~2026-11-13 22:46 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-13 22:33 [PATCH 00/19] riscv: add initial support for the Allwinner V861 and Avaota F2 Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 01/19] riscv: sunxi: describe the wider Allwinner SoC family Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 02/19] dt-bindings: riscv: cpus: add the XuanTie C907 Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 03/19] dt-bindings: interrupt-controller: add the Allwinner V861 PLIC Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 04/19] dt-bindings: timer: add the Allwinner V861 CLINT Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 05/19] dt-bindings: clock: sunxi-ng: document the Allwinner V861 CCUs Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 06/19] clk: sunxi-ng: add support for the Allwinner V861 CCU Han Gao via B4 Relay
2026-11-13 22:46   ` sashiko-bot
2026-11-13 22:33 ` [PATCH 07/19] clk: sunxi-ng: add support for the Allwinner V861 PRCM CCU Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 08/19] dt-bindings: rtc: sun6i: add the Allwinner V861 RTC Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 09/19] clk: sunxi-ng: sun6i-rtc: allow variants without a 32k fanout mux Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 10/19] clk: sunxi-ng: sun6i-rtc: allow another 24 MHz to 32k divider ratio Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 11/19] clk: sunxi-ng: sun6i-rtc: add Allwinner V861 support Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 12/19] dt-bindings: pinctrl: add the Allwinner V861 pin controllers Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 13/19] pinctrl: sunxi: allow a per-controller IRQ register base Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 14/19] pinctrl: sunxi: add support for the Allwinner V861 PIO Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 15/19] pinctrl: sunxi: add support for the Allwinner V861 R-PIO Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 16/19] riscv: dts: allwinner: add the Allwinner V861 SoC Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 17/19] dt-bindings: riscv: sunxi: add the YuzukiHD Avaota F2 Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 18/19] riscv: dts: allwinner: add the YuzukiHD Avaota F2 board Han Gao via B4 Relay
2026-11-13 22:33 ` [PATCH 19/19] MAINTAINERS: add an entry for the Allwinner V861 SoC Han Gao via B4 Relay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox