mbox series

[00/17] Basical Allwinner R329 support

Message ID 20210802062212.73220-1-icenowy@sipeed.com
Headers show
Series Basical Allwinner R329 support | expand

Message

Icenowy Zheng Aug. 2, 2021, 6:21 a.m. UTC
This patchset tries to add basical support for Allwinner R329 SoC to the
Linux kernel, including clock/pintrl driver and MMC support.

Three patches from the H616 patchset, which are used to support the RTC
with linear day, are attached into this patchset. Other RTC-related
patches of that patchset is not included, because the binding of the
clock part there is still under discussion.

Then I added RTC binding and support (which is now only a struct
addition). I added RTC into this patchset, with the same reason that
H616 patchset contains RTC, which is to make the clock tree correct at
the first inclusion.

After RTC, main basical SoC-specific part, pinctrl and CCU, come. The
R329 CCU is something special because PLLs are in R-CCU, no main CCU.

MMC support is added here because it's also a simple struct addition
work, no main driver code change needed.

Finally it comes the DT part. The DT binding of MaixSense, the device
that I am working on now, is added. Then the DTSI for R329 SoC, the DTSI
file for Sipeed Maix IIA SoM (which is utilized on MaixSense) and the
main DT file for MaixSense are added.

Andre Przywara (3):
  rtc: sun6i: Fix time overflow handling
  rtc: sun6i: Add support for linear day storage
  rtc: sun6i: Add support for broken-down alarm registers

Icenowy Zheng (14):
  dt-bindings: rtc: sun6i: add compatible string for R329 RTC
  rtc: sun6i: add support for R329 RTC
  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
  dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs
  clk: sunxi=ng: add support for R329 R-CCU
  clk: sunxi-ng: add support for Allwinner R329 CCU
  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        |   4 +
 .../bindings/mmc/allwinner,sun4i-a10-mmc.yaml |   1 +
 .../pinctrl/allwinner,sun4i-a10-pinctrl.yaml  |   4 +
 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml |   6 +-
 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 | 244 ++++++++
 drivers/clk/sunxi-ng/Kconfig                  |  10 +
 drivers/clk/sunxi-ng/Makefile                 |   2 +
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 +++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
 drivers/clk/sunxi-ng/ccu-sun50i-r329.c        | 526 ++++++++++++++++++
 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                       | 154 +++--
 include/dt-bindings/clock/sun50i-r329-ccu.h   |  73 +++
 include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
 include/dt-bindings/reset/sun50i-r329-ccu.h   |  45 ++
 include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 +
 25 files changed, 2320 insertions(+), 47 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

Comments

Ulf Hansson Aug. 10, 2021, 11:04 a.m. UTC | #1
On Mon, 2 Aug 2021 at 08:24, Icenowy Zheng <icenowy@sipeed.com> wrote:
>
> This patchset tries to add basical support for Allwinner R329 SoC to the
> Linux kernel, including clock/pintrl driver and MMC support.
>
> Three patches from the H616 patchset, which are used to support the RTC
> with linear day, are attached into this patchset. Other RTC-related
> patches of that patchset is not included, because the binding of the
> clock part there is still under discussion.
>
> Then I added RTC binding and support (which is now only a struct
> addition). I added RTC into this patchset, with the same reason that
> H616 patchset contains RTC, which is to make the clock tree correct at
> the first inclusion.
>
> After RTC, main basical SoC-specific part, pinctrl and CCU, come. The
> R329 CCU is something special because PLLs are in R-CCU, no main CCU.
>
> MMC support is added here because it's also a simple struct addition
> work, no main driver code change needed.

It sounds like the MMC updates can be posted separately to linux-mmc.
Please do so I can pick them up.

[...]

Kind regards
Uffe
Linus Walleij Aug. 11, 2021, 9:23 a.m. UTC | #2
On Mon, Aug 2, 2021 at 8:23 AM Icenowy Zheng <icenowy@sipeed.com> wrote:

> 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 <icenowy@sipeed.com>

Can you send the pin control changes separately?
Also the bindings.

Then they can be reviewed and merged separately so I
don't have to pick out the stuff I can apply.

Yours,
Linus Walleij
Maxime Ripard Aug. 18, 2021, 8:47 a.m. UTC | #3
On Mon, Aug 02, 2021 at 02:22:08PM +0800, Icenowy Zheng wrote:
> 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 <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime
Maxime Ripard Aug. 18, 2021, 8:48 a.m. UTC | #4
On Mon, Aug 02, 2021 at 02:22:02PM +0800, Icenowy Zheng wrote:
> 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 <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime
Maxime Ripard Aug. 18, 2021, 8:52 a.m. UTC | #5
On Mon, Aug 02, 2021 at 02:22:03PM +0800, Icenowy Zheng wrote:
> Allwinner R320 SoC has a pin controller in the CPUS power domain.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>

Acked-by: Maxime Ripard <maxime@cerno.tech>

Maxime
Maxime Ripard Aug. 18, 2021, 9:01 a.m. UTC | #6
On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
> Allwinner R329 is a new SoC focused on smart audio devices.
> 
> Add a DTSI file for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
>  1 file changed, 244 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> new file mode 100644
> index 000000000000..bfefa2b734b0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> @@ -0,0 +1,244 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (c) 2021 Sipeed
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu@0 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <0>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu1: cpu@1 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <1>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	osc24M: osc24M_clk {
> +		#clock-cells = <0>;
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc24M";
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		arm,no-tick-in-suspend;
> +		interrupts = <GIC_PPI 13
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		pio: pinctrl@2000400 {
> +			compatible = "allwinner,sun50i-r329-pinctrl";
> +			reg = <0x02000400 0x400>;
> +			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
> +			clock-names = "apb", "hosc", "losc";
> +			gpio-controller;
> +			#gpio-cells = <3>;
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +
> +			uart0_pb_pins: uart0-pb-pins {
> +				pins = "PB4", "PB5";
> +				function = "uart0";
> +			};
> +
> +			mmc0_pf_pins: mmc0-pf-pins {
> +				pins = "PF0", "PF1", "PF2",
> +				       "PF3", "PF4", "PF5";
> +				function = "mmc0";
> +			};
> +
> +			mmc1_clk_pg0: mmc1-clk-pg0 {
> +				pins = "PG0";
> +				function = "mmc1_clk";
> +			};

Argh, of course it was bound to happen :)

Make sure your DT pass validation though, all your mmc1 node names will report errors.

> +
> +			mmc1_cmd_pg1: mmc1-clk-pg1 {

s/clk/cmd/ ?

> +				pins = "PG1";
> +				function = "mmc1_cmd";
> +			};
> +
> +			mmc1_d0_pg2: mmc1-clk-pg2 {

s/clk/d0/

> +				pins = "PG2";
> +				function = "mmc1_d0";
> +			};
> +
> +			mmc1_d1_pg3: mmc1-clk-pg3 {

s/clk/d1/

> +				pins = "PG3";
> +				function = "mmc1_d1";
> +			};
> +
> +			mmc1_d2_pg4: mmc1-clk-pg4 {

s/clk/d2/

> +				pins = "PG4";
> +				function = "mmc1_d2";
> +			};
> +
> +			mmc1_d3_pg5: mmc1-clk-pg5 {

s/clk/d3/

> +				pins = "PG5";
> +				function = "mmc1_d3";
> +			};
> +		};
> +
> +		ccu: clock@2001000 {
> +			compatible = "allwinner,sun50i-r329-ccu";
> +			reg = <0x02001000 0x1000>;
> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
> +			clock-names = "hosc", "losc", "iosc";

Do we have a clock tree for the RTC? Is it the same than the H616?

Maxime
Samuel Holland Aug. 19, 2021, 2:32 a.m. UTC | #7
On 8/18/21 4:15 AM, Icenowy Zheng wrote:
> 于 2021年8月18日 GMT+08:00 下午5:01:39, Maxime Ripard <maxime@cerno.tech> 写到:
>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
>>> +		ccu: clock@2001000 {
>>> +			compatible = "allwinner,sun50i-r329-ccu";
>>> +			reg = <0x02001000 0x1000>;
>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
>>> +			clock-names = "hosc", "losc", "iosc";
>>
>> Do we have a clock tree for the RTC? Is it the same than the H616?
> 
> Nope, it's the same with H6 because of external LOSC crystal is
> possible. (Although production M2A SoMs has it NC for cost control.)

It is not the same as the H6, either. The clock tree _is_ identical to the D1,
which has three diagrams on pages 363-364 of its user manual here:

https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf

Compared to the H6, the R329/D1:
 - Loses the LOSC calibration circuit
 - Gains a third mux input for LOSC (not external 32k) to fanout
 - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
 - Gains an SPI bus clock input divided from the PRCM AHB

Compared to the H616, the R329/D1:
 - Has an external 32k crystal input
   - Gains the IOSC vs. external 32k crystal mux for LOSC
   - Switches fanout mux input #1 from pll_periph0/N to external 32k
 - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
 - Gains an SPI bus clock input divided from the PRCM AHB

So the R329/D1 RTC has three inputs:
 - SPI clock from PRCM
 - 24 MHz DCXO crystal
 - 32 kHz external crystal (optional)

and four outputs:
 - 16 MHz "IOSC" RC oscillator
 - 32 kHz "LOSC"
 - ~1 kHz for RTC timekeeping
 - 32 kHz fanout

(Arguably, since the 24 MHz DCXO can be turned on/off from the RTC registers, it
should be an "output" and not an "input".)

Regards,
Samuel
Samuel Holland Aug. 19, 2021, 3:09 a.m. UTC | #8
On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> 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 <icenowy@sipeed.com>
> ---
>  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 */

Please be consistent between "nand" and "nand0". "nand0" looks like it is much
more common.

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

Should be "uart0".

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

"uart0" here as well.

> +		  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"),

Missing function 5 "pll".

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

Should be function 4.

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

You have PH8 and PH9 functions 2 through 5 swapped.

And I won't be surprised if I missed something too :)

Regards,
Samuel

> +		  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);
>
Samuel Holland Aug. 19, 2021, 3:22 a.m. UTC | #9
On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R320 SoC has a pin controller in the CPUS power domain.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  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..dc4792c685ba
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
> @@ -0,0 +1,292 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Allwinner H616 R_PIO pin controller driver

This needs to be updated.

> + *
> + * Copyright (C) 2020 Arm Ltd.
> + * Based on former work, which is:
> + *   Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
> + */
> +
> +#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 */

"s_i2s0" for these would match existing drivers (and the manual).

Everything else matches the manual.

Regards,
Samuel
Samuel Holland Aug. 20, 2021, 2:43 a.m. UTC | #10
On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> 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 <icenowy@sipeed.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Reviewed-by: Samuel Holland <samuel@sholland.org>
Samuel Holland Aug. 20, 2021, 2:59 a.m. UTC | #11
On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 is a new SoC focused on smart audio devices.
> 
> Add a DTSI file for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy@sipeed.com>
> ---
>  .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
>  1 file changed, 244 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi

One comment below.

All of my other concerns are about the CCU and RTC bindings, which I have
commented on elsewhere.

Regards,
Samuel

> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> new file mode 100644
> index 000000000000..bfefa2b734b0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> @@ -0,0 +1,244 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (c) 2021 Sipeed
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu@0 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <0>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu1: cpu@1 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <1>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	osc24M: osc24M_clk {
> +		#clock-cells = <0>;
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc24M";
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		arm,no-tick-in-suspend;
> +		interrupts = <GIC_PPI 13
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		pio: pinctrl@2000400 {
> +			compatible = "allwinner,sun50i-r329-pinctrl";
> +			reg = <0x02000400 0x400>;
> +			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,

There is an IRQ documented for port C (at SPI 70). Do those pins possibly have
interrupt capability?

> +				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
> +			clock-names = "apb", "hosc", "losc";
> +			gpio-controller;
> +			#gpio-cells = <3>;
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
Samuel Holland Aug. 20, 2021, 3:06 a.m. UTC | #12
On 8/18/21 9:32 PM, Samuel Holland wrote:
> On 8/18/21 4:15 AM, Icenowy Zheng wrote:
>> 于 2021年8月18日 GMT+08:00 下午5:01:39, Maxime Ripard <maxime@cerno.tech> 写到:
>>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
>>>> +		ccu: clock@2001000 {
>>>> +			compatible = "allwinner,sun50i-r329-ccu";
>>>> +			reg = <0x02001000 0x1000>;
>>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
>>>> +			clock-names = "hosc", "losc", "iosc";
>>>
>>> Do we have a clock tree for the RTC? Is it the same than the H616?
>>
>> Nope, it's the same with H6 because of external LOSC crystal is
>> possible. (Although production M2A SoMs has it NC for cost control.)
> 
> It is not the same as the H6, either. The clock tree _is_ identical to the D1,
> which has three diagrams on pages 363-364 of its user manual here:
> 
> https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf
> 
> Compared to the H6, the R329/D1:
>  - Loses the LOSC calibration circuit
>  - Gains a third mux input for LOSC (not external 32k) to fanout
>  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
>  - Gains an SPI bus clock input divided from the PRCM AHB
> 
> Compared to the H616, the R329/D1:
>  - Has an external 32k crystal input
>    - Gains the IOSC vs. external 32k crystal mux for LOSC
>    - Switches fanout mux input #1 from pll_periph0/N to external 32k
>  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
>  - Gains an SPI bus clock input divided from the PRCM AHB
> 
> So the R329/D1 RTC has three^Wfour inputs:
>  - SPI clock from PRCM
>  - 24 MHz DCXO crystal
>  - 32 kHz external crystal (optional)

Whoops, I missed one here:
 - Bus clock from PRCM

The SPI clock is new for R329, but the bus clock has been around since H6.

> and four outputs:
>  - 16 MHz "IOSC" RC oscillator
>  - 32 kHz "LOSC"
>  - ~1 kHz for RTC timekeeping

Even though this is internal to the RTC, it is still useful to model, as it can
be used to correct for known RTC drift. (For example, HOSC/750 is 32000 Hz
instead of 32768 Hz, so 2.34375% slow. But that is better than IOSC, which has
unknown error.)

>  - 32 kHz fanout
> 
> (Arguably, since the 24 MHz DCXO can be turned on/off from the RTC registers, it
> should be an "output" and not an "input".)
> 
> Regards,
> Samuel
>
Maxime Ripard Aug. 25, 2021, 3 p.m. UTC | #13
On Thu, Aug 19, 2021 at 10:06:43PM -0500, Samuel Holland wrote:
> On 8/18/21 9:32 PM, Samuel Holland wrote:
> > On 8/18/21 4:15 AM, Icenowy Zheng wrote:
> >> 于 2021年8月18日 GMT+08:00 下午5:01:39, Maxime Ripard <maxime@cerno.tech> 写到:
> >>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
> >>>> +		ccu: clock@2001000 {
> >>>> +			compatible = "allwinner,sun50i-r329-ccu";
> >>>> +			reg = <0x02001000 0x1000>;
> >>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
> >>>> +			clock-names = "hosc", "losc", "iosc";
> >>>
> >>> Do we have a clock tree for the RTC? Is it the same than the H616?
> >>
> >> Nope, it's the same with H6 because of external LOSC crystal is
> >> possible. (Although production M2A SoMs has it NC for cost control.)
> > 
> > It is not the same as the H6, either. The clock tree _is_ identical to the D1,
> > which has three diagrams on pages 363-364 of its user manual here:
> > 
> > https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf
> > 
> > Compared to the H6, the R329/D1:
> >  - Loses the LOSC calibration circuit
> >  - Gains a third mux input for LOSC (not external 32k) to fanout
> >  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
> >  - Gains an SPI bus clock input divided from the PRCM AHB
> > 
> > Compared to the H616, the R329/D1:
> >  - Has an external 32k crystal input
> >    - Gains the IOSC vs. external 32k crystal mux for LOSC
> >    - Switches fanout mux input #1 from pll_periph0/N to external 32k
> >  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
> >  - Gains an SPI bus clock input divided from the PRCM AHB
> > 
> > So the R329/D1 RTC has three^Wfour inputs:
> >  - SPI clock from PRCM
> >  - 24 MHz DCXO crystal
> >  - 32 kHz external crystal (optional)
> 
> Whoops, I missed one here:
>  - Bus clock from PRCM
> 
> The SPI clock is new for R329, but the bus clock has been around since H6.
> 
> > and four outputs:
> >  - 16 MHz "IOSC" RC oscillator
> >  - 32 kHz "LOSC"
> >  - ~1 kHz for RTC timekeeping
> 
> Even though this is internal to the RTC, it is still useful to model, as it can
> be used to correct for known RTC drift. (For example, HOSC/750 is 32000 Hz
> instead of 32768 Hz, so 2.34375% slow. But that is better than IOSC, which has
> unknown error.)

If it's not useful to any other device, there's no real reason to model
it in the clock framework. We should still force the source of the RTC
to the most accurate option we have, but we can do that without the CCF.

Maxime