2022-04-22 17:37:01

by Icenowy Zheng

[permalink] [raw]
Subject: [PATCH 00/12] Initial support for Allwinner R329

Allwinner R329 is a SoC targeting smart audio devices, with integrated
128M or 256M DRAM.

This patchset adds initial support for it, including pinctrl, rtc
(for rtc ccu), clocks and mmc. These makes a system booting.

The demo board for this support is Sipeed MaixSense (based on Sipeed
MIIA SoM).

Icenowy Zheng (12):
dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO
pinctrl: sunxi: add support for R329 CPUX pin controller
pinctrl: sunxi: add support for R329 R-PIO pin controller
rtc: sun6i: add support for R329 RTC
dt-bindings: clock: sunxi-ng: add bindings for R329 CCUs
clk: sunxi=ng: add support for R329 CCUs
dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string
mmc: sunxi: add support for R329 MMC controllers
dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense
arm64: allwinner: dts: add DTSI file for R329 SoC
arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA
arm64: allwinner: dts: r329: add support for Sipeed MaixSense

.../devicetree/bindings/arm/sunxi.yaml | 6 +
.../clock/allwinner,sun4i-a10-ccu.yaml | 62 +-
.../bindings/mmc/allwinner,sun4i-a10-mmc.yaml | 1 +
.../pinctrl/allwinner,sun4i-a10-pinctrl.yaml | 4 +
arch/arm64/boot/dts/allwinner/Makefile | 1 +
.../dts/allwinner/sun50i-r329-maix-iia.dtsi | 34 +
.../dts/allwinner/sun50i-r329-maixsense.dts | 37 ++
.../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 275 ++++++++
drivers/clk/sunxi-ng/Kconfig | 10 +
drivers/clk/sunxi-ng/Makefile | 4 +
drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c | 401 ++++++++++++
drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h | 25 +
drivers/clk/sunxi-ng/ccu-sun50i-r329.c | 587 ++++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun50i-r329.h | 32 +
drivers/mmc/host/sunxi-mmc.c | 10 +
drivers/pinctrl/sunxi/Kconfig | 10 +
drivers/pinctrl/sunxi/Makefile | 2 +
drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 +++++++++
drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c | 410 ++++++++++++
drivers/rtc/rtc-sun6i.c | 2 +
include/dt-bindings/clock/sun50i-r329-ccu.h | 73 +++
include/dt-bindings/clock/sun50i-r329-r-ccu.h | 45 ++
include/dt-bindings/reset/sun50i-r329-ccu.h | 45 ++
include/dt-bindings/reset/sun50i-r329-r-ccu.h | 24 +
24 files changed, 2384 insertions(+), 8 deletions(-)
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h

--
2.35.1


2022-04-22 17:48:34

by icenowy

[permalink] [raw]
Subject: [PATCH 07/12] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string

From: Icenowy Zheng <[email protected]>

R329 SoC has two MMC controllers similar to ones in the previous
Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
controllers look like a mixture of previous SoCs' ordinary MMC
controller and eMMC controller.

Add a compatible string for R329 MMC controllers.

Signed-off-by: Icenowy Zheng <[email protected]>
---
.../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml | 1 +
1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
index 7803597b6366..afc380dae776 100644
--- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
+++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
@@ -29,6 +29,7 @@ properties:
- const: allwinner,sun50i-a64-mmc
- const: allwinner,sun50i-a100-emmc
- const: allwinner,sun50i-a100-mmc
+ - const: allwinner,sun50i-r329-mmc
- items:
- const: allwinner,sun8i-a83t-mmc
- const: allwinner,sun7i-a20-mmc
--
2.35.1

2022-04-22 17:54:03

by icenowy

[permalink] [raw]
Subject: [PATCH 03/12] pinctrl: sunxi: add support for R329 R-PIO pin controller

From: Icenowy Zheng <[email protected]>

Allwinner R320 SoC has a pin controller in the CPUS power domain.

Add support for it.

Signed-off-by: Icenowy Zheng <[email protected]>
---
drivers/pinctrl/sunxi/Kconfig | 5 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 ++++++++++++++++++
3 files changed, 298 insertions(+)
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index c662e8b1b351..abd60ff8daec 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -134,4 +134,9 @@ config PINCTRL_SUN50I_R329
default ARM64 && ARCH_SUNXI
select PINCTRL_SUNXI

+config PINCTRL_SUN50I_R329_R
+ bool "Support for the Allwinner R329 R-PIO"
+ default ARM64 && ARCH_SUNXI
+ select PINCTRL_SUNXI
+
endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index e33f7c5f1ff9..245840a7959e 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6_R) += pinctrl-sun50i-h6-r.o
obj-$(CONFIG_PINCTRL_SUN50I_H616) += pinctrl-sun50i-h616.o
obj-$(CONFIG_PINCTRL_SUN50I_H616_R) += pinctrl-sun50i-h616-r.o
obj-$(CONFIG_PINCTRL_SUN50I_R329) += pinctrl-sun50i-r329.o
+obj-$(CONFIG_PINCTRL_SUN50I_R329_R) += pinctrl-sun50i-r329-r.o
obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o
obj-$(CONFIG_PINCTRL_SUN9I_A80_R) += pinctrl-sun9i-a80-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
new file mode 100644
index 000000000000..268f03d79755
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner R329 R_PIO pin controller driver
+ *
+ * Copyright (C) 2021 Sipeed
+ * Based on former work, which is:
+ * Copyright (C) 2020 Arm Ltd.
+ * Copyright (C) 2017 Icenowy Zheng <[email protected]>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/reset.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun50i_r329_r_pins[] = {
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2s"), /* LRCK */
+ SUNXI_FUNCTION(0x4, "s_dmic"), /* DATA3 */
+ SUNXI_FUNCTION(0x5, "s_pwm"), /* PWM0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PL_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2s"), /* BCLK */
+ SUNXI_FUNCTION(0x4, "s_dmic"), /* DATA2 */
+ SUNXI_FUNCTION(0x5, "s_pwm"), /* PWM1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PL_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2s_dout0"),
+ SUNXI_FUNCTION(0x3, "s_i2s_din1"),
+ SUNXI_FUNCTION(0x4, "s_dmic"), /* DATA1 */
+ SUNXI_FUNCTION(0x5, "s_pwm"), /* PWM2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PL_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2s_dout1"),
+ SUNXI_FUNCTION(0x3, "s_i2s_din0"),
+ SUNXI_FUNCTION(0x4, "s_dmic"), /* DATA0 */
+ SUNXI_FUNCTION(0x5, "s_i2c"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PL_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2s"), /* MCLK */
+ SUNXI_FUNCTION(0x3, "s_ir"), /* RX */
+ SUNXI_FUNCTION(0x4, "s_dmic"), /* CLK */
+ SUNXI_FUNCTION(0x5, "s_i2c"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PL_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SDA */
+ SUNXI_FUNCTION(0x5, "s_pwm"), /* PWM3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PL_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SCK */
+ SUNXI_FUNCTION(0x5, "s_pwm"), /* PWM4 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PL_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_ir"), /* RX */
+ SUNXI_FUNCTION(0x4, "clock"), /* X32KFOUT */
+ SUNXI_FUNCTION(0x5, "s_pwm"), /* PWM5 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PL_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* TX */
+ SUNXI_FUNCTION(0x3, "s_i2c"), /* SDA */
+ SUNXI_FUNCTION(0x4, "s_ir"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PL_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* RX */
+ SUNXI_FUNCTION(0x3, "s_i2c"), /* SCK */
+ SUNXI_FUNCTION(0x4, "clock"), /* X32KFOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PL_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PL_EINT10 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* TX */
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* MS */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)), /* PM_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_uart"), /* RX */
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* CK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)), /* PM_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* DO */
+ SUNXI_FUNCTION(0x4, "s_i2c"), /* SDA */
+ SUNXI_FUNCTION(0x5, "s_ir"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)), /* PM_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SDA */
+ SUNXI_FUNCTION(0x3, "s_ir"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)), /* PM_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)), /* PM_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "clock"), /* X32KFOUT */
+ SUNXI_FUNCTION(0x3, "s_jtag"), /* DI */
+ SUNXI_FUNCTION(0x4, "s_i2c"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PM_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nmi"),
+ SUNXI_FUNCTION(0x3, "s_ir"), /* RX */
+ SUNXI_FUNCTION(0x4, "clock"), /* X32KFOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PM_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "s_ir"), /* RX */
+ SUNXI_FUNCTION(0x3, "clock"), /* X32KFOUT */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)), /* PM_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 8)), /* PM_EINT8 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PN_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* MDC */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PN_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* MDIO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PN_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* TXD3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PN_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* TXCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PN_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* RXD2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PN_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* RXD0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PN_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* RXCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PN_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* RXERR */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PN_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* TXCTL/TXEN */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PN_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* RXD3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PN_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* RXD1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PN_EINT11 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* RXCTL/CRS_DV */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PN_EINT12 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* TXD2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PN_EINT13 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* TXD1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PN_EINT14 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 15),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* TXD0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)), /* PN_EINT15 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 16),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* EPHY-25M */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)), /* PN_EINT16 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 17),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "emac"), /* CLKIN */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 17)), /* PN_EINT17 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 18),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 18)), /* PN_EINT18 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 19),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 19)), /* PN_EINT19 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 20),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 20)), /* PN_EINT20 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 21),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 21)), /* PN_EINT21 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 22),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 22)), /* PN_EINT22 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 23),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 23)), /* PN_EINT23 */
+};
+
+static const struct sunxi_pinctrl_desc sun50i_r329_r_pinctrl_data = {
+ .pins = sun50i_r329_r_pins,
+ .npins = ARRAY_SIZE(sun50i_r329_r_pins),
+ .pin_base = PL_BASE,
+ .irq_banks = 3,
+ .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
+};
+
+static int sun50i_r329_r_pinctrl_probe(struct platform_device *pdev)
+{
+ return sunxi_pinctrl_init(pdev,
+ &sun50i_r329_r_pinctrl_data);
+}
+
+static const struct of_device_id sun50i_r329_r_pinctrl_match[] = {
+ { .compatible = "allwinner,sun50i-r329-r-pinctrl", },
+ {}
+};
+
+static struct platform_driver sun50i_r329_r_pinctrl_driver = {
+ .probe = sun50i_r329_r_pinctrl_probe,
+ .driver = {
+ .name = "sun50i-r329-r-pinctrl",
+ .of_match_table = sun50i_r329_r_pinctrl_match,
+ },
+};
--
2.35.1

2022-04-22 19:01:42

by icenowy

[permalink] [raw]
Subject: [PATCH 02/12] pinctrl: sunxi: add support for R329 CPUX pin controller

From: Icenowy Zheng <[email protected]>

Allwinner R329 SoC has two pin controllers similar to ones on previous
SoCs, one in CPUX power domain and another in CPUS.

This patch adds support for the CPUX domain pin controller.

Signed-off-by: Icenowy Zheng <[email protected]>
---
drivers/pinctrl/sunxi/Kconfig | 5 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c | 410 ++++++++++++++++++++
3 files changed, 416 insertions(+)
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 33751a6a0757..c662e8b1b351 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -129,4 +129,9 @@ config PINCTRL_SUN50I_H616_R
default ARM64 && ARCH_SUNXI
select PINCTRL_SUNXI

+config PINCTRL_SUN50I_R329
+ bool "Support for the Allwinner R329 PIO"
+ default ARM64 && ARCH_SUNXI
+ select PINCTRL_SUNXI
+
endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index d3440c42b9d6..e33f7c5f1ff9 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -25,5 +25,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6) += pinctrl-sun50i-h6.o
obj-$(CONFIG_PINCTRL_SUN50I_H6_R) += pinctrl-sun50i-h6-r.o
obj-$(CONFIG_PINCTRL_SUN50I_H616) += pinctrl-sun50i-h616.o
obj-$(CONFIG_PINCTRL_SUN50I_H616_R) += pinctrl-sun50i-h616-r.o
+obj-$(CONFIG_PINCTRL_SUN50I_R329) += pinctrl-sun50i-r329.o
obj-$(CONFIG_PINCTRL_SUN9I_A80) += pinctrl-sun9i-a80.o
obj-$(CONFIG_PINCTRL_SUN9I_A80_R) += pinctrl-sun9i-a80-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
new file mode 100644
index 000000000000..742f437ec0b6
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner R329 SoC pinctrl driver.
+ *
+ * Copyright (C) 2021 Sipeed
+ * based on the H616 pinctrl driver
+ * Copyright (C) 2020 Arm Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin r329_pins[] = {
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* TX */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM0 */
+ SUNXI_FUNCTION(0x4, "jtag"), /* MS */
+ SUNXI_FUNCTION(0x5, "ledc"), /* DO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PB_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RX */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM1 */
+ SUNXI_FUNCTION(0x4, "jtag"), /* CK */
+ SUNXI_FUNCTION(0x5, "i2s0"), /* MCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PB_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* RTS */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM2 */
+ SUNXI_FUNCTION(0x4, "jtag"), /* DO */
+ SUNXI_FUNCTION(0x5, "i2s0"), /* LRCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PB_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart2"), /* CTS */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM3 */
+ SUNXI_FUNCTION(0x4, "jtag"), /* DI */
+ SUNXI_FUNCTION(0x5, "i2s0"), /* BCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PB_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart0"), /* TX */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM4 */
+ SUNXI_FUNCTION(0x4, "i2s0_dout0"),
+ SUNXI_FUNCTION(0x5, "i2s0_din1"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PB_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart0"), /* RX */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM5 */
+ SUNXI_FUNCTION(0x4, "i2s0_dout1"),
+ SUNXI_FUNCTION(0x5, "i2s0_din0"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PB_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "ir"), /* RX */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM6 */
+ SUNXI_FUNCTION(0x4, "i2s0"), /* DOUT2 */
+ SUNXI_FUNCTION(0x5, "i2c0"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PB_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "ir"), /* TX */
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM7 */
+ SUNXI_FUNCTION(0x4, "i2s0"), /* DOUT3 */
+ SUNXI_FUNCTION(0x5, "i2c0"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PB_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "ir_tx"),
+ SUNXI_FUNCTION(0x3, "pwm"), /* PWM8 */
+ SUNXI_FUNCTION(0x4, "ir_rx"),
+ SUNXI_FUNCTION(0x5, "ledc"), /* DO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PB_EINT8 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RB0 */
+ SUNXI_FUNCTION(0x3, "mmc0"), /* CLK */
+ SUNXI_FUNCTION(0x4, "spi0")), /* CS */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* RE */
+ SUNXI_FUNCTION(0x3, "mmc0"), /* CMD */
+ SUNXI_FUNCTION(0x4, "spi0")), /* MISO */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CE0 */
+ SUNXI_FUNCTION(0x3, "mmc0"), /* D2 */
+ SUNXI_FUNCTION(0x4, "spi0")), /* WP */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* CLE */
+ SUNXI_FUNCTION(0x3, "mmc0"), /* D1 */
+ SUNXI_FUNCTION(0x4, "spi0")), /* MOSI */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* ALE */
+ SUNXI_FUNCTION(0x3, "mmc0"), /* D0 */
+ SUNXI_FUNCTION(0x4, "spi0")), /* CLK */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* WE */
+ SUNXI_FUNCTION(0x3, "mmc0"), /* D3 */
+ SUNXI_FUNCTION(0x4, "spi0")), /* HOLD */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ0 */
+ SUNXI_FUNCTION(0x3, "mmc0")), /* RST */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand0"), /* DQ1 */
+ SUNXI_FUNCTION(0x5, "boot_sel")),
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */
+ SUNXI_FUNCTION(0x3, "sim0"), /* VPPEN */
+ SUNXI_FUNCTION(0x4, "jtag"), /* MS */
+ SUNXI_FUNCTION(0x5, "mmc0"), /* D1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)), /* PF_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */
+ SUNXI_FUNCTION(0x3, "sim0"), /* VPPPP */
+ SUNXI_FUNCTION(0x4, "jtag"), /* DI */
+ SUNXI_FUNCTION(0x5, "mmc0"), /* D0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)), /* PF_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ5 */
+ SUNXI_FUNCTION(0x3, "sim0"), /* PWREN */
+ SUNXI_FUNCTION(0x4, "uart"), /* TX */
+ SUNXI_FUNCTION(0x5, "mmc0"), /* CLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)), /* PF_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ4 */
+ SUNXI_FUNCTION(0x3, "sim0"), /* CLK */
+ SUNXI_FUNCTION(0x4, "jtag"), /* DO */
+ SUNXI_FUNCTION(0x5, "mmc0"), /* CMD */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)), /* PF_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQS */
+ SUNXI_FUNCTION(0x3, "sim0"), /* DATA */
+ SUNXI_FUNCTION(0x4, "uart"), /* RX */
+ SUNXI_FUNCTION(0x5, "mmc0"), /* D3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)), /* PF_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ2 */
+ SUNXI_FUNCTION(0x3, "sim0"), /* RST */
+ SUNXI_FUNCTION(0x4, "jtag"), /* CK */
+ SUNXI_FUNCTION(0x5, "mmc0"), /* D2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)), /* PF_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "nand"), /* DQ1 */
+ SUNXI_FUNCTION(0x3, "sim0"), /* DET */
+ SUNXI_FUNCTION(0x4, "spdif_in"),
+ SUNXI_FUNCTION(0x5, "spdif_out"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)), /* PF_EINT6 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1_clk"),
+ SUNXI_FUNCTION(0x3, "mmc1_d2"),
+ /* 0x4 is also mmc1_d2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)), /* PG_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1_cmd"),
+ SUNXI_FUNCTION(0x3, "mmc1_d3"),
+ SUNXI_FUNCTION(0x4, "mmc1_clk"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PG_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1_d0"),
+ SUNXI_FUNCTION(0x3, "mmc1_cmd"),
+ SUNXI_FUNCTION(0x4, "mmc1_d3"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)), /* PG_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1_d1"),
+ SUNXI_FUNCTION(0x3, "mmc1_clk"),
+ /* 0x4 is also mmc1_d1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)), /* PG_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1_d2"),
+ SUNXI_FUNCTION(0x3, "mmc1_d0"),
+ /* 0x4 is also mmc1_d0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)), /* PG_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "mmc1_d3"),
+ SUNXI_FUNCTION(0x3, "mmc1_d1"),
+ SUNXI_FUNCTION(0x4, "mmc1_cmd"),
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)), /* PG_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* TX */
+ SUNXI_FUNCTION(0x3, "i2c0"), /* SCK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)), /* PG_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* RX */
+ SUNXI_FUNCTION(0x3, "i2c0"), /* SDA */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)), /* PG_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* RTS */
+ SUNXI_FUNCTION(0x3, "i2c1"), /* SCK */
+ SUNXI_FUNCTION(0x5, "spi1"), /* HOLD/DBI-DCX/DBI-WRX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)), /* PG_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart1"), /* CTS */
+ SUNXI_FUNCTION(0x3, "i2c1"), /* SDA */
+ SUNXI_FUNCTION(0x5, "spi1"), /* WP/DBI-TE */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)), /* PG_EINT9 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x3, "i2s1"), /* MCLK */
+ SUNXI_FUNCTION(0x3, "ledc"), /* DO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)), /* PG_EINT10 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* TX */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* LRCK */
+ SUNXI_FUNCTION(0x5, "spi1"), /* CS/DBI-CSX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PG_EINT11 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* RX */
+ SUNXI_FUNCTION(0x3, "i2s1"), /* BCLK */
+ SUNXI_FUNCTION(0x5, "spi1"), /* CLK/DBI-SCLK */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)), /* PG_EINT12 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* RTS */
+ SUNXI_FUNCTION(0x3, "i2s1_dout0"),
+ SUNXI_FUNCTION(0x4, "i2s1_din1"),
+ SUNXI_FUNCTION(0x5, "spi1"), /* MOSI/DBI-SDO */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)), /* PG_EINT13 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* CTS */
+ SUNXI_FUNCTION(0x3, "i2s1_dout1"),
+ SUNXI_FUNCTION(0x4, "i2s1_din0"),
+ SUNXI_FUNCTION(0x5, "spi1"), /* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)), /* PG_EINT14 */
+ /* Hole */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0"), /* SCK */
+ SUNXI_FUNCTION(0x3, "uart0"), /* TX */
+ SUNXI_FUNCTION(0x4, "spi1"), /* CS/DBI-CSX */
+ SUNXI_FUNCTION(0x5, "pwm"), /* PWM0 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)), /* PH_EINT0 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c0"), /* SDA */
+ SUNXI_FUNCTION(0x3, "uart0"), /* RX */
+ SUNXI_FUNCTION(0x4, "spi1"), /* CLK/DBI-SCLK */
+ SUNXI_FUNCTION(0x5, "pwm"), /* PWM1 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)), /* PH_EINT1 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1"), /* SCK */
+ SUNXI_FUNCTION(0x3, "ledc"), /* DO */
+ SUNXI_FUNCTION(0x4, "spi1"), /* MOSI/DBI-SDO */
+ SUNXI_FUNCTION(0x5, "ir"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)), /* PH_EINT2 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1"), /* SDA */
+ SUNXI_FUNCTION(0x3, "spdif"), /* OUT */
+ SUNXI_FUNCTION(0x4, "spi1"), /* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+ SUNXI_FUNCTION(0x5, "ir"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)), /* PH_EINT3 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* TX */
+ SUNXI_FUNCTION(0x3, "spi1_cs"), /* CS/DBI-CSX */
+ SUNXI_FUNCTION(0x4, "spi1_hold"), /* HOLD/DBI-DCX/DBI-WRX */
+ SUNXI_FUNCTION(0x5, "pwm"), /* PWM2 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)), /* PH_EINT4 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* RX */
+ SUNXI_FUNCTION(0x3, "spi1_clk"), /* CLK/DBI-SCLK */
+ SUNXI_FUNCTION(0x4, "spi1_wp"), /* WP/DBI-TE */
+ SUNXI_FUNCTION(0x5, "pwm"), /* PWM3 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)), /* PH_EINT5 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* RTS */
+ SUNXI_FUNCTION(0x3, "spi1"), /* MOSI/SPI-DBO */
+ SUNXI_FUNCTION(0x4, "i2c0"), /* SCK */
+ SUNXI_FUNCTION(0x5, "pwm"), /* PWM4 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)), /* PH_EINT6 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "uart3"), /* CTS */
+ SUNXI_FUNCTION(0x3, "spi1"), /* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+ SUNXI_FUNCTION(0x4, "i2c0"), /* SDA */
+ SUNXI_FUNCTION(0x5, "pwm"), /* PWM5 */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)), /* PH_EINT7 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1"), /* SDA */
+ SUNXI_FUNCTION(0x3, "spi1"), /* WP/DBI-TE */
+ SUNXI_FUNCTION(0x4, "ledc"), /* DO */
+ SUNXI_FUNCTION(0x5, "ir"), /* TX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PH_EINT8 */
+ SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
+ SUNXI_FUNCTION(0x0, "gpio_in"),
+ SUNXI_FUNCTION(0x1, "gpio_out"),
+ SUNXI_FUNCTION(0x2, "i2c1"), /* SCK */
+ SUNXI_FUNCTION(0x3, "spi1"), /* HOLD/DBI-DCX/DBI-WRX */
+ SUNXI_FUNCTION(0x4, "spdif"), /* IN */
+ SUNXI_FUNCTION(0x5, "ir"), /* RX */
+ SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PH_EINT9 */
+};
+static const unsigned int r329_irq_bank_map[] = { 1, 5, 6, 7 };
+
+static const struct sunxi_pinctrl_desc r329_pinctrl_data = {
+ .pins = r329_pins,
+ .npins = ARRAY_SIZE(r329_pins),
+ .irq_banks = ARRAY_SIZE(r329_irq_bank_map),
+ .irq_bank_map = r329_irq_bank_map,
+ .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
+};
+
+static int r329_pinctrl_probe(struct platform_device *pdev)
+{
+ return sunxi_pinctrl_init(pdev, &r329_pinctrl_data);
+}
+
+static const struct of_device_id r329_pinctrl_match[] = {
+ { .compatible = "allwinner,sun50i-r329-pinctrl", },
+ {}
+};
+
+static struct platform_driver r329_pinctrl_driver = {
+ .probe = r329_pinctrl_probe,
+ .driver = {
+ .name = "sun50i-r329-pinctrl",
+ .of_match_table = r329_pinctrl_match,
+ },
+};
+builtin_platform_driver(r329_pinctrl_driver);
--
2.35.1

2022-04-22 19:14:30

by icenowy

[permalink] [raw]
Subject: [PATCH 08/12] mmc: sunxi: add support for R329 MMC controllers

From: Icenowy Zheng <[email protected]>

The two MMC controllers in Allwinner R329 have a mixed feature set
comparing to the previous SoCs' ordinary MMC and eMMC controllers.

Add support for them.

Signed-off-by: Icenowy Zheng <[email protected]>
---
drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 0e8fbf4957d8..06934eef8be5 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1207,6 +1207,15 @@ static const struct sunxi_mmc_cfg sun50i_a100_emmc_cfg = {
.needs_new_timings = true,
};

+static const struct sunxi_mmc_cfg sun50i_r329_cfg = {
+ .idma_des_size_bits = 13,
+ .idma_des_shift = 2,
+ .clk_delays = NULL,
+ .can_calibrate = true,
+ .mask_data0 = true,
+ .needs_new_timings = true,
+};
+
static const struct of_device_id sunxi_mmc_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
{ .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
@@ -1218,6 +1227,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = {
{ .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
{ .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
{ .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
+ { .compatible = "allwinner,sun50i-r329-mmc", .data = &sun50i_r329_cfg },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
--
2.35.1

2022-04-22 19:15:32

by icenowy

[permalink] [raw]
Subject: [PATCH 05/12] dt-bindings: clock: sunxi-ng: add bindings for R329 CCUs

From: Icenowy Zheng <[email protected]>

R329 has a CPUX CCU and a R-CCU, with all PLLs in R-CCU.

Add bindings for them, with R-CCU only taking 3 oscillators as input and
main CCU taking oscillators + PLLs as input.

Signed-off-by: Icenowy Zheng <[email protected]>
---
.../clock/allwinner,sun4i-a10-ccu.yaml | 62 ++++++++++++++--
include/dt-bindings/clock/sun50i-r329-ccu.h | 73 +++++++++++++++++++
include/dt-bindings/clock/sun50i-r329-r-ccu.h | 45 ++++++++++++
include/dt-bindings/reset/sun50i-r329-ccu.h | 45 ++++++++++++
include/dt-bindings/reset/sun50i-r329-r-ccu.h | 24 ++++++
5 files changed, 241 insertions(+), 8 deletions(-)
create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h

diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
index 15ed64d35261..c7a429e55483 100644
--- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
+++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
@@ -45,6 +45,8 @@ properties:
- allwinner,sun50i-h6-r-ccu
- allwinner,sun50i-h616-ccu
- allwinner,sun50i-h616-r-ccu
+ - allwinner,sun50i-r329-ccu
+ - allwinner,sun50i-r329-r-ccu
- allwinner,suniv-f1c100s-ccu
- nextthing,gr8-ccu

@@ -106,6 +108,7 @@ else:
- allwinner,sun50i-a100-ccu
- allwinner,sun50i-h6-ccu
- allwinner,sun50i-h616-ccu
+ - allwinner,sun50i-r329-r-ccu

then:
properties:
@@ -118,14 +121,57 @@ else:
maxItems: 3

else:
- properties:
- clocks:
- minItems: 2
- maxItems: 2
-
- clock-names:
- minItems: 2
- maxItems: 2
+ if:
+ properties:
+ compatible:
+ const: allwinner,sun50i-r329-ccu
+ then:
+ properties:
+ clocks:
+ minItems: 13
+ maxItems: 13
+ items:
+ - description: High Frequency Oscillator (usually at 24MHz)
+ - description: Low Frequency Oscillator (usually at 32kHz)
+ - description: Internal Oscillator
+ - description: CPUX PLL
+ - description: Peripherals PLL
+ - description: Peripherals PLL (2x)
+ - description: Peripherals PLL derivated 800MHz clock
+ - description: Audio PLL 0
+ - description: Audio PLL 0 (/2)
+ - description: Audio PLL 0 (/5)
+ - description: Audio PLL 1
+ - description: Audio PLL 1 (2x)
+ - description: Audio PLL 1 (4x)
+
+ clock-names:
+ minItems: 13
+ maxItems: 13
+ items:
+ - const: hosc
+ - const: losc
+ - const: iosc
+ - const: pll-cpux
+ - const: pll-periph
+ - const: pll-periph-2x
+ - const: pll-periph-800m
+ - const: pll-audio0
+ - const: pll-audio0-div2
+ - const: pll-audio0-div5
+ - const: pll-audio1
+ - const: pll-audio1-2x
+ - const: pll-audio1-4x
+
+ else:
+ properties:
+ clocks:
+ minItems: 2
+ maxItems: 2
+
+ clock-names:
+ minItems: 2
+ maxItems: 2

additionalProperties: false

diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-bindings/clock/sun50i-r329-ccu.h
new file mode 100644
index 000000000000..116f8d13a9b3
--- /dev/null
+++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
+
+#define CLK_CPUX 1
+
+#define CLK_APB1 5
+
+#define CLK_CE 7
+#define CLK_BUS_CE 8
+#define CLK_AIPU 9
+#define CLK_BUS_AIPU 10
+#define CLK_BUS_DMA 11
+#define CLK_BUS_MSGBOX 12
+#define CLK_BUS_SPINLOCK 13
+#define CLK_BUS_HSTIMER 14
+#define CLK_AVS 15
+#define CLK_BUS_DBG 16
+#define CLK_BUS_PWM 17
+
+#define CLK_MBUS_DMA 19
+#define CLK_MBUS_CE 20
+#define CLK_MBUS_R_DMA 21
+#define CLK_MBUS_NAND 22
+#define CLK_MBUS_AIPU 23
+
+#define CLK_NAND0 25
+#define CLK_NAND1 26
+#define CLK_BUS_NAND 27
+#define CLK_MMC0 28
+#define CLK_MMC1 29
+#define CLK_BUS_MMC0 30
+#define CLK_BUS_MMC1 31
+#define CLK_BUS_UART0 32
+#define CLK_BUS_UART1 33
+#define CLK_BUS_UART2 34
+#define CLK_BUS_UART3 35
+#define CLK_BUS_I2C0 36
+#define CLK_BUS_I2C1 37
+#define CLK_BUS_SCR 38
+#define CLK_SPI0 39
+#define CLK_SPI1 40
+#define CLK_BUS_SPI0 41
+#define CLK_BUS_SPI1 42
+#define CLK_EMAC_25M_DIV 43
+#define CLK_EMAC_25M 44
+#define CLK_BUS_EMAC 45
+#define CLK_IR_RX 46
+#define CLK_BUS_IR_RX 47
+#define CLK_IR_TX 48
+#define CLK_BUS_IR_TX 49
+#define CLK_I2S0 50
+#define CLK_I2S1 51
+#define CLK_BUS_I2S0 52
+#define CLK_BUS_I2S1 53
+#define CLK_SPDIF 54
+#define CLK_BUS_SPDIF 55
+#define CLK_USB_OHCI0 56
+#define CLK_USB_PHY0 57
+#define CLK_USB_OHCI1 58
+#define CLK_USB_PHY1 59
+#define CLK_BUS_OHCI0 60
+#define CLK_BUS_OHCI1 61
+#define CLK_BUS_EHCI0 62
+#define CLK_BUS_OTG 63
+#define CLK_LEDC 64
+#define CLK_BUS_LEDC 65
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_ */
diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
new file mode 100644
index 000000000000..c327d1a1b602
--- /dev/null
+++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
+
+#define CLK_PLL_CPUX 0
+#define CLK_PLL_PERIPH_2X 2
+#define CLK_PLL_PERIPH_800M 3
+#define CLK_PLL_PERIPH 4
+#define CLK_PLL_AUDIO0 5
+#define CLK_PLL_AUDIO0_DIV2 6
+#define CLK_PLL_AUDIO0_DIV5 7
+#define CLK_PLL_AUDIO1_4X 8
+#define CLK_PLL_AUDIO1_2X 9
+#define CLK_PLL_AUDIO1 10
+
+#define CLK_R_AHB 11
+#define CLK_R_APB1 12
+
+#define CLK_R_BUS_GPADC 14
+#define CLK_R_BUS_THS 15
+#define CLK_R_BUS_DMA 16
+#define CLK_R_PWM 17
+#define CLK_R_BUS_PWM 18
+#define CLK_R_CODEC_ADC 19
+#define CLK_R_CODEC_DAC 20
+#define CLK_R_BUS_CODEC 21
+#define CLK_R_DMIC 22
+#define CLK_R_BUS_DMIC 23
+#define CLK_R_BUS_LRADC 24
+#define CLK_R_I2S 25
+#define CLK_R_I2S_ASRC 26
+#define CLK_R_BUS_I2S 27
+#define CLK_R_BUS_UART 28
+#define CLK_R_BUS_I2C 29
+#define CLK_R_IR 30
+#define CLK_R_BUS_IR 31
+#define CLK_R_BUS_MSGBOX 32
+#define CLK_R_BUS_SPINLOCK 33
+#define CLK_R_BUS_RTC 34
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-bindings/reset/sun50i-r329-ccu.h
new file mode 100644
index 000000000000..bb704a82443f
--- /dev/null
+++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
+#define _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
+
+#define RST_MBUS 0
+#define RST_BUS_CE 1
+#define RST_BUS_AIPU 2
+#define RST_BUS_DMA 3
+#define RST_BUS_MSGBOX 4
+#define RST_BUS_SPINLOCK 5
+#define RST_BUS_HSTIMER 6
+#define RST_BUS_DBG 7
+#define RST_BUS_PWM 8
+#define RST_BUS_DRAM 9
+#define RST_BUS_NAND 10
+#define RST_BUS_MMC0 11
+#define RST_BUS_MMC1 12
+#define RST_BUS_UART0 13
+#define RST_BUS_UART1 14
+#define RST_BUS_UART2 15
+#define RST_BUS_UART3 16
+#define RST_BUS_I2C0 17
+#define RST_BUS_I2C1 18
+#define RST_BUS_SCR 19
+#define RST_BUS_SPI0 20
+#define RST_BUS_SPI1 21
+#define RST_BUS_EMAC 22
+#define RST_BUS_IR_RX 23
+#define RST_BUS_IR_TX 24
+#define RST_BUS_I2S0 25
+#define RST_BUS_I2S1 26
+#define RST_BUS_SPDIF 27
+#define RST_USB_PHY0 28
+#define RST_USB_PHY1 29
+#define RST_BUS_OHCI0 30
+#define RST_BUS_OHCI1 31
+#define RST_BUS_EHCI0 32
+#define RST_BUS_OTG 33
+#define RST_BUS_LEDC 34
+
+#endif /* _DT_BINDINGS_RST_SUN50I_R329_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
new file mode 100644
index 000000000000..40644f2f21c6
--- /dev/null
+++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
+
+#define RST_R_BUS_GPADC 0
+#define RST_R_BUS_THS 1
+#define RST_R_BUS_DMA 2
+#define RST_R_BUS_PWM 3
+#define RST_R_BUS_CODEC 4
+#define RST_R_BUS_DMIC 5
+#define RST_R_BUS_LRADC 6
+#define RST_R_BUS_I2S 7
+#define RST_R_BUS_UART 8
+#define RST_R_BUS_I2C 9
+#define RST_R_BUS_IR 10
+#define RST_R_BUS_MSGBOX 11
+#define RST_R_BUS_SPINLOCK 12
+#define RST_R_BUS_RTC 13
+
+#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */
--
2.35.1

2022-04-22 19:36:11

by icenowy

[permalink] [raw]
Subject: [PATCH 11/12] arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA

From: Icenowy Zheng <[email protected]>

Sipeed Maix IIA is a R329-N4 (AIPU available and 256MiB DRAM) based SoM,
with a Realtek SDIO Wi-Fi module on it.

Add a DTSI file for it.

Signed-off-by: Icenowy Zheng <[email protected]>
---
.../dts/allwinner/sun50i-r329-maix-iia.dtsi | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
new file mode 100644
index 000000000000..15774f8a5445
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+#include "sun50i-r329.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ reg_vcc3v3: vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ wifi_pwrseq: wifi_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&r_pio 1 0 GPIO_ACTIVE_LOW>; /* PM0 */
+ post-power-on-delay-ms = <200>;
+ };
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_clk_pg0>, <&mmc1_cmd_pg1>, <&mmc1_d0_pg2>,
+ <&mmc1_d1_pg3>, <&mmc1_d2_pg4>, <&mmc1_d3_pg5>;
+
+ vmmc-supply = <&reg_vcc3v3>;
+ vqmmc-supply = <&reg_vcc3v3>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+};
--
2.35.1

2022-04-22 20:04:30

by icenowy

[permalink] [raw]
Subject: [PATCH 09/12] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense

From: Icenowy Zheng <[email protected]>

Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
SoM.

Add compatible strings for it.

Signed-off-by: Icenowy Zheng <[email protected]>
---
Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index 95278a6a9a8e..d2f5bb1ab136 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -454,6 +454,12 @@ properties:
- const: haoyu,a20-marsboard
- const: allwinner,sun7i-a20

+ - description: Sipeed MaixSense
+ items:
+ - const: sipeed,maixsense
+ - const: sipeed,maix-iia
+ - const: allwinner,sun50i-r329
+
- description: MapleBoard MP130
items:
- const: mapleboard,mp130
--
2.35.1

2022-04-22 20:54:13

by icenowy

[permalink] [raw]
Subject: [PATCH 12/12] arm64: allwinner: dts: r329: add support for Sipeed MaixSense

From: Icenowy Zheng <[email protected]>

Sipeed MaixSense is a R329 devkit based on Maix IIA SoM.

Add support for it.

Signed-off-by: Icenowy Zheng <[email protected]>
---
arch/arm64/boot/dts/allwinner/Makefile | 1 +
.../dts/allwinner/sun50i-r329-maixsense.dts | 37 +++++++++++++++++++
2 files changed, 38 insertions(+)
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 8fa5c060a4fe..81fe954ba2ef 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -38,3 +38,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6-mini.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-r329-maixsense.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts b/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
new file mode 100644
index 000000000000..1876b9d0b080
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+/dts-v1/;
+
+#include "sun50i-r329-maix-iia.dtsi"
+
+/ {
+ model = "Sipeed MaixSense";
+ compatible = "sipeed,maixsense", "sipeed,maix-iia",
+ "allwinner,sun50i-r329";
+
+ aliases {
+ serial0 = &uart0;
+ mmc0 = &mmc0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pf_pins>;
+
+ vmmc-supply = <&reg_vcc3v3>;
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pb_pins>;
+ status = "okay";
+};
--
2.35.1

2022-04-22 21:23:34

by Icenowy Zheng

[permalink] [raw]
Subject: [PATCH 01/12] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO

Allwinner R329 have two pin controllers similar to previous Allwinner
SoCs, PIO and R-PIO.

Add compatible strings for them.

Signed-off-by: Icenowy Zheng <[email protected]>
---
.../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
index bfce850c2035..3fa7891381e7 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
@@ -55,6 +55,8 @@ properties:
- allwinner,sun50i-h6-r-pinctrl
- allwinner,sun50i-h616-pinctrl
- allwinner,sun50i-h616-r-pinctrl
+ - allwinner,sun50i-r329-pinctrl
+ - allwinner,sun50i-r329-r-pinctrl
- allwinner,suniv-f1c100s-pinctrl
- nextthing,gr8-pinctrl

@@ -190,6 +192,7 @@ allOf:
- allwinner,sun6i-a31-pinctrl
- allwinner,sun6i-a31s-pinctrl
- allwinner,sun50i-h6-pinctrl
+ - allwinner,sun50i-r329-pinctrl

then:
properties:
@@ -205,6 +208,7 @@ allOf:
- allwinner,sun8i-a83t-pinctrl
- allwinner,sun50i-a64-pinctrl
- allwinner,sun50i-h5-pinctrl
+ - allwinner,sun50i-r329-r-pinctrl
- allwinner,suniv-f1c100s-pinctrl

then:
--
2.35.1

2022-04-22 21:37:44

by icenowy

[permalink] [raw]
Subject: [PATCH 06/12] clk: sunxi=ng: add support for R329 CCUs

From: Icenowy Zheng <[email protected]>

Allwinner R329 has two CCUs, one in CPUX and another in PRCM.

Add support for them.

Signed-off-by: Icenowy Zheng <[email protected]>
---
drivers/clk/sunxi-ng/Kconfig | 10 +
drivers/clk/sunxi-ng/Makefile | 4 +
drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c | 401 ++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h | 25 +
drivers/clk/sunxi-ng/ccu-sun50i-r329.c | 587 +++++++++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun50i-r329.h | 32 ++
6 files changed, 1059 insertions(+)
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 461537679c04..2ae2a5a65c05 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -52,6 +52,16 @@ config SUN50I_H6_R_CCU
default ARM64 && ARCH_SUNXI
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST

+config SUN50I_R329_CCU
+ tristate "Support for the Allwinner R329 CCU"
+ default ARM64 && ARCH_SUNXI
+ depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
+config SUN50I_R329_R_CCU
+ tristate "Support for the Allwinner R329 PRCM CCU"
+ default ARM64 && ARCH_SUNXI
+ depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
config SUN4I_A10_CCU
tristate "Support for the Allwinner A10/A20 CCU"
default MACH_SUN4I
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 6b3ae2b620db..7cf4c708e4b2 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -33,6 +33,8 @@ obj-$(CONFIG_SUN50I_A100_R_CCU) += sun50i-a100-r-ccu.o
obj-$(CONFIG_SUN50I_H6_CCU) += sun50i-h6-ccu.o
obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o
obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o
+obj-$(CONFIG_SUN50I_R329_CCU) += sun50i-r329-ccu.o
+obj-$(CONFIG_SUN50I_R329_R_CCU) += sun50i-r329-r-ccu.o
obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o
obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o
obj-$(CONFIG_SUN6I_A31_CCU) += sun6i-a31-ccu.o
@@ -58,6 +60,8 @@ sun50i-a100-r-ccu-y += ccu-sun50i-a100-r.o
sun50i-h6-ccu-y += ccu-sun50i-h6.o
sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o
sun50i-h616-ccu-y += ccu-sun50i-h616.o
+sun50i-r329-ccu-y += ccu-sun50i-r329.o
+sun50i-r329-r-ccu-y += ccu-sun50i-r329-r.o
sun4i-a10-ccu-y += ccu-sun4i-a10.o
sun5i-ccu-y += ccu-sun5i.o
sun6i-a31-ccu-y += ccu-sun6i-a31.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
new file mode 100644
index 000000000000..5533b768b45b
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
@@ -0,0 +1,401 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Sipeed
+ * Based on the H616 CCU driver, which is:
+ * Copyright (c) 2020 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-r329-r.h"
+
+static const struct clk_parent_data osc24M[] = {
+ { .fw_name = "hosc" }
+};
+
+/*
+ * The M factor is present in the register's description, but not in the
+ * frequency formula, and it's documented as "The bit is only for
+ * testing", so it's not modelled and then force to 0.
+ */
+#define SUN50I_R329_PLL_CPUX_REG 0x1000
+static struct ccu_mult pll_cpux_clk = {
+ .enable = BIT(31),
+ .lock = BIT(28),
+ .mult = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+ .common = {
+ .reg = 0x1000,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-cpux", osc24M,
+ &ccu_mult_ops,
+ CLK_SET_RATE_UNGATE),
+ },
+};
+
+#define SUN50I_R329_PLL_PERIPH_REG 0x1010
+static struct ccu_nm pll_periph_base_clk = {
+ .enable = BIT(31),
+ .lock = BIT(28),
+ .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+ .m = _SUNXI_CCU_DIV(1, 1), /* input divider */
+ .common = {
+ .reg = 0x1010,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-periph-base", osc24M,
+ &ccu_nm_ops,
+ CLK_SET_RATE_UNGATE),
+ },
+};
+
+static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-base",
+ 0x1010, 16, 3, 0);
+static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m", "pll-periph-base",
+ 0x1010, 20, 3, 0);
+static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
+ &pll_periph_2x_clk.common.hw, 2, 1, 0);
+
+#define SUN50I_R329_PLL_AUDIO0_REG 0x1020
+static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
+ { .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64 },
+};
+
+static struct ccu_nm pll_audio0_clk = {
+ .enable = BIT(31),
+ .lock = BIT(28),
+ .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+ .m = _SUNXI_CCU_DIV(1, 1),
+ .sdm = _SUNXI_CCU_SDM(pll_audio0_sdm_table,
+ BIT(24), 0x1120, BIT(31)),
+ .common = {
+ .features = CCU_FEATURE_SIGMA_DELTA_MOD,
+ .reg = 0x1020,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-audio0", osc24M,
+ &ccu_nm_ops,
+ CLK_SET_RATE_UNGATE),
+ },
+};
+
+static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-audio0",
+ 0x1020, 16, 3, 0);
+static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-audio0",
+ 0x1020, 20, 3, 0);
+
+/*
+ * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
+ * BSP driver always has M0 = 1 and M1 = 2 (this is also the
+ * reset value in the register).
+ *
+ * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
+ */
+#define SUN50I_R329_PLL_AUDIO1_REG 0x1030
+static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
+ { .rate = 45158400, .pattern = 0xc001288d, .m = 12, .n = 22 },
+ { .rate = 49152000, .pattern = 0xc00126e9, .m = 12, .n = 24 },
+ { .rate = 180633600, .pattern = 0xc001288d, .m = 3, .n = 22 },
+ { .rate = 196608000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
+};
+static struct ccu_nm pll_audio1_4x_clk = {
+ .enable = BIT(31),
+ .lock = BIT(28),
+ .n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+ .m = _SUNXI_CCU_DIV(16, 6),
+ .fixed_post_div = 2,
+ .sdm = _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
+ BIT(24), 0x1130, BIT(31)),
+ .common = {
+ .features = CCU_FEATURE_FIXED_POSTDIV |
+ CCU_FEATURE_SIGMA_DELTA_MOD,
+ .reg = 0x1030,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("pll-audio1-4x", osc24M,
+ &ccu_nm_ops,
+ CLK_SET_RATE_UNGATE),
+ },
+};
+
+static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
+ &pll_audio1_4x_clk.common.hw, 2, 1,
+ CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
+ &pll_audio1_4x_clk.common.hw, 4, 1,
+ CLK_SET_RATE_PARENT);
+
+static const struct clk_parent_data r_bus_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "losc" },
+ { .fw_name = "iosc" },
+ { .hw = &pll_periph_2x_clk.common.hw },
+ { .hw = &pll_audio0_div2_clk.common.hw },
+};
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents, 0x000,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents, 0x00c,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents, 0x010,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ 0);
+
+static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
+ 0x0ec, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c, BIT(0), 0);
+
+static const struct clk_parent_data r_pwm_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "losc" },
+ { .fw_name = "iosc" },
+};
+static SUNXI_CCU_MUX_DATA_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents, 0x130,
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c, BIT(0), 0);
+
+static const char * const r_audio_parents[] = { "pll-audio0-div5", "pll-audio0-div2",
+ "pll-audio1-1x", "pll-audio1-4x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc", r_audio_parents, 0x140,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac", r_audio_parents, 0x144,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
+ 0x14c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic", r_audio_parents, 0x150,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc", "r-apb1",
+ 0x16c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s", r_audio_parents, 0x170,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
+ r_audio_parents, 0x174,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart", "r-apb2", 0x18c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_i2c_clk, "r-bus-i2c", "r-apb2", 0x19c, BIT(0), 0);
+
+static const struct clk_parent_data r_ir_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "losc" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents, 0x1c0,
+ 0, 5, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
+ 0x1dc, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-apb1",
+ 0x1ec, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
+ 0x20c, BIT(0), 0);
+
+static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
+ &pll_cpux_clk.common,
+ &pll_periph_base_clk.common,
+ &pll_periph_2x_clk.common,
+ &pll_periph_800m_clk.common,
+ &pll_audio0_clk.common,
+ &pll_audio0_div2_clk.common,
+ &pll_audio0_div5_clk.common,
+ &pll_audio1_4x_clk.common,
+ &r_ahb_clk.common,
+ &r_apb1_clk.common,
+ &r_apb2_clk.common,
+ &r_bus_gpadc_clk.common,
+ &r_bus_ths_clk.common,
+ &r_bus_dma_clk.common,
+ &r_pwm_clk.common,
+ &r_bus_pwm_clk.common,
+ &r_codec_adc_clk.common,
+ &r_codec_dac_clk.common,
+ &r_bus_codec_clk.common,
+ &r_dmic_clk.common,
+ &r_bus_dmic_clk.common,
+ &r_bus_lradc_clk.common,
+ &r_i2s_clk.common,
+ &r_i2s_asrc_clk.common,
+ &r_bus_i2s_clk.common,
+ &r_bus_uart_clk.common,
+ &r_bus_i2c_clk.common,
+ &r_ir_clk.common,
+ &r_bus_ir_clk.common,
+ &r_bus_msgbox_clk.common,
+ &r_bus_spinlock_clk.common,
+ &r_bus_rtc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
+ .hws = {
+ [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
+ [CLK_PLL_PERIPH_BASE] = &pll_periph_base_clk.common.hw,
+ [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.common.hw,
+ [CLK_PLL_PERIPH_800M] = &pll_periph_800m_clk.common.hw,
+ [CLK_PLL_PERIPH] = &pll_periph_clk.hw,
+ [CLK_PLL_AUDIO0] = &pll_audio0_clk.common.hw,
+ [CLK_PLL_AUDIO0_DIV2] = &pll_audio0_div2_clk.common.hw,
+ [CLK_PLL_AUDIO0_DIV5] = &pll_audio0_div5_clk.common.hw,
+ [CLK_PLL_AUDIO1_4X] = &pll_audio1_4x_clk.common.hw,
+ [CLK_PLL_AUDIO1_2X] = &pll_audio1_2x_clk.hw,
+ [CLK_PLL_AUDIO1] = &pll_audio1_clk.hw,
+ [CLK_R_AHB] = &r_ahb_clk.common.hw,
+ [CLK_R_APB1] = &r_apb1_clk.common.hw,
+ [CLK_R_APB2] = &r_apb2_clk.common.hw,
+ [CLK_R_BUS_GPADC] = &r_bus_gpadc_clk.common.hw,
+ [CLK_R_BUS_THS] = &r_bus_ths_clk.common.hw,
+ [CLK_R_BUS_DMA] = &r_bus_dma_clk.common.hw,
+ [CLK_R_PWM] = &r_pwm_clk.common.hw,
+ [CLK_R_BUS_PWM] = &r_bus_pwm_clk.common.hw,
+ [CLK_R_CODEC_ADC] = &r_codec_adc_clk.common.hw,
+ [CLK_R_CODEC_DAC] = &r_codec_dac_clk.common.hw,
+ [CLK_R_BUS_CODEC] = &r_bus_codec_clk.common.hw,
+ [CLK_R_DMIC] = &r_dmic_clk.common.hw,
+ [CLK_R_BUS_DMIC] = &r_bus_dmic_clk.common.hw,
+ [CLK_R_BUS_LRADC] = &r_bus_lradc_clk.common.hw,
+ [CLK_R_I2S] = &r_i2s_clk.common.hw,
+ [CLK_R_I2S_ASRC] = &r_i2s_asrc_clk.common.hw,
+ [CLK_R_BUS_I2S] = &r_bus_i2s_clk.common.hw,
+ [CLK_R_BUS_UART] = &r_bus_uart_clk.common.hw,
+ [CLK_R_BUS_I2C] = &r_bus_i2c_clk.common.hw,
+ [CLK_R_IR] = &r_ir_clk.common.hw,
+ [CLK_R_BUS_IR] = &r_bus_ir_clk.common.hw,
+ [CLK_R_BUS_MSGBOX] = &r_bus_msgbox_clk.common.hw,
+ [CLK_R_BUS_SPINLOCK] = &r_bus_spinlock_clk.common.hw,
+ [CLK_R_BUS_RTC] = &r_bus_rtc_clk.common.hw,
+ },
+ .num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
+ [RST_R_BUS_GPADC] = { 0x0ec, BIT(16) },
+ [RST_R_BUS_THS] = { 0x0fc, BIT(16) },
+ [RST_R_BUS_DMA] = { 0x10c, BIT(16) },
+ [RST_R_BUS_PWM] = { 0x13c, BIT(16) },
+ [RST_R_BUS_CODEC] = { 0x14c, BIT(16) },
+ [RST_R_BUS_DMIC] = { 0x15c, BIT(16) },
+ [RST_R_BUS_LRADC] = { 0x16c, BIT(16) },
+ [RST_R_BUS_I2S] = { 0x17c, BIT(16) },
+ [RST_R_BUS_UART] = { 0x18c, BIT(16) },
+ [RST_R_BUS_I2C] = { 0x19c, BIT(16) },
+ [RST_R_BUS_IR] = { 0x1cc, BIT(16) },
+ [RST_R_BUS_MSGBOX] = { 0x1dc, BIT(16) },
+ [RST_R_BUS_SPINLOCK] = { 0x1ec, BIT(16) },
+ [RST_R_BUS_RTC] = { 0x20c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
+ .ccu_clks = sun50i_r329_r_ccu_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun50i_r329_r_ccu_clks),
+
+ .hw_clks = &sun50i_r329_r_hw_clks,
+
+ .resets = sun50i_r329_r_ccu_resets,
+ .num_resets = ARRAY_SIZE(sun50i_r329_r_ccu_resets),
+};
+
+static const u32 pll_regs[] = {
+ SUN50I_R329_PLL_CPUX_REG,
+ SUN50I_R329_PLL_PERIPH_REG,
+ SUN50I_R329_PLL_AUDIO0_REG,
+ SUN50I_R329_PLL_AUDIO1_REG,
+};
+
+static int sun50i_r329_r_ccu_probe(struct platform_device *pdev)
+{
+ void __iomem *reg;
+ int i;
+ u32 val;
+
+ reg = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(reg))
+ return PTR_ERR(reg);
+
+ /* Enable the lock bits and the output enable bits on all PLLs */
+ for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
+ val = readl(reg + pll_regs[i]);
+ val |= BIT(29) | BIT(27);
+ writel(val, reg + pll_regs[i]);
+ }
+
+ /*
+ * Force the I/O dividers of PLL-AUDIO1 to reset default value
+ *
+ * See the comment before pll-audio1 definition for the reason.
+ */
+
+ val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
+ val &= ~BIT(1);
+ val |= BIT(0);
+ writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
+
+ return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_r329_r_ccu_desc);
+}
+
+static const struct of_device_id sun50i_r329_r_ccu_ids[] = {
+ { .compatible = "allwinner,sun50i-r329-r-ccu" },
+ { }
+};
+
+static struct platform_driver sun50i_r329_r_ccu_driver = {
+ .probe = sun50i_r329_r_ccu_probe,
+ .driver = {
+ .name = "sun50i-r329-r-ccu",
+ .suppress_bind_attrs = true,
+ .of_match_table = sun50i_r329_r_ccu_ids,
+ },
+};
+module_platform_driver(sun50i_r329_r_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
new file mode 100644
index 000000000000..1e04772b6515
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _CCU_SUN50I_R329_R_H
+#define _CCU_SUN50I_R329_R_H
+
+#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
+
+/* PLLs exported for main CCU except a virtual base */
+
+#define CLK_PLL_PERIPH_BASE 1
+
+/* R_AHB exported for RTC */
+/* R_APB1 exported for PIO */
+
+#define CLK_R_APB2 13
+
+/* All module / bus gate clocks exported */
+
+#define CLK_NUMBER (CLK_R_BUS_RTC + 1)
+
+#endif /* _CCU_SUN50I_R329_R_H */
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
new file mode 100644
index 000000000000..652770f1b9c8
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
@@ -0,0 +1,587 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Based on the H616 CCU driver, which is:
+ * Copyright (c) 2020 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-r329.h"
+
+/*
+ * An external divider of PLL-CPUX is controlled here. As it's similar to
+ * the external divider of PLL-CPUX on previous SoCs (only usable under
+ * 288MHz}, ignore it.
+ */
+static const struct clk_parent_data cpux_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "losc" },
+ { .fw_name = "iosc" },
+ { .fw_name = "pll-cpux" },
+ { .fw_name = "pll-periph" },
+ { .fw_name = "pll-periph-2x" },
+ { .fw_name = "pll-periph-800m" },
+};
+static SUNXI_CCU_MUX_DATA(cpux_clk, "cpux", cpux_parents,
+ 0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
+static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
+
+static const struct clk_parent_data ahb_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "losc" },
+ { .fw_name = "iosc" },
+ { .fw_name = "pll-periph" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX(ahb_clk, "ahb",
+ ahb_parents, 0x510,
+ 0, 2, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ 0);
+
+static const struct clk_parent_data apb_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "losc" },
+ { .hw = &ahb_clk.common.hw },
+ { .fw_name = "pll-periph" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX(apb1_clk, "apb1", apb_parents, 0x520,
+ 0, 2, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX(apb2_clk, "apb2", apb_parents, 0x524,
+ 0, 2, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ 0);
+
+static const struct clk_parent_data ce_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "pll-periph-2x" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 1, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb",
+ 0x68c, BIT(0), 0);
+
+static const struct clk_parent_data aipu_parents[] = {
+ { .fw_name = "pll-periph-2x" },
+ { .fw_name = "pll-periph-800m" },
+ { .fw_name = "pll-audio0-div2" },
+ { .fw_name = "pll-audio0-div5" },
+ { .fw_name = "pll-cpux" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(aipu_clk, "aipu", aipu_parents, 0x6f0,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_aipu_clk, "bus-aipu", "ahb",
+ 0x6fc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
+ 0x70c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb",
+ 0x71c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb",
+ 0x72c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb",
+ 0x73c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31), 0);
+
+static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb",
+ 0x78c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
+
+static const struct clk_parent_data dram_parents[] = {
+ { .fw_name = "pll-periph-2x" },
+ { .fw_name = "pll-periph-800m" },
+ { .fw_name = "pll-audio0-div2" },
+ { .fw_name = "pll-audio0-div5" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
+ 0, 2, /* M */
+ 8, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ CLK_IS_CRITICAL);
+
+
+static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "dram",
+ 0x804, BIT(0), 0);
+static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "dram",
+ 0x804, BIT(2), 0);
+static SUNXI_CCU_GATE(mbus_r_dma_clk, "mbus-r-dma", "dram",
+ 0x804, BIT(3), 0);
+static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "dram",
+ 0x804, BIT(5), 0);
+static SUNXI_CCU_GATE(mbus_aipu_clk, "mbus-aipu", "dram",
+ 0x804, BIT(16), 0);
+
+static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
+ 0x80c, BIT(0), CLK_IS_CRITICAL);
+
+static const struct clk_parent_data nand_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "pll-periph" },
+ { .fw_name = "pll-audio0-div2" },
+ { .fw_name = "pll-periph-2x" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(nand0_clk, "nand0", nand_parents, 0x810,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(nand1_clk, "nand1", nand_parents, 0x814,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 3, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb", 0x82c, BIT(0), 0);
+
+static const struct clk_parent_data mmc_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "pll-periph" },
+ { .fw_name = "pll-periph-2x" },
+ { .fw_name = "pll-audio0-div2" },
+};
+
+static struct ccu_mp mmc0_clk = {
+ .enable = BIT(31),
+ .m = _SUNXI_CCU_DIV(0, 4),
+ .p = _SUNXI_CCU_DIV(8, 2),
+ .mux = _SUNXI_CCU_MUX(24, 2),
+ .fixed_post_div = 2,
+ .common = {
+ .reg = 0x830,
+ .features = CCU_FEATURE_FIXED_POSTDIV,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("mmc0",
+ mmc_parents,
+ &ccu_mp_ops,
+ 0),
+ }
+};
+
+static struct ccu_mp mmc1_clk = {
+ .enable = BIT(31),
+ .m = _SUNXI_CCU_DIV(0, 4),
+ .p = _SUNXI_CCU_DIV(8, 2),
+ .mux = _SUNXI_CCU_MUX(24, 2),
+ .fixed_post_div = 2,
+ .common = {
+ .reg = 0x834,
+ .features = CCU_FEATURE_FIXED_POSTDIV,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("mmc1",
+ mmc_parents,
+ &ccu_mp_ops,
+ 0),
+ }
+};
+
+static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb", 0x84c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb", 0x84c, BIT(1), 0);
+
+static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
+
+static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
+
+static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", 0x93c, BIT(0), 0);
+
+static const struct clk_parent_data spi_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "pll-periph" },
+ { .fw_name = "pll-periph-2x" },
+ { .fw_name = "pll-audio0-div2" },
+ { .fw_name = "pll-audio0-div5" },
+};
+
+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_GATE(bus_spi0_clk, "bus-spi0", "ahb", 0x96c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb", 0x96c, BIT(1), 0);
+
+static CLK_FIXED_FACTOR_FW_NAME(emac_25m_div_clk, "emac-25m-div", "pll-periph",
+ 2, 1, 0);
+static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "emac-25m-div", 0x970,
+ BIT(31) | BIT(30), 0);
+
+static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb", 0x97c, BIT(0), 0);
+
+static const struct clk_parent_data ir_parents[] = {
+ { .fw_name = "losc" },
+ { .fw_name = "iosc" },
+ { .fw_name = "pll-periph" },
+ { .fw_name = "pll-audio0-div2" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "apb1", 0x99c, BIT(0), 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0);
+
+static const struct clk_parent_data audio_parents[] = {
+ { .fw_name = "pll-audio1" },
+ { .fw_name = "pll-audio1-4x" },
+ { .fw_name = "pll-audio0-div2" },
+ { .fw_name = "pll-audio0-div5" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(i2s0_clk, "i2s0", audio_parents, 0xa10,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(i2s1_clk, "i2s1", audio_parents, 0xa14,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
+
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spdif_clk, "spdif", audio_parents, 0xa20,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 2, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
+
+/*
+ * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports.
+ * We will force them to 0 (12M divided from 48M).
+ */
+#define SUN50I_R329_USB0_CLK_REG 0xa70
+#define SUN50I_R329_USB1_CLK_REG 0xa74
+
+static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70, BIT(29), 0);
+
+static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74, BIT(29), 0);
+
+static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb", 0xa8c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb", 0xa8c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb", 0xa8c, BIT(4), 0);
+static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb", 0xa8c, BIT(8), 0);
+
+static const struct clk_parent_data ledc_parents[] = {
+ { .fw_name = "hosc" },
+ { .fw_name = "pll-periph" },
+};
+static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ledc_parents, 0xbf0,
+ 0, 4, /* M */
+ 8, 2, /* P */
+ 24, 1, /* mux */
+ BIT(31), /* gate */
+ 0);
+
+static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "apb1", 0xbfc, BIT(0), 0);
+
+/* Fixed factor clocks */
+static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
+
+static struct ccu_common *sun50i_r329_ccu_clks[] = {
+ &cpux_clk.common,
+ &axi_clk.common,
+ &cpux_apb_clk.common,
+ &ahb_clk.common,
+ &apb1_clk.common,
+ &apb2_clk.common,
+ &ce_clk.common,
+ &bus_ce_clk.common,
+ &aipu_clk.common,
+ &bus_aipu_clk.common,
+ &bus_dma_clk.common,
+ &bus_msgbox_clk.common,
+ &bus_spinlock_clk.common,
+ &bus_hstimer_clk.common,
+ &avs_clk.common,
+ &bus_dbg_clk.common,
+ &bus_pwm_clk.common,
+ &dram_clk.common,
+ &mbus_dma_clk.common,
+ &mbus_ce_clk.common,
+ &mbus_r_dma_clk.common,
+ &mbus_nand_clk.common,
+ &mbus_aipu_clk.common,
+ &bus_dram_clk.common,
+ &nand0_clk.common,
+ &nand1_clk.common,
+ &bus_nand_clk.common,
+ &mmc0_clk.common,
+ &mmc1_clk.common,
+ &bus_mmc0_clk.common,
+ &bus_mmc1_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_scr_clk.common,
+ &spi0_clk.common,
+ &spi1_clk.common,
+ &bus_spi0_clk.common,
+ &bus_spi1_clk.common,
+ &emac_25m_clk.common,
+ &bus_emac_clk.common,
+ &ir_rx_clk.common,
+ &bus_ir_rx_clk.common,
+ &ir_tx_clk.common,
+ &bus_ir_tx_clk.common,
+ &i2s0_clk.common,
+ &i2s1_clk.common,
+ &bus_i2s0_clk.common,
+ &bus_i2s1_clk.common,
+ &spdif_clk.common,
+ &bus_spdif_clk.common,
+ &usb_ohci0_clk.common,
+ &usb_phy0_clk.common,
+ &usb_ohci1_clk.common,
+ &usb_phy1_clk.common,
+ &bus_ohci0_clk.common,
+ &bus_ohci1_clk.common,
+ &bus_ehci0_clk.common,
+ &bus_otg_clk.common,
+ &ledc_clk.common,
+ &bus_ledc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_r329_hw_clks = {
+ .hws = {
+ [CLK_OSC12M] = &osc12M_clk.hw,
+ [CLK_CPUX] = &cpux_clk.common.hw,
+ [CLK_AXI] = &axi_clk.common.hw,
+ [CLK_CPUX_APB] = &cpux_apb_clk.common.hw,
+ [CLK_AHB] = &ahb_clk.common.hw,
+ [CLK_APB1] = &apb1_clk.common.hw,
+ [CLK_APB2] = &apb2_clk.common.hw,
+ [CLK_CE] = &ce_clk.common.hw,
+ [CLK_BUS_CE] = &bus_ce_clk.common.hw,
+ [CLK_AIPU] = &aipu_clk.common.hw,
+ [CLK_BUS_AIPU] = &bus_aipu_clk.common.hw,
+ [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
+ [CLK_BUS_MSGBOX] = &bus_msgbox_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_DBG] = &bus_dbg_clk.common.hw,
+ [CLK_BUS_PWM] = &bus_pwm_clk.common.hw,
+ [CLK_DRAM] = &dram_clk.common.hw,
+ [CLK_MBUS_DMA] = &mbus_dma_clk.common.hw,
+ [CLK_MBUS_CE] = &mbus_ce_clk.common.hw,
+ [CLK_MBUS_R_DMA] = &mbus_r_dma_clk.common.hw,
+ [CLK_MBUS_NAND] = &mbus_nand_clk.common.hw,
+ [CLK_MBUS_AIPU] = &mbus_aipu_clk.common.hw,
+ [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
+ [CLK_NAND0] = &nand0_clk.common.hw,
+ [CLK_NAND1] = &nand1_clk.common.hw,
+ [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
+ [CLK_MMC0] = &mmc0_clk.common.hw,
+ [CLK_MMC1] = &mmc1_clk.common.hw,
+ [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
+ [CLK_BUS_MMC1] = &bus_mmc1_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_SCR] = &bus_scr_clk.common.hw,
+ [CLK_SPI0] = &spi0_clk.common.hw,
+ [CLK_SPI1] = &spi1_clk.common.hw,
+ [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
+ [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
+ [CLK_EMAC_25M_DIV] = &emac_25m_div_clk.hw,
+ [CLK_EMAC_25M] = &emac_25m_clk.common.hw,
+ [CLK_BUS_EMAC] = &bus_emac_clk.common.hw,
+ [CLK_IR_RX] = &ir_rx_clk.common.hw,
+ [CLK_BUS_IR_RX] = &bus_ir_rx_clk.common.hw,
+ [CLK_IR_TX] = &ir_tx_clk.common.hw,
+ [CLK_BUS_IR_TX] = &bus_ir_tx_clk.common.hw,
+ [CLK_I2S0] = &i2s0_clk.common.hw,
+ [CLK_I2S1] = &i2s1_clk.common.hw,
+ [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
+ [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
+ [CLK_SPDIF] = &spdif_clk.common.hw,
+ [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw,
+ [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
+ [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
+ [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
+ [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
+ [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw,
+ [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw,
+ [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw,
+ [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
+ [CLK_LEDC] = &ledc_clk.common.hw,
+ [CLK_BUS_LEDC] = &bus_ledc_clk.common.hw,
+ },
+ .num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_r329_ccu_resets[] = {
+ [RST_MBUS] = { 0x540, BIT(30) },
+
+ [RST_BUS_CE] = { 0x68c, BIT(16) },
+ [RST_BUS_AIPU] = { 0x6fc, BIT(16) },
+ [RST_BUS_DMA] = { 0x70c, BIT(16) },
+ [RST_BUS_MSGBOX] = { 0x71c, BIT(16) },
+ [RST_BUS_SPINLOCK] = { 0x72c, BIT(16) },
+ [RST_BUS_HSTIMER] = { 0x73c, BIT(16) },
+ [RST_BUS_DBG] = { 0x78c, BIT(16) },
+ [RST_BUS_PWM] = { 0x7ac, BIT(16) },
+ [RST_BUS_DRAM] = { 0x80c, BIT(16) },
+ [RST_BUS_NAND] = { 0x82c, BIT(16) },
+ [RST_BUS_MMC0] = { 0x84c, BIT(16) },
+ [RST_BUS_MMC1] = { 0x84c, BIT(17) },
+ [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_SCR] = { 0x93c, BIT(16) },
+ [RST_BUS_SPI0] = { 0x96c, BIT(16) },
+ [RST_BUS_SPI1] = { 0x96c, BIT(17) },
+ [RST_BUS_EMAC] = { 0x97c, BIT(16) },
+ [RST_BUS_IR_RX] = { 0x99c, BIT(16) },
+ [RST_BUS_IR_TX] = { 0x9cc, BIT(16) },
+ [RST_BUS_I2S0] = { 0xa1c, BIT(16) },
+ [RST_BUS_I2S1] = { 0xa1c, BIT(17) },
+ [RST_BUS_SPDIF] = { 0xa2c, BIT(16) },
+
+ [RST_USB_PHY0] = { 0xa70, BIT(30) },
+ [RST_USB_PHY1] = { 0xa74, BIT(30) },
+
+ [RST_BUS_OHCI0] = { 0xa8c, BIT(16) },
+ [RST_BUS_OHCI1] = { 0xa8c, BIT(17) },
+ [RST_BUS_EHCI0] = { 0xa8c, BIT(20) },
+ [RST_BUS_OTG] = { 0xa8c, BIT(24) },
+
+ [RST_BUS_LEDC] = { 0xbfc, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_r329_ccu_desc = {
+ .ccu_clks = sun50i_r329_ccu_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun50i_r329_ccu_clks),
+
+ .hw_clks = &sun50i_r329_hw_clks,
+
+ .resets = sun50i_r329_ccu_resets,
+ .num_resets = ARRAY_SIZE(sun50i_r329_ccu_resets),
+};
+
+static const u32 sun50i_r329_usb_clk_regs[] = {
+ SUN50I_R329_USB0_CLK_REG,
+ SUN50I_R329_USB1_CLK_REG,
+};
+
+static int sun50i_r329_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);
+
+ /*
+ * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
+ *
+ * This clock mux is still mysterious, and the code just enforces
+ * it to have a valid clock parent.
+ */
+ for (i = 0; i < ARRAY_SIZE(sun50i_r329_usb_clk_regs); i++) {
+ val = readl(reg + sun50i_r329_usb_clk_regs[i]);
+ val &= ~GENMASK(25, 24);
+ writel(val, reg + sun50i_r329_usb_clk_regs[i]);
+ }
+
+ return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_r329_ccu_desc);
+}
+
+static const struct of_device_id sun50i_r329_ccu_ids[] = {
+ { .compatible = "allwinner,sun50i-r329-ccu" },
+ { }
+};
+
+static struct platform_driver sun50i_r329_ccu_driver = {
+ .probe = sun50i_r329_ccu_probe,
+ .driver = {
+ .name = "sun50i-r329-ccu",
+ .of_match_table = sun50i_r329_ccu_ids,
+ },
+};
+module_platform_driver(sun50i_r329_ccu_driver);
+
+MODULE_IMPORT_NS(SUNXI_CCU);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
new file mode 100644
index 000000000000..144ac9954ef3
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _CCU_SUN50I_R329_H_
+#define _CCU_SUN50I_R329_H_
+
+#include <dt-bindings/clock/sun50i-r329-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-ccu.h>
+
+#define CLK_OSC12M 0
+
+/* CPUX exported for DVFS */
+
+#define CLK_AXI 2
+#define CLK_CPUX_APB 3
+#define CLK_AHB 4
+
+/* APB1 exported for PIO */
+
+#define CLK_APB2 6
+
+/* Peripheral module and gate clock exported except for DRAM ones */
+
+#define CLK_DRAM 18
+
+#define CLK_BUS_DRAM 24
+
+#define CLK_NUMBER (CLK_BUS_LEDC + 1)
+
+#endif /* _CCU_SUN50I_R329_H_ */
--
2.35.1

2022-04-22 21:54:36

by icenowy

[permalink] [raw]
Subject: [PATCH 04/12] rtc: sun6i: add support for R329 RTC

From: Icenowy Zheng <[email protected]>

Allwinner R329 has a RTC with a similar time storage with H616 but a
slightly different clock part.

As we have already handled the R329 RTC clocks in the CCU driver, add a
compatible string to RTC driver to allow probing of the RTC.

Signed-off-by: Icenowy Zheng <[email protected]>
---
drivers/rtc/rtc-sun6i.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 5b3e4da63406..522e28fb05c9 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -816,6 +816,8 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
{ .compatible = "allwinner,sun50i-h6-rtc" },
{ .compatible = "allwinner,sun50i-h616-rtc",
.data = (void *)RTC_LINEAR_DAY },
+ { .compatible = "allwinner,sun50i-r329-rtc",
+ .data = (void *)RTC_LINEAR_DAY },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
--
2.35.1

2022-04-24 00:01:32

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 02/12] pinctrl: sunxi: add support for R329 CPUX pin controller

On 4/22/22 10:40 AM, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> Allwinner R329 SoC has two pin controllers similar to ones on previous
> SoCs, one in CPUX power domain and another in CPUS.
>
> This patch adds support for the CPUX domain pin controller.
>
> Signed-off-by: Icenowy Zheng <[email protected]>

This is identical to the previous version. Please see my comments on that, as
they still apply:

https://lore.kernel.org/linux-sunxi/[email protected]/

2022-04-24 03:25:22

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 05/12] dt-bindings: clock: sunxi-ng: add bindings for R329 CCUs

On 4/22/22 10:41 AM, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> R329 has a CPUX CCU and a R-CCU, with all PLLs in R-CCU.
>
> Add bindings for them, with R-CCU only taking 3 oscillators as input and
> main CCU taking oscillators + PLLs as input.
>
> Signed-off-by: Icenowy Zheng <[email protected]>
> ---
> .../clock/allwinner,sun4i-a10-ccu.yaml | 62 ++++++++++++++--
> include/dt-bindings/clock/sun50i-r329-ccu.h | 73 +++++++++++++++++++
> include/dt-bindings/clock/sun50i-r329-r-ccu.h | 45 ++++++++++++
> include/dt-bindings/reset/sun50i-r329-ccu.h | 45 ++++++++++++
> include/dt-bindings/reset/sun50i-r329-r-ccu.h | 24 ++++++
> 5 files changed, 241 insertions(+), 8 deletions(-)
> create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
> create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
> create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
>
> diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> index 15ed64d35261..c7a429e55483 100644
> --- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> +++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> @@ -45,6 +45,8 @@ properties:
> - allwinner,sun50i-h6-r-ccu
> - allwinner,sun50i-h616-ccu
> - allwinner,sun50i-h616-r-ccu
> + - allwinner,sun50i-r329-ccu
> + - allwinner,sun50i-r329-r-ccu
> - allwinner,suniv-f1c100s-ccu
> - nextthing,gr8-ccu
>
> @@ -106,6 +108,7 @@ else:
> - allwinner,sun50i-a100-ccu
> - allwinner,sun50i-h6-ccu
> - allwinner,sun50i-h616-ccu
> + - allwinner,sun50i-r329-r-ccu
>
> then:
> properties:
> @@ -118,14 +121,57 @@ else:
> maxItems: 3
>
> else:
> - properties:
> - clocks:
> - minItems: 2
> - maxItems: 2
> -
> - clock-names:
> - minItems: 2
> - maxItems: 2
> + if:
> + properties:
> + compatible:
> + const: allwinner,sun50i-r329-ccu
> + then:
> + properties:
> + clocks:
> + minItems: 13
> + maxItems: 13

The conditional part of the binding can only be more restrictive than the main
binding. So you need to increase maxItems above.

Also, I believe minItems/maxItems in this section is not needed when specifying
a list of items.

> + items:
> + - description: High Frequency Oscillator (usually at 24MHz)
> + - description: Low Frequency Oscillator (usually at 32kHz)
> + - description: Internal Oscillator
> + - description: CPUX PLL
> + - description: Peripherals PLL
> + - description: Peripherals PLL (2x)
> + - description: Peripherals PLL derivated 800MHz clock
> + - description: Audio PLL 0
> + - description: Audio PLL 0 (/2)
> + - description: Audio PLL 0 (/5)
> + - description: Audio PLL 1
> + - description: Audio PLL 1 (2x)
> + - description: Audio PLL 1 (4x)
> +
> + clock-names:
> + minItems: 13
> + maxItems: 13
> + items:
> + - const: hosc
> + - const: losc
> + - const: iosc
> + - const: pll-cpux
> + - const: pll-periph
> + - const: pll-periph-2x
> + - const: pll-periph-800m
> + - const: pll-audio0
> + - const: pll-audio0-div2
> + - const: pll-audio0-div5
> + - const: pll-audio1
> + - const: pll-audio1-2x
> + - const: pll-audio1-4x
> +
> + else:
> + properties:
> + clocks:
> + minItems: 2
> + maxItems: 2
> +
> + clock-names:
> + minItems: 2
> + maxItems: 2
>
> additionalProperties: false
>
> diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-bindings/clock/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..116f8d13a9b3
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> +
> +#define CLK_CPUX 1
> +
> +#define CLK_APB1 5
> +
> +#define CLK_CE 7
> +#define CLK_BUS_CE 8
> +#define CLK_AIPU 9
> +#define CLK_BUS_AIPU 10
> +#define CLK_BUS_DMA 11
> +#define CLK_BUS_MSGBOX 12
> +#define CLK_BUS_SPINLOCK 13
> +#define CLK_BUS_HSTIMER 14
> +#define CLK_AVS 15
> +#define CLK_BUS_DBG 16
> +#define CLK_BUS_PWM 17
> +
> +#define CLK_MBUS_DMA 19
> +#define CLK_MBUS_CE 20
> +#define CLK_MBUS_R_DMA 21
> +#define CLK_MBUS_NAND 22
> +#define CLK_MBUS_AIPU 23
> +
> +#define CLK_NAND0 25
> +#define CLK_NAND1 26
> +#define CLK_BUS_NAND 27
> +#define CLK_MMC0 28
> +#define CLK_MMC1 29
> +#define CLK_BUS_MMC0 30
> +#define CLK_BUS_MMC1 31
> +#define CLK_BUS_UART0 32
> +#define CLK_BUS_UART1 33
> +#define CLK_BUS_UART2 34
> +#define CLK_BUS_UART3 35
> +#define CLK_BUS_I2C0 36
> +#define CLK_BUS_I2C1 37
> +#define CLK_BUS_SCR 38
> +#define CLK_SPI0 39
> +#define CLK_SPI1 40
> +#define CLK_BUS_SPI0 41
> +#define CLK_BUS_SPI1 42
> +#define CLK_EMAC_25M_DIV 43
> +#define CLK_EMAC_25M 44
> +#define CLK_BUS_EMAC 45
> +#define CLK_IR_RX 46
> +#define CLK_BUS_IR_RX 47
> +#define CLK_IR_TX 48
> +#define CLK_BUS_IR_TX 49
> +#define CLK_I2S0 50
> +#define CLK_I2S1 51
> +#define CLK_BUS_I2S0 52
> +#define CLK_BUS_I2S1 53
> +#define CLK_SPDIF 54
> +#define CLK_BUS_SPDIF 55
> +#define CLK_USB_OHCI0 56
> +#define CLK_USB_PHY0 57
> +#define CLK_USB_OHCI1 58
> +#define CLK_USB_PHY1 59
> +#define CLK_BUS_OHCI0 60
> +#define CLK_BUS_OHCI1 61
> +#define CLK_BUS_EHCI0 62
> +#define CLK_BUS_OTG 63
> +#define CLK_LEDC 64
> +#define CLK_BUS_LEDC 65
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_ */
> diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..c327d1a1b602
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +
> +#define CLK_PLL_CPUX 0
> +#define CLK_PLL_PERIPH_2X 2
> +#define CLK_PLL_PERIPH_800M 3
> +#define CLK_PLL_PERIPH 4
> +#define CLK_PLL_AUDIO0 5
> +#define CLK_PLL_AUDIO0_DIV2 6
> +#define CLK_PLL_AUDIO0_DIV5 7
> +#define CLK_PLL_AUDIO1_4X 8
> +#define CLK_PLL_AUDIO1_2X 9
> +#define CLK_PLL_AUDIO1 10
> +
> +#define CLK_R_AHB 11
> +#define CLK_R_APB1 12
> +
> +#define CLK_R_BUS_GPADC 14

These are a bit backward. For example, this is the bus clock for the R_GPADC
peripheral. So I would recommend s/R_BUS/BUS_R/ here and for the resets. At
least that's what I did for D1.

Regards,
Samuel

> +#define CLK_R_BUS_THS 15
> +#define CLK_R_BUS_DMA 16
> +#define CLK_R_PWM 17
> +#define CLK_R_BUS_PWM 18
> +#define CLK_R_CODEC_ADC 19
> +#define CLK_R_CODEC_DAC 20
> +#define CLK_R_BUS_CODEC 21
> +#define CLK_R_DMIC 22
> +#define CLK_R_BUS_DMIC 23
> +#define CLK_R_BUS_LRADC 24
> +#define CLK_R_I2S 25
> +#define CLK_R_I2S_ASRC 26
> +#define CLK_R_BUS_I2S 27
> +#define CLK_R_BUS_UART 28
> +#define CLK_R_BUS_I2C 29
> +#define CLK_R_IR 30
> +#define CLK_R_BUS_IR 31
> +#define CLK_R_BUS_MSGBOX 32
> +#define CLK_R_BUS_SPINLOCK 33
> +#define CLK_R_BUS_RTC 34
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-bindings/reset/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..bb704a82443f
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> +
> +#define RST_MBUS 0
> +#define RST_BUS_CE 1
> +#define RST_BUS_AIPU 2
> +#define RST_BUS_DMA 3
> +#define RST_BUS_MSGBOX 4
> +#define RST_BUS_SPINLOCK 5
> +#define RST_BUS_HSTIMER 6
> +#define RST_BUS_DBG 7
> +#define RST_BUS_PWM 8
> +#define RST_BUS_DRAM 9
> +#define RST_BUS_NAND 10
> +#define RST_BUS_MMC0 11
> +#define RST_BUS_MMC1 12
> +#define RST_BUS_UART0 13
> +#define RST_BUS_UART1 14
> +#define RST_BUS_UART2 15
> +#define RST_BUS_UART3 16
> +#define RST_BUS_I2C0 17
> +#define RST_BUS_I2C1 18
> +#define RST_BUS_SCR 19
> +#define RST_BUS_SPI0 20
> +#define RST_BUS_SPI1 21
> +#define RST_BUS_EMAC 22
> +#define RST_BUS_IR_RX 23
> +#define RST_BUS_IR_TX 24
> +#define RST_BUS_I2S0 25
> +#define RST_BUS_I2S1 26
> +#define RST_BUS_SPDIF 27
> +#define RST_USB_PHY0 28
> +#define RST_USB_PHY1 29
> +#define RST_BUS_OHCI0 30
> +#define RST_BUS_OHCI1 31
> +#define RST_BUS_EHCI0 32
> +#define RST_BUS_OTG 33
> +#define RST_BUS_LEDC 34
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..40644f2f21c6
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +
> +#define RST_R_BUS_GPADC 0
> +#define RST_R_BUS_THS 1
> +#define RST_R_BUS_DMA 2
> +#define RST_R_BUS_PWM 3
> +#define RST_R_BUS_CODEC 4
> +#define RST_R_BUS_DMIC 5
> +#define RST_R_BUS_LRADC 6
> +#define RST_R_BUS_I2S 7
> +#define RST_R_BUS_UART 8
> +#define RST_R_BUS_I2C 9
> +#define RST_R_BUS_IR 10
> +#define RST_R_BUS_MSGBOX 11
> +#define RST_R_BUS_SPINLOCK 12
> +#define RST_R_BUS_RTC 13
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */
>

2022-04-24 06:58:21

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 07/12] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string

On 4/22/22 10:41 AM, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> R329 SoC has two MMC controllers similar to ones in the previous
> Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
> controllers look like a mixture of previous SoCs' ordinary MMC
> controller and eMMC controller.
>
> Add a compatible string for R329 MMC controllers.
>
> Signed-off-by: Icenowy Zheng <[email protected]>

Acked-by: Samuel Holland <[email protected]>

You can also pick up Rob and Maxime's acks from the previous submission[1]
(which was identical).

Regards,
Samuel

[1]: https://lore.kernel.org/linux-sunxi/[email protected]/

2022-04-24 13:48:58

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 08/12] mmc: sunxi: add support for R329 MMC controllers

On 4/22/22 10:41 AM, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> The two MMC controllers in Allwinner R329 have a mixed feature set
> comparing to the previous SoCs' ordinary MMC and eMMC controllers.
>
> Add support for them.
>
> Signed-off-by: Icenowy Zheng <[email protected]>

Acked-by: Samuel Holland <[email protected]>

> ---
> drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 0e8fbf4957d8..06934eef8be5 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -1207,6 +1207,15 @@ static const struct sunxi_mmc_cfg sun50i_a100_emmc_cfg = {
> .needs_new_timings = true,
> };
>
> +static const struct sunxi_mmc_cfg sun50i_r329_cfg = {
> + .idma_des_size_bits = 13,
> + .idma_des_shift = 2,
> + .clk_delays = NULL,
> + .can_calibrate = true,
> + .mask_data0 = true,
> + .needs_new_timings = true,
> +};
> +

This is the same as D1, so you could reuse or replace that configuration constant.

Regards,
Samuel

> static const struct of_device_id sunxi_mmc_of_match[] = {
> { .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
> { .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
> @@ -1218,6 +1227,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = {
> { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
> { .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
> { .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
> + { .compatible = "allwinner,sun50i-r329-mmc", .data = &sun50i_r329_cfg },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
>

2022-04-24 14:23:41

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 06/12] clk: sunxi=ng: add support for R329 CCUs

On 4/22/22 10:41 AM, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> Allwinner R329 has two CCUs, one in CPUX and another in PRCM.
>
> Add support for them.
>
> Signed-off-by: Icenowy Zheng <[email protected]>

There is a typo in your commit title. = should be -.

Thanks for updating the driver to use .fw_name and be loadable as a module. All
of those changes look good.

There are still some missing clocks here compared to the BSP, and a couple of
other minor issues. Please see my earlier review:

https://lore.kernel.org/linux-sunxi/[email protected]/

So far it's been consistent that any settable bits in the CCU registers actually
do something. So I would expect all of those bits to have an index reserved in
the binding, even if we do not model them. I want to avoid having to go back and
add gates to the binding out-of-order later, like we are doing for H6.

Regards,
Samuel

2022-04-25 03:43:13

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 01/12] dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO

On 4/22/22 9:08 AM, Icenowy Zheng wrote:
> Allwinner R329 have two pin controllers similar to previous Allwinner
> SoCs, PIO and R-PIO.
>
> Add compatible strings for them.
>
> Signed-off-by: Icenowy Zheng <[email protected]>

Acked-by: Samuel Holland <[email protected]>

This is identical to the previous submission[1], which was already acked by Rob
and Maxime. Please add those tags.

Regards,
Samuel

[1]: https://lore.kernel.org/linux-sunxi/[email protected]/

2022-04-25 06:46:13

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 04/12] rtc: sun6i: add support for R329 RTC

+RTC maintainers

On 4/22/22 10:41 AM, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> Allwinner R329 has a RTC with a similar time storage with H616 but a
> slightly different clock part.
>
> As we have already handled the R329 RTC clocks in the CCU driver, add a
> compatible string to RTC driver to allow probing of the RTC.
>
> Signed-off-by: Icenowy Zheng <[email protected]>

Acked-by: Samuel Holland <[email protected]>

> ---
> drivers/rtc/rtc-sun6i.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
> index 5b3e4da63406..522e28fb05c9 100644
> --- a/drivers/rtc/rtc-sun6i.c
> +++ b/drivers/rtc/rtc-sun6i.c
> @@ -816,6 +816,8 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
> { .compatible = "allwinner,sun50i-h6-rtc" },
> { .compatible = "allwinner,sun50i-h616-rtc",
> .data = (void *)RTC_LINEAR_DAY },
> + { .compatible = "allwinner,sun50i-r329-rtc",
> + .data = (void *)RTC_LINEAR_DAY },
> { /* sentinel */ },
> };
> MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
>

2022-04-25 06:47:56

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 03/12] pinctrl: sunxi: add support for R329 R-PIO pin controller

On 4/22/22 10:41 AM, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> Allwinner R320 SoC has a pin controller in the CPUS power domain.

This should be "R329". Also see my comments on the previous version, which still
apply:

https://lore.kernel.org/linux-sunxi/[email protected]/

Regards,
Samuel

2022-05-02 22:56:29

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 05/12] dt-bindings: clock: sunxi-ng: add bindings for R329 CCUs

On Fri, Apr 22, 2022 at 11:41:08PM +0800, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> R329 has a CPUX CCU and a R-CCU, with all PLLs in R-CCU.
>
> Add bindings for them, with R-CCU only taking 3 oscillators as input and
> main CCU taking oscillators + PLLs as input.
>
> Signed-off-by: Icenowy Zheng <[email protected]>
> ---
> .../clock/allwinner,sun4i-a10-ccu.yaml | 62 ++++++++++++++--
> include/dt-bindings/clock/sun50i-r329-ccu.h | 73 +++++++++++++++++++
> include/dt-bindings/clock/sun50i-r329-r-ccu.h | 45 ++++++++++++
> include/dt-bindings/reset/sun50i-r329-ccu.h | 45 ++++++++++++
> include/dt-bindings/reset/sun50i-r329-r-ccu.h | 24 ++++++
> 5 files changed, 241 insertions(+), 8 deletions(-)
> create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
> create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
> create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
>
> diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> index 15ed64d35261..c7a429e55483 100644
> --- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> +++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> @@ -45,6 +45,8 @@ properties:
> - allwinner,sun50i-h6-r-ccu
> - allwinner,sun50i-h616-ccu
> - allwinner,sun50i-h616-r-ccu
> + - allwinner,sun50i-r329-ccu
> + - allwinner,sun50i-r329-r-ccu
> - allwinner,suniv-f1c100s-ccu
> - nextthing,gr8-ccu
>
> @@ -106,6 +108,7 @@ else:
> - allwinner,sun50i-a100-ccu
> - allwinner,sun50i-h6-ccu
> - allwinner,sun50i-h616-ccu
> + - allwinner,sun50i-r329-r-ccu
>
> then:
> properties:
> @@ -118,14 +121,57 @@ else:
> maxItems: 3
>
> else:
> - properties:
> - clocks:
> - minItems: 2
> - maxItems: 2
> -
> - clock-names:
> - minItems: 2
> - maxItems: 2
> + if:
> + properties:
> + compatible:
> + const: allwinner,sun50i-r329-ccu
> + then:
> + properties:
> + clocks:
> + minItems: 13
> + maxItems: 13

This is (or should be) implied by the size of 'items'. Did you find that
to not be the case?

> + items:
> + - description: High Frequency Oscillator (usually at 24MHz)
> + - description: Low Frequency Oscillator (usually at 32kHz)
> + - description: Internal Oscillator
> + - description: CPUX PLL
> + - description: Peripherals PLL
> + - description: Peripherals PLL (2x)
> + - description: Peripherals PLL derivated 800MHz clock
> + - description: Audio PLL 0
> + - description: Audio PLL 0 (/2)
> + - description: Audio PLL 0 (/5)
> + - description: Audio PLL 1
> + - description: Audio PLL 1 (2x)
> + - description: Audio PLL 1 (4x)

> diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-bindings/clock/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..116f8d13a9b3
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed

It's 2022.

> diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..c327d1a1b602
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0 */

> diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-bindings/reset/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..bb704a82443f
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */

> diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..40644f2f21c6
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */

Why the different licenses? GPL-2.0 OR BSD-2-Clause is preferred. MIT is
fine if that's what matches the dts files.

Rob

2022-05-02 23:17:51

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 09/12] dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense

On Fri, 22 Apr 2022 23:41:12 +0800, [email protected] wrote:
> From: Icenowy Zheng <[email protected]>
>
> Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
> SoM.
>
> Add compatible strings for it.
>
> Signed-off-by: Icenowy Zheng <[email protected]>
> ---
> Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
> 1 file changed, 6 insertions(+)
>

Acked-by: Rob Herring <[email protected]>

2022-05-04 00:05:16

by Jernej Škrabec

[permalink] [raw]
Subject: Re: Re: [PATCH 05/12] dt-bindings: clock: sunxi-ng: add bindings for R329 CCUs

Dne ponedeljek, 02. maj 2022 ob 23:34:27 CEST je Rob Herring napisal(a):
> On Fri, Apr 22, 2022 at 11:41:08PM +0800, [email protected] wrote:
> > From: Icenowy Zheng <[email protected]>
> >
> > R329 has a CPUX CCU and a R-CCU, with all PLLs in R-CCU.
> >
> > Add bindings for them, with R-CCU only taking 3 oscillators as input and
> > main CCU taking oscillators + PLLs as input.
> >
> > Signed-off-by: Icenowy Zheng <[email protected]>
> > ---
> > .../clock/allwinner,sun4i-a10-ccu.yaml | 62 ++++++++++++++--
> > include/dt-bindings/clock/sun50i-r329-ccu.h | 73 +++++++++++++++++++
> > include/dt-bindings/clock/sun50i-r329-r-ccu.h | 45 ++++++++++++
> > include/dt-bindings/reset/sun50i-r329-ccu.h | 45 ++++++++++++
> > include/dt-bindings/reset/sun50i-r329-r-ccu.h | 24 ++++++
> > 5 files changed, 241 insertions(+), 8 deletions(-)
> > create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
> > create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
> > create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> > create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
> >
> > diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-
ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-
ccu.yaml
> > index 15ed64d35261..c7a429e55483 100644
> > --- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> > +++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
> > @@ -45,6 +45,8 @@ properties:
> > - allwinner,sun50i-h6-r-ccu
> > - allwinner,sun50i-h616-ccu
> > - allwinner,sun50i-h616-r-ccu
> > + - allwinner,sun50i-r329-ccu
> > + - allwinner,sun50i-r329-r-ccu
> > - allwinner,suniv-f1c100s-ccu
> > - nextthing,gr8-ccu
> >
> > @@ -106,6 +108,7 @@ else:
> > - allwinner,sun50i-a100-ccu
> > - allwinner,sun50i-h6-ccu
> > - allwinner,sun50i-h616-ccu
> > + - allwinner,sun50i-r329-r-ccu
> >
> > then:
> > properties:
> > @@ -118,14 +121,57 @@ else:
> > maxItems: 3
> >
> > else:
> > - properties:
> > - clocks:
> > - minItems: 2
> > - maxItems: 2
> > -
> > - clock-names:
> > - minItems: 2
> > - maxItems: 2
> > + if:
> > + properties:
> > + compatible:
> > + const: allwinner,sun50i-r329-ccu
> > + then:
> > + properties:
> > + clocks:
> > + minItems: 13
> > + maxItems: 13
>
> This is (or should be) implied by the size of 'items'. Did you find that
> to not be the case?
>
> > + items:
> > + - description: High Frequency Oscillator (usually at 24MHz)
> > + - description: Low Frequency Oscillator (usually at 32kHz)
> > + - description: Internal Oscillator
> > + - description: CPUX PLL
> > + - description: Peripherals PLL
> > + - description: Peripherals PLL (2x)
> > + - description: Peripherals PLL derivated 800MHz clock
> > + - description: Audio PLL 0
> > + - description: Audio PLL 0 (/2)
> > + - description: Audio PLL 0 (/5)
> > + - description: Audio PLL 1
> > + - description: Audio PLL 1 (2x)
> > + - description: Audio PLL 1 (4x)
>
> > diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-
bindings/clock/sun50i-r329-ccu.h
> > new file mode 100644
> > index 000000000000..116f8d13a9b3
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
> > @@ -0,0 +1,73 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2021 Sipeed
>
> It's 2022.
>
> > diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-
bindings/clock/sun50i-r329-r-ccu.h
> > new file mode 100644
> > index 000000000000..c327d1a1b602
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> > @@ -0,0 +1,45 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
>
> > diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-
bindings/reset/sun50i-r329-ccu.h
> > new file mode 100644
> > index 000000000000..bb704a82443f
> > --- /dev/null
> > +++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
> > @@ -0,0 +1,45 @@
> > +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
>
> > diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-
bindings/reset/sun50i-r329-r-ccu.h
> > new file mode 100644
> > index 000000000000..40644f2f21c6
> > --- /dev/null
> > +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > @@ -0,0 +1,24 @@
> > +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
>
> Why the different licenses? GPL-2.0 OR BSD-2-Clause is preferred. MIT is
> fine if that's what matches the dts files.

Yes, most, if not all, DT files for Allwinner are dual licensed under GPL2+ and
MIT. There are still some files under include/dt-bindings which are dual
licensed under GPL2+ and X11, but I believe those files are for older SoCs.

Best regards,
Jernej


2022-05-04 21:33:28

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH 08/12] mmc: sunxi: add support for R329 MMC controllers

On Fri, 22 Apr 2022 at 17:42, <[email protected]> wrote:
>
> From: Icenowy Zheng <[email protected]>
>
> The two MMC controllers in Allwinner R329 have a mixed feature set
> comparing to the previous SoCs' ordinary MMC and eMMC controllers.
>
> Add support for them.
>
> Signed-off-by: Icenowy Zheng <[email protected]>

Please repost this (and the DT patch) to linux-mmc, so I can pick them
up from the patch-tracker.

Kind regards
Uffe

> ---
> drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 0e8fbf4957d8..06934eef8be5 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -1207,6 +1207,15 @@ static const struct sunxi_mmc_cfg sun50i_a100_emmc_cfg = {
> .needs_new_timings = true,
> };
>
> +static const struct sunxi_mmc_cfg sun50i_r329_cfg = {
> + .idma_des_size_bits = 13,
> + .idma_des_shift = 2,
> + .clk_delays = NULL,
> + .can_calibrate = true,
> + .mask_data0 = true,
> + .needs_new_timings = true,
> +};
> +
> static const struct of_device_id sunxi_mmc_of_match[] = {
> { .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
> { .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
> @@ -1218,6 +1227,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = {
> { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
> { .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
> { .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
> + { .compatible = "allwinner,sun50i-r329-mmc", .data = &sun50i_r329_cfg },
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
> --
> 2.35.1
>

2022-05-05 12:13:48

by Rob Herring

[permalink] [raw]
Subject: Re: Re: [PATCH 05/12] dt-bindings: clock: sunxi-ng: add bindings for R329 CCUs

On Tue, May 03, 2022 at 09:55:08PM +0200, Jernej Škrabec wrote:
> Dne ponedeljek, 02. maj 2022 ob 23:34:27 CEST je Rob Herring napisal(a):
> > On Fri, Apr 22, 2022 at 11:41:08PM +0800, [email protected] wrote:
> > > From: Icenowy Zheng <[email protected]>
> > >
> > > R329 has a CPUX CCU and a R-CCU, with all PLLs in R-CCU.
> > >
> > > Add bindings for them, with R-CCU only taking 3 oscillators as input and
> > > main CCU taking oscillators + PLLs as input.
> > >
> > > Signed-off-by: Icenowy Zheng <[email protected]>
> > > ---

> > > --- /dev/null
> > > +++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
> > > @@ -0,0 +1,73 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Copyright (c) 2021 Sipeed
> >
> > It's 2022.
> >
> > > diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-
> bindings/clock/sun50i-r329-r-ccu.h
> > > new file mode 100644
> > > index 000000000000..c327d1a1b602
> > > --- /dev/null
> > > +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> > > @@ -0,0 +1,45 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> >
> > > diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-
> bindings/reset/sun50i-r329-ccu.h
> > > new file mode 100644
> > > index 000000000000..bb704a82443f
> > > --- /dev/null
> > > +++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
> > > @@ -0,0 +1,45 @@
> > > +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> >
> > > diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-
> bindings/reset/sun50i-r329-r-ccu.h
> > > new file mode 100644
> > > index 000000000000..40644f2f21c6
> > > --- /dev/null
> > > +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > > @@ -0,0 +1,24 @@
> > > +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> >
> > Why the different licenses? GPL-2.0 OR BSD-2-Clause is preferred. MIT is
> > fine if that's what matches the dts files.
>
> Yes, most, if not all, DT files for Allwinner are dual licensed under GPL2+ and
> MIT. There are still some files under include/dt-bindings which are dual
> licensed under GPL2+ and X11, but I believe those files are for older SoCs.

Okay. FWIW, the SPDX definition of X11 means copyrighted by Xorg
Consortium or something where as MIT is the same license with any other
copyright.

Rob

2022-07-12 12:24:42

by Icenowy Zheng

[permalink] [raw]
Subject: Re: [PATCH 06/12] clk: sunxi=ng: add support for R329 CCUs

在 2022-07-12星期二的 19:57 +0800,Icenowy Zheng写道:
> 在 2022-04-23星期六的 21:12 -0500,Samuel Holland写道:
> > On 4/22/22 10:41 AM, [email protected] wrote:
> > > From: Icenowy Zheng <[email protected]>
> > >
> > > Allwinner R329 has two CCUs, one in CPUX and another in PRCM.
> > >
> > > Add support for them.
> > >
> > > Signed-off-by: Icenowy Zheng <[email protected]>
> >
> > There is a typo in your commit title. = should be -.
> >
> > Thanks for updating the driver to use .fw_name and be loadable as a
> > module. All
> > of those changes look good.
> >
> > There are still some missing clocks here compared to the BSP, and a
> > couple of
> > other minor issues. Please see my earlier review:
> >
> > https://lore.kernel.org/linux-sunxi/[email protected]/
> >
> > So far it's been consistent that any settable bits in the CCU
> > registers actually
> > do something. So I would expect all of those bits to have an index
> > reserved in
> > the binding, even if we do not model them. I want to avoid having
> > to
>
> Sorry but I don't think it proper to reserve unclear bits, because
> we're just allocating the numbers as a random sequence (in fact it's
> the sequence that it gets implemented).
>
> Or consider a structural number scheme, in which a value can be
> uniquely predicted by its name?

Well by thinking a little further, I realized our current CCU DT
binding is just based on implementation details of sunxi-ng drivers
(for example, some intermediate clocks get a number too, just not
exposed to the DT binding header). This continues to prove that
reserving numbers is just needed at all, and the current way to make
CCU DT bindings might be totally wrong.

Maybe we should start to use reasonable slice numbers in the next CCU
driver?

>
> > go back and
> > add gates to the binding out-of-order later, like we are doing for
> > H6.
> >
> > Regards,
> > Samuel
>
>
>


2022-07-12 12:39:23

by Icenowy Zheng

[permalink] [raw]
Subject: Re: [PATCH 06/12] clk: sunxi=ng: add support for R329 CCUs

在 2022-04-23星期六的 21:12 -0500,Samuel Holland写道:
> On 4/22/22 10:41 AM, [email protected] wrote:
> > From: Icenowy Zheng <[email protected]>
> >
> > Allwinner R329 has two CCUs, one in CPUX and another in PRCM.
> >
> > Add support for them.
> >
> > Signed-off-by: Icenowy Zheng <[email protected]>
>
> There is a typo in your commit title. = should be -.
>
> Thanks for updating the driver to use .fw_name and be loadable as a
> module. All
> of those changes look good.
>
> There are still some missing clocks here compared to the BSP, and a
> couple of
> other minor issues. Please see my earlier review:
>
> https://lore.kernel.org/linux-sunxi/[email protected]/
>
> So far it's been consistent that any settable bits in the CCU
> registers actually
> do something. So I would expect all of those bits to have an index
> reserved in
> the binding, even if we do not model them. I want to avoid having to

Sorry but I don't think it proper to reserve unclear bits, because
we're just allocating the numbers as a random sequence (in fact it's
the sequence that it gets implemented).

Or consider a structural number scheme, in which a value can be
uniquely predicted by its name?

> go back and
> add gates to the binding out-of-order later, like we are doing for
> H6.
>
> Regards,
> Samuel