uboot-sunxi: t113: refresh patches to fix clock issues
authorZoltan HERPAI <wigyori@uid0.hu>
Sat, 26 Aug 2023 23:05:32 +0000 (01:05 +0200)
committerZoltan HERPAI <wigyori@uid0.hu>
Sat, 26 Aug 2023 23:05:32 +0000 (01:05 +0200)
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
87 files changed:
package/boot/uboot-sunxi/patches/4000-ARM-dts-sun8i-a83t-bananapi-m3-describe-SATA-disk-re.patch [deleted file]
package/boot/uboot-sunxi/patches/4000-sunxi-remove-CONFIG_SATAPWR.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4001-net-sunxi_emac-Switch-to-new-U-Boot-PHY-API.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4001-sunxi-remove-CONFIG_SATAPWR.patch [deleted file]
package/boot/uboot-sunxi/patches/4002-net-sunxi_emac-chase-DT-nodes-to-find-PHY-regulator.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4002-sunxi-remove-CONFIG_MACPWR.patch [deleted file]
package/boot/uboot-sunxi/patches/4003-net-sun8i-emac-Add-a-structure-for-variant-data.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4003-pinctrl-sunxi-remove-struct-sunxi_gpio.patch [deleted file]
package/boot/uboot-sunxi/patches/4004-net-sun8i-emac-Add-a-flag-for-RMII-support.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4004-pinctrl-sunxi-add-GPIO-in-out-wrappers.patch [deleted file]
package/boot/uboot-sunxi/patches/4005-net-sun8i-emac-Add-a-flag-for-the-internal-PHY-switc.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4005-pinctrl-sunxi-move-pinctrl-code-and-remove-GPIO_EXTR.patch [deleted file]
package/boot/uboot-sunxi/patches/4006-net-sun8i-emac-Use-common-syscon-setup-for-R40.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4006-pinctrl-sunxi-move-PIO_BASE-into-sunxi_gpio.h.patch [deleted file]
package/boot/uboot-sunxi/patches/4007-net-sun8i-emac-Remove-the-SoC-variant-ID.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4007-pinctrl-sunxi-add-new-D1-pinctrl-support.patch [deleted file]
package/boot/uboot-sunxi/patches/4008-sunxi-introduce-NCAT2-generation-model.patch [deleted file]
package/boot/uboot-sunxi/patches/4008-sunxi-remove-CONFIG_MACPWR.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4009-pinctrl-sunxi-add-Allwinner-D1-pinctrl-description.patch [deleted file]
package/boot/uboot-sunxi/patches/4009-pinctrl-sunxi-add-GPIO-in-out-wrappers.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4010-clk-sunxi-Add-support-for-the-D1-CCU.patch [deleted file]
package/boot/uboot-sunxi/patches/4010-pinctrl-sunxi-remove-struct-sunxi_gpio.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4011-pinctrl-sunxi-move-pinctrl-code-and-remove-GPIO_EXTR.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4011-sunxi-clock-D1-R528-Enable-PLL-LDO-during-PLL1-setup.patch [deleted file]
package/boot/uboot-sunxi/patches/4012-pinctrl-sunxi-move-PIO_BASE-into-sunxi_gpio.h.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4012-sunxi-clock-support-D1-R528-PLL6-clock.patch [deleted file]
package/boot/uboot-sunxi/patches/4013-Kconfig-sunxi-prepare-for-using-drivers-ram-sunxi.patch [deleted file]
package/boot/uboot-sunxi/patches/4013-pinctrl-sunxi-add-new-D1-pinctrl-support.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4014-sunxi-add-R528-T113-s3-D1-s-DRAM-initialisation-code.patch [deleted file]
package/boot/uboot-sunxi/patches/4014-sunxi-introduce-NCAT2-generation-model.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4015-pinctrl-sunxi-add-Allwinner-D1-pinctrl-description.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4015-sunxi-add-early-Allwinner-R528-T113-SoC-support.patch [deleted file]
package/boot/uboot-sunxi/patches/4016-clk-sunxi-Add-support-for-the-D1-CCU.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4016-sunxi-refactor-serial-base-addresses-to-avoid-asm-ar.patch [deleted file]
package/boot/uboot-sunxi/patches/4017-riscv-dts-allwinner-Add-the-D1-D1s-SoC-devicetree.patch [deleted file]
package/boot/uboot-sunxi/patches/4017-sunxi-clock-D1-R528-Enable-PLL-LDO-during-PLL1-setup.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4018-ARM-dts-sunxi-add-Allwinner-T113-s-SoC-.dtsi.patch [deleted file]
package/boot/uboot-sunxi/patches/4018-sunxi-clock-support-D1-R528-PLL6-clock.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4019-sunxi-add-preliminary-MangoPi-MQ-R-board-support.patch [deleted file]
package/boot/uboot-sunxi/patches/4019-sunxi-clock-h6-prepare-for-PRCM-less-SoCs.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4020-Kconfig-sunxi-prepare-for-using-drivers-ram-sunxi.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4020-sunxi-add-uart0_pins-on-Port-E-PE2-PE3-on-D1s-T133.patch [deleted file]
package/boot/uboot-sunxi/patches/4021-sunxi-add-R528-T113-s3-D1-s-DRAM-initialisation-code.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4021-sunxi-add-support-for-MangoPI-MQDual-T113-variant.patch [deleted file]
package/boot/uboot-sunxi/patches/4022-sunxi-add-Allwinner-R528-T113-SoC-support.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4022-sunxi-add-support-for-UART5-in-Port-E-group-on-T133.patch [deleted file]
package/boot/uboot-sunxi/patches/4023-sunxi-add-MYIR-MYD-YT113X-board.patch [deleted file]
package/boot/uboot-sunxi/patches/4023-sunxi-refactor-serial-base-addresses-to-avoid-asm-ar.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4024-riscv-dts-allwinner-Add-the-D1-D1s-SoC-devicetree.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4024-sunxi-add-support-for-UART3-on-PE-pins.patch [deleted file]
package/boot/uboot-sunxi/patches/4025-ARM-dts-sunxi-add-Allwinner-T113-s-SoC-.dtsi.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4025-sunxi-add-support-for-Rongpin-RP-T113-board.patch [deleted file]
package/boot/uboot-sunxi/patches/4026-net-add-ICPlus-PHY-driver.patch [deleted file]
package/boot/uboot-sunxi/patches/4026-sunxi-add-MangoPi-MQ-R-board-support.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4027-sunxi-add-uart0_pins-on-Port-E-PE2-PE3-on-D1s-T133.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4027-sunxi-enable-emac-on-Rongpin-RP-T113.patch [deleted file]
package/boot/uboot-sunxi/patches/4028-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethe.patch [deleted file]
package/boot/uboot-sunxi/patches/4028-sunxi-add-support-for-MangoPI-MQDual-T113-variant.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4029-sunxi-add-support-for-UART5-in-Port-E-group-on-T133.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4029-sunxi-enable-gmac-on-MYIR-MYD-YT113X-with-the-YT8531.patch [deleted file]
package/boot/uboot-sunxi/patches/4030-net-phy-backport-and-update-driver-for-Motorcomm-yt8.patch [deleted file]
package/boot/uboot-sunxi/patches/4030-sunxi-add-MYIR-MYD-YT113X-board.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4031-sunxi-add-support-for-UART3-on-PE-pins.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4031-sunxi-rongpin-rp-t113-add-missing-gpio.h-include.patch [deleted file]
package/boot/uboot-sunxi/patches/4032-sunxi-add-support-for-Rongpin-RP-T113-board.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4033-net-add-ICPlus-PHY-driver.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4034-sunxi-enable-emac-on-Rongpin-RP-T113.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4035-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethe.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4036-sunxi-enable-gmac-on-MYIR-MYD-YT113X-with-the-YT8531.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4037-net-phy-backport-and-update-driver-for-Motorcomm-yt8.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4038-sunxi-rongpin-rp-t113-add-missing-gpio.h-include.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4039-sunxi-SPL-SPI-Add-SPI-boot-support-for-the-Allwinner.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4040-spi-sunxi-Add-support-for-R329-D1-R528-T113-SPI-cont.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4041-riscv-dts-allwinner-d1-Add-SPI-controllers-node.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4042-sunxi-add-MYIR-MYD-YT113X-SPI-board.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4043-sunxi-add-support-for-emac-on-PG-pins.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4044-sunxi-add-ethernet-support-on-MYIR-MYD-YT113X-SPI.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4045-mtd-spi-nand-backport-from-upstream-kernel.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4046-arm-dts-add-partition-table-for-MYIR-MYD-YT113X-SPI.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4047-configs-enable-UBI-support-for-MYIR-MYD-YT113X-SPI.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4048-sunxi-r528-d1-t113-add-SDC2-pinmux-on-PC2-7-pins.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/4100-SQUASH-ME.patch [deleted file]
package/boot/uboot-sunxi/patches/4101-sunxi-psci-clean-away-preprocessor-macros.patch [deleted file]
package/boot/uboot-sunxi/patches/4102-sunxi-psci-refactor-register-access-to-separate-func.patch [deleted file]
package/boot/uboot-sunxi/patches/4103-sunxi-psci-implement-PSCI-on-R528.patch [deleted file]
package/boot/uboot-sunxi/patches/4200-spi.patch [deleted file]
package/boot/uboot-sunxi/patches/4201-myir-spi.patch [deleted file]

diff --git a/package/boot/uboot-sunxi/patches/4000-ARM-dts-sun8i-a83t-bananapi-m3-describe-SATA-disk-re.patch b/package/boot/uboot-sunxi/patches/4000-ARM-dts-sun8i-a83t-bananapi-m3-describe-SATA-disk-re.patch
deleted file mode 100644 (file)
index 0abc2e6..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-From 99a186dbbbc9869d705fb3c189bcafc87c3bfe75 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Thu, 19 Jan 2023 23:40:20 +0000
-Subject: [PATCH 4000/4031] ARM: dts: sun8i: a83t: bananapi-m3: describe SATA
- disk regulator
-
-The Bananapi-M3 has a SATA connector, driven by a USB-to-SATA bridge
-soldered on the board. The power for the SATA device is provided by a
-GPIO controlled regulator. Since the SATA device is behind USB, it has
-no DT node, so we never described this regulator. Instead U-Boot was
-turning this on in a rather hackish way, which we now want to get rid of.
-On top of that it seems fragile to leave this GPIO undescribed, as
-userland could claim it and turn the disk off.
-
-Add a fixed regulator, controlled by the PD25 GPIO, and mark it as
-always-on. This would mimic the current situation, but in a safer way,
-and would allow U-Boot to drop the CONFIG_SATAPWR enable hack.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/dts/sun8i-a83t-bananapi-m3.dts | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
-diff --git a/arch/arm/dts/sun8i-a83t-bananapi-m3.dts b/arch/arm/dts/sun8i-a83t-bananapi-m3.dts
-index b60016a442..197cf6959b 100644
---- a/arch/arm/dts/sun8i-a83t-bananapi-m3.dts
-+++ b/arch/arm/dts/sun8i-a83t-bananapi-m3.dts
-@@ -105,6 +105,21 @@
-               /* enables internal regulator and de-asserts reset */
-               reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 WL-PMU-EN */
-       };
-+
-+      /*
-+       * Power supply for the SATA disk, behind a USB-SATA bridge.
-+       * Since it is a USB device, there is no consumer in the DT, so we
-+       * have to keep this always on.
-+       */
-+      regulator-sata-disk-pwr {
-+              compatible = "regulator-fixed";
-+              regulator-name = "sata-disk-pwr";
-+              regulator-min-microvolt = <5000000>;
-+              regulator-max-microvolt = <5000000>;
-+              regulator-always-on;
-+              enable-active-high;
-+              gpio = <&pio 3 25 GPIO_ACTIVE_HIGH>; /* PD25 */
-+      };
- };
- &cpu0 {
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4000-sunxi-remove-CONFIG_SATAPWR.patch b/package/boot/uboot-sunxi/patches/4000-sunxi-remove-CONFIG_SATAPWR.patch
new file mode 100644 (file)
index 0000000..8924000
--- /dev/null
@@ -0,0 +1,370 @@
+From cb7c055953c65ce4b532e3548fb6676515c1c1b9 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 15 Jul 2022 16:52:14 +0100
+Subject: [PATCH 4000/4044] sunxi: remove CONFIG_SATAPWR
+
+The CONFIG_SATAPWR Kconfig symbol was used to point to a GPIO that
+enables the power for a SATA harddisk.
+In the DT this is described with the target-supply property in the AHCI
+DT node, pointing to a (GPIO controlled) regulator. Since we need SATA
+only in U-Boot proper, and use a DM driver for AHCI there, we should use
+the DT instead of hardcoding this.
+
+Add code to the sunxi AHCI driver to check the DT for that regulator and
+enable it, at probe time. Then drop the current code from board.c, which
+was doing that job before.
+This allows us to remove the SATAPWR Kconfig definition and the
+respective values from the defconfigs.
+We also select the generic fixed regulator driver, which handles those
+GPIO controlled regulators.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/Kconfig                             |  2 ++
+ arch/arm/mach-sunxi/Kconfig                  |  8 --------
+ board/sunxi/board.c                          | 16 +---------------
+ configs/A10-OLinuXino-Lime_defconfig         |  1 -
+ configs/A20-OLinuXino-Lime2-eMMC_defconfig   |  1 -
+ configs/A20-OLinuXino-Lime2_defconfig        |  1 -
+ configs/A20-OLinuXino-Lime_defconfig         |  1 -
+ configs/A20-OLinuXino_MICRO-eMMC_defconfig   |  1 -
+ configs/A20-OLinuXino_MICRO_defconfig        |  1 -
+ configs/A20-Olimex-SOM-EVB_defconfig         |  1 -
+ configs/A20-Olimex-SOM204-EVB-eMMC_defconfig |  1 -
+ configs/A20-Olimex-SOM204-EVB_defconfig      |  1 -
+ configs/Cubieboard2_defconfig                |  1 -
+ configs/Cubieboard_defconfig                 |  1 -
+ configs/Cubietruck_defconfig                 |  1 -
+ configs/Itead_Ibox_A20_defconfig             |  1 -
+ configs/Lamobo_R1_defconfig                  |  1 -
+ configs/Linksprite_pcDuino3_Nano_defconfig   |  1 -
+ configs/Linksprite_pcDuino3_defconfig        |  1 -
+ configs/Sinovoip_BPI_M3_defconfig            |  1 -
+ configs/orangepi_plus_defconfig              |  2 +-
+ drivers/ata/ahci_sunxi.c                     |  9 +++++++++
+ 22 files changed, 13 insertions(+), 41 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 8a1e223422..d5a6d293ce 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1130,6 +1130,8 @@ config ARCH_SUNXI
+       imply CMD_GPT
+       imply CMD_UBI if MTD_RAW_NAND
+       imply DISTRO_DEFAULTS
++      imply DM_REGULATOR
++      imply DM_REGULATOR_FIXED
+       imply FAT_WRITE
+       imply FIT
+       imply OF_LIBFDT_OVERLAY
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index 6417aee944..c78a553493 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -958,14 +958,6 @@ config VIDEO_LCD_TL059WV5C0
+ endchoice
+-config SATAPWR
+-      string "SATA power pin"
+-      default ""
+-      help
+-        Set the pins used to power the SATA. This takes a string in the
+-        format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of
+-        port H.
+-
+ config GMAC_TX_DELAY
+       int "GMAC Transmit Clock Delay Chain"
+       default 0
+diff --git a/board/sunxi/board.c b/board/sunxi/board.c
+index 827e545032..fe0e7bc2d9 100644
+--- a/board/sunxi/board.c
++++ b/board/sunxi/board.c
+@@ -187,7 +187,7 @@ enum env_location env_get_location(enum env_operation op, int prio)
+ /* add board specific code here */
+ int board_init(void)
+ {
+-      __maybe_unused int id_pfr1, ret, satapwr_pin, macpwr_pin;
++      __maybe_unused int id_pfr1, ret, macpwr_pin;
+       gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
+@@ -225,20 +225,6 @@ int board_init(void)
+               return ret;
+       /* strcmp() would look better, but doesn't get optimised away. */
+-      if (CONFIG_SATAPWR[0]) {
+-              satapwr_pin = sunxi_name_to_gpio(CONFIG_SATAPWR);
+-              if (satapwr_pin >= 0) {
+-                      gpio_request(satapwr_pin, "satapwr");
+-                      gpio_direction_output(satapwr_pin, 1);
+-
+-                      /*
+-                       * Give the attached SATA device time to power-up
+-                       * to avoid link timeouts
+-                       */
+-                      mdelay(500);
+-              }
+-      }
+-
+       if (CONFIG_MACPWR[0]) {
+               macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
+               if (macpwr_pin >= 0) {
+diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig
+index df4fdfaba4..57e91d0f01 100644
+--- a/configs/A10-OLinuXino-Lime_defconfig
++++ b/configs/A10-OLinuXino-Lime_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=480
+ CONFIG_DRAM_EMR1=4
+ CONFIG_SYS_CLK_FREQ=912000000
+ CONFIG_I2C1_ENABLE=y
+-CONFIG_SATAPWR="PC3"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+index be49e9323a..44770ffb04 100644
+--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
++++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+@@ -8,7 +8,6 @@ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB0_VBUS_PIN="PC17"
+ CONFIG_USB0_VBUS_DET="PH5"
+ CONFIG_I2C1_ENABLE=y
+-CONFIG_SATAPWR="PC3"
+ CONFIG_SPL_SPI_SUNXI=y
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
+index 43cd28c3dd..e10660c933 100644
+--- a/configs/A20-OLinuXino-Lime2_defconfig
++++ b/configs/A20-OLinuXino-Lime2_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
+ CONFIG_USB0_VBUS_PIN="PC17"
+ CONFIG_USB0_VBUS_DET="PH5"
+ CONFIG_I2C1_ENABLE=y
+-CONFIG_SATAPWR="PC3"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig
+index 7c77f38fba..4ed666a034 100644
+--- a/configs/A20-OLinuXino-Lime_defconfig
++++ b/configs/A20-OLinuXino-Lime_defconfig
+@@ -5,7 +5,6 @@ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=384
+ CONFIG_I2C1_ENABLE=y
+-CONFIG_SATAPWR="PC3"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/A20-OLinuXino_MICRO-eMMC_defconfig b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
+index 02116995a3..ca5869f43d 100644
+--- a/configs/A20-OLinuXino_MICRO-eMMC_defconfig
++++ b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_I2C1_ENABLE=y
+ CONFIG_VIDEO_VGA=y
+-CONFIG_SATAPWR="PB8"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig
+index 895e8dbcbd..db4270f9b2 100644
+--- a/configs/A20-OLinuXino_MICRO_defconfig
++++ b/configs/A20-OLinuXino_MICRO_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=3
+ CONFIG_I2C1_ENABLE=y
+ CONFIG_VIDEO_VGA=y
+-CONFIG_SATAPWR="PB8"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/A20-Olimex-SOM-EVB_defconfig b/configs/A20-Olimex-SOM-EVB_defconfig
+index 5bcc9f9f3c..ac900477d1 100644
+--- a/configs/A20-Olimex-SOM-EVB_defconfig
++++ b/configs/A20-Olimex-SOM-EVB_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=3
+ CONFIG_USB0_VBUS_PIN="PB9"
+ CONFIG_USB0_VBUS_DET="PH5"
+-CONFIG_SATAPWR="PC3"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
+index e5881090dd..00a98140b3 100644
+--- a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
++++ b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
+@@ -8,7 +8,6 @@ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB0_VBUS_PIN="PC17"
+ CONFIG_USB0_VBUS_DET="PH5"
+ CONFIG_I2C1_ENABLE=y
+-CONFIG_SATAPWR="PC3"
+ CONFIG_GMAC_TX_DELAY=4
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/A20-Olimex-SOM204-EVB_defconfig b/configs/A20-Olimex-SOM204-EVB_defconfig
+index 592a79a6c7..f4ae3ae6d8 100644
+--- a/configs/A20-Olimex-SOM204-EVB_defconfig
++++ b/configs/A20-Olimex-SOM204-EVB_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
+ CONFIG_USB0_VBUS_PIN="PC17"
+ CONFIG_USB0_VBUS_DET="PH5"
+ CONFIG_I2C1_ENABLE=y
+-CONFIG_SATAPWR="PC3"
+ CONFIG_GMAC_TX_DELAY=4
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig
+index 0c23368741..ef4f11b7c6 100644
+--- a/configs/Cubieboard2_defconfig
++++ b/configs/Cubieboard2_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubieboard2"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=480
+-CONFIG_SATAPWR="PB8"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig
+index 71743f7b8a..ab3f65ad66 100644
+--- a/configs/Cubieboard_defconfig
++++ b/configs/Cubieboard_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-cubieboard"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN4I=y
+ CONFIG_DRAM_CLK=480
+-CONFIG_SATAPWR="PB8"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
+index 184f305b19..184143d708 100644
+--- a/configs/Cubietruck_defconfig
++++ b/configs/Cubietruck_defconfig
+@@ -8,7 +8,6 @@ CONFIG_USB0_VBUS_PIN="PH17"
+ CONFIG_USB0_VBUS_DET="PH22"
+ CONFIG_USB0_ID_DET="PH19"
+ CONFIG_VIDEO_VGA=y
+-CONFIG_SATAPWR="PH12"
+ CONFIG_GMAC_TX_DELAY=1
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/Itead_Ibox_A20_defconfig b/configs/Itead_Ibox_A20_defconfig
+index 5d05f33798..d03fa62196 100644
+--- a/configs/Itead_Ibox_A20_defconfig
++++ b/configs/Itead_Ibox_A20_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-itead-ibox"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=480
+-CONFIG_SATAPWR="PB8"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig
+index 5294608459..9639cb6aad 100644
+--- a/configs/Lamobo_R1_defconfig
++++ b/configs/Lamobo_R1_defconfig
+@@ -5,7 +5,6 @@ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=432
+ CONFIG_MACPWR="PH23"
+-CONFIG_SATAPWR="PB3"
+ CONFIG_GMAC_TX_DELAY=4
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig
+index e3e30a4949..9eb9a918ae 100644
+--- a/configs/Linksprite_pcDuino3_Nano_defconfig
++++ b/configs/Linksprite_pcDuino3_Nano_defconfig
+@@ -6,7 +6,6 @@ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=408
+ CONFIG_DRAM_ZQ=122
+ CONFIG_USB1_VBUS_PIN="PH11"
+-CONFIG_SATAPWR="PH2"
+ CONFIG_GMAC_TX_DELAY=3
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
+index 1fda0db4c9..7db10e685b 100644
+--- a/configs/Linksprite_pcDuino3_defconfig
++++ b/configs/Linksprite_pcDuino3_defconfig
+@@ -5,7 +5,6 @@ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=480
+ CONFIG_DRAM_ZQ=122
+-CONFIG_SATAPWR="PH2"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig
+index 5116fab52d..5545b3d464 100644
+--- a/configs/Sinovoip_BPI_M3_defconfig
++++ b/configs/Sinovoip_BPI_M3_defconfig
+@@ -13,7 +13,6 @@ CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+ CONFIG_USB0_ID_DET="PH11"
+ CONFIG_USB1_VBUS_PIN="PD24"
+ CONFIG_AXP_GPIO=y
+-CONFIG_SATAPWR="PD25"
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_CONSOLE_MUX=y
+ CONFIG_PHY_REALTEK=y
+diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig
+index 76de72aa22..ed585881d4 100644
+--- a/configs/orangepi_plus_defconfig
++++ b/configs/orangepi_plus_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=672
+ CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB1_VBUS_PIN="PG13"
+-CONFIG_SATAPWR="PG11"
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+ CONFIG_SPL_SYS_I2C_LEGACY=y
+@@ -16,3 +15,4 @@ CONFIG_SUN8I_EMAC=y
+ CONFIG_SY8106A_POWER=y
+ CONFIG_USB_EHCI_HCD=y
+ CONFIG_USB_OHCI_HCD=y
++CONFIG_USB3_VBUS_PIN="PG11"
+diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
+index 94a3379c53..9064774e66 100644
+--- a/drivers/ata/ahci_sunxi.c
++++ b/drivers/ata/ahci_sunxi.c
+@@ -7,6 +7,7 @@
+ #include <asm/io.h>
+ #include <asm/gpio.h>
+ #include <linux/delay.h>
++#include <power/regulator.h>
+ #define AHCI_PHYCS0R 0x00c0
+ #define AHCI_PHYCS1R 0x00c4
+@@ -74,6 +75,7 @@ static int sunxi_ahci_phy_init(u8 *reg_base)
+ static int sunxi_sata_probe(struct udevice *dev)
+ {
++      struct udevice *reg_dev;
+       ulong base;
+       u8 *reg;
+       int ret;
+@@ -89,6 +91,13 @@ static int sunxi_sata_probe(struct udevice *dev)
+               debug("%s: Failed to init phy (err=%d)\n", __func__, ret);
+               return ret;
+       }
++
++      ret = device_get_supply_regulator(dev, "target-supply", &reg_dev);
++      if (ret == 0) {
++              regulator_set_enable(reg_dev, true);
++              mdelay(500);
++      }
++
+       ret = ahci_probe_scsi(dev, base);
+       if (ret) {
+               debug("%s: Failed to probe (err=%d)\n", __func__, ret);
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4001-net-sunxi_emac-Switch-to-new-U-Boot-PHY-API.patch b/package/boot/uboot-sunxi/patches/4001-net-sunxi_emac-Switch-to-new-U-Boot-PHY-API.patch
new file mode 100644 (file)
index 0000000..d3d1ae0
--- /dev/null
@@ -0,0 +1,46 @@
+From b68b48654248dedb7127631003a206cbfe7c5a2c Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marek.vasut+renesas@mailbox.org>
+Date: Wed, 31 May 2023 00:51:24 +0200
+Subject: [PATCH 4001/4044] net: sunxi_emac: Switch to new U-Boot PHY API
+
+Use new U-Boot phy_connect() API which also supports fixed PHYs.
+
+Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
+Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
+---
+ drivers/net/sunxi_emac.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
+index ad9e1abd16..4c90d4b498 100644
+--- a/drivers/net/sunxi_emac.c
++++ b/drivers/net/sunxi_emac.c
+@@ -248,10 +248,10 @@ static int emac_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+ static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
+ {
+-      int ret, mask = 0xffffffff;
++      int ret, mask = -1;
+ #ifdef CONFIG_PHY_ADDR
+-      mask = 1 << CONFIG_PHY_ADDR;
++      mask = CONFIG_PHY_ADDR;
+ #endif
+       priv->bus = mdio_alloc();
+@@ -269,11 +269,10 @@ static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
+       if (ret)
+               return ret;
+-      priv->phydev = phy_find_by_mask(priv->bus, mask);
++      priv->phydev = phy_connect(priv->bus, mask, dev, PHY_INTERFACE_MODE_MII);
+       if (!priv->phydev)
+               return -ENODEV;
+-      phy_connect_dev(priv->phydev, dev, PHY_INTERFACE_MODE_MII);
+       phy_config(priv->phydev);
+       return 0;
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4001-sunxi-remove-CONFIG_SATAPWR.patch b/package/boot/uboot-sunxi/patches/4001-sunxi-remove-CONFIG_SATAPWR.patch
deleted file mode 100644 (file)
index eb4e543..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-From f79b84dca3597605c29793ad69ada86d5932d8cb Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Fri, 15 Jul 2022 16:52:14 +0100
-Subject: [PATCH 4001/4031] sunxi: remove CONFIG_SATAPWR
-
-The CONFIG_SATAPWR Kconfig symbol was used to point to a GPIO that
-enables the power for a SATA harddisk.
-In the DT this is described with the target-supply property in the AHCI
-DT node, pointing to a (GPIO controlled) regulator. Since we need SATA
-only in U-Boot proper, and use a DM driver for AHCI there, we should use
-the DT instead of hardcoding this.
-
-Add code to the sunxi AHCI driver to check the DT for that regulator and
-enable it, at probe time. Then drop the current code from board.c, which
-was doing that job before.
-This allows us to remove the SATAPWR Kconfig definition and the
-respective values from the defconfigs.
-We also select the generic fixed regulator driver, which handles those
-GPIO controlled regulators.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/Kconfig                             |  2 ++
- arch/arm/mach-sunxi/Kconfig                  |  8 --------
- board/sunxi/board.c                          | 16 +---------------
- configs/A10-OLinuXino-Lime_defconfig         |  1 -
- configs/A20-OLinuXino-Lime2-eMMC_defconfig   |  1 -
- configs/A20-OLinuXino-Lime2_defconfig        |  1 -
- configs/A20-OLinuXino-Lime_defconfig         |  1 -
- configs/A20-OLinuXino_MICRO-eMMC_defconfig   |  1 -
- configs/A20-OLinuXino_MICRO_defconfig        |  1 -
- configs/A20-Olimex-SOM-EVB_defconfig         |  1 -
- configs/A20-Olimex-SOM204-EVB-eMMC_defconfig |  1 -
- configs/A20-Olimex-SOM204-EVB_defconfig      |  1 -
- configs/Cubieboard2_defconfig                |  1 -
- configs/Cubieboard_defconfig                 |  1 -
- configs/Cubietruck_defconfig                 |  1 -
- configs/Itead_Ibox_A20_defconfig             |  1 -
- configs/Lamobo_R1_defconfig                  |  1 -
- configs/Linksprite_pcDuino3_Nano_defconfig   |  1 -
- configs/Linksprite_pcDuino3_defconfig        |  1 -
- configs/Sinovoip_BPI_M3_defconfig            |  1 -
- configs/orangepi_plus_defconfig              |  2 +-
- drivers/ata/ahci_sunxi.c                     |  9 +++++++++
- 22 files changed, 13 insertions(+), 41 deletions(-)
-
-diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 8a1e223422..d5a6d293ce 100644
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1130,6 +1130,8 @@ config ARCH_SUNXI
-       imply CMD_GPT
-       imply CMD_UBI if MTD_RAW_NAND
-       imply DISTRO_DEFAULTS
-+      imply DM_REGULATOR
-+      imply DM_REGULATOR_FIXED
-       imply FAT_WRITE
-       imply FIT
-       imply OF_LIBFDT_OVERLAY
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index 6417aee944..c78a553493 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -958,14 +958,6 @@ config VIDEO_LCD_TL059WV5C0
- endchoice
--config SATAPWR
--      string "SATA power pin"
--      default ""
--      help
--        Set the pins used to power the SATA. This takes a string in the
--        format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of
--        port H.
--
- config GMAC_TX_DELAY
-       int "GMAC Transmit Clock Delay Chain"
-       default 0
-diff --git a/board/sunxi/board.c b/board/sunxi/board.c
-index 827e545032..fe0e7bc2d9 100644
---- a/board/sunxi/board.c
-+++ b/board/sunxi/board.c
-@@ -187,7 +187,7 @@ enum env_location env_get_location(enum env_operation op, int prio)
- /* add board specific code here */
- int board_init(void)
- {
--      __maybe_unused int id_pfr1, ret, satapwr_pin, macpwr_pin;
-+      __maybe_unused int id_pfr1, ret, macpwr_pin;
-       gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
-@@ -225,20 +225,6 @@ int board_init(void)
-               return ret;
-       /* strcmp() would look better, but doesn't get optimised away. */
--      if (CONFIG_SATAPWR[0]) {
--              satapwr_pin = sunxi_name_to_gpio(CONFIG_SATAPWR);
--              if (satapwr_pin >= 0) {
--                      gpio_request(satapwr_pin, "satapwr");
--                      gpio_direction_output(satapwr_pin, 1);
--
--                      /*
--                       * Give the attached SATA device time to power-up
--                       * to avoid link timeouts
--                       */
--                      mdelay(500);
--              }
--      }
--
-       if (CONFIG_MACPWR[0]) {
-               macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
-               if (macpwr_pin >= 0) {
-diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig
-index df4fdfaba4..57e91d0f01 100644
---- a/configs/A10-OLinuXino-Lime_defconfig
-+++ b/configs/A10-OLinuXino-Lime_defconfig
-@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=480
- CONFIG_DRAM_EMR1=4
- CONFIG_SYS_CLK_FREQ=912000000
- CONFIG_I2C1_ENABLE=y
--CONFIG_SATAPWR="PC3"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
-index be49e9323a..44770ffb04 100644
---- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
-+++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
-@@ -8,7 +8,6 @@ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_USB0_VBUS_PIN="PC17"
- CONFIG_USB0_VBUS_DET="PH5"
- CONFIG_I2C1_ENABLE=y
--CONFIG_SATAPWR="PC3"
- CONFIG_SPL_SPI_SUNXI=y
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
-index 43cd28c3dd..e10660c933 100644
---- a/configs/A20-OLinuXino-Lime2_defconfig
-+++ b/configs/A20-OLinuXino-Lime2_defconfig
-@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
- CONFIG_USB0_VBUS_PIN="PC17"
- CONFIG_USB0_VBUS_DET="PH5"
- CONFIG_I2C1_ENABLE=y
--CONFIG_SATAPWR="PC3"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig
-index 7c77f38fba..4ed666a034 100644
---- a/configs/A20-OLinuXino-Lime_defconfig
-+++ b/configs/A20-OLinuXino-Lime_defconfig
-@@ -5,7 +5,6 @@ CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=384
- CONFIG_I2C1_ENABLE=y
--CONFIG_SATAPWR="PC3"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/A20-OLinuXino_MICRO-eMMC_defconfig b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
-index 02116995a3..ca5869f43d 100644
---- a/configs/A20-OLinuXino_MICRO-eMMC_defconfig
-+++ b/configs/A20-OLinuXino_MICRO-eMMC_defconfig
-@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_I2C1_ENABLE=y
- CONFIG_VIDEO_VGA=y
--CONFIG_SATAPWR="PB8"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig
-index 895e8dbcbd..db4270f9b2 100644
---- a/configs/A20-OLinuXino_MICRO_defconfig
-+++ b/configs/A20-OLinuXino_MICRO_defconfig
-@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
- CONFIG_MMC_SUNXI_SLOT_EXTRA=3
- CONFIG_I2C1_ENABLE=y
- CONFIG_VIDEO_VGA=y
--CONFIG_SATAPWR="PB8"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/A20-Olimex-SOM-EVB_defconfig b/configs/A20-Olimex-SOM-EVB_defconfig
-index 5bcc9f9f3c..ac900477d1 100644
---- a/configs/A20-Olimex-SOM-EVB_defconfig
-+++ b/configs/A20-Olimex-SOM-EVB_defconfig
-@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
- CONFIG_MMC_SUNXI_SLOT_EXTRA=3
- CONFIG_USB0_VBUS_PIN="PB9"
- CONFIG_USB0_VBUS_DET="PH5"
--CONFIG_SATAPWR="PC3"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
-index e5881090dd..00a98140b3 100644
---- a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
-+++ b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
-@@ -8,7 +8,6 @@ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_USB0_VBUS_PIN="PC17"
- CONFIG_USB0_VBUS_DET="PH5"
- CONFIG_I2C1_ENABLE=y
--CONFIG_SATAPWR="PC3"
- CONFIG_GMAC_TX_DELAY=4
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/A20-Olimex-SOM204-EVB_defconfig b/configs/A20-Olimex-SOM204-EVB_defconfig
-index 592a79a6c7..f4ae3ae6d8 100644
---- a/configs/A20-Olimex-SOM204-EVB_defconfig
-+++ b/configs/A20-Olimex-SOM204-EVB_defconfig
-@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=384
- CONFIG_USB0_VBUS_PIN="PC17"
- CONFIG_USB0_VBUS_DET="PH5"
- CONFIG_I2C1_ENABLE=y
--CONFIG_SATAPWR="PC3"
- CONFIG_GMAC_TX_DELAY=4
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig
-index 0c23368741..ef4f11b7c6 100644
---- a/configs/Cubieboard2_defconfig
-+++ b/configs/Cubieboard2_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubieboard2"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=480
--CONFIG_SATAPWR="PB8"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig
-index 71743f7b8a..ab3f65ad66 100644
---- a/configs/Cubieboard_defconfig
-+++ b/configs/Cubieboard_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-cubieboard"
- CONFIG_SPL=y
- CONFIG_MACH_SUN4I=y
- CONFIG_DRAM_CLK=480
--CONFIG_SATAPWR="PB8"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
-index 184f305b19..184143d708 100644
---- a/configs/Cubietruck_defconfig
-+++ b/configs/Cubietruck_defconfig
-@@ -8,7 +8,6 @@ CONFIG_USB0_VBUS_PIN="PH17"
- CONFIG_USB0_VBUS_DET="PH22"
- CONFIG_USB0_ID_DET="PH19"
- CONFIG_VIDEO_VGA=y
--CONFIG_SATAPWR="PH12"
- CONFIG_GMAC_TX_DELAY=1
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/Itead_Ibox_A20_defconfig b/configs/Itead_Ibox_A20_defconfig
-index 5d05f33798..d03fa62196 100644
---- a/configs/Itead_Ibox_A20_defconfig
-+++ b/configs/Itead_Ibox_A20_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-itead-ibox"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=480
--CONFIG_SATAPWR="PB8"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig
-index 5294608459..9639cb6aad 100644
---- a/configs/Lamobo_R1_defconfig
-+++ b/configs/Lamobo_R1_defconfig
-@@ -5,7 +5,6 @@ CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=432
- CONFIG_MACPWR="PH23"
--CONFIG_SATAPWR="PB3"
- CONFIG_GMAC_TX_DELAY=4
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig
-index e3e30a4949..9eb9a918ae 100644
---- a/configs/Linksprite_pcDuino3_Nano_defconfig
-+++ b/configs/Linksprite_pcDuino3_Nano_defconfig
-@@ -6,7 +6,6 @@ CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=408
- CONFIG_DRAM_ZQ=122
- CONFIG_USB1_VBUS_PIN="PH11"
--CONFIG_SATAPWR="PH2"
- CONFIG_GMAC_TX_DELAY=3
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
-index 1fda0db4c9..7db10e685b 100644
---- a/configs/Linksprite_pcDuino3_defconfig
-+++ b/configs/Linksprite_pcDuino3_defconfig
-@@ -5,7 +5,6 @@ CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=480
- CONFIG_DRAM_ZQ=122
--CONFIG_SATAPWR="PH2"
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/Sinovoip_BPI_M3_defconfig b/configs/Sinovoip_BPI_M3_defconfig
-index 5116fab52d..5545b3d464 100644
---- a/configs/Sinovoip_BPI_M3_defconfig
-+++ b/configs/Sinovoip_BPI_M3_defconfig
-@@ -13,7 +13,6 @@ CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
- CONFIG_USB0_ID_DET="PH11"
- CONFIG_USB1_VBUS_PIN="PD24"
- CONFIG_AXP_GPIO=y
--CONFIG_SATAPWR="PD25"
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_CONSOLE_MUX=y
- CONFIG_PHY_REALTEK=y
-diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig
-index 76de72aa22..ed585881d4 100644
---- a/configs/orangepi_plus_defconfig
-+++ b/configs/orangepi_plus_defconfig
-@@ -7,7 +7,6 @@ CONFIG_DRAM_CLK=672
- CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_USB1_VBUS_PIN="PG13"
--CONFIG_SATAPWR="PG11"
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
- CONFIG_SPL_SYS_I2C_LEGACY=y
-@@ -16,3 +15,4 @@ CONFIG_SUN8I_EMAC=y
- CONFIG_SY8106A_POWER=y
- CONFIG_USB_EHCI_HCD=y
- CONFIG_USB_OHCI_HCD=y
-+CONFIG_USB3_VBUS_PIN="PG11"
-diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
-index 94a3379c53..9064774e66 100644
---- a/drivers/ata/ahci_sunxi.c
-+++ b/drivers/ata/ahci_sunxi.c
-@@ -7,6 +7,7 @@
- #include <asm/io.h>
- #include <asm/gpio.h>
- #include <linux/delay.h>
-+#include <power/regulator.h>
- #define AHCI_PHYCS0R 0x00c0
- #define AHCI_PHYCS1R 0x00c4
-@@ -74,6 +75,7 @@ static int sunxi_ahci_phy_init(u8 *reg_base)
- static int sunxi_sata_probe(struct udevice *dev)
- {
-+      struct udevice *reg_dev;
-       ulong base;
-       u8 *reg;
-       int ret;
-@@ -89,6 +91,13 @@ static int sunxi_sata_probe(struct udevice *dev)
-               debug("%s: Failed to init phy (err=%d)\n", __func__, ret);
-               return ret;
-       }
-+
-+      ret = device_get_supply_regulator(dev, "target-supply", &reg_dev);
-+      if (ret == 0) {
-+              regulator_set_enable(reg_dev, true);
-+              mdelay(500);
-+      }
-+
-       ret = ahci_probe_scsi(dev, base);
-       if (ret) {
-               debug("%s: Failed to probe (err=%d)\n", __func__, ret);
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4002-net-sunxi_emac-chase-DT-nodes-to-find-PHY-regulator.patch b/package/boot/uboot-sunxi/patches/4002-net-sunxi_emac-chase-DT-nodes-to-find-PHY-regulator.patch
new file mode 100644 (file)
index 0000000..e3d5ca3
--- /dev/null
@@ -0,0 +1,102 @@
+From 91d57f14ebe23a425354a039d0a68926f3292d5f Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:47 +0100
+Subject: [PATCH 4002/4044] net: sunxi_emac: chase DT nodes to find PHY
+ regulator
+
+At the moment the sun4i EMAC driver relies on hardcoded CONFIG_MACPWR
+Kconfig symbols to enable potential PHY regulators. As we want to get rid
+of those, we need to find the regulator by chasing up the DT.
+
+The sun4i-emac binding puts the PHY regulator into the MDIO node, which
+is the parent of the PHY device. U-Boot does not have (and does not
+need) an MDIO driver, so we need to chase down the regulator through the
+EMAC node: we follow the "phy-handle" property to find the PHY node,
+then go up to its parent, where we find the "phy-supply" link to the
+regulator. Let U-Boot find the associated regulator device, and put that
+into the private device struct, so we can find and enable the regulator
+at probe time, later.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Sam Edwards <CFSworks@gmail.com>
+---
+ drivers/net/sunxi_emac.c | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
+index 4c90d4b498..f1f0e5bbbb 100644
+--- a/drivers/net/sunxi_emac.c
++++ b/drivers/net/sunxi_emac.c
+@@ -17,6 +17,7 @@
+ #include <net.h>
+ #include <asm/io.h>
+ #include <asm/arch/clock.h>
++#include <power/regulator.h>
+ /* EMAC register  */
+ struct emac_regs {
+@@ -165,6 +166,7 @@ struct emac_eth_dev {
+       struct phy_device *phydev;
+       int link_printed;
+       uchar rx_buf[EMAC_RX_BUFSIZE];
++      struct udevice *phy_reg;
+ };
+ struct emac_rxhdr {
+@@ -572,6 +574,9 @@ static int sunxi_emac_eth_probe(struct udevice *dev)
+       if (ret)
+               return ret;
++      if (priv->phy_reg)
++              regulator_set_enable(priv->phy_reg, true);
++
+       return sunxi_emac_init_phy(priv, dev);
+ }
+@@ -585,9 +590,43 @@ static const struct eth_ops sunxi_emac_eth_ops = {
+ static int sunxi_emac_eth_of_to_plat(struct udevice *dev)
+ {
+       struct eth_pdata *pdata = dev_get_plat(dev);
++      struct emac_eth_dev *priv = dev_get_priv(dev);
++      struct ofnode_phandle_args args;
++      ofnode mdio_node;
++      int ret;
+       pdata->iobase = dev_read_addr(dev);
++      /* The PHY regulator is in the MDIO node, not the EMAC or PHY node. */
++      ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0, &args);
++      if (ret) {
++              dev_err(dev, "failed to get PHY node\n");
++              return ret;
++      }
++
++      /*
++       * U-Boot does not have (and does not need) a device driver for the
++       * MDIO device, so just "pass through" that DT node to get to the
++       * regulator phandle.
++       * The PHY regulator is optional, though: ignore if we cannot find
++       * a phy-supply property.
++       */
++      mdio_node = ofnode_get_parent(args.node);
++      ret= ofnode_parse_phandle_with_args(mdio_node, "phy-supply", NULL, 0, 0,
++                                          &args);
++      if (ret && ret != -ENOENT) {
++              dev_err(dev, "failed to get PHY supply node\n");
++              return ret;
++      }
++      if (!ret) {
++              ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR, args.node,
++                                                &priv->phy_reg);
++              if (ret) {
++                      dev_err(dev, "failed to get PHY regulator node\n");
++                      return ret;
++              }
++      }
++
+       return 0;
+ }
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4002-sunxi-remove-CONFIG_MACPWR.patch b/package/boot/uboot-sunxi/patches/4002-sunxi-remove-CONFIG_MACPWR.patch
deleted file mode 100644 (file)
index a58f69e..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-From 9c399ed4ff3e2eb5a4e051be211e9da1fe9c27cb Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Wed, 8 Jun 2022 14:56:56 +0100
-Subject: [PATCH 4002/4031] sunxi: remove CONFIG_MACPWR
-
-The CONFIG_MACPWR Kconfig symbol is used to point to a GPIO that enables
-the power for the Ethernet "MAC" (mostly PHY, really).
-In the DT this is described with the phy-supply property in the MAC DT
-node, pointing to a (GPIO controlled) regulator. Since we need Ethernet
-only in U-Boot proper, and use a DM driver there, we should use the DT
-instead of hardcoding this.
-
-Add code to the sun8i_emac and sunxi_emac drivers to check the DT for
-that regulator and enable it, at probe time. Then drop the current code
-from board.c, which was doing that job before.
-This allows us to remove the MACPWR Kconfig definition and the respective
-values from the defconfigs.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/mach-sunxi/Kconfig           |  7 -------
- board/sunxi/board.c                   | 12 +-----------
- configs/Bananapi_M2_Ultra_defconfig   |  1 -
- configs/Bananapi_defconfig            |  1 -
- configs/Bananapro_defconfig           |  1 -
- configs/Lamobo_R1_defconfig           |  1 -
- configs/Mele_A1000_defconfig          |  1 -
- configs/Orangepi_defconfig            |  1 -
- configs/Orangepi_mini_defconfig       |  1 -
- configs/bananapi_m1_plus_defconfig    |  1 -
- configs/bananapi_m2_plus_h3_defconfig |  1 -
- configs/bananapi_m2_plus_h5_defconfig |  1 -
- configs/i12-tvbox_defconfig           |  1 -
- configs/jesurun_q5_defconfig          |  1 -
- configs/mixtile_loftq_defconfig       |  1 -
- configs/nanopi_m1_plus_defconfig      |  1 -
- configs/nanopi_neo_plus2_defconfig    |  1 -
- configs/nanopi_r1s_h5_defconfig       |  1 -
- configs/orangepi_pc2_defconfig        |  1 -
- configs/orangepi_plus2e_defconfig     |  1 -
- configs/orangepi_plus_defconfig       |  1 -
- configs/orangepi_win_defconfig        |  1 -
- configs/pine_h64_defconfig            |  1 -
- configs/zeropi_defconfig              |  1 -
- drivers/net/sun8i_emac.c              |  9 +++++++--
- drivers/net/sunxi_emac.c              |  8 ++++++++
- 26 files changed, 16 insertions(+), 42 deletions(-)
-
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index c78a553493..d716054f72 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -645,13 +645,6 @@ config OLD_SUNXI_KERNEL_COMPAT
-       Set this to enable various workarounds for old kernels, this results in
-       sub-optimal settings for newer kernels, only enable if needed.
--config MACPWR
--      string "MAC power pin"
--      default ""
--      help
--        Set the pin used to power the MAC. This takes a string in the format
--        understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
--
- config MMC1_PINS_PH
-       bool "Pins for mmc1 are on Port H"
-       depends on MACH_SUN4I || MACH_SUN7I || MACH_SUN8I_R40
-diff --git a/board/sunxi/board.c b/board/sunxi/board.c
-index fe0e7bc2d9..9900c66ed0 100644
---- a/board/sunxi/board.c
-+++ b/board/sunxi/board.c
-@@ -187,7 +187,7 @@ enum env_location env_get_location(enum env_operation op, int prio)
- /* add board specific code here */
- int board_init(void)
- {
--      __maybe_unused int id_pfr1, ret, macpwr_pin;
-+      __maybe_unused int id_pfr1, ret;
-       gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
-@@ -224,15 +224,6 @@ int board_init(void)
-       if (ret)
-               return ret;
--      /* strcmp() would look better, but doesn't get optimised away. */
--      if (CONFIG_MACPWR[0]) {
--              macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
--              if (macpwr_pin >= 0) {
--                      gpio_request(macpwr_pin, "macpwr");
--                      gpio_direction_output(macpwr_pin, 1);
--              }
--      }
--
- #if CONFIG_IS_ENABLED(DM_I2C)
-       /*
-        * Temporary workaround for enabling I2C clocks until proper sunxi DM
-@@ -240,7 +231,6 @@ int board_init(void)
-        */
-       i2c_init_board();
- #endif
--
-       eth_init_board();
-       return 0;
-diff --git a/configs/Bananapi_M2_Ultra_defconfig b/configs/Bananapi_M2_Ultra_defconfig
-index a5fe76af56..2cc7bbbd8b 100644
---- a/configs/Bananapi_M2_Ultra_defconfig
-+++ b/configs/Bananapi_M2_Ultra_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-r40-bananapi-m2-ultra"
- CONFIG_SPL=y
- CONFIG_MACH_SUN8I_R40=y
- CONFIG_DRAM_CLK=576
--CONFIG_MACPWR="PA17"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_USB1_VBUS_PIN="PH23"
- CONFIG_USB2_VBUS_PIN="PH23"
-diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig
-index 6c2a1f630e..f4910ba13a 100644
---- a/configs/Bananapi_defconfig
-+++ b/configs/Bananapi_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapi"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=432
--CONFIG_MACPWR="PH23"
- CONFIG_VIDEO_COMPOSITE=y
- CONFIG_GMAC_TX_DELAY=3
- CONFIG_AHCI=y
-diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig
-index 94fd74754e..02be8971df 100644
---- a/configs/Bananapro_defconfig
-+++ b/configs/Bananapro_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapro"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=432
--CONFIG_MACPWR="PH23"
- CONFIG_USB1_VBUS_PIN="PH0"
- CONFIG_USB2_VBUS_PIN="PH1"
- CONFIG_VIDEO_COMPOSITE=y
-diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig
-index 9639cb6aad..66f57ab3c8 100644
---- a/configs/Lamobo_R1_defconfig
-+++ b/configs/Lamobo_R1_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-lamobo-r1"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=432
--CONFIG_MACPWR="PH23"
- CONFIG_GMAC_TX_DELAY=4
- CONFIG_AHCI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/Mele_A1000_defconfig b/configs/Mele_A1000_defconfig
-index f5b6d908cd..9ac2e4839d 100644
---- a/configs/Mele_A1000_defconfig
-+++ b/configs/Mele_A1000_defconfig
-@@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
- CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-a1000"
- CONFIG_SPL=y
- CONFIG_MACH_SUN4I=y
--CONFIG_MACPWR="PH15"
- CONFIG_VIDEO_VGA=y
- CONFIG_VIDEO_COMPOSITE=y
- CONFIG_AHCI=y
-diff --git a/configs/Orangepi_defconfig b/configs/Orangepi_defconfig
-index c89a9a1f9d..53edf525ec 100644
---- a/configs/Orangepi_defconfig
-+++ b/configs/Orangepi_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=432
--CONFIG_MACPWR="PH23"
- CONFIG_USB1_VBUS_PIN="PH26"
- CONFIG_USB2_VBUS_PIN="PH22"
- CONFIG_VIDEO_VGA=y
-diff --git a/configs/Orangepi_mini_defconfig b/configs/Orangepi_mini_defconfig
-index fe9ce808a1..ccf3267017 100644
---- a/configs/Orangepi_mini_defconfig
-+++ b/configs/Orangepi_mini_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi-mini"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=432
--CONFIG_MACPWR="PH23"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=3
- CONFIG_USB1_VBUS_PIN="PH26"
- CONFIG_USB2_VBUS_PIN="PH22"
-diff --git a/configs/bananapi_m1_plus_defconfig b/configs/bananapi_m1_plus_defconfig
-index 0fbb619d62..a432a01f6b 100644
---- a/configs/bananapi_m1_plus_defconfig
-+++ b/configs/bananapi_m1_plus_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapi-m1-plus"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=432
--CONFIG_MACPWR="PH23"
- CONFIG_VIDEO_COMPOSITE=y
- CONFIG_GMAC_TX_DELAY=3
- CONFIG_AHCI=y
-diff --git a/configs/bananapi_m2_plus_h3_defconfig b/configs/bananapi_m2_plus_h3_defconfig
-index 26ced59fb0..a8f9b5044b 100644
---- a/configs/bananapi_m2_plus_h3_defconfig
-+++ b/configs/bananapi_m2_plus_h3_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-bananapi-m2-plus"
- CONFIG_SPL=y
- CONFIG_MACH_SUN8I_H3=y
- CONFIG_DRAM_CLK=672
--CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SUN8I_EMAC=y
-diff --git a/configs/bananapi_m2_plus_h5_defconfig b/configs/bananapi_m2_plus_h5_defconfig
-index fb6c945919..1634f62619 100644
---- a/configs/bananapi_m2_plus_h5_defconfig
-+++ b/configs/bananapi_m2_plus_h5_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-bananapi-m2-plus"
- CONFIG_SPL=y
- CONFIG_MACH_SUN50I_H5=y
- CONFIG_DRAM_CLK=672
--CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SUN8I_EMAC=y
-diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig
-index 257dd89af4..37f0f53ae7 100644
---- a/configs/i12-tvbox_defconfig
-+++ b/configs/i12-tvbox_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-i12-tvbox"
- CONFIG_SPL=y
- CONFIG_MACH_SUN7I=y
- CONFIG_DRAM_CLK=384
--CONFIG_MACPWR="PH21"
- CONFIG_VIDEO_COMPOSITE=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/jesurun_q5_defconfig b/configs/jesurun_q5_defconfig
-index 0ff666b2ee..c99be7cea4 100644
---- a/configs/jesurun_q5_defconfig
-+++ b/configs/jesurun_q5_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-jesurun-q5"
- CONFIG_SPL=y
- CONFIG_MACH_SUN4I=y
- CONFIG_DRAM_CLK=312
--CONFIG_MACPWR="PH19"
- CONFIG_USB0_VBUS_PIN="PB9"
- CONFIG_VIDEO_COMPOSITE=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig
-index 0e4cdc4467..2f92228eb7 100644
---- a/configs/mixtile_loftq_defconfig
-+++ b/configs/mixtile_loftq_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-mixtile-loftq"
- CONFIG_SPL=y
- CONFIG_MACH_SUN6I=y
- CONFIG_DRAM_ZQ=251
--CONFIG_MACPWR="PA21"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_USB1_VBUS_PIN="PH24"
- CONFIG_USB2_VBUS_PIN=""
-diff --git a/configs/nanopi_m1_plus_defconfig b/configs/nanopi_m1_plus_defconfig
-index 76655d79ae..078e98b644 100644
---- a/configs/nanopi_m1_plus_defconfig
-+++ b/configs/nanopi_m1_plus_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-m1-plus"
- CONFIG_SPL=y
- CONFIG_MACH_SUN8I_H3=y
- CONFIG_DRAM_CLK=408
--CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SUN8I_EMAC=y
-diff --git a/configs/nanopi_neo_plus2_defconfig b/configs/nanopi_neo_plus2_defconfig
-index 924ff38f17..85ff31c6fe 100644
---- a/configs/nanopi_neo_plus2_defconfig
-+++ b/configs/nanopi_neo_plus2_defconfig
-@@ -6,7 +6,6 @@ CONFIG_MACH_SUN50I_H5=y
- CONFIG_DRAM_CLK=408
- CONFIG_DRAM_ZQ=3881977
- # CONFIG_DRAM_ODT_EN is not set
--CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SUN8I_EMAC=y
-diff --git a/configs/nanopi_r1s_h5_defconfig b/configs/nanopi_r1s_h5_defconfig
-index 27cf172d72..2a6f94afe4 100644
---- a/configs/nanopi_r1s_h5_defconfig
-+++ b/configs/nanopi_r1s_h5_defconfig
-@@ -6,7 +6,6 @@ CONFIG_MACH_SUN50I_H5=y
- CONFIG_DRAM_CLK=672
- CONFIG_DRAM_ZQ=3881977
- # CONFIG_DRAM_ODT_EN is not set
--CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SUN8I_EMAC=y
-diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig
-index 777af8c60e..fb6fbaf787 100644
---- a/configs/orangepi_pc2_defconfig
-+++ b/configs/orangepi_pc2_defconfig
-@@ -5,7 +5,6 @@ CONFIG_SPL=y
- CONFIG_MACH_SUN50I_H5=y
- CONFIG_DRAM_CLK=672
- CONFIG_DRAM_ZQ=3881977
--CONFIG_MACPWR="PD6"
- CONFIG_SPL_SPI_SUNXI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/orangepi_plus2e_defconfig b/configs/orangepi_plus2e_defconfig
-index 138a6a72b8..5e2cbc48ea 100644
---- a/configs/orangepi_plus2e_defconfig
-+++ b/configs/orangepi_plus2e_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-plus2e"
- CONFIG_SPL=y
- CONFIG_MACH_SUN8I_H3=y
- CONFIG_DRAM_CLK=672
--CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPL_I2C=y
-diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig
-index ed585881d4..092ce77a6c 100644
---- a/configs/orangepi_plus_defconfig
-+++ b/configs/orangepi_plus_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-plus"
- CONFIG_SPL=y
- CONFIG_MACH_SUN8I_H3=y
- CONFIG_DRAM_CLK=672
--CONFIG_MACPWR="PD6"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_USB1_VBUS_PIN="PG13"
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-diff --git a/configs/orangepi_win_defconfig b/configs/orangepi_win_defconfig
-index 3b78ad7e52..bf52d1ea6b 100644
---- a/configs/orangepi_win_defconfig
-+++ b/configs/orangepi_win_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-orangepi-win"
- CONFIG_SPL=y
- CONFIG_MACH_SUN50I=y
- CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
--CONFIG_MACPWR="PD14"
- CONFIG_SPL_SPI_SUNXI=y
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_SPI_FLASH_WINBOND=y
-diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
-index 6dac6098d0..4712b8e469 100644
---- a/configs/pine_h64_defconfig
-+++ b/configs/pine_h64_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun50i-h6-pine-h64"
- CONFIG_SPL=y
- CONFIG_MACH_SUN50I_H6=y
- CONFIG_SUNXI_DRAM_H6_LPDDR3=y
--CONFIG_MACPWR="PC16"
- CONFIG_MMC_SUNXI_SLOT_EXTRA=2
- CONFIG_USB3_VBUS_PIN="PL5"
- CONFIG_SPL_SPI_SUNXI=y
-diff --git a/configs/zeropi_defconfig b/configs/zeropi_defconfig
-index 11f3715e6d..7901bffd15 100644
---- a/configs/zeropi_defconfig
-+++ b/configs/zeropi_defconfig
-@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-zeropi"
- CONFIG_SPL=y
- CONFIG_MACH_SUN8I_H3=y
- CONFIG_DRAM_CLK=408
--CONFIG_MACPWR="PD6"
- # CONFIG_VIDEO_DE2 is not set
- # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
- CONFIG_CONSOLE_MUX=y
-diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
-index e800a326b8..0937ec3c86 100644
---- a/drivers/net/sun8i_emac.c
-+++ b/drivers/net/sun8i_emac.c
-@@ -29,6 +29,7 @@
- #include <net.h>
- #include <reset.h>
- #include <wait_bit.h>
-+#include <power/regulator.h>
- #define MDIO_CMD_MII_BUSY             BIT(0)
- #define MDIO_CMD_MII_WRITE            BIT(1)
-@@ -169,9 +170,8 @@ struct emac_eth_dev {
-       struct clk ephy_clk;
-       struct reset_ctl tx_rst;
-       struct reset_ctl ephy_rst;
--#if CONFIG_IS_ENABLED(DM_GPIO)
-       struct gpio_desc reset_gpio;
--#endif
-+      struct udevice *phy_reg;
- };
-@@ -738,6 +738,9 @@ static int sun8i_emac_eth_probe(struct udevice *dev)
-       sun8i_emac_set_syscon(sun8i_pdata, priv);
-+      if (priv->phy_reg)
-+              regulator_set_enable(priv->phy_reg, true);
-+
-       sun8i_mdio_init(dev->name, dev);
-       priv->bus = miiphy_get_dev_by_name(dev->name);
-@@ -844,6 +847,8 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
-               return -EINVAL;
-       }
-+      device_get_supply_regulator(dev, "phy-supply", &priv->phy_reg);
-+
-       pdata->phy_interface = -1;
-       priv->phyaddr = -1;
-       priv->use_internal_phy = false;
-diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
-index ad9e1abd16..ee8b8a1667 100644
---- a/drivers/net/sunxi_emac.c
-+++ b/drivers/net/sunxi_emac.c
-@@ -17,6 +17,7 @@
- #include <net.h>
- #include <asm/io.h>
- #include <asm/arch/clock.h>
-+#include <power/regulator.h>
- /* EMAC register  */
- struct emac_regs {
-@@ -165,6 +166,7 @@ struct emac_eth_dev {
-       struct phy_device *phydev;
-       int link_printed;
-       uchar rx_buf[EMAC_RX_BUFSIZE];
-+      struct udevice *phy_reg;
- };
- struct emac_rxhdr {
-@@ -573,6 +575,9 @@ static int sunxi_emac_eth_probe(struct udevice *dev)
-       if (ret)
-               return ret;
-+      if (priv->phy_reg)
-+              regulator_set_enable(priv->phy_reg, true);
-+
-       return sunxi_emac_init_phy(priv, dev);
- }
-@@ -586,9 +591,12 @@ static const struct eth_ops sunxi_emac_eth_ops = {
- static int sunxi_emac_eth_of_to_plat(struct udevice *dev)
- {
-       struct eth_pdata *pdata = dev_get_plat(dev);
-+      struct emac_eth_dev *priv = dev_get_priv(dev);
-       pdata->iobase = dev_read_addr(dev);
-+      device_get_supply_regulator(dev, "phy-supply", &priv->phy_reg);
-+
-       return 0;
- }
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4003-net-sun8i-emac-Add-a-structure-for-variant-data.patch b/package/boot/uboot-sunxi/patches/4003-net-sun8i-emac-Add-a-structure-for-variant-data.patch
new file mode 100644 (file)
index 0000000..edadb24
--- /dev/null
@@ -0,0 +1,152 @@
+From 418993044499a9466a6be214c9d996e6e3b09798 Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Sun, 22 Jan 2023 16:51:02 -0600
+Subject: [PATCH 4003/4044] net: sun8i-emac: Add a structure for variant data
+
+Currently, EMAC variants are distinguished by their identity, but this
+gets unwieldy as more overlapping variants are added. Add a structure so
+we can describe the individual feature differences between the variants.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
+---
+ drivers/net/sun8i_emac.c | 65 +++++++++++++++++++++++++++-------------
+ 1 file changed, 45 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
+index e800a326b8..986e565cd8 100644
+--- a/drivers/net/sun8i_emac.c
++++ b/drivers/net/sun8i_emac.c
+@@ -127,7 +127,7 @@
+ DECLARE_GLOBAL_DATA_PTR;
+-enum emac_variant {
++enum emac_variant_id {
+       A83T_EMAC = 1,
+       H3_EMAC,
+       A64_EMAC,
+@@ -135,6 +135,10 @@ enum emac_variant {
+       H6_EMAC,
+ };
++struct emac_variant {
++      enum emac_variant_id    variant;
++};
++
+ struct emac_dma_desc {
+       u32 status;
+       u32 ctl_size;
+@@ -160,7 +164,7 @@ struct emac_eth_dev {
+       u32 tx_slot;
+       bool use_internal_phy;
+-      enum emac_variant variant;
++      const struct emac_variant *variant;
+       void *mac_reg;
+       phys_addr_t sysctl_reg;
+       struct phy_device *phydev;
+@@ -317,7 +321,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+ {
+       u32 reg;
+-      if (priv->variant == R40_GMAC) {
++      if (priv->variant->variant == R40_GMAC) {
+               /* Select RGMII for R40 */
+               reg = readl(priv->sysctl_reg + 0x164);
+               reg |= SC_ETCS_INT_GMII |
+@@ -333,9 +337,9 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+       reg = sun8i_emac_set_syscon_ephy(priv, reg);
+       reg &= ~(SC_ETCS_MASK | SC_EPIT);
+-      if (priv->variant == H3_EMAC ||
+-          priv->variant == A64_EMAC ||
+-          priv->variant == H6_EMAC)
++      if (priv->variant->variant == H3_EMAC ||
++          priv->variant->variant == A64_EMAC ||
++          priv->variant->variant == H6_EMAC)
+               reg &= ~SC_RMII_EN;
+       switch (priv->interface) {
+@@ -349,9 +353,9 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+               reg |= SC_EPIT | SC_ETCS_INT_GMII;
+               break;
+       case PHY_INTERFACE_MODE_RMII:
+-              if (priv->variant == H3_EMAC ||
+-                  priv->variant == A64_EMAC ||
+-                  priv->variant == H6_EMAC) {
++              if (priv->variant->variant == H3_EMAC ||
++                  priv->variant->variant == A64_EMAC ||
++                  priv->variant->variant == H6_EMAC) {
+                       reg |= SC_RMII_EN | SC_ETCS_EXT_GMII;
+               break;
+               }
+@@ -806,7 +810,7 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+               return -EINVAL;
+       }
+-      priv->variant = dev_get_driver_data(dev);
++      priv->variant = (const void *)dev_get_driver_data(dev);
+       if (!priv->variant) {
+               printf("%s: Missing variant\n", __func__);
+@@ -860,7 +864,7 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+       if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
+               return -EINVAL;
+-      if (priv->variant == H3_EMAC) {
++      if (priv->variant->variant == H3_EMAC) {
+               ret = sun8i_handle_internal_phy(dev, priv);
+               if (ret)
+                       return ret;
+@@ -900,16 +904,37 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+       return 0;
+ }
++static const struct emac_variant emac_variant_a83t = {
++      .variant                = A83T_EMAC,
++};
++
++static const struct emac_variant emac_variant_h3 = {
++      .variant                = H3_EMAC,
++};
++
++static const struct emac_variant emac_variant_r40 = {
++      .variant                = R40_GMAC,
++};
++
++static const struct emac_variant emac_variant_a64 = {
++      .variant                = A64_EMAC,
++};
++
++static const struct emac_variant emac_variant_h6 = {
++      .variant                = H6_EMAC,
++};
++
+ static const struct udevice_id sun8i_emac_eth_ids[] = {
+-      {.compatible = "allwinner,sun8i-h3-emac", .data = (uintptr_t)H3_EMAC },
+-      {.compatible = "allwinner,sun50i-a64-emac",
+-              .data = (uintptr_t)A64_EMAC },
+-      {.compatible = "allwinner,sun8i-a83t-emac",
+-              .data = (uintptr_t)A83T_EMAC },
+-      {.compatible = "allwinner,sun8i-r40-gmac",
+-              .data = (uintptr_t)R40_GMAC },
+-      {.compatible = "allwinner,sun50i-h6-emac",
+-              .data = (uintptr_t)H6_EMAC },
++      { .compatible = "allwinner,sun8i-a83t-emac",
++        .data = (ulong)&emac_variant_a83t },
++      { .compatible = "allwinner,sun8i-h3-emac",
++        .data = (ulong)&emac_variant_h3 },
++      { .compatible = "allwinner,sun8i-r40-gmac",
++        .data = (ulong)&emac_variant_r40 },
++      { .compatible = "allwinner,sun50i-a64-emac",
++        .data = (ulong)&emac_variant_a64 },
++      { .compatible = "allwinner,sun50i-h6-emac",
++        .data = (ulong)&emac_variant_h6 },
+       { }
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4003-pinctrl-sunxi-remove-struct-sunxi_gpio.patch b/package/boot/uboot-sunxi/patches/4003-pinctrl-sunxi-remove-struct-sunxi_gpio.patch
deleted file mode 100644 (file)
index e9623c9..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-From 32d2c051ef1568445a5a27b1d2d5ffe6a9483ef3 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 5 Sep 2022 18:12:39 +0100
-Subject: [PATCH 4003/4031] pinctrl: sunxi: remove struct sunxi_gpio
-
-So far every Allwinner SoC used the same basic pincontroller/GPIO
-register frame, and just differed by the number of implemented banks and
-pins, plus some special functionality from time to time. However the D1
-and successors use a slightly different pinctrl register layout.
-Use that opportunity to drop "struct sunxi_gpio", that described that
-MMIO frame in a C struct. That approach is somewhat frowned upon in the
-Linux world and rarely used there, though still popular with U-Boot.
-
-Switching from a C struct to a "base address plus offset" approach allows
-to switch between the two models more dynamically, without reverting to
-preprocessor macros and #ifdef's.
-
-Model the pinctrl MMIO register frame in the usual "base address +
-offset" way, and replace a hard-to-parse CPP macro with a more readable
-static function.
-All the users get converted over. There are no functional changes at
-this point, it just prepares the stages for the D1 and friends.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/include/asm/arch-sunxi/gpio.h | 63 +++++++++++---------------
- arch/arm/mach-sunxi/pinmux.c           | 51 +++++++++++----------
- drivers/gpio/sunxi_gpio.c              | 15 +++---
- drivers/pinctrl/sunxi/pinctrl-sunxi.c  | 14 +++---
- 4 files changed, 68 insertions(+), 75 deletions(-)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
-index 437e86479c..8333810a69 100644
---- a/arch/arm/include/asm/arch-sunxi/gpio.h
-+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
-@@ -28,13 +28,6 @@
- #define SUNXI_GPIO_H  7
- #define SUNXI_GPIO_I  8
--/*
-- * This defines the number of GPIO banks for the _main_ GPIO controller.
-- * You should fix up the padding in struct sunxi_gpio_reg below if you
-- * change this.
-- */
--#define SUNXI_GPIO_BANKS 9
--
- /*
-  * sun6i/sun8i and later SoCs have an additional GPIO controller (R_PIO)
-  * at a different register offset.
-@@ -52,46 +45,42 @@
- #define SUNXI_GPIO_M  12
- #define SUNXI_GPIO_N  13
--struct sunxi_gpio {
--      u32 cfg[4];
--      u32 dat;
--      u32 drv[2];
--      u32 pull[2];
--};
--
--/* gpio interrupt control */
--struct sunxi_gpio_int {
--      u32 cfg[3];
--      u32 ctl;
--      u32 sta;
--      u32 deb;                /* interrupt debounce */
--};
--
--struct sunxi_gpio_reg {
--      struct sunxi_gpio gpio_bank[SUNXI_GPIO_BANKS];
--      u8 res[0xbc];
--      struct sunxi_gpio_int gpio_int;
--};
--
- #define SUN50I_H6_GPIO_POW_MOD_SEL    0x340
- #define SUN50I_H6_GPIO_POW_MOD_VAL    0x348
--#define BANK_TO_GPIO(bank)    (((bank) < SUNXI_GPIO_L) ? \
--      &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \
--      &((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
--
- #define GPIO_BANK(pin)                ((pin) >> 5)
- #define GPIO_NUM(pin)         ((pin) & 0x1f)
-+#define GPIO_CFG_REG_OFFSET   0x00
- #define GPIO_CFG_INDEX(pin)   (((pin) & 0x1f) >> 3)
- #define GPIO_CFG_OFFSET(pin)  ((((pin) & 0x1f) & 0x7) << 2)
-+#define GPIO_DAT_REG_OFFSET   0x10
-+
-+#define GPIO_DRV_REG_OFFSET   0x14
- #define GPIO_DRV_INDEX(pin)   (((pin) & 0x1f) >> 4)
- #define GPIO_DRV_OFFSET(pin)  ((((pin) & 0x1f) & 0xf) << 1)
-+#define GPIO_PULL_REG_OFFSET  0x1c
- #define GPIO_PULL_INDEX(pin)  (((pin) & 0x1f) >> 4)
- #define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1)
-+#define SUNXI_PINCTRL_BANK_SIZE 0x24
-+
-+static inline void* BANK_TO_GPIO(int bank)
-+{
-+      void *pio_base;
-+
-+      if (bank < SUNXI_GPIO_L) {
-+              pio_base = (void *)(uintptr_t)SUNXI_PIO_BASE;
-+      } else {
-+              pio_base = (void *)(uintptr_t)SUNXI_R_PIO_BASE;
-+              bank -= SUNXI_GPIO_L;
-+      }
-+
-+      return pio_base + bank * SUNXI_PINCTRL_BANK_SIZE;
-+}
-+
- /* GPIO bank sizes */
- #define SUNXI_GPIOS_PER_BANK  32
-@@ -214,18 +203,18 @@ enum sunxi_gpio_number {
- #define SUNXI_GPIO_AXP0_GPIO_COUNT    6
- struct sunxi_gpio_plat {
--      struct sunxi_gpio       *regs;
-+      void                    *regs;
-       char                    bank_name[3];
- };
--void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
-+void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val);
- void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
--int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset);
-+int sunxi_gpio_get_cfgbank(void *bank_base, int pin_offset);
- int sunxi_gpio_get_cfgpin(u32 pin);
- void sunxi_gpio_set_drv(u32 pin, u32 val);
--void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val);
-+void sunxi_gpio_set_drv_bank(void *bank_base, u32 pin_offset, u32 val);
- void sunxi_gpio_set_pull(u32 pin, u32 val);
--void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val);
-+void sunxi_gpio_set_pull_bank(void *bank_base, int pin_offset, u32 val);
- int sunxi_name_to_gpio(const char *name);
- #if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
-diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c
-index c95fcee9f6..b650f6b1ae 100644
---- a/arch/arm/mach-sunxi/pinmux.c
-+++ b/arch/arm/mach-sunxi/pinmux.c
-@@ -9,29 +9,30 @@
- #include <asm/io.h>
- #include <asm/arch/gpio.h>
--void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val)
-+void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val)
- {
--      u32 index = GPIO_CFG_INDEX(bank_offset);
--      u32 offset = GPIO_CFG_OFFSET(bank_offset);
-+      u32 index = GPIO_CFG_INDEX(pin_offset);
-+      u32 offset = GPIO_CFG_OFFSET(pin_offset);
--      clrsetbits_le32(&pio->cfg[index], 0xf << offset, val << offset);
-+      clrsetbits_le32(bank_base + GPIO_CFG_REG_OFFSET + index * 4,
-+                      0xfU << offset, val << offset);
- }
- void sunxi_gpio_set_cfgpin(u32 pin, u32 val)
- {
-       u32 bank = GPIO_BANK(pin);
--      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
-+      void *pio = BANK_TO_GPIO(bank);
--      sunxi_gpio_set_cfgbank(pio, pin, val);
-+      sunxi_gpio_set_cfgbank(pio, pin % 32, val);
- }
--int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset)
-+int sunxi_gpio_get_cfgbank(void *bank_base, int pin_offset)
- {
--      u32 index = GPIO_CFG_INDEX(bank_offset);
--      u32 offset = GPIO_CFG_OFFSET(bank_offset);
-+      u32 index = GPIO_CFG_INDEX(pin_offset);
-+      u32 offset = GPIO_CFG_OFFSET(pin_offset);
-       u32 cfg;
--      cfg = readl(&pio->cfg[index]);
-+      cfg = readl(bank_base + GPIO_CFG_REG_OFFSET + index * 4);
-       cfg >>= offset;
-       return cfg & 0xf;
-@@ -40,39 +41,41 @@ int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset)
- int sunxi_gpio_get_cfgpin(u32 pin)
- {
-       u32 bank = GPIO_BANK(pin);
--      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
-+      void *bank_base = BANK_TO_GPIO(bank);
--      return sunxi_gpio_get_cfgbank(pio, pin);
-+      return sunxi_gpio_get_cfgbank(bank_base, pin % 32);
- }
- void sunxi_gpio_set_drv(u32 pin, u32 val)
- {
-       u32 bank = GPIO_BANK(pin);
--      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
-+      void *bank_base = BANK_TO_GPIO(bank);
--      sunxi_gpio_set_drv_bank(pio, pin, val);
-+      sunxi_gpio_set_drv_bank(bank_base, pin % 32, val);
- }
--void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val)
-+void sunxi_gpio_set_drv_bank(void *bank_base, u32 pin_offset, u32 val)
- {
--      u32 index = GPIO_DRV_INDEX(bank_offset);
--      u32 offset = GPIO_DRV_OFFSET(bank_offset);
-+      u32 index = GPIO_DRV_INDEX(pin_offset);
-+      u32 offset = GPIO_DRV_OFFSET(pin_offset);
--      clrsetbits_le32(&pio->drv[index], 0x3 << offset, val << offset);
-+      clrsetbits_le32(bank_base + GPIO_DRV_REG_OFFSET + index * 4,
-+                      0x3U << offset, val << offset);
- }
- void sunxi_gpio_set_pull(u32 pin, u32 val)
- {
-       u32 bank = GPIO_BANK(pin);
--      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
-+      void *bank_base = BANK_TO_GPIO(bank);
--      sunxi_gpio_set_pull_bank(pio, pin, val);
-+      sunxi_gpio_set_pull_bank(bank_base, pin % 32, val);
- }
--void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val)
-+void sunxi_gpio_set_pull_bank(void *bank_base, int pin_offset, u32 val)
- {
--      u32 index = GPIO_PULL_INDEX(bank_offset);
--      u32 offset = GPIO_PULL_OFFSET(bank_offset);
-+      u32 index = GPIO_PULL_INDEX(pin_offset);
-+      u32 offset = GPIO_PULL_OFFSET(pin_offset);
--      clrsetbits_le32(&pio->pull[index], 0x3 << offset, val << offset);
-+      clrsetbits_le32(bank_base + GPIO_PULL_REG_OFFSET + index * 4,
-+                      0x3U << offset, val << offset);
- }
-diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
-index 1e85db179a..1bf691a204 100644
---- a/drivers/gpio/sunxi_gpio.c
-+++ b/drivers/gpio/sunxi_gpio.c
-@@ -24,15 +24,15 @@ static int sunxi_gpio_output(u32 pin, u32 val)
-       u32 dat;
-       u32 bank = GPIO_BANK(pin);
-       u32 num = GPIO_NUM(pin);
--      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
-+      void *pio = BANK_TO_GPIO(bank);
--      dat = readl(&pio->dat);
-+      dat = readl(pio + 0x10);
-       if (val)
-               dat |= 0x1 << num;
-       else
-               dat &= ~(0x1 << num);
--      writel(dat, &pio->dat);
-+      writel(dat, pio + 0x10);
-       return 0;
- }
-@@ -42,9 +42,9 @@ static int sunxi_gpio_input(u32 pin)
-       u32 dat;
-       u32 bank = GPIO_BANK(pin);
-       u32 num = GPIO_NUM(pin);
--      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
-+      void *pio = BANK_TO_GPIO(bank);
--      dat = readl(&pio->dat);
-+      dat = readl(pio + 0x10);
-       dat >>= num;
-       return dat & 0x1;
-@@ -138,7 +138,7 @@ static int sunxi_gpio_get_value(struct udevice *dev, unsigned offset)
-       u32 num = GPIO_NUM(offset);
-       unsigned dat;
--      dat = readl(&plat->regs->dat);
-+      dat = readl(plat->regs + GPIO_DAT_REG_OFFSET);
-       dat >>= num;
-       return dat & 0x1;
-@@ -181,7 +181,8 @@ static int sunxi_gpio_set_flags(struct udevice *dev, unsigned int offset,
-               u32 value = !!(flags & GPIOD_IS_OUT_ACTIVE);
-               u32 num = GPIO_NUM(offset);
--              clrsetbits_le32(&plat->regs->dat, 1 << num, value << num);
-+              clrsetbits_le32(plat->regs + GPIO_DAT_REG_OFFSET,
-+                              1 << num, value << num);
-               sunxi_gpio_set_cfgbank(plat->regs, offset, SUNXI_GPIO_OUTPUT);
-       } else if (flags & GPIOD_IS_IN) {
-               u32 pull = 0;
-diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-index c4fbda7a92..b0144edcf4 100644
---- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-@@ -35,7 +35,7 @@ struct sunxi_pinctrl_desc {
- };
- struct sunxi_pinctrl_plat {
--      struct sunxi_gpio __iomem *base;
-+      void __iomem *base;
- };
- static int sunxi_pinctrl_get_pins_count(struct udevice *dev)
-@@ -86,8 +86,8 @@ static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector,
-             sunxi_pinctrl_get_function_name(dev, func_selector),
-             desc->functions[func_selector].mux);
--      sunxi_gpio_set_cfgbank(plat->base + bank, pin,
--                             desc->functions[func_selector].mux);
-+      sunxi_gpio_set_cfgbank(plat->base + bank * SUNXI_PINCTRL_BANK_SIZE,
-+                             pin, desc->functions[func_selector].mux);
-       return 0;
- }
-@@ -102,7 +102,7 @@ static const struct pinconf_param sunxi_pinctrl_pinconf_params[] = {
- static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
-                                         uint bank, uint pin, uint bias)
- {
--      struct sunxi_gpio *regs = &plat->base[bank];
-+      void *regs = plat->base + bank * SUNXI_PINCTRL_BANK_SIZE;
-       sunxi_gpio_set_pull_bank(regs, pin, bias);
-@@ -112,7 +112,7 @@ static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
- static int sunxi_pinctrl_pinconf_set_drive(struct sunxi_pinctrl_plat *plat,
-                                          uint bank, uint pin, uint drive)
- {
--      struct sunxi_gpio *regs = &plat->base[bank];
-+      void *regs = plat->base + bank * SUNXI_PINCTRL_BANK_SIZE;
-       if (drive < 10 || drive > 40)
-               return -EINVAL;
-@@ -148,7 +148,7 @@ static int sunxi_pinctrl_get_pin_muxing(struct udevice *dev, uint pin_selector,
-       struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
-       int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
-       int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
--      int mux  = sunxi_gpio_get_cfgbank(plat->base + bank, pin);
-+      int mux  = sunxi_gpio_get_cfgbank(plat->base + bank * SUNXI_PINCTRL_BANK_SIZE, pin);
-       switch (mux) {
-       case SUNXI_GPIO_INPUT:
-@@ -206,7 +206,7 @@ static int sunxi_pinctrl_bind(struct udevice *dev)
-               if (!gpio_plat)
-                       return -ENOMEM;
--              gpio_plat->regs = plat->base + i;
-+              gpio_plat->regs = plat->base + i * SUNXI_PINCTRL_BANK_SIZE;
-               gpio_plat->bank_name[0] = 'P';
-               gpio_plat->bank_name[1] = 'A' + desc->first_bank + i;
-               gpio_plat->bank_name[2] = '\0';
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4004-net-sun8i-emac-Add-a-flag-for-RMII-support.patch b/package/boot/uboot-sunxi/patches/4004-net-sun8i-emac-Add-a-flag-for-RMII-support.patch
new file mode 100644 (file)
index 0000000..17715b7
--- /dev/null
@@ -0,0 +1,77 @@
+From d9fd9f067e9bfcc03a70a0ead0bbe14595976edd Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Sun, 22 Jan 2023 16:51:03 -0600
+Subject: [PATCH 4004/4044] net: sun8i-emac: Add a flag for RMII support
+
+Describe this feature instead of using the SoC ID.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
+---
+ drivers/net/sun8i_emac.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
+index 986e565cd8..f232b8f087 100644
+--- a/drivers/net/sun8i_emac.c
++++ b/drivers/net/sun8i_emac.c
+@@ -137,6 +137,7 @@ enum emac_variant_id {
+ struct emac_variant {
+       enum emac_variant_id    variant;
++      bool                    support_rmii;
+ };
+ struct emac_dma_desc {
+@@ -337,9 +338,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+       reg = sun8i_emac_set_syscon_ephy(priv, reg);
+       reg &= ~(SC_ETCS_MASK | SC_EPIT);
+-      if (priv->variant->variant == H3_EMAC ||
+-          priv->variant->variant == A64_EMAC ||
+-          priv->variant->variant == H6_EMAC)
++      if (priv->variant->support_rmii)
+               reg &= ~SC_RMII_EN;
+       switch (priv->interface) {
+@@ -353,13 +352,10 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+               reg |= SC_EPIT | SC_ETCS_INT_GMII;
+               break;
+       case PHY_INTERFACE_MODE_RMII:
+-              if (priv->variant->variant == H3_EMAC ||
+-                  priv->variant->variant == A64_EMAC ||
+-                  priv->variant->variant == H6_EMAC) {
++              if (priv->variant->support_rmii) {
+                       reg |= SC_RMII_EN | SC_ETCS_EXT_GMII;
+-              break;
++                      break;
+               }
+-              /* RMII not supported on A83T */
+       default:
+               debug("%s: Invalid PHY interface\n", __func__);
+               return -EINVAL;
+@@ -910,6 +906,7 @@ static const struct emac_variant emac_variant_a83t = {
+ static const struct emac_variant emac_variant_h3 = {
+       .variant                = H3_EMAC,
++      .support_rmii           = true,
+ };
+ static const struct emac_variant emac_variant_r40 = {
+@@ -918,10 +915,12 @@ static const struct emac_variant emac_variant_r40 = {
+ static const struct emac_variant emac_variant_a64 = {
+       .variant                = A64_EMAC,
++      .support_rmii           = true,
+ };
+ static const struct emac_variant emac_variant_h6 = {
+       .variant                = H6_EMAC,
++      .support_rmii           = true,
+ };
+ static const struct udevice_id sun8i_emac_eth_ids[] = {
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4004-pinctrl-sunxi-add-GPIO-in-out-wrappers.patch b/package/boot/uboot-sunxi/patches/4004-pinctrl-sunxi-add-GPIO-in-out-wrappers.patch
deleted file mode 100644 (file)
index 872ac62..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-From be773ad59da355ca608287db4c4771bf9120241c Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Tue, 6 Sep 2022 10:07:18 +0100
-Subject: [PATCH 4004/4031] pinctrl: sunxi: add GPIO in/out wrappers
-
-So far we were open-coding the pincontroller's GPIO output/input access
-in each function using that.
-
-Provide two functions that wrap that nicely, so users don't need to know
-about the internals, and we can abstract the new D1 pinctrl more easily.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/include/asm/arch-sunxi/gpio.h |  2 ++
- arch/arm/mach-sunxi/pinmux.c           | 10 ++++++++++
- drivers/gpio/sunxi_gpio.c              | 26 +++++---------------------
- 3 files changed, 17 insertions(+), 21 deletions(-)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
-index 8333810a69..42ca03d8c1 100644
---- a/arch/arm/include/asm/arch-sunxi/gpio.h
-+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
-@@ -211,6 +211,8 @@ void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val);
- void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
- int sunxi_gpio_get_cfgbank(void *bank_base, int pin_offset);
- int sunxi_gpio_get_cfgpin(u32 pin);
-+void sunxi_gpio_set_output_bank(void *bank_base, u32 clear_mask, u32 set_mask);
-+u32 sunxi_gpio_get_output_bank(void *bank_base);
- void sunxi_gpio_set_drv(u32 pin, u32 val);
- void sunxi_gpio_set_drv_bank(void *bank_base, u32 pin_offset, u32 val);
- void sunxi_gpio_set_pull(u32 pin, u32 val);
-diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c
-index b650f6b1ae..91acbf9269 100644
---- a/arch/arm/mach-sunxi/pinmux.c
-+++ b/arch/arm/mach-sunxi/pinmux.c
-@@ -46,6 +46,16 @@ int sunxi_gpio_get_cfgpin(u32 pin)
-       return sunxi_gpio_get_cfgbank(bank_base, pin % 32);
- }
-+void sunxi_gpio_set_output_bank(void *bank_base, u32 clear_mask, u32 set_mask)
-+{
-+      clrsetbits_le32(bank_base + GPIO_DAT_REG_OFFSET, clear_mask, set_mask);
-+}
-+
-+u32 sunxi_gpio_get_output_bank(void *bank_base)
-+{
-+      return readl(bank_base + GPIO_DAT_REG_OFFSET);
-+}
-+
- void sunxi_gpio_set_drv(u32 pin, u32 val)
- {
-       u32 bank = GPIO_BANK(pin);
-diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
-index 1bf691a204..767996c10f 100644
---- a/drivers/gpio/sunxi_gpio.c
-+++ b/drivers/gpio/sunxi_gpio.c
-@@ -21,33 +21,22 @@
- #if !CONFIG_IS_ENABLED(DM_GPIO)
- static int sunxi_gpio_output(u32 pin, u32 val)
- {
--      u32 dat;
-       u32 bank = GPIO_BANK(pin);
-       u32 num = GPIO_NUM(pin);
-       void *pio = BANK_TO_GPIO(bank);
--      dat = readl(pio + 0x10);
--      if (val)
--              dat |= 0x1 << num;
--      else
--              dat &= ~(0x1 << num);
--
--      writel(dat, pio + 0x10);
--
-+      sunxi_gpio_set_output_bank(pio, val ? 0 : 1U << num,
-+                                      val ? 1U << num : 0);
-       return 0;
- }
- static int sunxi_gpio_input(u32 pin)
- {
--      u32 dat;
-       u32 bank = GPIO_BANK(pin);
-       u32 num = GPIO_NUM(pin);
-       void *pio = BANK_TO_GPIO(bank);
--      dat = readl(pio + 0x10);
--      dat >>= num;
--
--      return dat & 0x1;
-+      return (sunxi_gpio_get_output_bank(pio) >> num) & 0x1;
- }
- int gpio_request(unsigned gpio, const char *label)
-@@ -136,12 +125,8 @@ static int sunxi_gpio_get_value(struct udevice *dev, unsigned offset)
- {
-       struct sunxi_gpio_plat *plat = dev_get_plat(dev);
-       u32 num = GPIO_NUM(offset);
--      unsigned dat;
--
--      dat = readl(plat->regs + GPIO_DAT_REG_OFFSET);
--      dat >>= num;
--      return dat & 0x1;
-+      return (sunxi_gpio_get_output_bank(plat->regs) >> num) & 0x1;
- }
- static int sunxi_gpio_get_function(struct udevice *dev, unsigned offset)
-@@ -181,8 +166,7 @@ static int sunxi_gpio_set_flags(struct udevice *dev, unsigned int offset,
-               u32 value = !!(flags & GPIOD_IS_OUT_ACTIVE);
-               u32 num = GPIO_NUM(offset);
--              clrsetbits_le32(plat->regs + GPIO_DAT_REG_OFFSET,
--                              1 << num, value << num);
-+              sunxi_gpio_set_output_bank(plat->regs, 1U << num, value << num);
-               sunxi_gpio_set_cfgbank(plat->regs, offset, SUNXI_GPIO_OUTPUT);
-       } else if (flags & GPIOD_IS_IN) {
-               u32 pull = 0;
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4005-net-sun8i-emac-Add-a-flag-for-the-internal-PHY-switc.patch b/package/boot/uboot-sunxi/patches/4005-net-sun8i-emac-Add-a-flag-for-the-internal-PHY-switc.patch
new file mode 100644 (file)
index 0000000..455eccf
--- /dev/null
@@ -0,0 +1,47 @@
+From 0b22263387bb55c70fb774ea70dd386bf6228c97 Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Sun, 22 Jan 2023 16:51:04 -0600
+Subject: [PATCH 4005/4044] net: sun8i-emac: Add a flag for the internal PHY
+ switch
+
+Describe this feature instead of using the SoC ID.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
+---
+ drivers/net/sun8i_emac.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
+index f232b8f087..36cc2498b5 100644
+--- a/drivers/net/sun8i_emac.c
++++ b/drivers/net/sun8i_emac.c
+@@ -137,6 +137,7 @@ enum emac_variant_id {
+ struct emac_variant {
+       enum emac_variant_id    variant;
++      bool                    soc_has_internal_phy;
+       bool                    support_rmii;
+ };
+@@ -860,7 +861,7 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+       if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
+               return -EINVAL;
+-      if (priv->variant->variant == H3_EMAC) {
++      if (priv->variant->soc_has_internal_phy) {
+               ret = sun8i_handle_internal_phy(dev, priv);
+               if (ret)
+                       return ret;
+@@ -906,6 +907,7 @@ static const struct emac_variant emac_variant_a83t = {
+ static const struct emac_variant emac_variant_h3 = {
+       .variant                = H3_EMAC,
++      .soc_has_internal_phy   = true,
+       .support_rmii           = true,
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4005-pinctrl-sunxi-move-pinctrl-code-and-remove-GPIO_EXTR.patch b/package/boot/uboot-sunxi/patches/4005-pinctrl-sunxi-move-pinctrl-code-and-remove-GPIO_EXTR.patch
deleted file mode 100644 (file)
index 54b975f..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-From 3e291cf021a0fd248c4a4d86e8bb2b65ca1b0f5c Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Tue, 6 Sep 2022 10:36:38 +0100
-Subject: [PATCH 4005/4031] pinctrl: sunxi: move pinctrl code and remove
- GPIO_EXTRA_HEADER
-
-U-Boot's generic GPIO_EXTRA_HEADER is a convenience symbol to allow code
-to more easily include platform specific GPIO headers. This should not
-be needed in a DM world anymore, since the generic GPIO framework
-handles that nicely.
-For Allwinner boards we still need to deal with non-DM GPIO in the SPL,
-but this should become the exception, not the rule.
-
-Make this more obvious by removing the definition of GPIO_EXTRA_HEADER,
-and just force every legacy user of platform specific GPIO to include
-the new sunxi_gpio.h header explicitly. Everyone doing so should feel
-ashamed and should find a way to avoid it from now on.
-This also moves and renames the existing sunxi-specific low level
-pinctrl routines from arch/arm/mach-sunxi into board/sunxi, and the
-gpio.h header to the generic include/ directory, so the common code can
-be shared outside of arch/arm.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/Kconfig                                             | 1 -
- arch/arm/mach-sunxi/Makefile                                 | 1 -
- arch/arm/mach-sunxi/board.c                                  | 1 +
- arch/arm/mach-sunxi/dram_suniv.c                             | 2 +-
- arch/arm/mach-sunxi/spl_spi_sunxi.c                          | 1 +
- board/sunxi/Makefile                                         | 1 +
- board/sunxi/board.c                                          | 1 +
- board/sunxi/chip.c                                           | 2 +-
- arch/arm/mach-sunxi/pinmux.c => board/sunxi/pinctrl.c        | 5 ++++-
- drivers/gpio/axp_gpio.c                                      | 1 +
- drivers/gpio/sunxi_gpio.c                                    | 1 +
- drivers/i2c/sun6i_p2wi.c                                     | 2 +-
- drivers/i2c/sun8i_rsb.c                                      | 2 +-
- drivers/mmc/sunxi_mmc.c                                      | 1 +
- drivers/pinctrl/sunxi/pinctrl-sunxi.c                        | 1 +
- drivers/video/hitachi_tx18d42vm_lcd.c                        | 1 +
- drivers/video/ssd2828.c                                      | 1 -
- drivers/video/sunxi/sunxi_display.c                          | 1 +
- drivers/video/sunxi/sunxi_lcd.c                              | 1 +
- .../include/asm/arch-sunxi/gpio.h => include/sunxi_gpio.h    | 0
- 20 files changed, 19 insertions(+), 8 deletions(-)
- rename arch/arm/mach-sunxi/pinmux.c => board/sunxi/pinctrl.c (93%)
- rename arch/arm/include/asm/arch-sunxi/gpio.h => include/sunxi_gpio.h (100%)
-
-diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index d5a6d293ce..2904e91ad3 100644
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1106,7 +1106,6 @@ config ARCH_SUNXI
-       select DM_MMC if MMC
-       select DM_SCSI if SCSI
-       select DM_SERIAL
--      select GPIO_EXTRA_HEADER
-       select OF_BOARD_SETUP
-       select OF_CONTROL
-       select OF_SEPARATE
-diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
-index 58f807cb82..671211e932 100644
---- a/arch/arm/mach-sunxi/Makefile
-+++ b/arch/arm/mach-sunxi/Makefile
-@@ -10,7 +10,6 @@ obj-y        += board.o
- obj-y += clock.o
- obj-y += cpu_info.o
- obj-y += dram_helpers.o
--obj-y += pinmux.o
- obj-$(CONFIG_SUN6I_PRCM)      += prcm.o
- obj-$(CONFIG_AXP_PMIC_BUS)    += pmic_bus.o
- obj-$(CONFIG_MACH_SUNIV)      += clock_sun6i.o
-diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
-index 391a65a549..ec46ab9279 100644
---- a/arch/arm/mach-sunxi/board.c
-+++ b/arch/arm/mach-sunxi/board.c
-@@ -17,6 +17,7 @@
- #include <i2c.h>
- #include <serial.h>
- #include <spl.h>
-+#include <sunxi_gpio.h>
- #include <asm/cache.h>
- #include <asm/gpio.h>
- #include <asm/io.h>
-diff --git a/arch/arm/mach-sunxi/dram_suniv.c b/arch/arm/mach-sunxi/dram_suniv.c
-index 3aa3ce7627..9e583e1855 100644
---- a/arch/arm/mach-sunxi/dram_suniv.c
-+++ b/arch/arm/mach-sunxi/dram_suniv.c
-@@ -13,10 +13,10 @@
- #include <asm/io.h>
- #include <asm/arch/clock.h>
- #include <asm/arch/dram.h>
--#include <asm/arch/gpio.h>
- #include <linux/bitops.h>
- #include <linux/delay.h>
- #include <hang.h>
-+#include <sunxi_gpio.h>
- #define SDR_T_CAS                     (0x2)
- #define SDR_T_RAS                     (0x8)
-diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
-index 81159cfee6..c2410dd7bb 100644
---- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
-+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
-@@ -13,6 +13,7 @@
- #include <linux/bitops.h>
- #include <linux/delay.h>
- #include <linux/libfdt.h>
-+#include <sunxi_gpio.h>
- #ifdef CONFIG_SPL_OS_BOOT
- #error CONFIG_SPL_OS_BOOT is not supported yet
-diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
-index d96b7897b6..7763b032c8 100644
---- a/board/sunxi/Makefile
-+++ b/board/sunxi/Makefile
-@@ -7,6 +7,7 @@
- # (C) Copyright 2000-2003
- # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- obj-y += board.o
-+obj-y += pinctrl.o
- obj-$(CONFIG_SUN7I_GMAC)      += gmac.o
- obj-$(CONFIG_MACH_SUN4I)      += dram_sun4i_auto.o
- obj-$(CONFIG_MACH_SUN5I)      += dram_sun5i_auto.o
-diff --git a/board/sunxi/board.c b/board/sunxi/board.c
-index 9900c66ed0..661137f43c 100644
---- a/board/sunxi/board.c
-+++ b/board/sunxi/board.c
-@@ -38,6 +38,7 @@
- #include <asm/armv7.h>
- #endif
- #include <asm/gpio.h>
-+#include <sunxi_gpio.h>
- #include <asm/io.h>
- #include <u-boot/crc.h>
- #include <env_internal.h>
-diff --git a/board/sunxi/chip.c b/board/sunxi/chip.c
-index cde04bebe9..eeee6319e7 100644
---- a/board/sunxi/chip.c
-+++ b/board/sunxi/chip.c
-@@ -12,7 +12,7 @@
- #include <w1-eeprom.h>
- #include <dm/device-internal.h>
--#include <asm/arch/gpio.h>
-+#include <sunxi_gpio.h>
- #include <extension_board.h>
-diff --git a/arch/arm/mach-sunxi/pinmux.c b/board/sunxi/pinctrl.c
-similarity index 93%
-rename from arch/arm/mach-sunxi/pinmux.c
-rename to board/sunxi/pinctrl.c
-index 91acbf9269..aac37f639b 100644
---- a/arch/arm/mach-sunxi/pinmux.c
-+++ b/board/sunxi/pinctrl.c
-@@ -3,11 +3,14 @@
-  * (C) Copyright 2007-2011
-  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
-  * Tom Cubie <tangliang@allwinnertech.com>
-+ *
-+ * Low level GPIO/pin controller access functions, to be shared by non-DM
-+ * SPL code and the DM pinctrl/GPIO drivers.
-  */
- #include <common.h>
- #include <asm/io.h>
--#include <asm/arch/gpio.h>
-+#include <sunxi_gpio.h>
- void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val)
- {
-diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c
-index 35585dc8ac..14a99ce4c9 100644
---- a/drivers/gpio/axp_gpio.c
-+++ b/drivers/gpio/axp_gpio.c
-@@ -14,6 +14,7 @@
- #include <dm/lists.h>
- #include <dm/root.h>
- #include <errno.h>
-+#include <sunxi_gpio.h>
- static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
-diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
-index 767996c10f..49a6be6fd0 100644
---- a/drivers/gpio/sunxi_gpio.c
-+++ b/drivers/gpio/sunxi_gpio.c
-@@ -17,6 +17,7 @@
- #include <asm/io.h>
- #include <asm/gpio.h>
- #include <dt-bindings/gpio/gpio.h>
-+#include <sunxi_gpio.h>
- #if !CONFIG_IS_ENABLED(DM_GPIO)
- static int sunxi_gpio_output(u32 pin, u32 val)
-diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c
-index d221323295..b8e07a533c 100644
---- a/drivers/i2c/sun6i_p2wi.c
-+++ b/drivers/i2c/sun6i_p2wi.c
-@@ -20,10 +20,10 @@
- #include <errno.h>
- #include <i2c.h>
- #include <reset.h>
-+#include <sunxi_gpio.h>
- #include <time.h>
- #include <asm/io.h>
- #include <asm/arch/cpu.h>
--#include <asm/arch/gpio.h>
- #include <asm/arch/p2wi.h>
- #include <asm/arch/prcm.h>
- #include <asm/arch/sys_proto.h>
-diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c
-index 47fa05b6d1..f36f2c7afa 100644
---- a/drivers/i2c/sun8i_rsb.c
-+++ b/drivers/i2c/sun8i_rsb.c
-@@ -14,10 +14,10 @@
- #include <dm.h>
- #include <errno.h>
- #include <i2c.h>
-+#include <sunxi_gpio.h>
- #include <reset.h>
- #include <time.h>
- #include <asm/arch/cpu.h>
--#include <asm/arch/gpio.h>
- #include <asm/arch/prcm.h>
- #include <asm/arch/rsb.h>
-diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
-index 23bc7da917..03e33753fc 100644
---- a/drivers/mmc/sunxi_mmc.c
-+++ b/drivers/mmc/sunxi_mmc.c
-@@ -27,6 +27,7 @@
- #include <asm/arch/cpu.h>
- #include <asm/arch/mmc.h>
- #include <linux/delay.h>
-+#include <sunxi_gpio.h>
- #ifndef CCM_MMC_CTRL_MODE_SEL_NEW
- #define CCM_MMC_CTRL_MODE_SEL_NEW     0
-diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-index b0144edcf4..4c52e3fa74 100644
---- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-@@ -7,6 +7,7 @@
- #include <dm/pinctrl.h>
- #include <errno.h>
- #include <malloc.h>
-+#include <sunxi_gpio.h>
- #include <asm/gpio.h>
-diff --git a/drivers/video/hitachi_tx18d42vm_lcd.c b/drivers/video/hitachi_tx18d42vm_lcd.c
-index 87c4d27438..95984fe3d3 100644
---- a/drivers/video/hitachi_tx18d42vm_lcd.c
-+++ b/drivers/video/hitachi_tx18d42vm_lcd.c
-@@ -10,6 +10,7 @@
- #include <linux/delay.h>
- #include <asm/gpio.h>
-+#include <sunxi_gpio.h>
- #include <errno.h>
- /*
-diff --git a/drivers/video/ssd2828.c b/drivers/video/ssd2828.c
-index 4cdcbe7755..948f5e74d0 100644
---- a/drivers/video/ssd2828.c
-+++ b/drivers/video/ssd2828.c
-@@ -12,7 +12,6 @@
- #include <common.h>
- #include <malloc.h>
- #include <mipi_display.h>
--#include <asm/arch/gpio.h>
- #include <asm/gpio.h>
- #include <linux/delay.h>
-diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
-index 9110a48482..8da44a1bb6 100644
---- a/drivers/video/sunxi/sunxi_display.c
-+++ b/drivers/video/sunxi/sunxi_display.c
-@@ -31,6 +31,7 @@
- #include <malloc.h>
- #include <video.h>
- #include <dm/uclass-internal.h>
-+#include <sunxi_gpio.h>
- #include "../videomodes.h"
- #include "../anx9804.h"
- #include "../hitachi_tx18d42vm_lcd.h"
-diff --git a/drivers/video/sunxi/sunxi_lcd.c b/drivers/video/sunxi/sunxi_lcd.c
-index 8b9c3b2bfa..7a01cc343c 100644
---- a/drivers/video/sunxi/sunxi_lcd.c
-+++ b/drivers/video/sunxi/sunxi_lcd.c
-@@ -17,6 +17,7 @@
- #include <asm/arch/lcdc.h>
- #include <asm/global_data.h>
- #include <asm/gpio.h>
-+#include <sunxi_gpio.h>
- struct sunxi_lcd_priv {
-       struct display_timing timing;
-diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/include/sunxi_gpio.h
-similarity index 100%
-rename from arch/arm/include/asm/arch-sunxi/gpio.h
-rename to include/sunxi_gpio.h
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4006-net-sun8i-emac-Use-common-syscon-setup-for-R40.patch b/package/boot/uboot-sunxi/patches/4006-net-sun8i-emac-Use-common-syscon-setup-for-R40.patch
new file mode 100644 (file)
index 0000000..f98c35c
--- /dev/null
@@ -0,0 +1,133 @@
+From e2305bd1beef8597351e6036c7c1597c6cd5ca0d Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Sun, 22 Jan 2023 16:51:05 -0600
+Subject: [PATCH 4006/4044] net: sun8i-emac: Use common syscon setup for R40
+
+While R40 puts the EMAC syscon register at a different address from
+other variants, the relevant portion of the register's layout is the
+same. Factor out the register offset so the same code can be shared
+by all variants. This matches what the Linux driver does.
+
+This change provides two benefits beyond the simplification:
+ - R40 boards now respect the RX delays from the devicetree
+ - This resolves a warning on architectures where readl/writel
+   expect the address to have a pointer type, not phys_addr_t.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
+---
+ drivers/net/sun8i_emac.c | 32 +++++++++++++++-----------------
+ 1 file changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
+index 36cc2498b5..231aac19e3 100644
+--- a/drivers/net/sun8i_emac.c
++++ b/drivers/net/sun8i_emac.c
+@@ -137,6 +137,7 @@ enum emac_variant_id {
+ struct emac_variant {
+       enum emac_variant_id    variant;
++      uint                    syscon_offset;
+       bool                    soc_has_internal_phy;
+       bool                    support_rmii;
+ };
+@@ -168,7 +169,7 @@ struct emac_eth_dev {
+       const struct emac_variant *variant;
+       void *mac_reg;
+-      phys_addr_t sysctl_reg;
++      void *sysctl_reg;
+       struct phy_device *phydev;
+       struct mii_dev *bus;
+       struct clk tx_clk;
+@@ -323,18 +324,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+ {
+       u32 reg;
+-      if (priv->variant->variant == R40_GMAC) {
+-              /* Select RGMII for R40 */
+-              reg = readl(priv->sysctl_reg + 0x164);
+-              reg |= SC_ETCS_INT_GMII |
+-                     SC_EPIT |
+-                     (CONFIG_GMAC_TX_DELAY << SC_ETXDC_OFFSET);
+-
+-              writel(reg, priv->sysctl_reg + 0x164);
+-              return 0;
+-      }
+-
+-      reg = readl(priv->sysctl_reg + 0x30);
++      reg = readl(priv->sysctl_reg);
+       reg = sun8i_emac_set_syscon_ephy(priv, reg);
+@@ -370,7 +360,7 @@ static int sun8i_emac_set_syscon(struct sun8i_eth_pdata *pdata,
+               reg |= ((pdata->rx_delay_ps / 100) << SC_ERXDC_OFFSET)
+                        & SC_ERXDC_MASK;
+-      writel(reg, priv->sysctl_reg + 0x30);
++      writel(reg, priv->sysctl_reg);
+       return 0;
+ }
+@@ -793,6 +783,7 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+       struct sun8i_eth_pdata *sun8i_pdata = dev_get_plat(dev);
+       struct eth_pdata *pdata = &sun8i_pdata->eth_pdata;
+       struct emac_eth_dev *priv = dev_get_priv(dev);
++      phys_addr_t syscon_base;
+       const fdt32_t *reg;
+       int node = dev_of_offset(dev);
+       int offset = 0;
+@@ -838,13 +829,15 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+                     __func__);
+               return -EINVAL;
+       }
+-      priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob,
+-                                               offset, reg);
+-      if (priv->sysctl_reg == FDT_ADDR_T_NONE) {
++
++      syscon_base = fdt_translate_address((void *)gd->fdt_blob, offset, reg);
++      if (syscon_base == FDT_ADDR_T_NONE) {
+               debug("%s: Cannot find syscon base address\n", __func__);
+               return -EINVAL;
+       }
++      priv->sysctl_reg = (void *)syscon_base + priv->variant->syscon_offset;
++
+       pdata->phy_interface = -1;
+       priv->phyaddr = -1;
+       priv->use_internal_phy = false;
+@@ -903,25 +896,30 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+ static const struct emac_variant emac_variant_a83t = {
+       .variant                = A83T_EMAC,
++      .syscon_offset          = 0x30,
+ };
+ static const struct emac_variant emac_variant_h3 = {
+       .variant                = H3_EMAC,
++      .syscon_offset          = 0x30,
+       .soc_has_internal_phy   = true,
+       .support_rmii           = true,
+ };
+ static const struct emac_variant emac_variant_r40 = {
+       .variant                = R40_GMAC,
++      .syscon_offset          = 0x164,
+ };
+ static const struct emac_variant emac_variant_a64 = {
+       .variant                = A64_EMAC,
++      .syscon_offset          = 0x30,
+       .support_rmii           = true,
+ };
+ static const struct emac_variant emac_variant_h6 = {
+       .variant                = H6_EMAC,
++      .syscon_offset          = 0x30,
+       .support_rmii           = true,
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4006-pinctrl-sunxi-move-PIO_BASE-into-sunxi_gpio.h.patch b/package/boot/uboot-sunxi/patches/4006-pinctrl-sunxi-move-PIO_BASE-into-sunxi_gpio.h.patch
deleted file mode 100644 (file)
index ee932a7..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-From 69c0dbc968700d57189fd19e082f0f8a4b1df878 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Tue, 6 Sep 2022 11:50:54 +0100
-Subject: [PATCH 4006/4031] pinctrl: sunxi: move PIO_BASE into sunxi_gpio.h
-
-On the Allwinner platform we were describing a quite comprehensive
-memory map in a per-SoC header unser arch/arm.
-In the old days that was used by every driver, but nowadays it should
-only be needed by SPL drivers (not using the DT). Many addresses in
-there were never used, and some are not needed anymore.
-
-To avoid a dependency on CPU specific headers in an arch specific
-directory, move the definition of the pinctroller MMIO base address into
-the sunxi_gpio.h header, because the SPL routines for GPIO should be the
-only one needing this address.
-This is a first step towards getting rid of cpu_sun[x]i.h completely,
-and allows to remove the inclusion of that file from the sunxi_gpio.h
-header.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h     |  2 --
- arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h |  2 --
- arch/arm/include/asm/arch-sunxi/cpu_sun9i.h     |  2 --
- include/sunxi_gpio.h                            | 12 +++++++++++-
- 4 files changed, 11 insertions(+), 7 deletions(-)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
-index f7ecc790db..d6fe51f24b 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
-@@ -91,7 +91,6 @@
- #define SUNXI_CCM_BASE                        0x01c20000
- #define SUNXI_INTC_BASE                       0x01c20400
--#define SUNXI_PIO_BASE                        0x01c20800
- #define SUNXI_TIMER_BASE              0x01c20c00
- #ifndef CONFIG_SUNXI_GEN_SUN6I
- #define SUNXI_PWM_BASE                        0x01c20e00
-@@ -210,7 +209,6 @@ defined(CONFIG_MACH_SUN50I)
- #define SUNXI_R_TWI_BASE              0x01f02400
- #define SUNXI_R_UART_BASE             0x01f02800
--#define SUNXI_R_PIO_BASE              0x01f02c00
- #define SUN6I_P2WI_BASE                       0x01f03400
- #define SUNXI_RSB_BASE                        0x01f03400
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
-index d9cf8ae042..9b6bf84360 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
-@@ -22,7 +22,6 @@
- #define SUNXI_SIDC_BASE                       0x03006000
- #define SUNXI_SID_BASE                        0x03006200
- #define SUNXI_TIMER_BASE              0x03009000
--#define SUNXI_PIO_BASE                        0x0300B000
- #define SUNXI_PSI_BASE                        0x0300C000
- #define SUNXI_GIC400_BASE             0x03020000
-@@ -68,7 +67,6 @@
- #define SUNXI_R_CPUCFG_BASE           0x07000400
- #define SUNXI_PRCM_BASE                       0x07010000
- #define SUNXI_R_WDOG_BASE             0x07020400
--#define SUNXI_R_PIO_BASE              0x07022000
- #define SUNXI_R_UART_BASE             0x07080000
- #define SUNXI_R_TWI_BASE              0x07081400
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
-index 9c2d11b590..20025be231 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
-@@ -81,7 +81,6 @@
- /* APB0 Module */
- #define SUNXI_CCM_BASE                        (REGS_APB0_BASE + 0x0000)
- #define SUNXI_CCMMODULE_BASE          (REGS_APB0_BASE + 0x0400)
--#define SUNXI_PIO_BASE                        (REGS_APB0_BASE + 0x0800)
- #define SUNXI_TIMER_BASE              (REGS_APB0_BASE + 0x0C00)
- #define SUNXI_PWM_BASE                        (REGS_APB0_BASE + 0x1400)
- #define SUNXI_LRADC_BASE              (REGS_APB0_BASE + 0x1800)
-@@ -102,7 +101,6 @@
- /* RCPUS Module */
- #define SUNXI_PRCM_BASE                       (REGS_RCPUS_BASE + 0x1400)
- #define SUNXI_R_UART_BASE             (REGS_RCPUS_BASE + 0x2800)
--#define SUNXI_R_PIO_BASE              (REGS_RCPUS_BASE + 0x2c00)
- #define SUNXI_RSB_BASE                        (REGS_RCPUS_BASE + 0x3400)
- /* Misc. */
-diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
-index 42ca03d8c1..5ac476f960 100644
---- a/include/sunxi_gpio.h
-+++ b/include/sunxi_gpio.h
-@@ -9,7 +9,17 @@
- #define _SUNXI_GPIO_H
- #include <linux/types.h>
--#include <asm/arch/cpu.h>
-+
-+#if defined(CONFIG_MACH_SUN9I)
-+#define SUNXI_PIO_BASE                0x06000800
-+#define SUNXI_R_PIO_BASE      0x08002c00
-+#elif defined(CONFIG_SUN50I_GEN_H6)
-+#define SUNXI_PIO_BASE                0x0300b000
-+#define SUNXI_R_PIO_BASE      0x07022000
-+#else
-+#define SUNXI_PIO_BASE                0x01c20800
-+#define SUNXI_R_PIO_BASE      0x01f02c00
-+#endif
- /*
-  * sunxi has 9 banks of gpio, they are:
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4007-net-sun8i-emac-Remove-the-SoC-variant-ID.patch b/package/boot/uboot-sunxi/patches/4007-net-sun8i-emac-Remove-the-SoC-variant-ID.patch
new file mode 100644 (file)
index 0000000..1b63599
--- /dev/null
@@ -0,0 +1,70 @@
+From 3cfbf01d126f127aa812102f9c42f9787748cc21 Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Sun, 22 Jan 2023 16:51:06 -0600
+Subject: [PATCH 4007/4044] net: sun8i-emac: Remove the SoC variant ID
+
+Now that all differences in functionality are covered by individual
+flags, remove the enumeration of SoC variants.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
+---
+ drivers/net/sun8i_emac.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
+index 231aac19e3..04c3274fbe 100644
+--- a/drivers/net/sun8i_emac.c
++++ b/drivers/net/sun8i_emac.c
+@@ -127,16 +127,7 @@
+ DECLARE_GLOBAL_DATA_PTR;
+-enum emac_variant_id {
+-      A83T_EMAC = 1,
+-      H3_EMAC,
+-      A64_EMAC,
+-      R40_GMAC,
+-      H6_EMAC,
+-};
+-
+ struct emac_variant {
+-      enum emac_variant_id    variant;
+       uint                    syscon_offset;
+       bool                    soc_has_internal_phy;
+       bool                    support_rmii;
+@@ -895,30 +886,25 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+ }
+ static const struct emac_variant emac_variant_a83t = {
+-      .variant                = A83T_EMAC,
+       .syscon_offset          = 0x30,
+ };
+ static const struct emac_variant emac_variant_h3 = {
+-      .variant                = H3_EMAC,
+       .syscon_offset          = 0x30,
+       .soc_has_internal_phy   = true,
+       .support_rmii           = true,
+ };
+ static const struct emac_variant emac_variant_r40 = {
+-      .variant                = R40_GMAC,
+       .syscon_offset          = 0x164,
+ };
+ static const struct emac_variant emac_variant_a64 = {
+-      .variant                = A64_EMAC,
+       .syscon_offset          = 0x30,
+       .support_rmii           = true,
+ };
+ static const struct emac_variant emac_variant_h6 = {
+-      .variant                = H6_EMAC,
+       .syscon_offset          = 0x30,
+       .support_rmii           = true,
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4007-pinctrl-sunxi-add-new-D1-pinctrl-support.patch b/package/boot/uboot-sunxi/patches/4007-pinctrl-sunxi-add-new-D1-pinctrl-support.patch
deleted file mode 100644 (file)
index ca984cc..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-From 20903c89595e5ad0eb5fd91eebf0a02f6843e8a6 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Tue, 6 Sep 2022 12:12:50 +0100
-Subject: [PATCH 4007/4031] pinctrl: sunxi: add new D1 pinctrl support
-
-For the first time since at least the Allwinner A10 SoCs, the D1 (and
-related cores) use a new pincontroller MMIO register layout, so we
-cannot use our hardcoded, fixed offsets anymore.
-Ideally this would all be handled by devicetree and DM drivers, but for
-the DT-less SPL we still need the legacy interfaces.
-
-Add a new Kconfig symbol to differenciate between the two generations of
-pincontrollers, and just use that to just switch some basic symbols.
-The rest is already abstracted enough, so works out of the box.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/mach-sunxi/Kconfig |  6 ++++++
- include/sunxi_gpio.h        | 26 +++++++++++++++++++++-----
- 2 files changed, 27 insertions(+), 5 deletions(-)
-
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index d716054f72..b328ce8960 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -113,6 +113,12 @@ config SUNXI_SRAM_ADDRESS
- config SUNXI_A64_TIMER_ERRATUM
-       bool
-+config SUNXI_NEW_PINCTRL
-+      bool
-+      ---help---
-+      The Allwinner D1 and other new SoCs use a different register map
-+      for the GPIO block, which we need to know about in the SPL.
-+
- # Note only one of these may be selected at a time! But hidden choices are
- # not supported by Kconfig
- config SUNXI_GEN_SUN4I
-diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
-index 5ac476f960..2f8b220f75 100644
---- a/include/sunxi_gpio.h
-+++ b/include/sunxi_gpio.h
-@@ -68,15 +68,32 @@
- #define GPIO_DAT_REG_OFFSET   0x10
- #define GPIO_DRV_REG_OFFSET   0x14
--#define GPIO_DRV_INDEX(pin)   (((pin) & 0x1f) >> 4)
--#define GPIO_DRV_OFFSET(pin)  ((((pin) & 0x1f) & 0xf) << 1)
-+
-+/*            Newer SoCs use a slightly different register layout */
-+#ifdef CONFIG_SUNXI_NEW_PINCTRL
-+/* pin drive strength: 4 bits per pin */
-+#define GPIO_DRV_INDEX(pin)   ((pin) / 8)
-+#define GPIO_DRV_OFFSET(pin)  (((pin) % 8) * 4)
-+
-+#define GPIO_PULL_REG_OFFSET  0x24
-+
-+#define SUNXI_PINCTRL_BANK_SIZE       0x30
-+#define SUNXI_GPIO_DISABLE    0xf
-+
-+#else /* older generation pin controllers */
-+/* pin drive strength: 2 bits per pin */
-+#define GPIO_DRV_INDEX(pin)   ((pin) / 16)
-+#define GPIO_DRV_OFFSET(pin)  (((pin) % 16) * 2)
- #define GPIO_PULL_REG_OFFSET  0x1c
-+
-+#define SUNXI_PINCTRL_BANK_SIZE       0x24
-+#define SUNXI_GPIO_DISABLE    0x7
-+#endif
-+
- #define GPIO_PULL_INDEX(pin)  (((pin) & 0x1f) >> 4)
- #define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1)
--#define SUNXI_PINCTRL_BANK_SIZE 0x24
--
- static inline void* BANK_TO_GPIO(int bank)
- {
-       void *pio_base;
-@@ -132,7 +149,6 @@ enum sunxi_gpio_number {
- /* GPIO pin function config */
- #define SUNXI_GPIO_INPUT      0
- #define SUNXI_GPIO_OUTPUT     1
--#define SUNXI_GPIO_DISABLE    7
- #define SUN8I_H3_GPA_UART0    2
- #define SUN8I_H3_GPA_UART2    2
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4008-sunxi-introduce-NCAT2-generation-model.patch b/package/boot/uboot-sunxi/patches/4008-sunxi-introduce-NCAT2-generation-model.patch
deleted file mode 100644 (file)
index 0efdf41..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-From fccd059eaa3b1fa5873606ffbc700e300a4aec17 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Wed, 5 Oct 2022 17:54:19 +0100
-Subject: [PATCH 4008/4031] sunxi: introduce NCAT2 generation model
-
-Allwinner seems to typically stick to a common MMIO memory map for
-several SoCs, but from time to time does some breaking changes, which
-also introduce new generations of some peripherals. The last time this
-happened with the H6, which apart from re-organising the base addresses
-also changed the clock controller significantly. We added a
-CONFIG_SUN50I_GEN_H6 symbol back then to mark SoCs sharing those traits.
-
-Now the Allwinner D1 changes the memory map again, and also extends the
-pincontroller, among other peripherals.
-To mark this generation of SoCs, add a CONFIG_SUNXI_GEN_NCAT2 symbol,
-this name is reportedly used in the Allwinner BSP code, and prevents us
-from inventing our own name.
-
-Add this new symbol to some guards that were already checking for the H6
-generation, since many features are shared between the two (like the
-renovated clock controller).
-
-This paves the way to introduce a first user of this generation.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/include/asm/arch-sunxi/clock.h       |  2 +-
- arch/arm/include/asm/arch-sunxi/cpu.h         |  2 +
- .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h  | 54 +++++++++++++++++++
- arch/arm/include/asm/arch-sunxi/mmc.h         |  2 +-
- arch/arm/include/asm/arch-sunxi/prcm.h        |  2 +-
- arch/arm/include/asm/arch-sunxi/timer.h       |  2 +-
- arch/arm/mach-sunxi/Kconfig                   | 14 ++++-
- arch/arm/mach-sunxi/Makefile                  |  1 +
- arch/arm/mach-sunxi/board.c                   |  4 +-
- common/spl/Kconfig                            |  2 +-
- drivers/mmc/sunxi_mmc.c                       | 10 ++--
- include/sunxi_gpio.h                          |  3 ++
- 12 files changed, 86 insertions(+), 12 deletions(-)
- create mode 100644 arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-
-diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
-index 2cfd540742..3d34261b0e 100644
---- a/arch/arm/include/asm/arch-sunxi/clock.h
-+++ b/arch/arm/include/asm/arch-sunxi/clock.h
-@@ -16,7 +16,7 @@
- /* clock control module regs definition */
- #if defined(CONFIG_MACH_SUN8I_A83T)
- #include <asm/arch/clock_sun8i_a83t.h>
--#elif defined(CONFIG_SUN50I_GEN_H6)
-+#elif defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
- #include <asm/arch/clock_sun50i_h6.h>
- #elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
-       defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
-index b08f202374..768c6572d6 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
-@@ -10,6 +10,8 @@
- #include <asm/arch/cpu_sun9i.h>
- #elif defined(CONFIG_SUN50I_GEN_H6)
- #include <asm/arch/cpu_sun50i_h6.h>
-+#elif defined(CONFIG_SUNXI_GEN_NCAT2)
-+#include <asm/arch/cpu_sunxi_ncat2.h>
- #else
- #include <asm/arch/cpu_sun4i.h>
- #endif
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-new file mode 100644
-index 0000000000..13093085a5
---- /dev/null
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-@@ -0,0 +1,54 @@
-+/*
-+ * (C) Copyright 2022 Arm Limited
-+ *
-+ * SPDX-License-Identifier:   GPL-2.0+
-+ */
-+
-+#ifndef _SUNXI_CPU_SUNXI_NCAT2_H
-+#define _SUNXI_CPU_SUNXI_NCAT2_H
-+
-+#define SUNXI_SRAM_A1_BASE            CONFIG_SUNXI_SRAM_ADDRESS
-+#define SUNXI_SRAM_C_BASE             0x00028000
-+#define SUNXI_SRAM_A2_BASE            0x00100000
-+
-+#define SUNXI_SRAMC_BASE              0x02800000
-+#define SUNXI_CCM_BASE                        0x02001000
-+/* SID address space starts at 0x03006000, but e-fuse is at offset 0x200 */
-+#define SUNXI_SIDC_BASE                       0x03006000
-+#define SUNXI_SID_BASE                        0x03006200
-+#define SUNXI_TIMER_BASE              0x02050000
-+
-+#ifdef CONFIG_MACH_SUN50I_H6
-+#define SUNXI_DRAM_COM_BASE           0x04002000
-+#define SUNXI_DRAM_CTL0_BASE          0x04003000
-+#define SUNXI_DRAM_PHY0_BASE          0x04005000
-+#endif
-+#define SUNXI_MMC0_BASE                       0x04020000
-+#define SUNXI_MMC1_BASE                       0x04021000
-+#define SUNXI_MMC2_BASE                       0x04022000
-+
-+#define SUNXI_UART0_BASE              0x02500000
-+#define SUNXI_UART1_BASE              0x02500400
-+#define SUNXI_UART2_BASE              0x02500800
-+#define SUNXI_UART3_BASE              0x02500C00
-+#define SUNXI_TWI0_BASE                       0x02502000
-+#define SUNXI_TWI1_BASE                       0x02502400
-+#define SUNXI_TWI2_BASE                       0x02502800
-+#define SUNXI_TWI3_BASE                       0x02502C00
-+#define SUNXI_SPI0_BASE                       0x04025000
-+#define SUNXI_SPI1_BASE                       0x04026000
-+
-+#define SUNXI_RTC_BASE                        0x07000000
-+#define SUNXI_R_CPUCFG_BASE           0x07000400
-+#define SUNXI_PRCM_BASE                       0x07010000
-+#define SUNXI_R_WDOG_BASE             0x07020400
-+#define SUNXI_R_UART_BASE             0x07080000
-+#define SUNXI_R_TWI_BASE              0x07081400
-+
-+#ifndef __ASSEMBLY__
-+void sunxi_board_init(void);
-+void sunxi_reset(void);
-+int sunxi_get_sid(unsigned int *sid);
-+#endif
-+
-+#endif /* _SUNXI_CPU_SUNXI_NCAT2_H */
-diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
-index 5daacf10eb..8ed3e0459c 100644
---- a/arch/arm/include/asm/arch-sunxi/mmc.h
-+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
-@@ -45,7 +45,7 @@ struct sunxi_mmc {
-       u32 chda;               /* 0x90 */
-       u32 cbda;               /* 0x94 */
-       u32 res2[26];
--#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
-+#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
-       u32 res3[17];
-       u32 samp_dl;
-       u32 res4[46];
-diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h
-index 5106076f5e..c5418cfd28 100644
---- a/arch/arm/include/asm/arch-sunxi/prcm.h
-+++ b/arch/arm/include/asm/arch-sunxi/prcm.h
-@@ -9,7 +9,7 @@
- #define _SUNXI_PRCM_H
- /* prcm regs definition */
--#if defined(CONFIG_SUN50I_GEN_H6)
-+#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
- #include <asm/arch/prcm_sun50i.h>
- #else
- #include <asm/arch/prcm_sun6i.h>
-diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h
-index bb5626d893..e17db8588e 100644
---- a/arch/arm/include/asm/arch-sunxi/timer.h
-+++ b/arch/arm/include/asm/arch-sunxi/timer.h
-@@ -76,7 +76,7 @@ struct sunxi_timer_reg {
-       struct sunxi_tgp tgp[4];
-       u8 res5[8];
-       u32 cpu_cfg;
--#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
-+#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
-       u8 res3[16];
-       struct sunxi_wdog wdog[5];      /* We have 5 watchdogs */
- #endif
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index b328ce8960..057b0ccd33 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -102,7 +102,7 @@ config AXP_PMIC_BUS
- config SUNXI_SRAM_ADDRESS
-       hex
-       default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
--      default 0x20000 if SUN50I_GEN_H6
-+      default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
-       default 0x0
-       ---help---
-       Older Allwinner SoCs have their mask boot ROM mapped just below 4GB,
-@@ -144,6 +144,16 @@ config SUN50I_GEN_H6
-       Select this for sunxi SoCs which have H6 like peripherals, clocks
-       and memory map.
-+config SUNXI_GEN_NCAT2
-+      bool
-+      select FIT
-+      select SPL_LOAD_FIT
-+      select MMC_SUNXI_HAS_NEW_MODE
-+      select SUPPORT_SPL
-+      ---help---
-+      Select this for sunxi SoCs which have D1 like peripherals, clocks
-+      and memory map.
-+
- config SUNXI_DRAM_DW
-       bool
-       ---help---
-@@ -760,6 +770,7 @@ config VIDEO_SUNXI
-       depends on !MACH_SUN9I
-       depends on !MACH_SUN50I
-       depends on !SUN50I_GEN_H6
-+      depends on !SUNXI_GEN_NCAT2
-       select VIDEO
-       select DISPLAY
-       imply VIDEO_DT_SIMPLEFB
-@@ -973,6 +984,7 @@ config SPL_STACK_R_ADDR
-       default 0x2fe00000 if MACH_SUN9I
-       default 0x4fe00000 if MACH_SUN50I
-       default 0x4fe00000 if SUN50I_GEN_H6
-+      default 0x4fe00000 if SUNXI_GEN_NCAT2
- config SPL_SPI_SUNXI
-       bool "Support for SPI Flash on Allwinner SoCs in SPL"
-diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
-index 671211e932..1d4c70ec35 100644
---- a/arch/arm/mach-sunxi/Makefile
-+++ b/arch/arm/mach-sunxi/Makefile
-@@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_SUN8I)     += clock_sun6i.o
- endif
- obj-$(CONFIG_MACH_SUN9I)      += clock_sun9i.o gtbus_sun9i.o
- obj-$(CONFIG_SUN50I_GEN_H6)   += clock_sun50i_h6.o
-+obj-$(CONFIG_SUNXI_GEN_NCAT2) += clock_sun50i_h6.o
- ifndef CONFIG_ARM64
- obj-y += timer.o
- endif
-diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
-index ec46ab9279..6d96182226 100644
---- a/arch/arm/mach-sunxi/board.c
-+++ b/arch/arm/mach-sunxi/board.c
-@@ -176,7 +176,7 @@ static int gpio_init(void)
- #error Unsupported console port number. Please fix pin mux settings in board.c
- #endif
--#ifdef CONFIG_SUN50I_GEN_H6
-+#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
-       /* Update PIO power bias configuration by copy hardware detected value */
-       val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
-       writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
-@@ -481,7 +481,7 @@ void reset_cpu(void)
-               /* sun5i sometimes gets stuck without this */
-               writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
-       }
--#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
-+#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
- #if defined(CONFIG_MACH_SUN50I_H6)
-       /* WDOG is broken for some H6 rev. use the R_WDOG instead */
-       static const struct sunxi_wdog *wdog =
-diff --git a/common/spl/Kconfig b/common/spl/Kconfig
-index 3c2af453ab..06bcedca7d 100644
---- a/common/spl/Kconfig
-+++ b/common/spl/Kconfig
-@@ -265,7 +265,7 @@ config SPL_TEXT_BASE
-       default 0x402F0400 if AM33XX
-       default 0x40301350 if OMAP54XX
-       default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
--      default 0x20060 if SUN50I_GEN_H6
-+      default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
-       default 0x00060 if ARCH_SUNXI
-       default 0xfffc0000 if ARCH_ZYNQMP
-       default 0x0
-diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
-index 03e33753fc..a8e590561c 100644
---- a/drivers/mmc/sunxi_mmc.c
-+++ b/drivers/mmc/sunxi_mmc.c
-@@ -57,6 +57,7 @@ static bool sunxi_mmc_can_calibrate(void)
-       return IS_ENABLED(CONFIG_MACH_SUN50I) ||
-              IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
-              IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
-+             IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) ||
-              IS_ENABLED(CONFIG_MACH_SUN8I_R40);
- }
-@@ -191,7 +192,7 @@ static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
-       rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
-       writel(rval, &priv->reg->clkcr);
--#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
-+#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
-       /* A64 supports calibration of delays on MMC controller and we
-        * have to set delay of zero before starting calibration.
-        * Allwinner BSP driver sets a delay only in the case of
-@@ -530,7 +531,8 @@ struct mmc *sunxi_mmc_init(int sdc_no)
-       cfg->host_caps = MMC_MODE_4BIT;
-       if ((IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_MACH_SUN8I) ||
--          IS_ENABLED(CONFIG_SUN50I_GEN_H6)) && (sdc_no == 2))
-+          IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
-+          IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) && (sdc_no == 2))
-               cfg->host_caps = MMC_MODE_8BIT;
-       cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-@@ -544,7 +546,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
-       /* config ahb clock */
-       debug("init mmc %d clock and io\n", sdc_no);
--#if !defined(CONFIG_SUN50I_GEN_H6)
-+#if !defined(CONFIG_SUN50I_GEN_H6) && !defined(CONFIG_SUNXI_GEN_NCAT2)
-       setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
- #ifdef CONFIG_SUNXI_GEN_SUN6I
-@@ -619,7 +621,7 @@ static unsigned get_mclk_offset(void)
-       if (IS_ENABLED(CONFIG_MACH_SUN9I_A80))
-               return 0x410;
--      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-+      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-               return 0x830;
-       return 0x88;
-diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
-index 2f8b220f75..04d7aa3d63 100644
---- a/include/sunxi_gpio.h
-+++ b/include/sunxi_gpio.h
-@@ -16,6 +16,9 @@
- #elif defined(CONFIG_SUN50I_GEN_H6)
- #define SUNXI_PIO_BASE                0x0300b000
- #define SUNXI_R_PIO_BASE      0x07022000
-+#elif defined(CONFIG_SUNXI_GEN_NCAT2)
-+#define SUNXI_PIO_BASE                0x02000000
-+#define SUNXI_R_PIO_BASE      0
- #else
- #define SUNXI_PIO_BASE                0x01c20800
- #define SUNXI_R_PIO_BASE      0x01f02c00
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4008-sunxi-remove-CONFIG_MACPWR.patch b/package/boot/uboot-sunxi/patches/4008-sunxi-remove-CONFIG_MACPWR.patch
new file mode 100644 (file)
index 0000000..a0b4090
--- /dev/null
@@ -0,0 +1,399 @@
+From 0f7241f68bd8dc76665a050b4012e5882e7badaa Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:48 +0100
+Subject: [PATCH 4008/4044] sunxi: remove CONFIG_MACPWR
+
+The CONFIG_MACPWR Kconfig symbol is used to point to a GPIO that enables
+the power for the Ethernet "MAC" (mostly PHY, really).
+In the DT this is described with the phy-supply property in the MAC DT
+node, pointing to a (GPIO controlled) regulator. Since we need Ethernet
+only in U-Boot proper, and use a DM driver there, we should use the DT
+instead of hardcoding this.
+
+Add code to the sun8i_emac and sunxi_emac drivers to check the DT for
+that regulator and enable it, at probe time. Then drop the current code
+from board.c, which was doing that job before.
+This allows us to remove the MACPWR Kconfig definition and the respective
+values from the defconfigs.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Sam Edwards <CFSworks@gmail.com>
+---
+ arch/arm/mach-sunxi/Kconfig           |  7 -------
+ board/sunxi/board.c                   | 12 +-----------
+ configs/Bananapi_M2_Ultra_defconfig   |  1 -
+ configs/Bananapi_defconfig            |  1 -
+ configs/Bananapro_defconfig           |  1 -
+ configs/Lamobo_R1_defconfig           |  1 -
+ configs/Mele_A1000_defconfig          |  1 -
+ configs/Orangepi_defconfig            |  1 -
+ configs/Orangepi_mini_defconfig       |  1 -
+ configs/bananapi_m1_plus_defconfig    |  1 -
+ configs/bananapi_m2_plus_h3_defconfig |  1 -
+ configs/bananapi_m2_plus_h5_defconfig |  1 -
+ configs/i12-tvbox_defconfig           |  1 -
+ configs/jesurun_q5_defconfig          |  1 -
+ configs/mixtile_loftq_defconfig       |  1 -
+ configs/nanopi_m1_plus_defconfig      |  1 -
+ configs/nanopi_neo_plus2_defconfig    |  1 -
+ configs/nanopi_r1s_h5_defconfig       |  1 -
+ configs/orangepi_pc2_defconfig        |  1 -
+ configs/orangepi_plus2e_defconfig     |  1 -
+ configs/orangepi_plus_defconfig       |  1 -
+ configs/pine_h64_defconfig            |  1 -
+ configs/zeropi_defconfig              |  1 -
+ drivers/net/sun8i_emac.c              |  9 +++++++--
+ 24 files changed, 8 insertions(+), 41 deletions(-)
+
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index c78a553493..d716054f72 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -645,13 +645,6 @@ config OLD_SUNXI_KERNEL_COMPAT
+       Set this to enable various workarounds for old kernels, this results in
+       sub-optimal settings for newer kernels, only enable if needed.
+-config MACPWR
+-      string "MAC power pin"
+-      default ""
+-      help
+-        Set the pin used to power the MAC. This takes a string in the format
+-        understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
+-
+ config MMC1_PINS_PH
+       bool "Pins for mmc1 are on Port H"
+       depends on MACH_SUN4I || MACH_SUN7I || MACH_SUN8I_R40
+diff --git a/board/sunxi/board.c b/board/sunxi/board.c
+index fe0e7bc2d9..9900c66ed0 100644
+--- a/board/sunxi/board.c
++++ b/board/sunxi/board.c
+@@ -187,7 +187,7 @@ enum env_location env_get_location(enum env_operation op, int prio)
+ /* add board specific code here */
+ int board_init(void)
+ {
+-      __maybe_unused int id_pfr1, ret, macpwr_pin;
++      __maybe_unused int id_pfr1, ret;
+       gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
+@@ -224,15 +224,6 @@ int board_init(void)
+       if (ret)
+               return ret;
+-      /* strcmp() would look better, but doesn't get optimised away. */
+-      if (CONFIG_MACPWR[0]) {
+-              macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
+-              if (macpwr_pin >= 0) {
+-                      gpio_request(macpwr_pin, "macpwr");
+-                      gpio_direction_output(macpwr_pin, 1);
+-              }
+-      }
+-
+ #if CONFIG_IS_ENABLED(DM_I2C)
+       /*
+        * Temporary workaround for enabling I2C clocks until proper sunxi DM
+@@ -240,7 +231,6 @@ int board_init(void)
+        */
+       i2c_init_board();
+ #endif
+-
+       eth_init_board();
+       return 0;
+diff --git a/configs/Bananapi_M2_Ultra_defconfig b/configs/Bananapi_M2_Ultra_defconfig
+index a5fe76af56..2cc7bbbd8b 100644
+--- a/configs/Bananapi_M2_Ultra_defconfig
++++ b/configs/Bananapi_M2_Ultra_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-r40-bananapi-m2-ultra"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN8I_R40=y
+ CONFIG_DRAM_CLK=576
+-CONFIG_MACPWR="PA17"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB1_VBUS_PIN="PH23"
+ CONFIG_USB2_VBUS_PIN="PH23"
+diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig
+index 6c2a1f630e..f4910ba13a 100644
+--- a/configs/Bananapi_defconfig
++++ b/configs/Bananapi_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapi"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=432
+-CONFIG_MACPWR="PH23"
+ CONFIG_VIDEO_COMPOSITE=y
+ CONFIG_GMAC_TX_DELAY=3
+ CONFIG_AHCI=y
+diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig
+index 94fd74754e..02be8971df 100644
+--- a/configs/Bananapro_defconfig
++++ b/configs/Bananapro_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapro"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=432
+-CONFIG_MACPWR="PH23"
+ CONFIG_USB1_VBUS_PIN="PH0"
+ CONFIG_USB2_VBUS_PIN="PH1"
+ CONFIG_VIDEO_COMPOSITE=y
+diff --git a/configs/Lamobo_R1_defconfig b/configs/Lamobo_R1_defconfig
+index 9639cb6aad..66f57ab3c8 100644
+--- a/configs/Lamobo_R1_defconfig
++++ b/configs/Lamobo_R1_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-lamobo-r1"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=432
+-CONFIG_MACPWR="PH23"
+ CONFIG_GMAC_TX_DELAY=4
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/Mele_A1000_defconfig b/configs/Mele_A1000_defconfig
+index f5b6d908cd..9ac2e4839d 100644
+--- a/configs/Mele_A1000_defconfig
++++ b/configs/Mele_A1000_defconfig
+@@ -3,7 +3,6 @@ CONFIG_ARCH_SUNXI=y
+ CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-a1000"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN4I=y
+-CONFIG_MACPWR="PH15"
+ CONFIG_VIDEO_VGA=y
+ CONFIG_VIDEO_COMPOSITE=y
+ CONFIG_AHCI=y
+diff --git a/configs/Orangepi_defconfig b/configs/Orangepi_defconfig
+index c89a9a1f9d..53edf525ec 100644
+--- a/configs/Orangepi_defconfig
++++ b/configs/Orangepi_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=432
+-CONFIG_MACPWR="PH23"
+ CONFIG_USB1_VBUS_PIN="PH26"
+ CONFIG_USB2_VBUS_PIN="PH22"
+ CONFIG_VIDEO_VGA=y
+diff --git a/configs/Orangepi_mini_defconfig b/configs/Orangepi_mini_defconfig
+index fe9ce808a1..ccf3267017 100644
+--- a/configs/Orangepi_mini_defconfig
++++ b/configs/Orangepi_mini_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi-mini"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=432
+-CONFIG_MACPWR="PH23"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=3
+ CONFIG_USB1_VBUS_PIN="PH26"
+ CONFIG_USB2_VBUS_PIN="PH22"
+diff --git a/configs/bananapi_m1_plus_defconfig b/configs/bananapi_m1_plus_defconfig
+index 0fbb619d62..a432a01f6b 100644
+--- a/configs/bananapi_m1_plus_defconfig
++++ b/configs/bananapi_m1_plus_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapi-m1-plus"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=432
+-CONFIG_MACPWR="PH23"
+ CONFIG_VIDEO_COMPOSITE=y
+ CONFIG_GMAC_TX_DELAY=3
+ CONFIG_AHCI=y
+diff --git a/configs/bananapi_m2_plus_h3_defconfig b/configs/bananapi_m2_plus_h3_defconfig
+index 26ced59fb0..a8f9b5044b 100644
+--- a/configs/bananapi_m2_plus_h3_defconfig
++++ b/configs/bananapi_m2_plus_h3_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-bananapi-m2-plus"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN8I_H3=y
+ CONFIG_DRAM_CLK=672
+-CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SUN8I_EMAC=y
+diff --git a/configs/bananapi_m2_plus_h5_defconfig b/configs/bananapi_m2_plus_h5_defconfig
+index fb6c945919..1634f62619 100644
+--- a/configs/bananapi_m2_plus_h5_defconfig
++++ b/configs/bananapi_m2_plus_h5_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun50i-h5-bananapi-m2-plus"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN50I_H5=y
+ CONFIG_DRAM_CLK=672
+-CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SUN8I_EMAC=y
+diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig
+index 257dd89af4..37f0f53ae7 100644
+--- a/configs/i12-tvbox_defconfig
++++ b/configs/i12-tvbox_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-i12-tvbox"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN7I=y
+ CONFIG_DRAM_CLK=384
+-CONFIG_MACPWR="PH21"
+ CONFIG_VIDEO_COMPOSITE=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/jesurun_q5_defconfig b/configs/jesurun_q5_defconfig
+index 0ff666b2ee..c99be7cea4 100644
+--- a/configs/jesurun_q5_defconfig
++++ b/configs/jesurun_q5_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-jesurun-q5"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN4I=y
+ CONFIG_DRAM_CLK=312
+-CONFIG_MACPWR="PH19"
+ CONFIG_USB0_VBUS_PIN="PB9"
+ CONFIG_VIDEO_COMPOSITE=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig
+index 0e4cdc4467..2f92228eb7 100644
+--- a/configs/mixtile_loftq_defconfig
++++ b/configs/mixtile_loftq_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-mixtile-loftq"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN6I=y
+ CONFIG_DRAM_ZQ=251
+-CONFIG_MACPWR="PA21"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB1_VBUS_PIN="PH24"
+ CONFIG_USB2_VBUS_PIN=""
+diff --git a/configs/nanopi_m1_plus_defconfig b/configs/nanopi_m1_plus_defconfig
+index 76655d79ae..078e98b644 100644
+--- a/configs/nanopi_m1_plus_defconfig
++++ b/configs/nanopi_m1_plus_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-m1-plus"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN8I_H3=y
+ CONFIG_DRAM_CLK=408
+-CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SUN8I_EMAC=y
+diff --git a/configs/nanopi_neo_plus2_defconfig b/configs/nanopi_neo_plus2_defconfig
+index 924ff38f17..85ff31c6fe 100644
+--- a/configs/nanopi_neo_plus2_defconfig
++++ b/configs/nanopi_neo_plus2_defconfig
+@@ -6,7 +6,6 @@ CONFIG_MACH_SUN50I_H5=y
+ CONFIG_DRAM_CLK=408
+ CONFIG_DRAM_ZQ=3881977
+ # CONFIG_DRAM_ODT_EN is not set
+-CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SUN8I_EMAC=y
+diff --git a/configs/nanopi_r1s_h5_defconfig b/configs/nanopi_r1s_h5_defconfig
+index 27cf172d72..2a6f94afe4 100644
+--- a/configs/nanopi_r1s_h5_defconfig
++++ b/configs/nanopi_r1s_h5_defconfig
+@@ -6,7 +6,6 @@ CONFIG_MACH_SUN50I_H5=y
+ CONFIG_DRAM_CLK=672
+ CONFIG_DRAM_ZQ=3881977
+ # CONFIG_DRAM_ODT_EN is not set
+-CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SUN8I_EMAC=y
+diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig
+index 777af8c60e..fb6fbaf787 100644
+--- a/configs/orangepi_pc2_defconfig
++++ b/configs/orangepi_pc2_defconfig
+@@ -5,7 +5,6 @@ CONFIG_SPL=y
+ CONFIG_MACH_SUN50I_H5=y
+ CONFIG_DRAM_CLK=672
+ CONFIG_DRAM_ZQ=3881977
+-CONFIG_MACPWR="PD6"
+ CONFIG_SPL_SPI_SUNXI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/orangepi_plus2e_defconfig b/configs/orangepi_plus2e_defconfig
+index 138a6a72b8..5e2cbc48ea 100644
+--- a/configs/orangepi_plus2e_defconfig
++++ b/configs/orangepi_plus2e_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-plus2e"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN8I_H3=y
+ CONFIG_DRAM_CLK=672
+-CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_SPL_I2C=y
+diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig
+index ed585881d4..092ce77a6c 100644
+--- a/configs/orangepi_plus_defconfig
++++ b/configs/orangepi_plus_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-plus"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN8I_H3=y
+ CONFIG_DRAM_CLK=672
+-CONFIG_MACPWR="PD6"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB1_VBUS_PIN="PG13"
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
+index 6dac6098d0..4712b8e469 100644
+--- a/configs/pine_h64_defconfig
++++ b/configs/pine_h64_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun50i-h6-pine-h64"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN50I_H6=y
+ CONFIG_SUNXI_DRAM_H6_LPDDR3=y
+-CONFIG_MACPWR="PC16"
+ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB3_VBUS_PIN="PL5"
+ CONFIG_SPL_SPI_SUNXI=y
+diff --git a/configs/zeropi_defconfig b/configs/zeropi_defconfig
+index 11f3715e6d..7901bffd15 100644
+--- a/configs/zeropi_defconfig
++++ b/configs/zeropi_defconfig
+@@ -4,7 +4,6 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-zeropi"
+ CONFIG_SPL=y
+ CONFIG_MACH_SUN8I_H3=y
+ CONFIG_DRAM_CLK=408
+-CONFIG_MACPWR="PD6"
+ # CONFIG_VIDEO_DE2 is not set
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+ CONFIG_CONSOLE_MUX=y
+diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
+index 04c3274fbe..7b60a60ad5 100644
+--- a/drivers/net/sun8i_emac.c
++++ b/drivers/net/sun8i_emac.c
+@@ -29,6 +29,7 @@
+ #include <net.h>
+ #include <reset.h>
+ #include <wait_bit.h>
++#include <power/regulator.h>
+ #define MDIO_CMD_MII_BUSY             BIT(0)
+ #define MDIO_CMD_MII_WRITE            BIT(1)
+@@ -167,9 +168,8 @@ struct emac_eth_dev {
+       struct clk ephy_clk;
+       struct reset_ctl tx_rst;
+       struct reset_ctl ephy_rst;
+-#if CONFIG_IS_ENABLED(DM_GPIO)
+       struct gpio_desc reset_gpio;
+-#endif
++      struct udevice *phy_reg;
+ };
+@@ -720,6 +720,9 @@ static int sun8i_emac_eth_probe(struct udevice *dev)
+       sun8i_emac_set_syscon(sun8i_pdata, priv);
++      if (priv->phy_reg)
++              regulator_set_enable(priv->phy_reg, true);
++
+       sun8i_mdio_init(dev->name, dev);
+       priv->bus = miiphy_get_dev_by_name(dev->name);
+@@ -829,6 +832,8 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev)
+       priv->sysctl_reg = (void *)syscon_base + priv->variant->syscon_offset;
++      device_get_supply_regulator(dev, "phy-supply", &priv->phy_reg);
++
+       pdata->phy_interface = -1;
+       priv->phyaddr = -1;
+       priv->use_internal_phy = false;
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4009-pinctrl-sunxi-add-Allwinner-D1-pinctrl-description.patch b/package/boot/uboot-sunxi/patches/4009-pinctrl-sunxi-add-Allwinner-D1-pinctrl-description.patch
deleted file mode 100644 (file)
index cecf18b..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-From c02a1ec850b5ff48527776589a0407004a92a33e Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Mon, 5 Sep 2022 16:25:57 +0100
-Subject: [PATCH 4009/4031] pinctrl: sunxi: add Allwinner D1 pinctrl
- description
-
-Apart from using the new pinctrl MMIO register layout, the Allwinner D1
-and related SoCs still need to usual set of mux values hardcoded in
-U-Boot's pinctrl driver.
-Add the values we need so far to this list, so that DM based drivers
-will just work without further ado.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- drivers/pinctrl/sunxi/Kconfig         |  4 ++++
- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 28 +++++++++++++++++++++++++++
- 2 files changed, 32 insertions(+)
-
-diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
-index 77da90836b..c8f937d91e 100644
---- a/drivers/pinctrl/sunxi/Kconfig
-+++ b/drivers/pinctrl/sunxi/Kconfig
-@@ -124,4 +124,8 @@ config PINCTRL_SUN50I_H616_R
-       default MACH_SUN50I_H616
-       select PINCTRL_SUNXI
-+config PINCTRL_SUN20I_D1
-+      bool "Support for the Allwinner D1/R528 PIO"
-+      select PINCTRL_SUNXI
-+
- endif
-diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-index 4c52e3fa74..614cfe6b73 100644
---- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-@@ -735,6 +735,28 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc
-       .num_banks      = 1,
- };
-+static const struct sunxi_pinctrl_function sun20i_d1_pinctrl_functions[] = {
-+      { "emac",       8 },    /* PE0-PE15 */
-+      { "gpio_in",    0 },
-+      { "gpio_out",   1 },
-+      { "mmc0",       2 },    /* PF0-PF5 */
-+      { "mmc2",       3 },    /* PC1-PC7 */
-+      { "spi0",       2 },    /* PC2-PC7 */
-+#if IS_ENABLED(CONFIG_UART0_PORT_F)
-+      { "uart0",      3 },    /* PF2-PF4 */
-+#else
-+      { "uart0",      6 },    /* PB2-PB3 */
-+#endif
-+      { "uart3",      7 },    /* PB6-PB9 */
-+};
-+
-+static const struct sunxi_pinctrl_desc __maybe_unused sun20i_d1_pinctrl_desc = {
-+      .functions      = sun20i_d1_pinctrl_functions,
-+      .num_functions  = ARRAY_SIZE(sun20i_d1_pinctrl_functions),
-+      .first_bank     = SUNXI_GPIO_A,
-+      .num_banks      = 7,
-+};
-+
- static const struct udevice_id sunxi_pinctrl_ids[] = {
- #ifdef CONFIG_PINCTRL_SUNIV_F1C100S
-       {
-@@ -891,6 +913,12 @@ static const struct udevice_id sunxi_pinctrl_ids[] = {
-               .compatible = "allwinner,sun50i-h616-r-pinctrl",
-               .data = (ulong)&sun50i_h616_r_pinctrl_desc,
-       },
-+#endif
-+#ifdef CONFIG_PINCTRL_SUN20I_D1
-+      {
-+              .compatible = "allwinner,sun20i-d1-pinctrl",
-+              .data = (ulong)&sun20i_d1_pinctrl_desc,
-+      },
- #endif
-       {}
- };
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4009-pinctrl-sunxi-add-GPIO-in-out-wrappers.patch b/package/boot/uboot-sunxi/patches/4009-pinctrl-sunxi-add-GPIO-in-out-wrappers.patch
new file mode 100644 (file)
index 0000000..98c80df
--- /dev/null
@@ -0,0 +1,169 @@
+From 83871970cde779ab23107aa46cc840afd435314e Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:49 +0100
+Subject: [PATCH 4009/4044] pinctrl: sunxi: add GPIO in/out wrappers
+
+So far we were open-coding the pincontroller's GPIO output/input access
+in each function using that.
+
+Provide functions that wrap that nicely, and follow the existing pattern
+(set/get_{bank,}), so users don't need to know about the internals, and
+we can abstract the new D1 pinctrl more easily.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Sam Edwards <CFSworks@gmail.com>
+Tested-by: Sam Edwards <CFSworks@gmail.com>
+---
+ arch/arm/include/asm/arch-sunxi/gpio.h |  4 +++
+ arch/arm/mach-sunxi/pinmux.c           | 28 +++++++++++++++
+ drivers/gpio/sunxi_gpio.c              | 49 +++++---------------------
+ 3 files changed, 40 insertions(+), 41 deletions(-)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
+index 437e86479c..2e7c84e410 100644
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -222,6 +222,10 @@ void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
+ void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
+ int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset);
+ int sunxi_gpio_get_cfgpin(u32 pin);
++void sunxi_gpio_set_output_bank(struct sunxi_gpio *pio, int pin, bool set);
++void sunxi_gpio_set_output(u32 pin, bool set);
++int sunxi_gpio_get_output_bank(struct sunxi_gpio *pio, int pin);
++int sunxi_gpio_get_output(u32 pin);
+ void sunxi_gpio_set_drv(u32 pin, u32 val);
+ void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val);
+ void sunxi_gpio_set_pull(u32 pin, u32 val);
+diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c
+index c95fcee9f6..751cac8e09 100644
+--- a/arch/arm/mach-sunxi/pinmux.c
++++ b/arch/arm/mach-sunxi/pinmux.c
+@@ -45,6 +45,34 @@ int sunxi_gpio_get_cfgpin(u32 pin)
+       return sunxi_gpio_get_cfgbank(pio, pin);
+ }
++void sunxi_gpio_set_output_bank(struct sunxi_gpio *pio, int pin, bool set)
++{
++      u32 mask = 1U << GPIO_NUM(pin);
++
++      clrsetbits_le32(&pio->dat, set ? 0 : mask, set ? mask : 0);
++}
++
++void sunxi_gpio_set_output(u32 pin, bool set)
++{
++      u32 bank = GPIO_BANK(pin);
++      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++
++      sunxi_gpio_set_output_bank(pio, pin, set);
++}
++
++int sunxi_gpio_get_output_bank(struct sunxi_gpio *pio, int pin)
++{
++      return !!(readl(&pio->dat) & (1U << GPIO_NUM(pin)));
++}
++
++int sunxi_gpio_get_output(u32 pin)
++{
++      u32 bank = GPIO_BANK(pin);
++      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++
++      return sunxi_gpio_get_output_bank(pio, pin);
++}
++
+ void sunxi_gpio_set_drv(u32 pin, u32 val)
+ {
+       u32 bank = GPIO_BANK(pin);
+diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
+index 1e85db179a..6796375d35 100644
+--- a/drivers/gpio/sunxi_gpio.c
++++ b/drivers/gpio/sunxi_gpio.c
+@@ -19,37 +19,6 @@
+ #include <dt-bindings/gpio/gpio.h>
+ #if !CONFIG_IS_ENABLED(DM_GPIO)
+-static int sunxi_gpio_output(u32 pin, u32 val)
+-{
+-      u32 dat;
+-      u32 bank = GPIO_BANK(pin);
+-      u32 num = GPIO_NUM(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+-
+-      dat = readl(&pio->dat);
+-      if (val)
+-              dat |= 0x1 << num;
+-      else
+-              dat &= ~(0x1 << num);
+-
+-      writel(dat, &pio->dat);
+-
+-      return 0;
+-}
+-
+-static int sunxi_gpio_input(u32 pin)
+-{
+-      u32 dat;
+-      u32 bank = GPIO_BANK(pin);
+-      u32 num = GPIO_NUM(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
+-
+-      dat = readl(&pio->dat);
+-      dat >>= num;
+-
+-      return dat & 0x1;
+-}
+-
+ int gpio_request(unsigned gpio, const char *label)
+ {
+       return 0;
+@@ -70,18 +39,21 @@ int gpio_direction_input(unsigned gpio)
+ int gpio_direction_output(unsigned gpio, int value)
+ {
+       sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
++      sunxi_gpio_set_output(gpio, value);
+-      return sunxi_gpio_output(gpio, value);
++      return 0;
+ }
+ int gpio_get_value(unsigned gpio)
+ {
+-      return sunxi_gpio_input(gpio);
++      return sunxi_gpio_get_output(gpio);
+ }
+ int gpio_set_value(unsigned gpio, int value)
+ {
+-      return sunxi_gpio_output(gpio, value);
++      sunxi_gpio_set_output(gpio, value);
++
++      return 0;
+ }
+ int sunxi_name_to_gpio(const char *name)
+@@ -135,13 +107,8 @@ int sunxi_name_to_gpio(const char *name)
+ static int sunxi_gpio_get_value(struct udevice *dev, unsigned offset)
+ {
+       struct sunxi_gpio_plat *plat = dev_get_plat(dev);
+-      u32 num = GPIO_NUM(offset);
+-      unsigned dat;
+-
+-      dat = readl(&plat->regs->dat);
+-      dat >>= num;
+-      return dat & 0x1;
++      return sunxi_gpio_get_output_bank(plat->regs, offset) & 0x1;
+ }
+ static int sunxi_gpio_get_function(struct udevice *dev, unsigned offset)
+@@ -181,7 +148,7 @@ static int sunxi_gpio_set_flags(struct udevice *dev, unsigned int offset,
+               u32 value = !!(flags & GPIOD_IS_OUT_ACTIVE);
+               u32 num = GPIO_NUM(offset);
+-              clrsetbits_le32(&plat->regs->dat, 1 << num, value << num);
++              sunxi_gpio_set_output_bank(plat->regs, num, value);
+               sunxi_gpio_set_cfgbank(plat->regs, offset, SUNXI_GPIO_OUTPUT);
+       } else if (flags & GPIOD_IS_IN) {
+               u32 pull = 0;
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4010-clk-sunxi-Add-support-for-the-D1-CCU.patch b/package/boot/uboot-sunxi/patches/4010-clk-sunxi-Add-support-for-the-D1-CCU.patch
deleted file mode 100644 (file)
index b9459be..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-From 67617005348057a6546b99125d64a7dcc440901a Mon Sep 17 00:00:00 2001
-From: Samuel Holland <samuel@sholland.org>
-Date: Sat, 30 Apr 2022 22:38:37 -0500
-Subject: [PATCH 4010/4031] clk: sunxi: Add support for the D1 CCU
-
-Since the D1 CCU binding is defined, we can add support for its
-gates/resets, following the pattern of the existing drivers.
-
-Signed-off-by: Samuel Holland <samuel@sholland.org>
-Reviewed-by: Andre Przywara <andre.przywara@arm.com>
-Acked-by: Sean Anderson <seanga2@gmail.com>
----
- drivers/clk/sunxi/Kconfig                 |   6 +
- drivers/clk/sunxi/Makefile                |   1 +
- drivers/clk/sunxi/clk_d1.c                | 101 ++++++++++++++
- include/dt-bindings/clock/sun20i-d1-ccu.h | 156 ++++++++++++++++++++++
- include/dt-bindings/reset/sun20i-d1-ccu.h |  77 +++++++++++
- 5 files changed, 341 insertions(+)
- create mode 100644 drivers/clk/sunxi/clk_d1.c
- create mode 100644 include/dt-bindings/clock/sun20i-d1-ccu.h
- create mode 100644 include/dt-bindings/reset/sun20i-d1-ccu.h
-
-diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
-index bf11fad6ee..f65e482ba4 100644
---- a/drivers/clk/sunxi/Kconfig
-+++ b/drivers/clk/sunxi/Kconfig
-@@ -87,6 +87,12 @@ config CLK_SUN8I_H3
-         This enables common clock driver support for platforms based
-         on Allwinner H3/H5 SoC.
-+config CLK_SUN20I_D1
-+      bool "Clock driver for Allwinner D1"
-+      help
-+        This enables common clock driver support for platforms based
-+        on Allwinner D1 SoC.
-+
- config CLK_SUN50I_H6
-       bool "Clock driver for Allwinner H6"
-       default MACH_SUN50I_H6
-diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
-index 895da02ebe..90a277489d 100644
---- a/drivers/clk/sunxi/Makefile
-+++ b/drivers/clk/sunxi/Makefile
-@@ -19,6 +19,7 @@ obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o
- obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o
- obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o
- obj-$(CONFIG_CLK_SUN8I_H3) += clk_h3.o
-+obj-$(CONFIG_CLK_SUN20I_D1) += clk_d1.o
- obj-$(CONFIG_CLK_SUN50I_H6) += clk_h6.o
- obj-$(CONFIG_CLK_SUN50I_H6_R) += clk_h6_r.o
- obj-$(CONFIG_CLK_SUN50I_H616) += clk_h616.o
-diff --git a/drivers/clk/sunxi/clk_d1.c b/drivers/clk/sunxi/clk_d1.c
-new file mode 100644
-index 0000000000..9412b77a54
---- /dev/null
-+++ b/drivers/clk/sunxi/clk_d1.c
-@@ -0,0 +1,101 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
-+ */
-+
-+#include <common.h>
-+#include <clk-uclass.h>
-+#include <dm.h>
-+#include <errno.h>
-+#include <clk/sunxi.h>
-+#include <dt-bindings/clock/sun20i-d1-ccu.h>
-+#include <dt-bindings/reset/sun20i-d1-ccu.h>
-+#include <linux/bitops.h>
-+
-+static struct ccu_clk_gate d1_gates[] = {
-+      [CLK_BUS_MMC0]          = GATE(0x84c, BIT(0)),
-+      [CLK_BUS_MMC1]          = GATE(0x84c, BIT(1)),
-+      [CLK_BUS_MMC2]          = GATE(0x84c, BIT(2)),
-+      [CLK_BUS_UART0]         = GATE(0x90c, BIT(0)),
-+      [CLK_BUS_UART1]         = GATE(0x90c, BIT(1)),
-+      [CLK_BUS_UART2]         = GATE(0x90c, BIT(2)),
-+      [CLK_BUS_UART3]         = GATE(0x90c, BIT(3)),
-+      [CLK_BUS_UART4]         = GATE(0x90c, BIT(4)),
-+      [CLK_BUS_UART5]         = GATE(0x90c, BIT(5)),
-+      [CLK_BUS_I2C0]          = GATE(0x91c, BIT(0)),
-+      [CLK_BUS_I2C1]          = GATE(0x91c, BIT(1)),
-+      [CLK_BUS_I2C2]          = GATE(0x91c, BIT(2)),
-+      [CLK_BUS_I2C3]          = GATE(0x91c, BIT(3)),
-+      [CLK_SPI0]              = GATE(0x940, BIT(31)),
-+      [CLK_SPI1]              = GATE(0x944, BIT(31)),
-+      [CLK_BUS_SPI0]          = GATE(0x96c, BIT(0)),
-+      [CLK_BUS_SPI1]          = GATE(0x96c, BIT(1)),
-+
-+      [CLK_BUS_EMAC]          = GATE(0x97c, BIT(0)),
-+
-+      [CLK_USB_OHCI0]         = GATE(0xa70, BIT(31)),
-+      [CLK_USB_OHCI1]         = GATE(0xa74, BIT(31)),
-+      [CLK_BUS_OHCI0]         = GATE(0xa8c, BIT(0)),
-+      [CLK_BUS_OHCI1]         = GATE(0xa8c, BIT(1)),
-+      [CLK_BUS_EHCI0]         = GATE(0xa8c, BIT(4)),
-+      [CLK_BUS_EHCI1]         = GATE(0xa8c, BIT(5)),
-+      [CLK_BUS_OTG]           = GATE(0xa8c, BIT(8)),
-+      [CLK_BUS_LRADC]         = GATE(0xa9c, BIT(0)),
-+
-+      [CLK_RISCV]             = GATE(0xd04, BIT(31)),
-+};
-+
-+static struct ccu_reset d1_resets[] = {
-+      [RST_BUS_MMC0]          = RESET(0x84c, BIT(16)),
-+      [RST_BUS_MMC1]          = RESET(0x84c, BIT(17)),
-+      [RST_BUS_MMC2]          = RESET(0x84c, BIT(18)),
-+      [RST_BUS_UART0]         = RESET(0x90c, BIT(16)),
-+      [RST_BUS_UART1]         = RESET(0x90c, BIT(17)),
-+      [RST_BUS_UART2]         = RESET(0x90c, BIT(18)),
-+      [RST_BUS_UART3]         = RESET(0x90c, BIT(19)),
-+      [RST_BUS_UART4]         = RESET(0x90c, BIT(20)),
-+      [RST_BUS_UART5]         = RESET(0x90c, BIT(21)),
-+      [RST_BUS_I2C0]          = RESET(0x91c, BIT(16)),
-+      [RST_BUS_I2C1]          = RESET(0x91c, BIT(17)),
-+      [RST_BUS_I2C2]          = RESET(0x91c, BIT(18)),
-+      [RST_BUS_I2C3]          = RESET(0x91c, BIT(19)),
-+      [RST_BUS_SPI0]          = RESET(0x96c, BIT(16)),
-+      [RST_BUS_SPI1]          = RESET(0x96c, BIT(17)),
-+
-+      [RST_BUS_EMAC]          = RESET(0x97c, BIT(16)),
-+
-+      [RST_USB_PHY0]          = RESET(0xa70, BIT(30)),
-+      [RST_USB_PHY1]          = RESET(0xa74, BIT(30)),
-+      [RST_BUS_OHCI0]         = RESET(0xa8c, BIT(16)),
-+      [RST_BUS_OHCI1]         = RESET(0xa8c, BIT(17)),
-+      [RST_BUS_EHCI0]         = RESET(0xa8c, BIT(20)),
-+      [RST_BUS_EHCI1]         = RESET(0xa8c, BIT(21)),
-+      [RST_BUS_OTG]           = RESET(0xa8c, BIT(24)),
-+      [RST_BUS_LRADC]         = RESET(0xa9c, BIT(16)),
-+};
-+
-+static const struct ccu_desc d1_ccu_desc = {
-+      .gates  = d1_gates,
-+      .resets = d1_resets,
-+};
-+
-+static int d1_clk_bind(struct udevice *dev)
-+{
-+      return sunxi_reset_bind(dev, ARRAY_SIZE(d1_resets));
-+}
-+
-+static const struct udevice_id d1_ccu_ids[] = {
-+      { .compatible = "allwinner,sun20i-d1-ccu",
-+        .data = (ulong)&d1_ccu_desc },
-+      { }
-+};
-+
-+U_BOOT_DRIVER(clk_sun20i_d1) = {
-+      .name           = "sun20i_d1_ccu",
-+      .id             = UCLASS_CLK,
-+      .of_match       = d1_ccu_ids,
-+      .priv_auto      = sizeof(struct ccu_priv),
-+      .ops            = &sunxi_clk_ops,
-+      .probe          = sunxi_clk_probe,
-+      .bind           = d1_clk_bind,
-+};
-diff --git a/include/dt-bindings/clock/sun20i-d1-ccu.h b/include/dt-bindings/clock/sun20i-d1-ccu.h
-new file mode 100644
-index 0000000000..e3ac53315e
---- /dev/null
-+++ b/include/dt-bindings/clock/sun20i-d1-ccu.h
-@@ -0,0 +1,156 @@
-+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
-+/*
-+ * Copyright (C) 2020 huangzhenwei@allwinnertech.com
-+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
-+#define _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
-+
-+#define CLK_PLL_CPUX          0
-+#define CLK_PLL_DDR0          1
-+#define CLK_PLL_PERIPH0_4X    2
-+#define CLK_PLL_PERIPH0_2X    3
-+#define CLK_PLL_PERIPH0_800M  4
-+#define CLK_PLL_PERIPH0               5
-+#define CLK_PLL_PERIPH0_DIV3  6
-+#define CLK_PLL_VIDEO0_4X     7
-+#define CLK_PLL_VIDEO0_2X     8
-+#define CLK_PLL_VIDEO0                9
-+#define CLK_PLL_VIDEO1_4X     10
-+#define CLK_PLL_VIDEO1_2X     11
-+#define CLK_PLL_VIDEO1                12
-+#define CLK_PLL_VE            13
-+#define CLK_PLL_AUDIO0_4X     14
-+#define CLK_PLL_AUDIO0_2X     15
-+#define CLK_PLL_AUDIO0                16
-+#define CLK_PLL_AUDIO1                17
-+#define CLK_PLL_AUDIO1_DIV2   18
-+#define CLK_PLL_AUDIO1_DIV5   19
-+#define CLK_CPUX              20
-+#define CLK_CPUX_AXI          21
-+#define CLK_CPUX_APB          22
-+#define CLK_PSI_AHB           23
-+#define CLK_APB0              24
-+#define CLK_APB1              25
-+#define CLK_MBUS              26
-+#define CLK_DE                        27
-+#define CLK_BUS_DE            28
-+#define CLK_DI                        29
-+#define CLK_BUS_DI            30
-+#define CLK_G2D                       31
-+#define CLK_BUS_G2D           32
-+#define CLK_CE                        33
-+#define CLK_BUS_CE            34
-+#define CLK_VE                        35
-+#define CLK_BUS_VE            36
-+#define CLK_BUS_DMA           37
-+#define CLK_BUS_MSGBOX0               38
-+#define CLK_BUS_MSGBOX1               39
-+#define CLK_BUS_MSGBOX2               40
-+#define CLK_BUS_SPINLOCK      41
-+#define CLK_BUS_HSTIMER               42
-+#define CLK_AVS                       43
-+#define CLK_BUS_DBG           44
-+#define CLK_BUS_PWM           45
-+#define CLK_BUS_IOMMU         46
-+#define CLK_DRAM              47
-+#define CLK_MBUS_DMA          48
-+#define CLK_MBUS_VE           49
-+#define CLK_MBUS_CE           50
-+#define CLK_MBUS_TVIN         51
-+#define CLK_MBUS_CSI          52
-+#define CLK_MBUS_G2D          53
-+#define CLK_MBUS_RISCV                54
-+#define CLK_BUS_DRAM          55
-+#define CLK_MMC0              56
-+#define CLK_MMC1              57
-+#define CLK_MMC2              58
-+#define CLK_BUS_MMC0          59
-+#define CLK_BUS_MMC1          60
-+#define CLK_BUS_MMC2          61
-+#define CLK_BUS_UART0         62
-+#define CLK_BUS_UART1         63
-+#define CLK_BUS_UART2         64
-+#define CLK_BUS_UART3         65
-+#define CLK_BUS_UART4         66
-+#define CLK_BUS_UART5         67
-+#define CLK_BUS_I2C0          68
-+#define CLK_BUS_I2C1          69
-+#define CLK_BUS_I2C2          70
-+#define CLK_BUS_I2C3          71
-+#define CLK_SPI0              72
-+#define CLK_SPI1              73
-+#define CLK_BUS_SPI0          74
-+#define CLK_BUS_SPI1          75
-+#define CLK_EMAC_25M          76
-+#define CLK_BUS_EMAC          77
-+#define CLK_IR_TX             78
-+#define CLK_BUS_IR_TX         79
-+#define CLK_BUS_GPADC         80
-+#define CLK_BUS_THS           81
-+#define CLK_I2S0              82
-+#define CLK_I2S1              83
-+#define CLK_I2S2              84
-+#define CLK_I2S2_ASRC         85
-+#define CLK_BUS_I2S0          86
-+#define CLK_BUS_I2S1          87
-+#define CLK_BUS_I2S2          88
-+#define CLK_SPDIF_TX          89
-+#define CLK_SPDIF_RX          90
-+#define CLK_BUS_SPDIF         91
-+#define CLK_DMIC              92
-+#define CLK_BUS_DMIC          93
-+#define CLK_AUDIO_DAC         94
-+#define CLK_AUDIO_ADC         95
-+#define CLK_BUS_AUDIO         96
-+#define CLK_USB_OHCI0         97
-+#define CLK_USB_OHCI1         98
-+#define CLK_BUS_OHCI0         99
-+#define CLK_BUS_OHCI1         100
-+#define CLK_BUS_EHCI0         101
-+#define CLK_BUS_EHCI1         102
-+#define CLK_BUS_OTG           103
-+#define CLK_BUS_LRADC         104
-+#define CLK_BUS_DPSS_TOP      105
-+#define CLK_HDMI_24M          106
-+#define CLK_HDMI_CEC_32K      107
-+#define CLK_HDMI_CEC          108
-+#define CLK_BUS_HDMI          109
-+#define CLK_MIPI_DSI          110
-+#define CLK_BUS_MIPI_DSI      111
-+#define CLK_TCON_LCD0         112
-+#define CLK_BUS_TCON_LCD0     113
-+#define CLK_TCON_TV           114
-+#define CLK_BUS_TCON_TV               115
-+#define CLK_TVE                       116
-+#define CLK_BUS_TVE_TOP               117
-+#define CLK_BUS_TVE           118
-+#define CLK_TVD                       119
-+#define CLK_BUS_TVD_TOP               120
-+#define CLK_BUS_TVD           121
-+#define CLK_LEDC              122
-+#define CLK_BUS_LEDC          123
-+#define CLK_CSI_TOP           124
-+#define CLK_CSI_MCLK          125
-+#define CLK_BUS_CSI           126
-+#define CLK_TPADC             127
-+#define CLK_BUS_TPADC         128
-+#define CLK_BUS_TZMA          129
-+#define CLK_DSP                       130
-+#define CLK_BUS_DSP_CFG               131
-+#define CLK_RISCV             132
-+#define CLK_RISCV_AXI         133
-+#define CLK_BUS_RISCV_CFG     134
-+#define CLK_FANOUT_24M                135
-+#define CLK_FANOUT_12M                136
-+#define CLK_FANOUT_16M                137
-+#define CLK_FANOUT_25M                138
-+#define CLK_FANOUT_32K                139
-+#define CLK_FANOUT_27M                140
-+#define CLK_FANOUT_PCLK               141
-+#define CLK_FANOUT0           142
-+#define CLK_FANOUT1           143
-+#define CLK_FANOUT2           144
-+
-+#endif /* _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_ */
-diff --git a/include/dt-bindings/reset/sun20i-d1-ccu.h b/include/dt-bindings/reset/sun20i-d1-ccu.h
-new file mode 100644
-index 0000000000..de9ff52032
---- /dev/null
-+++ b/include/dt-bindings/reset/sun20i-d1-ccu.h
-@@ -0,0 +1,77 @@
-+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
-+/*
-+ * Copyright (c) 2020 huangzhenwei@allwinnertech.com
-+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
-+ */
-+
-+#ifndef _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
-+#define _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
-+
-+#define RST_MBUS              0
-+#define RST_BUS_DE            1
-+#define RST_BUS_DI            2
-+#define RST_BUS_G2D           3
-+#define RST_BUS_CE            4
-+#define RST_BUS_VE            5
-+#define RST_BUS_DMA           6
-+#define RST_BUS_MSGBOX0               7
-+#define RST_BUS_MSGBOX1               8
-+#define RST_BUS_MSGBOX2               9
-+#define RST_BUS_SPINLOCK      10
-+#define RST_BUS_HSTIMER               11
-+#define RST_BUS_DBG           12
-+#define RST_BUS_PWM           13
-+#define RST_BUS_DRAM          14
-+#define RST_BUS_MMC0          15
-+#define RST_BUS_MMC1          16
-+#define RST_BUS_MMC2          17
-+#define RST_BUS_UART0         18
-+#define RST_BUS_UART1         19
-+#define RST_BUS_UART2         20
-+#define RST_BUS_UART3         21
-+#define RST_BUS_UART4         22
-+#define RST_BUS_UART5         23
-+#define RST_BUS_I2C0          24
-+#define RST_BUS_I2C1          25
-+#define RST_BUS_I2C2          26
-+#define RST_BUS_I2C3          27
-+#define RST_BUS_SPI0          28
-+#define RST_BUS_SPI1          29
-+#define RST_BUS_EMAC          30
-+#define RST_BUS_IR_TX         31
-+#define RST_BUS_GPADC         32
-+#define RST_BUS_THS           33
-+#define RST_BUS_I2S0          34
-+#define RST_BUS_I2S1          35
-+#define RST_BUS_I2S2          36
-+#define RST_BUS_SPDIF         37
-+#define RST_BUS_DMIC          38
-+#define RST_BUS_AUDIO         39
-+#define RST_USB_PHY0          40
-+#define RST_USB_PHY1          41
-+#define RST_BUS_OHCI0         42
-+#define RST_BUS_OHCI1         43
-+#define RST_BUS_EHCI0         44
-+#define RST_BUS_EHCI1         45
-+#define RST_BUS_OTG           46
-+#define RST_BUS_LRADC         47
-+#define RST_BUS_DPSS_TOP      48
-+#define RST_BUS_HDMI_SUB      49
-+#define RST_BUS_HDMI_MAIN     50
-+#define RST_BUS_MIPI_DSI      51
-+#define RST_BUS_TCON_LCD0     52
-+#define RST_BUS_TCON_TV               53
-+#define RST_BUS_LVDS0         54
-+#define RST_BUS_TVE           55
-+#define RST_BUS_TVE_TOP               56
-+#define RST_BUS_TVD           57
-+#define RST_BUS_TVD_TOP               58
-+#define RST_BUS_LEDC          59
-+#define RST_BUS_CSI           60
-+#define RST_BUS_TPADC         61
-+#define RST_DSP                       62
-+#define RST_BUS_DSP_CFG               63
-+#define RST_BUS_DSP_DBG               64
-+#define RST_BUS_RISCV_CFG     65
-+
-+#endif /* _DT_BINDINGS_RST_SUN20I_D1_CCU_H_ */
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4010-pinctrl-sunxi-remove-struct-sunxi_gpio.patch b/package/boot/uboot-sunxi/patches/4010-pinctrl-sunxi-remove-struct-sunxi_gpio.patch
new file mode 100644 (file)
index 0000000..8348ace
--- /dev/null
@@ -0,0 +1,347 @@
+From d795f4442b8c044346c0a7d7acf99481f5bbc45f Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:50 +0100
+Subject: [PATCH 4010/4044] pinctrl: sunxi: remove struct sunxi_gpio
+
+So far every Allwinner SoC used the same basic pincontroller/GPIO
+register frame, and just differed by the number of implemented banks and
+pins, plus some special functionality from time to time. However the D1
+and successors use a slightly different pinctrl register layout.
+Use that opportunity to drop "struct sunxi_gpio", that described that
+MMIO frame in a C struct. That approach is somewhat frowned upon in the
+Linux world and rarely used there, though still popular with U-Boot.
+
+Switching from a C struct to a "base address plus offset" approach allows
+to switch between the two models more dynamically, without reverting to
+preprocessor macros and #ifdef's.
+
+Model the pinctrl MMIO register frame in the usual "base address +
+offset" way, and replace a hard-to-parse CPP macro with a more readable
+static function.
+All the users get converted over. There are no functional changes at
+this point, it just prepares the stages for the D1 and friends.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/include/asm/arch-sunxi/gpio.h | 67 +++++++++++---------------
+ arch/arm/mach-sunxi/pinmux.c           | 66 +++++++++++++------------
+ drivers/pinctrl/sunxi/pinctrl-sunxi.c  | 14 +++---
+ 3 files changed, 71 insertions(+), 76 deletions(-)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
+index 2e7c84e410..96a29aa023 100644
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -28,13 +28,6 @@
+ #define SUNXI_GPIO_H  7
+ #define SUNXI_GPIO_I  8
+-/*
+- * This defines the number of GPIO banks for the _main_ GPIO controller.
+- * You should fix up the padding in struct sunxi_gpio_reg below if you
+- * change this.
+- */
+-#define SUNXI_GPIO_BANKS 9
+-
+ /*
+  * sun6i/sun8i and later SoCs have an additional GPIO controller (R_PIO)
+  * at a different register offset.
+@@ -52,46 +45,42 @@
+ #define SUNXI_GPIO_M  12
+ #define SUNXI_GPIO_N  13
+-struct sunxi_gpio {
+-      u32 cfg[4];
+-      u32 dat;
+-      u32 drv[2];
+-      u32 pull[2];
+-};
+-
+-/* gpio interrupt control */
+-struct sunxi_gpio_int {
+-      u32 cfg[3];
+-      u32 ctl;
+-      u32 sta;
+-      u32 deb;                /* interrupt debounce */
+-};
+-
+-struct sunxi_gpio_reg {
+-      struct sunxi_gpio gpio_bank[SUNXI_GPIO_BANKS];
+-      u8 res[0xbc];
+-      struct sunxi_gpio_int gpio_int;
+-};
+-
+ #define SUN50I_H6_GPIO_POW_MOD_SEL    0x340
+ #define SUN50I_H6_GPIO_POW_MOD_VAL    0x348
+-#define BANK_TO_GPIO(bank)    (((bank) < SUNXI_GPIO_L) ? \
+-      &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \
+-      &((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
+-
+ #define GPIO_BANK(pin)                ((pin) >> 5)
+ #define GPIO_NUM(pin)         ((pin) & 0x1f)
++#define GPIO_CFG_REG_OFFSET   0x00
+ #define GPIO_CFG_INDEX(pin)   (((pin) & 0x1f) >> 3)
+ #define GPIO_CFG_OFFSET(pin)  ((((pin) & 0x1f) & 0x7) << 2)
++#define GPIO_DAT_REG_OFFSET   0x10
++
++#define GPIO_DRV_REG_OFFSET   0x14
+ #define GPIO_DRV_INDEX(pin)   (((pin) & 0x1f) >> 4)
+ #define GPIO_DRV_OFFSET(pin)  ((((pin) & 0x1f) & 0xf) << 1)
++#define GPIO_PULL_REG_OFFSET  0x1c
+ #define GPIO_PULL_INDEX(pin)  (((pin) & 0x1f) >> 4)
+ #define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1)
++#define SUNXI_PINCTRL_BANK_SIZE 0x24
++
++static inline void* BANK_TO_GPIO(int bank)
++{
++      void *pio_base;
++
++      if (bank < SUNXI_GPIO_L) {
++              pio_base = (void *)(uintptr_t)SUNXI_PIO_BASE;
++      } else {
++              pio_base = (void *)(uintptr_t)SUNXI_R_PIO_BASE;
++              bank -= SUNXI_GPIO_L;
++      }
++
++      return pio_base + bank * SUNXI_PINCTRL_BANK_SIZE;
++}
++
+ /* GPIO bank sizes */
+ #define SUNXI_GPIOS_PER_BANK  32
+@@ -214,22 +203,22 @@ enum sunxi_gpio_number {
+ #define SUNXI_GPIO_AXP0_GPIO_COUNT    6
+ struct sunxi_gpio_plat {
+-      struct sunxi_gpio       *regs;
++      void                    *regs;
+       char                    bank_name[3];
+ };
+-void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
++void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val);
+ void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
+-int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset);
++int sunxi_gpio_get_cfgbank(void *bank_base, int pin_offset);
+ int sunxi_gpio_get_cfgpin(u32 pin);
+-void sunxi_gpio_set_output_bank(struct sunxi_gpio *pio, int pin, bool set);
++void sunxi_gpio_set_output_bank(void *bank_base, int pin, bool set);
+ void sunxi_gpio_set_output(u32 pin, bool set);
+-int sunxi_gpio_get_output_bank(struct sunxi_gpio *pio, int pin);
++int sunxi_gpio_get_output_bank(void *bank_base, int pin);
+ int sunxi_gpio_get_output(u32 pin);
+ void sunxi_gpio_set_drv(u32 pin, u32 val);
+-void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val);
++void sunxi_gpio_set_drv_bank(void *bank_base, u32 pin_offset, u32 val);
+ void sunxi_gpio_set_pull(u32 pin, u32 val);
+-void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val);
++void sunxi_gpio_set_pull_bank(void *bank_base, int pin_offset, u32 val);
+ int sunxi_name_to_gpio(const char *name);
+ #if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
+diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c
+index 751cac8e09..17d1a7bdb9 100644
+--- a/arch/arm/mach-sunxi/pinmux.c
++++ b/arch/arm/mach-sunxi/pinmux.c
+@@ -9,29 +9,30 @@
+ #include <asm/io.h>
+ #include <asm/arch/gpio.h>
+-void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val)
++void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val)
+ {
+-      u32 index = GPIO_CFG_INDEX(bank_offset);
+-      u32 offset = GPIO_CFG_OFFSET(bank_offset);
++      u32 index = GPIO_CFG_INDEX(pin_offset);
++      u32 offset = GPIO_CFG_OFFSET(pin_offset);
+-      clrsetbits_le32(&pio->cfg[index], 0xf << offset, val << offset);
++      clrsetbits_le32(bank_base + GPIO_CFG_REG_OFFSET + index * 4,
++                      0xfU << offset, val << offset);
+ }
+ void sunxi_gpio_set_cfgpin(u32 pin, u32 val)
+ {
+       u32 bank = GPIO_BANK(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++      void *pio = BANK_TO_GPIO(bank);
+-      sunxi_gpio_set_cfgbank(pio, pin, val);
++      sunxi_gpio_set_cfgbank(pio, pin % 32, val);
+ }
+-int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset)
++int sunxi_gpio_get_cfgbank(void *bank_base, int pin_offset)
+ {
+-      u32 index = GPIO_CFG_INDEX(bank_offset);
+-      u32 offset = GPIO_CFG_OFFSET(bank_offset);
++      u32 index = GPIO_CFG_INDEX(pin_offset);
++      u32 offset = GPIO_CFG_OFFSET(pin_offset);
+       u32 cfg;
+-      cfg = readl(&pio->cfg[index]);
++      cfg = readl(bank_base + GPIO_CFG_REG_OFFSET + index * 4);
+       cfg >>= offset;
+       return cfg & 0xf;
+@@ -40,35 +41,38 @@ int sunxi_gpio_get_cfgbank(struct sunxi_gpio *pio, int bank_offset)
+ int sunxi_gpio_get_cfgpin(u32 pin)
+ {
+       u32 bank = GPIO_BANK(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++      void *bank_base = BANK_TO_GPIO(bank);
+-      return sunxi_gpio_get_cfgbank(pio, pin);
++      return sunxi_gpio_get_cfgbank(bank_base, pin % 32);
+ }
+-void sunxi_gpio_set_output_bank(struct sunxi_gpio *pio, int pin, bool set)
++void sunxi_gpio_set_output_bank(void *bank_base, int pin, bool set)
+ {
+       u32 mask = 1U << GPIO_NUM(pin);
+-      clrsetbits_le32(&pio->dat, set ? 0 : mask, set ? mask : 0);
++      clrsetbits_le32(bank_base + GPIO_DAT_REG_OFFSET,
++                      set ? 0 : mask, set ? mask : 0);
+ }
+ void sunxi_gpio_set_output(u32 pin, bool set)
+ {
+       u32 bank = GPIO_BANK(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++      void *pio = BANK_TO_GPIO(bank);
+       sunxi_gpio_set_output_bank(pio, pin, set);
+ }
+-int sunxi_gpio_get_output_bank(struct sunxi_gpio *pio, int pin)
++int sunxi_gpio_get_output_bank(void *bank_base, int pin)
+ {
+-      return !!(readl(&pio->dat) & (1U << GPIO_NUM(pin)));
++      u32 mask = 1U << GPIO_NUM(pin);
++
++      return !!(readl(bank_base + GPIO_DAT_REG_OFFSET) & mask);
+ }
+ int sunxi_gpio_get_output(u32 pin)
+ {
+       u32 bank = GPIO_BANK(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++      void *pio = BANK_TO_GPIO(bank);
+       return sunxi_gpio_get_output_bank(pio, pin);
+ }
+@@ -76,31 +80,33 @@ int sunxi_gpio_get_output(u32 pin)
+ void sunxi_gpio_set_drv(u32 pin, u32 val)
+ {
+       u32 bank = GPIO_BANK(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++      void *bank_base = BANK_TO_GPIO(bank);
+-      sunxi_gpio_set_drv_bank(pio, pin, val);
++      sunxi_gpio_set_drv_bank(bank_base, pin % 32, val);
+ }
+-void sunxi_gpio_set_drv_bank(struct sunxi_gpio *pio, u32 bank_offset, u32 val)
++void sunxi_gpio_set_drv_bank(void *bank_base, u32 pin_offset, u32 val)
+ {
+-      u32 index = GPIO_DRV_INDEX(bank_offset);
+-      u32 offset = GPIO_DRV_OFFSET(bank_offset);
++      u32 index = GPIO_DRV_INDEX(pin_offset);
++      u32 offset = GPIO_DRV_OFFSET(pin_offset);
+-      clrsetbits_le32(&pio->drv[index], 0x3 << offset, val << offset);
++      clrsetbits_le32(bank_base + GPIO_DRV_REG_OFFSET + index * 4,
++                      0x3U << offset, val << offset);
+ }
+ void sunxi_gpio_set_pull(u32 pin, u32 val)
+ {
+       u32 bank = GPIO_BANK(pin);
+-      struct sunxi_gpio *pio = BANK_TO_GPIO(bank);
++      void *bank_base = BANK_TO_GPIO(bank);
+-      sunxi_gpio_set_pull_bank(pio, pin, val);
++      sunxi_gpio_set_pull_bank(bank_base, pin % 32, val);
+ }
+-void sunxi_gpio_set_pull_bank(struct sunxi_gpio *pio, int bank_offset, u32 val)
++void sunxi_gpio_set_pull_bank(void *bank_base, int pin_offset, u32 val)
+ {
+-      u32 index = GPIO_PULL_INDEX(bank_offset);
+-      u32 offset = GPIO_PULL_OFFSET(bank_offset);
++      u32 index = GPIO_PULL_INDEX(pin_offset);
++      u32 offset = GPIO_PULL_OFFSET(pin_offset);
+-      clrsetbits_le32(&pio->pull[index], 0x3 << offset, val << offset);
++      clrsetbits_le32(bank_base + GPIO_PULL_REG_OFFSET + index * 4,
++                      0x3U << offset, val << offset);
+ }
+diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+index c4fbda7a92..b0144edcf4 100644
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -35,7 +35,7 @@ struct sunxi_pinctrl_desc {
+ };
+ struct sunxi_pinctrl_plat {
+-      struct sunxi_gpio __iomem *base;
++      void __iomem *base;
+ };
+ static int sunxi_pinctrl_get_pins_count(struct udevice *dev)
+@@ -86,8 +86,8 @@ static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector,
+             sunxi_pinctrl_get_function_name(dev, func_selector),
+             desc->functions[func_selector].mux);
+-      sunxi_gpio_set_cfgbank(plat->base + bank, pin,
+-                             desc->functions[func_selector].mux);
++      sunxi_gpio_set_cfgbank(plat->base + bank * SUNXI_PINCTRL_BANK_SIZE,
++                             pin, desc->functions[func_selector].mux);
+       return 0;
+ }
+@@ -102,7 +102,7 @@ static const struct pinconf_param sunxi_pinctrl_pinconf_params[] = {
+ static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
+                                         uint bank, uint pin, uint bias)
+ {
+-      struct sunxi_gpio *regs = &plat->base[bank];
++      void *regs = plat->base + bank * SUNXI_PINCTRL_BANK_SIZE;
+       sunxi_gpio_set_pull_bank(regs, pin, bias);
+@@ -112,7 +112,7 @@ static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
+ static int sunxi_pinctrl_pinconf_set_drive(struct sunxi_pinctrl_plat *plat,
+                                          uint bank, uint pin, uint drive)
+ {
+-      struct sunxi_gpio *regs = &plat->base[bank];
++      void *regs = plat->base + bank * SUNXI_PINCTRL_BANK_SIZE;
+       if (drive < 10 || drive > 40)
+               return -EINVAL;
+@@ -148,7 +148,7 @@ static int sunxi_pinctrl_get_pin_muxing(struct udevice *dev, uint pin_selector,
+       struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
+       int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
+       int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
+-      int mux  = sunxi_gpio_get_cfgbank(plat->base + bank, pin);
++      int mux  = sunxi_gpio_get_cfgbank(plat->base + bank * SUNXI_PINCTRL_BANK_SIZE, pin);
+       switch (mux) {
+       case SUNXI_GPIO_INPUT:
+@@ -206,7 +206,7 @@ static int sunxi_pinctrl_bind(struct udevice *dev)
+               if (!gpio_plat)
+                       return -ENOMEM;
+-              gpio_plat->regs = plat->base + i;
++              gpio_plat->regs = plat->base + i * SUNXI_PINCTRL_BANK_SIZE;
+               gpio_plat->bank_name[0] = 'P';
+               gpio_plat->bank_name[1] = 'A' + desc->first_bank + i;
+               gpio_plat->bank_name[2] = '\0';
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4011-pinctrl-sunxi-move-pinctrl-code-and-remove-GPIO_EXTR.patch b/package/boot/uboot-sunxi/patches/4011-pinctrl-sunxi-move-pinctrl-code-and-remove-GPIO_EXTR.patch
new file mode 100644 (file)
index 0000000..02ae69a
--- /dev/null
@@ -0,0 +1,307 @@
+From 0fe6de16aa4a6164cd46ec5f8993bc058567fdd1 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:51 +0100
+Subject: [PATCH 4011/4044] pinctrl: sunxi: move pinctrl code and remove
+ GPIO_EXTRA_HEADER
+
+U-Boot's generic GPIO_EXTRA_HEADER is a convenience symbol to allow code
+to more easily include platform specific GPIO headers. This should not
+be needed in a DM world anymore, since the generic GPIO framework
+handles that nicely.
+For Allwinner boards we still need to deal with non-DM GPIO in the SPL,
+but this should become the exception, not the rule.
+
+Make this more obvious by removing the definition of GPIO_EXTRA_HEADER,
+and just force every legacy user of platform specific GPIO to include
+the new sunxi_gpio.h header explicitly. Everyone doing so should feel
+ashamed and should find a way to avoid it from now on.
+This also moves and renames the existing sunxi-specific low level
+pinctrl routines from arch/arm/mach-sunxi into board/sunxi, and the
+gpio.h header to the generic include/ directory, so the common code can
+be shared outside of arch/arm.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/Kconfig                                             | 1 -
+ arch/arm/mach-sunxi/Makefile                                 | 1 -
+ arch/arm/mach-sunxi/board.c                                  | 1 +
+ arch/arm/mach-sunxi/dram_suniv.c                             | 2 +-
+ arch/arm/mach-sunxi/spl_spi_sunxi.c                          | 1 +
+ board/sunxi/Makefile                                         | 1 +
+ board/sunxi/board.c                                          | 1 +
+ board/sunxi/chip.c                                           | 2 +-
+ arch/arm/mach-sunxi/pinmux.c => board/sunxi/pinctrl.c        | 5 ++++-
+ drivers/gpio/axp_gpio.c                                      | 1 +
+ drivers/gpio/sunxi_gpio.c                                    | 1 +
+ drivers/i2c/sun6i_p2wi.c                                     | 2 +-
+ drivers/i2c/sun8i_rsb.c                                      | 2 +-
+ drivers/mmc/sunxi_mmc.c                                      | 1 +
+ drivers/pinctrl/sunxi/pinctrl-sunxi.c                        | 1 +
+ drivers/video/hitachi_tx18d42vm_lcd.c                        | 1 +
+ drivers/video/ssd2828.c                                      | 1 -
+ drivers/video/sunxi/sunxi_display.c                          | 1 +
+ drivers/video/sunxi/sunxi_lcd.c                              | 1 +
+ .../include/asm/arch-sunxi/gpio.h => include/sunxi_gpio.h    | 0
+ 20 files changed, 19 insertions(+), 8 deletions(-)
+ rename arch/arm/mach-sunxi/pinmux.c => board/sunxi/pinctrl.c (94%)
+ rename arch/arm/include/asm/arch-sunxi/gpio.h => include/sunxi_gpio.h (100%)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index d5a6d293ce..2904e91ad3 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1106,7 +1106,6 @@ config ARCH_SUNXI
+       select DM_MMC if MMC
+       select DM_SCSI if SCSI
+       select DM_SERIAL
+-      select GPIO_EXTRA_HEADER
+       select OF_BOARD_SETUP
+       select OF_CONTROL
+       select OF_SEPARATE
+diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
+index 58f807cb82..671211e932 100644
+--- a/arch/arm/mach-sunxi/Makefile
++++ b/arch/arm/mach-sunxi/Makefile
+@@ -10,7 +10,6 @@ obj-y        += board.o
+ obj-y += clock.o
+ obj-y += cpu_info.o
+ obj-y += dram_helpers.o
+-obj-y += pinmux.o
+ obj-$(CONFIG_SUN6I_PRCM)      += prcm.o
+ obj-$(CONFIG_AXP_PMIC_BUS)    += pmic_bus.o
+ obj-$(CONFIG_MACH_SUNIV)      += clock_sun6i.o
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index 391a65a549..ec46ab9279 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -17,6 +17,7 @@
+ #include <i2c.h>
+ #include <serial.h>
+ #include <spl.h>
++#include <sunxi_gpio.h>
+ #include <asm/cache.h>
+ #include <asm/gpio.h>
+ #include <asm/io.h>
+diff --git a/arch/arm/mach-sunxi/dram_suniv.c b/arch/arm/mach-sunxi/dram_suniv.c
+index 3aa3ce7627..9e583e1855 100644
+--- a/arch/arm/mach-sunxi/dram_suniv.c
++++ b/arch/arm/mach-sunxi/dram_suniv.c
+@@ -13,10 +13,10 @@
+ #include <asm/io.h>
+ #include <asm/arch/clock.h>
+ #include <asm/arch/dram.h>
+-#include <asm/arch/gpio.h>
+ #include <linux/bitops.h>
+ #include <linux/delay.h>
+ #include <hang.h>
++#include <sunxi_gpio.h>
+ #define SDR_T_CAS                     (0x2)
+ #define SDR_T_RAS                     (0x8)
+diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
+index 81159cfee6..c2410dd7bb 100644
+--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
++++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
+@@ -13,6 +13,7 @@
+ #include <linux/bitops.h>
+ #include <linux/delay.h>
+ #include <linux/libfdt.h>
++#include <sunxi_gpio.h>
+ #ifdef CONFIG_SPL_OS_BOOT
+ #error CONFIG_SPL_OS_BOOT is not supported yet
+diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
+index d96b7897b6..7763b032c8 100644
+--- a/board/sunxi/Makefile
++++ b/board/sunxi/Makefile
+@@ -7,6 +7,7 @@
+ # (C) Copyright 2000-2003
+ # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ obj-y += board.o
++obj-y += pinctrl.o
+ obj-$(CONFIG_SUN7I_GMAC)      += gmac.o
+ obj-$(CONFIG_MACH_SUN4I)      += dram_sun4i_auto.o
+ obj-$(CONFIG_MACH_SUN5I)      += dram_sun5i_auto.o
+diff --git a/board/sunxi/board.c b/board/sunxi/board.c
+index 9900c66ed0..661137f43c 100644
+--- a/board/sunxi/board.c
++++ b/board/sunxi/board.c
+@@ -38,6 +38,7 @@
+ #include <asm/armv7.h>
+ #endif
+ #include <asm/gpio.h>
++#include <sunxi_gpio.h>
+ #include <asm/io.h>
+ #include <u-boot/crc.h>
+ #include <env_internal.h>
+diff --git a/board/sunxi/chip.c b/board/sunxi/chip.c
+index cde04bebe9..eeee6319e7 100644
+--- a/board/sunxi/chip.c
++++ b/board/sunxi/chip.c
+@@ -12,7 +12,7 @@
+ #include <w1-eeprom.h>
+ #include <dm/device-internal.h>
+-#include <asm/arch/gpio.h>
++#include <sunxi_gpio.h>
+ #include <extension_board.h>
+diff --git a/arch/arm/mach-sunxi/pinmux.c b/board/sunxi/pinctrl.c
+similarity index 94%
+rename from arch/arm/mach-sunxi/pinmux.c
+rename to board/sunxi/pinctrl.c
+index 17d1a7bdb9..494d92c73b 100644
+--- a/arch/arm/mach-sunxi/pinmux.c
++++ b/board/sunxi/pinctrl.c
+@@ -3,11 +3,14 @@
+  * (C) Copyright 2007-2011
+  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+  * Tom Cubie <tangliang@allwinnertech.com>
++ *
++ * Low level GPIO/pin controller access functions, to be shared by non-DM
++ * SPL code and the DM pinctrl/GPIO drivers.
+  */
+ #include <common.h>
+ #include <asm/io.h>
+-#include <asm/arch/gpio.h>
++#include <sunxi_gpio.h>
+ void sunxi_gpio_set_cfgbank(void *bank_base, int pin_offset, u32 val)
+ {
+diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c
+index 35585dc8ac..14a99ce4c9 100644
+--- a/drivers/gpio/axp_gpio.c
++++ b/drivers/gpio/axp_gpio.c
+@@ -14,6 +14,7 @@
+ #include <dm/lists.h>
+ #include <dm/root.h>
+ #include <errno.h>
++#include <sunxi_gpio.h>
+ static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val);
+diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
+index 6796375d35..921cf43b25 100644
+--- a/drivers/gpio/sunxi_gpio.c
++++ b/drivers/gpio/sunxi_gpio.c
+@@ -17,6 +17,7 @@
+ #include <asm/io.h>
+ #include <asm/gpio.h>
+ #include <dt-bindings/gpio/gpio.h>
++#include <sunxi_gpio.h>
+ #if !CONFIG_IS_ENABLED(DM_GPIO)
+ int gpio_request(unsigned gpio, const char *label)
+diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c
+index d221323295..b8e07a533c 100644
+--- a/drivers/i2c/sun6i_p2wi.c
++++ b/drivers/i2c/sun6i_p2wi.c
+@@ -20,10 +20,10 @@
+ #include <errno.h>
+ #include <i2c.h>
+ #include <reset.h>
++#include <sunxi_gpio.h>
+ #include <time.h>
+ #include <asm/io.h>
+ #include <asm/arch/cpu.h>
+-#include <asm/arch/gpio.h>
+ #include <asm/arch/p2wi.h>
+ #include <asm/arch/prcm.h>
+ #include <asm/arch/sys_proto.h>
+diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c
+index 47fa05b6d1..f36f2c7afa 100644
+--- a/drivers/i2c/sun8i_rsb.c
++++ b/drivers/i2c/sun8i_rsb.c
+@@ -14,10 +14,10 @@
+ #include <dm.h>
+ #include <errno.h>
+ #include <i2c.h>
++#include <sunxi_gpio.h>
+ #include <reset.h>
+ #include <time.h>
+ #include <asm/arch/cpu.h>
+-#include <asm/arch/gpio.h>
+ #include <asm/arch/prcm.h>
+ #include <asm/arch/rsb.h>
+diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
+index 23bc7da917..03e33753fc 100644
+--- a/drivers/mmc/sunxi_mmc.c
++++ b/drivers/mmc/sunxi_mmc.c
+@@ -27,6 +27,7 @@
+ #include <asm/arch/cpu.h>
+ #include <asm/arch/mmc.h>
+ #include <linux/delay.h>
++#include <sunxi_gpio.h>
+ #ifndef CCM_MMC_CTRL_MODE_SEL_NEW
+ #define CCM_MMC_CTRL_MODE_SEL_NEW     0
+diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+index b0144edcf4..4c52e3fa74 100644
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -7,6 +7,7 @@
+ #include <dm/pinctrl.h>
+ #include <errno.h>
+ #include <malloc.h>
++#include <sunxi_gpio.h>
+ #include <asm/gpio.h>
+diff --git a/drivers/video/hitachi_tx18d42vm_lcd.c b/drivers/video/hitachi_tx18d42vm_lcd.c
+index 87c4d27438..95984fe3d3 100644
+--- a/drivers/video/hitachi_tx18d42vm_lcd.c
++++ b/drivers/video/hitachi_tx18d42vm_lcd.c
+@@ -10,6 +10,7 @@
+ #include <linux/delay.h>
+ #include <asm/gpio.h>
++#include <sunxi_gpio.h>
+ #include <errno.h>
+ /*
+diff --git a/drivers/video/ssd2828.c b/drivers/video/ssd2828.c
+index 4cdcbe7755..948f5e74d0 100644
+--- a/drivers/video/ssd2828.c
++++ b/drivers/video/ssd2828.c
+@@ -12,7 +12,6 @@
+ #include <common.h>
+ #include <malloc.h>
+ #include <mipi_display.h>
+-#include <asm/arch/gpio.h>
+ #include <asm/gpio.h>
+ #include <linux/delay.h>
+diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
+index 9110a48482..8da44a1bb6 100644
+--- a/drivers/video/sunxi/sunxi_display.c
++++ b/drivers/video/sunxi/sunxi_display.c
+@@ -31,6 +31,7 @@
+ #include <malloc.h>
+ #include <video.h>
+ #include <dm/uclass-internal.h>
++#include <sunxi_gpio.h>
+ #include "../videomodes.h"
+ #include "../anx9804.h"
+ #include "../hitachi_tx18d42vm_lcd.h"
+diff --git a/drivers/video/sunxi/sunxi_lcd.c b/drivers/video/sunxi/sunxi_lcd.c
+index 8b9c3b2bfa..7a01cc343c 100644
+--- a/drivers/video/sunxi/sunxi_lcd.c
++++ b/drivers/video/sunxi/sunxi_lcd.c
+@@ -17,6 +17,7 @@
+ #include <asm/arch/lcdc.h>
+ #include <asm/global_data.h>
+ #include <asm/gpio.h>
++#include <sunxi_gpio.h>
+ struct sunxi_lcd_priv {
+       struct display_timing timing;
+diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/include/sunxi_gpio.h
+similarity index 100%
+rename from arch/arm/include/asm/arch-sunxi/gpio.h
+rename to include/sunxi_gpio.h
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4011-sunxi-clock-D1-R528-Enable-PLL-LDO-during-PLL1-setup.patch b/package/boot/uboot-sunxi/patches/4011-sunxi-clock-D1-R528-Enable-PLL-LDO-during-PLL1-setup.patch
deleted file mode 100644 (file)
index 5432f78..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From 90edf658a24549c3f5c568e54caa3230890918d8 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Fri, 2 Dec 2022 20:30:40 +0000
-Subject: [PATCH 4011/4031] sunxi: clock: D1/R528: Enable PLL LDO during PLL1
- setup
-
-The D1/R528/T113s SoCs introduce a new "LDO enable" bit in the CPUX_PLL.
-Just enable that when we program that PLL.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h |  1 +
- arch/arm/mach-sunxi/clock_sun50i_h6.c             | 12 +++++++-----
- 2 files changed, 8 insertions(+), 5 deletions(-)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-index 37df4410ea..9895c2c220 100644
---- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-+++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-@@ -228,6 +228,7 @@ struct sunxi_ccm_reg {
- /* pll1 bit field */
- #define CCM_PLL1_CTRL_EN              BIT(31)
-+#define CCM_PLL1_LDO_EN                       BIT(30)
- #define CCM_PLL1_LOCK_EN              BIT(29)
- #define CCM_PLL1_LOCK                 BIT(28)
- #define CCM_PLL1_OUT_EN                       BIT(27)
-diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
-index 7926394cf7..90110eab10 100644
---- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
-+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
-@@ -86,11 +86,13 @@ void clock_set_pll1(unsigned int clk)
-       writel(val, &ccm->cpu_axi_cfg);
-       /* clk = 24*n/p, p is ignored if clock is >288MHz */
--      writel(CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2 |
--#ifdef CONFIG_MACH_SUN50I_H616
--             CCM_PLL1_OUT_EN |
--#endif
--             CCM_PLL1_CTRL_N(clk / 24000000), &ccm->pll1_cfg);
-+      val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2;
-+      val |= CCM_PLL1_CTRL_N(clk / 24000000);
-+      if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
-+             val |= CCM_PLL1_OUT_EN;
-+      if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-+             val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN;
-+      writel(val, &ccm->pll1_cfg);
-       while (!(readl(&ccm->pll1_cfg) & CCM_PLL1_LOCK)) {}
-       /* Switch CPU to PLL1 */
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4012-pinctrl-sunxi-move-PIO_BASE-into-sunxi_gpio.h.patch b/package/boot/uboot-sunxi/patches/4012-pinctrl-sunxi-move-PIO_BASE-into-sunxi_gpio.h.patch
new file mode 100644 (file)
index 0000000..dac9772
--- /dev/null
@@ -0,0 +1,113 @@
+From 9dfef76a7374b5da636a50d2a439cb1da0c43421 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:52 +0100
+Subject: [PATCH 4012/4044] pinctrl: sunxi: move PIO_BASE into sunxi_gpio.h
+
+On the Allwinner platform we were describing a quite comprehensive
+memory map in a per-SoC header unser arch/arm.
+In the old days that was used by every driver, but nowadays it should
+only be needed by SPL drivers (not using the DT). Many addresses in
+there were never used, and some are not needed anymore.
+
+To avoid a dependency on CPU specific headers in an arch specific
+directory, move the definition of the pinctroller MMIO base address into
+the sunxi_gpio.h header, because the SPL routines for GPIO should be the
+only one needing this address.
+This is a first step towards getting rid of cpu_sun[x]i.h completely,
+and allows to remove the inclusion of that file from the sunxi_gpio.h
+header.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/include/asm/arch-sunxi/cpu_sun4i.h     |  2 --
+ arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h |  2 --
+ arch/arm/include/asm/arch-sunxi/cpu_sun9i.h     |  2 --
+ include/sunxi_gpio.h                            | 12 +++++++++++-
+ 4 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+index f7ecc790db..d6fe51f24b 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+@@ -91,7 +91,6 @@
+ #define SUNXI_CCM_BASE                        0x01c20000
+ #define SUNXI_INTC_BASE                       0x01c20400
+-#define SUNXI_PIO_BASE                        0x01c20800
+ #define SUNXI_TIMER_BASE              0x01c20c00
+ #ifndef CONFIG_SUNXI_GEN_SUN6I
+ #define SUNXI_PWM_BASE                        0x01c20e00
+@@ -210,7 +209,6 @@ defined(CONFIG_MACH_SUN50I)
+ #define SUNXI_R_TWI_BASE              0x01f02400
+ #define SUNXI_R_UART_BASE             0x01f02800
+-#define SUNXI_R_PIO_BASE              0x01f02c00
+ #define SUN6I_P2WI_BASE                       0x01f03400
+ #define SUNXI_RSB_BASE                        0x01f03400
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
+index d9cf8ae042..9b6bf84360 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
+@@ -22,7 +22,6 @@
+ #define SUNXI_SIDC_BASE                       0x03006000
+ #define SUNXI_SID_BASE                        0x03006200
+ #define SUNXI_TIMER_BASE              0x03009000
+-#define SUNXI_PIO_BASE                        0x0300B000
+ #define SUNXI_PSI_BASE                        0x0300C000
+ #define SUNXI_GIC400_BASE             0x03020000
+@@ -68,7 +67,6 @@
+ #define SUNXI_R_CPUCFG_BASE           0x07000400
+ #define SUNXI_PRCM_BASE                       0x07010000
+ #define SUNXI_R_WDOG_BASE             0x07020400
+-#define SUNXI_R_PIO_BASE              0x07022000
+ #define SUNXI_R_UART_BASE             0x07080000
+ #define SUNXI_R_TWI_BASE              0x07081400
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
+index 9c2d11b590..20025be231 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
+@@ -81,7 +81,6 @@
+ /* APB0 Module */
+ #define SUNXI_CCM_BASE                        (REGS_APB0_BASE + 0x0000)
+ #define SUNXI_CCMMODULE_BASE          (REGS_APB0_BASE + 0x0400)
+-#define SUNXI_PIO_BASE                        (REGS_APB0_BASE + 0x0800)
+ #define SUNXI_TIMER_BASE              (REGS_APB0_BASE + 0x0C00)
+ #define SUNXI_PWM_BASE                        (REGS_APB0_BASE + 0x1400)
+ #define SUNXI_LRADC_BASE              (REGS_APB0_BASE + 0x1800)
+@@ -102,7 +101,6 @@
+ /* RCPUS Module */
+ #define SUNXI_PRCM_BASE                       (REGS_RCPUS_BASE + 0x1400)
+ #define SUNXI_R_UART_BASE             (REGS_RCPUS_BASE + 0x2800)
+-#define SUNXI_R_PIO_BASE              (REGS_RCPUS_BASE + 0x2c00)
+ #define SUNXI_RSB_BASE                        (REGS_RCPUS_BASE + 0x3400)
+ /* Misc. */
+diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
+index 96a29aa023..2e06745a1c 100644
+--- a/include/sunxi_gpio.h
++++ b/include/sunxi_gpio.h
+@@ -9,7 +9,17 @@
+ #define _SUNXI_GPIO_H
+ #include <linux/types.h>
+-#include <asm/arch/cpu.h>
++
++#if defined(CONFIG_MACH_SUN9I)
++#define SUNXI_PIO_BASE                0x06000800
++#define SUNXI_R_PIO_BASE      0x08002c00
++#elif defined(CONFIG_SUN50I_GEN_H6)
++#define SUNXI_PIO_BASE                0x0300b000
++#define SUNXI_R_PIO_BASE      0x07022000
++#else
++#define SUNXI_PIO_BASE                0x01c20800
++#define SUNXI_R_PIO_BASE      0x01f02c00
++#endif
+ /*
+  * sunxi has 9 banks of gpio, they are:
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4012-sunxi-clock-support-D1-R528-PLL6-clock.patch b/package/boot/uboot-sunxi/patches/4012-sunxi-clock-support-D1-R528-PLL6-clock.patch
deleted file mode 100644 (file)
index 407b1cc..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From 434dce1b0bfd9d3ab3a28352b596d27de3622796 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Fri, 2 Dec 2022 21:48:19 +0000
-Subject: [PATCH 4012/4031] sunxi: clock: support D1/R528 PLL6 clock
-
-The PLL_PERIPH0 clock changed a bit in the D1/R528/T113s SoCs: there is
-new P0 divider at bits [18:16], and the M divider is 1.
-
-Add code to support this version of "PLL6".
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- .../include/asm/arch-sunxi/clock_sun50i_h6.h  |  2 ++
- arch/arm/mach-sunxi/clock_sun50i_h6.c         | 24 +++++++++++++------
- 2 files changed, 19 insertions(+), 7 deletions(-)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-index 9895c2c220..8471e11aa0 100644
---- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-+++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-@@ -249,6 +249,8 @@ struct sunxi_ccm_reg {
- #define CCM_PLL6_CTRL_EN              BIT(31)
- #define CCM_PLL6_LOCK_EN              BIT(29)
- #define CCM_PLL6_LOCK                 BIT(28)
-+#define CCM_PLL6_CTRL_P0_SHIFT                16
-+#define CCM_PLL6_CTRL_P0_MASK         (0x7 << CCM_PLL6_CTRL_P0_SHIFT)
- #define CCM_PLL6_CTRL_N_SHIFT         8
- #define CCM_PLL6_CTRL_N_MASK          (0xff << CCM_PLL6_CTRL_N_SHIFT)
- #define CCM_PLL6_CTRL_DIV1_SHIFT      0
-diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
-index 90110eab10..607efe6a9c 100644
---- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
-+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
-@@ -107,16 +107,26 @@ unsigned int clock_get_pll6(void)
- {
-       struct sunxi_ccm_reg *const ccm =
-               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
--      int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) ? 4 : 2;
--
-       uint32_t rval = readl(&ccm->pll6_cfg);
-       int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1;
--      int div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >>
--                      CCM_PLL6_CTRL_DIV1_SHIFT) + 1;
-       int div2 = ((rval & CCM_PLL6_CTRL_DIV2_MASK) >>
--                      CCM_PLL6_CTRL_DIV2_SHIFT) + 1;
--      /* The register defines PLL6-2X or PLL6-4X, not plain PLL6 */
--      return 24000000 / m * n / div1 / div2;
-+                  CCM_PLL6_CTRL_DIV2_SHIFT) + 1;
-+      int div1, m;
-+
-+      if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) {
-+              div1 = ((rval & CCM_PLL6_CTRL_P0_MASK) >>
-+                      CCM_PLL6_CTRL_P0_SHIFT) + 1;
-+              m = 1;
-+      } else {
-+              div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >>
-+                      CCM_PLL6_CTRL_DIV1_SHIFT) + 1;
-+              if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
-+                      m = 4;
-+              else
-+                      m = 2;
-+      }
-+
-+      return 24000000U * n / m / div1 / div2;
- }
- int clock_twi_onoff(int port, int state)
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4013-Kconfig-sunxi-prepare-for-using-drivers-ram-sunxi.patch b/package/boot/uboot-sunxi/patches/4013-Kconfig-sunxi-prepare-for-using-drivers-ram-sunxi.patch
deleted file mode 100644 (file)
index 02d2004..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-From af8381ba9b63dd3e79fb874da151d56af68b7930 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Sun, 18 Dec 2022 00:12:07 +0000
-Subject: [PATCH 4013/4031] Kconfig: sunxi: prepare for using drivers/ram/sunxi
-
-At the moment all Allwinner DRAM initialisation routines are stored in
-arch/arm/mach-sunxi, even though those "drivers" are just a giant
-collection of writel's, without any architectural dependency.
-
-The R528/T113-s SoC (with ARM cores) and the D1/D1s Soc (with RISC-V
-cores) share the same die, so should share the same DRAM init routines as
-well.
-
-To prepare for this, add a new sunxi directory inside drivers/ram, and
-add some stub entries to prepare for the addition of the share DRAM code
-for those SoCs.
-
-The RISC-V D1(s) SoCs will probably use SPL_DM, so make this entry
-depend on that already.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- drivers/ram/Kconfig       |  3 ++-
- drivers/ram/sunxi/Kconfig | 13 +++++++++++++
- 2 files changed, 15 insertions(+), 1 deletion(-)
- create mode 100644 drivers/ram/sunxi/Kconfig
-
-diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
-index e085119963..d162a7f0d9 100644
---- a/drivers/ram/Kconfig
-+++ b/drivers/ram/Kconfig
-@@ -108,7 +108,8 @@ config IMXRT_SDRAM
-         This driver is for the sdram memory interface with the SEMC.
- source "drivers/ram/aspeed/Kconfig"
-+source "drivers/ram/octeon/Kconfig"
- source "drivers/ram/rockchip/Kconfig"
- source "drivers/ram/sifive/Kconfig"
- source "drivers/ram/stm32mp1/Kconfig"
--source "drivers/ram/octeon/Kconfig"
-+source "drivers/ram/sunxi/Kconfig"
-diff --git a/drivers/ram/sunxi/Kconfig b/drivers/ram/sunxi/Kconfig
-new file mode 100644
-index 0000000000..97e261de54
---- /dev/null
-+++ b/drivers/ram/sunxi/Kconfig
-@@ -0,0 +1,13 @@
-+config DRAM_SUN20I_D1
-+      bool "DM DRAM driver support for Allwinner D1"
-+      depends on RAM && ARCH_SUNXI
-+      default y
-+      help
-+        This enables support for DRAM drivers using the driver model
-+        for Allwinner SoCs.
-+
-+config DRAM_SUN8I_R528
-+      bool "DRAM driver support for Allwinner R528/T113s"
-+      default y if MACH_SUN8I_R528
-+      help
-+        Select this DRAM controller driver for the R528/T113s SoCs.
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4013-pinctrl-sunxi-add-new-D1-pinctrl-support.patch b/package/boot/uboot-sunxi/patches/4013-pinctrl-sunxi-add-new-D1-pinctrl-support.patch
new file mode 100644 (file)
index 0000000..42ccdba
--- /dev/null
@@ -0,0 +1,92 @@
+From 1a97a80f9cd80d4ba65101ceef45de7d99d5aed6 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:53 +0100
+Subject: [PATCH 4013/4044] pinctrl: sunxi: add new D1 pinctrl support
+
+For the first time since at least the Allwinner A10 SoCs, the D1 (and
+related cores) use a new pincontroller MMIO register layout, so we
+cannot use our hardcoded, fixed offsets anymore.
+Ideally this would all be handled by devicetree and DM drivers, but for
+the DT-less SPL we still need the legacy interfaces.
+
+Add a new Kconfig symbol to differenciate between the two generations of
+pincontrollers, and just use that to just switch some basic symbols.
+The rest is already abstracted enough, so works out of the box.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Sam Edwards <CFSworks@gmail.com>
+Tested-by: Sam Edwards <CFSworks@gmail.com>
+---
+ arch/arm/mach-sunxi/Kconfig |  6 ++++++
+ include/sunxi_gpio.h        | 26 +++++++++++++++++++++-----
+ 2 files changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index d716054f72..b328ce8960 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -113,6 +113,12 @@ config SUNXI_SRAM_ADDRESS
+ config SUNXI_A64_TIMER_ERRATUM
+       bool
++config SUNXI_NEW_PINCTRL
++      bool
++      ---help---
++      The Allwinner D1 and other new SoCs use a different register map
++      for the GPIO block, which we need to know about in the SPL.
++
+ # Note only one of these may be selected at a time! But hidden choices are
+ # not supported by Kconfig
+ config SUNXI_GEN_SUN4I
+diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
+index 2e06745a1c..61978db6db 100644
+--- a/include/sunxi_gpio.h
++++ b/include/sunxi_gpio.h
+@@ -68,15 +68,32 @@
+ #define GPIO_DAT_REG_OFFSET   0x10
+ #define GPIO_DRV_REG_OFFSET   0x14
+-#define GPIO_DRV_INDEX(pin)   (((pin) & 0x1f) >> 4)
+-#define GPIO_DRV_OFFSET(pin)  ((((pin) & 0x1f) & 0xf) << 1)
++
++/*            Newer SoCs use a slightly different register layout */
++#ifdef CONFIG_SUNXI_NEW_PINCTRL
++/* pin drive strength: 4 bits per pin */
++#define GPIO_DRV_INDEX(pin)   ((pin) / 8)
++#define GPIO_DRV_OFFSET(pin)  (((pin) % 8) * 4)
++
++#define GPIO_PULL_REG_OFFSET  0x24
++
++#define SUNXI_PINCTRL_BANK_SIZE       0x30
++#define SUNXI_GPIO_DISABLE    0xf
++
++#else /* older generation pin controllers */
++/* pin drive strength: 2 bits per pin */
++#define GPIO_DRV_INDEX(pin)   ((pin) / 16)
++#define GPIO_DRV_OFFSET(pin)  (((pin) % 16) * 2)
+ #define GPIO_PULL_REG_OFFSET  0x1c
++
++#define SUNXI_PINCTRL_BANK_SIZE       0x24
++#define SUNXI_GPIO_DISABLE    0x7
++#endif
++
+ #define GPIO_PULL_INDEX(pin)  (((pin) & 0x1f) >> 4)
+ #define GPIO_PULL_OFFSET(pin) ((((pin) & 0x1f) & 0xf) << 1)
+-#define SUNXI_PINCTRL_BANK_SIZE 0x24
+-
+ static inline void* BANK_TO_GPIO(int bank)
+ {
+       void *pio_base;
+@@ -132,7 +149,6 @@ enum sunxi_gpio_number {
+ /* GPIO pin function config */
+ #define SUNXI_GPIO_INPUT      0
+ #define SUNXI_GPIO_OUTPUT     1
+-#define SUNXI_GPIO_DISABLE    7
+ #define SUN8I_H3_GPA_UART0    2
+ #define SUN8I_H3_GPA_UART2    2
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4014-sunxi-add-R528-T113-s3-D1-s-DRAM-initialisation-code.patch b/package/boot/uboot-sunxi/patches/4014-sunxi-add-R528-T113-s3-D1-s-DRAM-initialisation-code.patch
deleted file mode 100644 (file)
index f65074d..0000000
+++ /dev/null
@@ -1,1642 +0,0 @@
-From 6da5b94e68464980cb4e3425746d8b3b24590709 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Sat, 31 Dec 2022 18:38:21 +0000
-Subject: [PATCH 4014/4031] sunxi: add R528/T113-s3/D1(s) DRAM initialisation
- code
-
-The Allwinner R528/T113-s/D1/D1s SoCs all share the same die, so use the
-same DRAM initialisation code.
-Make use of prior art here and lift some code from awboot[1], which
-carried init code based on earlier decompilation efforts, but with a
-GPL2 license tag.
-This code has been heavily reworked and cleaned up, to match previous
-DRAM routines for other SoCs, and also to be closer to U-Boot's coding
-style and support routines.
-The actual DRAM chip timing parameters are included in the main file,
-since they cover all DRAM types, and are protected by a new Kconfig
-CONFIG_SUNXI_DRAM_TYPE symbol, which allows the compiler to pick only
-the relevant settings, at build time.
-
-The relevant DRAM chips/board specific configuration parameters are
-delivered via Kconfig, so this code here should work for all supported
-SoCs and DRAM chips combinations.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- drivers/Makefile                   |    1 +
- drivers/ram/Makefile               |    2 +
- drivers/ram/sunxi/Kconfig          |   55 ++
- drivers/ram/sunxi/Makefile         |    4 +
- drivers/ram/sunxi/dram_sun20i_d1.c | 1425 ++++++++++++++++++++++++++++
- drivers/ram/sunxi/dram_sun20i_d1.h |   70 ++
- 6 files changed, 1557 insertions(+)
- create mode 100644 drivers/ram/sunxi/Makefile
- create mode 100644 drivers/ram/sunxi/dram_sun20i_d1.c
- create mode 100644 drivers/ram/sunxi/dram_sun20i_d1.h
-
-diff --git a/drivers/Makefile b/drivers/Makefile
-index 15d19d0c8a..1542ce7caf 100644
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -52,6 +52,7 @@ obj-$(CONFIG_$(SPL_)ALTERA_SDRAM) += ddr/altera/
- obj-$(CONFIG_ARCH_IMX8M) += ddr/imx/imx8m/
- obj-$(CONFIG_IMX8ULP_DRAM) += ddr/imx/imx8ulp/
- obj-$(CONFIG_ARCH_IMX9) += ddr/imx/imx9/
-+obj-$(CONFIG_DRAM_SUN8I_R528) += ram/
- obj-$(CONFIG_SPL_DM_RESET) += reset/
- obj-$(CONFIG_SPL_MUSB_NEW) += usb/musb-new/
- obj-$(CONFIG_SPL_USB_GADGET) += usb/gadget/
-diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
-index 83948e2c43..050c11e840 100644
---- a/drivers/ram/Makefile
-+++ b/drivers/ram/Makefile
-@@ -21,4 +21,6 @@ obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o
- obj-$(CONFIG_RAM_SIFIVE) += sifive/
-+obj-$(CONFIG_DRAM_SUN8I_R528) += sunxi/
-+
- obj-$(CONFIG_ARCH_OCTEON) += octeon/
-diff --git a/drivers/ram/sunxi/Kconfig b/drivers/ram/sunxi/Kconfig
-index 97e261de54..36875ddf22 100644
---- a/drivers/ram/sunxi/Kconfig
-+++ b/drivers/ram/sunxi/Kconfig
-@@ -11,3 +11,58 @@ config DRAM_SUN8I_R528
-       default y if MACH_SUN8I_R528
-       help
-         Select this DRAM controller driver for the R528/T113s SoCs.
-+
-+config DRAM_SUNXI_ODT_EN
-+      hex "DRAM ODT EN parameter"
-+      default 0x1
-+      help
-+        ODT EN value from vendor DRAM settings.
-+
-+config DRAM_SUNXI_TPR0
-+      hex "DRAM TPR0 parameter"
-+      default 0x0
-+      help
-+        TPR0 value from vendor DRAM settings.
-+
-+config DRAM_SUNXI_TPR11
-+      hex "DRAM TPR11 parameter"
-+      default 0x0
-+      help
-+        TPR11 value from vendor DRAM settings.
-+
-+config DRAM_SUNXI_TPR12
-+      hex "DRAM TPR12 parameter"
-+      default 0x0
-+      help
-+        TPR12 value from vendor DRAM settings.
-+
-+config DRAM_SUNXI_TPR13
-+      hex "DRAM TPR13 parameter"
-+      default 0x0
-+      help
-+        TPR13 value from vendor DRAM settings. It tells which features
-+        should be configured.
-+
-+choice
-+      prompt "DRAM chip type"
-+      default SUNXI_DRAM_DDR3 if DRAM_SUN8I_R528 || DRAM_SUN20I_D1
-+
-+config SUNXI_DRAM_DDR2
-+        bool "DDR2 chips"
-+
-+config SUNXI_DRAM_DDR3
-+        bool "DDR3 chips"
-+
-+config SUNXI_DRAM_LPDDR2
-+        bool "LPDDR2 chips"
-+
-+config SUNXI_DRAM_LPDDR3
-+        bool "LPDDR3 chips"
-+endchoice
-+
-+config SUNXI_DRAM_TYPE
-+      int
-+      default 2 if SUNXI_DRAM_DDR2
-+      default 3 if SUNXI_DRAM_DDR3
-+      default 6 if SUNXI_DRAM_LPDDR2
-+      default 7 if SUNXI_DRAM_LPDDR3
-diff --git a/drivers/ram/sunxi/Makefile b/drivers/ram/sunxi/Makefile
-new file mode 100644
-index 0000000000..d6fb2cf0b6
---- /dev/null
-+++ b/drivers/ram/sunxi/Makefile
-@@ -0,0 +1,4 @@
-+# SPDX-License-Identifier: GPL-2.0+
-+
-+obj-$(CONFIG_DRAM_SUN20I_D1) += dram_sun20i_d1.o
-+obj-$(CONFIG_DRAM_SUN8I_R528) += dram_sun20i_d1.o
-diff --git a/drivers/ram/sunxi/dram_sun20i_d1.c b/drivers/ram/sunxi/dram_sun20i_d1.c
-new file mode 100644
-index 0000000000..25005ceefb
---- /dev/null
-+++ b/drivers/ram/sunxi/dram_sun20i_d1.c
-@@ -0,0 +1,1425 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Allwinner D1/D1s/R528/T113-sx DRAM initialisation
-+ *
-+ * As usual there is no documentation for the memory controller or PHY IP
-+ * used here. The baseline of this code was lifted from awboot[1], which
-+ * seems to be based on some form of de-compilation of some original Allwinner
-+ * code bits (with a GPL2 license tag from the very beginning).
-+ * This version here is a reworked version, to match the U-Boot coding style
-+ * and style of the other Allwinner DRAM drivers.
-+ *
-+ * [1] https://github.com/szemzoa/awboot.git
-+ */
-+
-+#include <asm/io.h>
-+#include <common.h>
-+#ifdef CONFIG_RAM
-+  #include <dm.h>
-+  #include <ram.h>
-+#endif
-+#include <linux/delay.h>
-+
-+#include "dram_sun20i_d1.h"
-+
-+#ifndef SUNXI_SID_BASE
-+#define SUNXI_SID_BASE        0x3006200
-+#endif
-+
-+static void sid_read_ldoB_cal(dram_para_t *para)
-+{
-+      uint32_t reg;
-+
-+      reg = (readl(SUNXI_SID_BASE + 0x1c) & 0xff00) >> 8;
-+
-+      if (reg == 0)
-+              return;
-+
-+      switch (para->dram_type) {
-+      case SUNXI_DRAM_TYPE_DDR2:
-+              break;
-+      case SUNXI_DRAM_TYPE_DDR3:
-+              if (reg > 0x20)
-+                      reg -= 0x16;
-+              break;
-+      default:
-+              reg = 0;
-+              break;
-+      }
-+
-+      clrsetbits_le32(0x3000150, 0xff00, reg << 8);
-+}
-+
-+static void dram_voltage_set(dram_para_t *para)
-+{
-+      int vol;
-+
-+      switch (para->dram_type) {
-+      case SUNXI_DRAM_TYPE_DDR2:
-+              vol = 47;
-+              break;
-+      case SUNXI_DRAM_TYPE_DDR3:
-+              vol = 25;
-+              break;
-+      default:
-+              vol = 0;
-+              break;
-+      }
-+
-+      clrsetbits_le32(0x3000150, 0x20ff00, vol << 8);
-+
-+      udelay(1);
-+
-+      sid_read_ldoB_cal(para);
-+}
-+
-+static void dram_enable_all_master(void)
-+{
-+      writel(~0, 0x3102020);
-+      writel(0xff, 0x3102024);
-+      writel(0xffff, 0x3102028);
-+      udelay(10);
-+}
-+
-+static void dram_disable_all_master(void)
-+{
-+      writel(1, 0x3102020);
-+      writel(0, 0x3102024);
-+      writel(0, 0x3102028);
-+      udelay(10);
-+}
-+
-+static void eye_delay_compensation(dram_para_t *para) // s1
-+{
-+      uint32_t delay;
-+      unsigned long ptr;
-+
-+      // DATn0IOCR, n =  0...7
-+      delay = (para->dram_tpr11 & 0xf) << 9;
-+      delay |= (para->dram_tpr12 & 0xf) << 1;
-+      for (ptr = 0x3103310; ptr < 0x3103334; ptr += 4)
-+              setbits_le32(ptr, delay);
-+
-+      // DATn1IOCR, n =  0...7
-+      delay = (para->dram_tpr11 & 0xf0) << 5;
-+      delay |= (para->dram_tpr12 & 0xf0) >> 3;
-+      for (ptr = 0x3103390; ptr != 0x31033b4; ptr += 4)
-+              setbits_le32(ptr, delay);
-+
-+      // PGCR0: assert AC loopback FIFO reset
-+      clrbits_le32(0x3103100, 0x04000000);
-+
-+      // ??
-+
-+      delay = (para->dram_tpr11 & 0xf0000) >> 7;
-+      delay |= (para->dram_tpr12 & 0xf0000) >> 15;
-+      setbits_le32(0x3103334, delay);
-+      setbits_le32(0x3103338, delay);
-+
-+      delay = (para->dram_tpr11 & 0xf00000) >> 11;
-+      delay |= (para->dram_tpr12 & 0xf00000) >> 19;
-+      setbits_le32(0x31033b4, delay);
-+      setbits_le32(0x31033b8, delay);
-+
-+      setbits_le32(0x310333c, (para->dram_tpr11 & 0xf0000) << 9);
-+      setbits_le32(0x31033bc, (para->dram_tpr11 & 0xf00000) << 5);
-+
-+      // PGCR0: release AC loopback FIFO reset
-+      setbits_le32(0x3103100, BIT(26));
-+
-+      udelay(1);
-+
-+      delay = (para->dram_tpr10 & 0xf0) << 4;
-+      for (ptr = 0x3103240; ptr != 0x310327c; ptr += 4)
-+              setbits_le32(ptr, delay);
-+      for (ptr = 0x3103228; ptr != 0x3103240; ptr += 4)
-+              setbits_le32(ptr, delay);
-+
-+      setbits_le32(0x3103218, (para->dram_tpr10 & 0x0f) << 8);
-+      setbits_le32(0x310321c, (para->dram_tpr10 & 0x0f) << 8);
-+
-+      setbits_le32(0x3103280, (para->dram_tpr10 & 0xf00) >> 4);
-+}
-+
-+/*
-+ * Main purpose of the auto_set_timing routine seems to be to calculate all
-+ * timing settings for the specific type of sdram used. Read together with
-+ * an sdram datasheet for context on the various variables.
-+ */
-+static void mctl_set_timing_params(dram_para_t *para)
-+{
-+      /* DRAM_TPR0 */
-+      u8 tccd         = 2;
-+      u8 tfaw;
-+      u8 trrd;
-+      u8 trcd;
-+      u8 trc;
-+
-+      /* DRAM_TPR1 */
-+      u8 txp;
-+      u8 twtr;
-+      u8 trtp         = 4;
-+      u8 twr;
-+      u8 trp;
-+      u8 tras;
-+
-+      /* DRAM_TPR2 */
-+      u16 trefi;
-+      u16 trfc;
-+
-+      u8 tcksrx;
-+      u8 tckesr;
-+      u8 trd2wr;
-+      u8 twr2rd;
-+      u8 trasmax;
-+      u8 twtp;
-+      u8 tcke;
-+      u8 tmod;
-+      u8 tmrd;
-+      u8 tmrw;
-+
-+      u8 tcl;
-+      u8 tcwl;
-+      u8 t_rdata_en;
-+      u8 wr_latency;
-+
-+      u32 mr0;
-+      u32 mr1;
-+      u32 mr2;
-+      u32 mr3;
-+
-+      u32 tdinit0;
-+      u32 tdinit1;
-+      u32 tdinit2;
-+      u32 tdinit3;
-+
-+      switch (CONFIG_SUNXI_DRAM_TYPE) {
-+      case SUNXI_DRAM_TYPE_DDR2:
-+              /* DRAM_TPR0 */
-+              tfaw            = ns_to_t(50);
-+              trrd            = ns_to_t(10);
-+              trcd            = ns_to_t(20);
-+              trc             = ns_to_t(65);
-+
-+              /* DRAM_TPR1 */
-+              txp             = 2;
-+              twtr            = ns_to_t(8);
-+              twr             = ns_to_t(15);
-+              trp             = ns_to_t(15);
-+              tras            = ns_to_t(45);
-+
-+              /* DRAM_TRP2 */
-+              trfc            = ns_to_t(328);
-+              trefi           = ns_to_t(7800) / 32;
-+
-+              trasmax         = CONFIG_DRAM_CLK / 30;
-+              if (CONFIG_DRAM_CLK < 409) {
-+                      t_rdata_en      = 1;
-+                      tcl             = 3;
-+                      mr0             = 0x06a3;
-+              } else {
-+                      t_rdata_en      = 2;
-+                      tcl             = 4;
-+                      mr0             = 0x0e73;
-+              }
-+              tmrd            = 2;
-+              twtp            = twr + 5;
-+              tcksrx          = 5;
-+              tckesr          = 4;
-+              trd2wr          = 4;
-+              tcke            = 3;
-+              tmod            = 12;
-+              wr_latency      = 1;
-+              tmrw            = 0;
-+              twr2rd          = twtr + 5;
-+              tcwl            = 0;
-+
-+              mr1             = para->dram_mr1;
-+              mr2             = 0;
-+              mr3             = 0;
-+
-+              tdinit0         = 200 * CONFIG_DRAM_CLK + 1;
-+              tdinit1         = 100 * CONFIG_DRAM_CLK / 1000 + 1;
-+              tdinit2         = 200 * CONFIG_DRAM_CLK + 1;
-+              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;
-+
-+              break;
-+      case SUNXI_DRAM_TYPE_DDR3:
-+              trfc            = ns_to_t(350);
-+              trefi           = ns_to_t(7800) / 32 + 1;       // XXX
-+
-+              twtr            = ns_to_t(8) + 2;               // + 2 ? XXX
-+              /* Only used by trd2wr calculation, which gets discard below */
-+//            twr             = max(ns_to_t(15), 2);
-+              trrd            = max(ns_to_t(10), 2);
-+              txp             = max(ns_to_t(10), 2);
-+
-+              if (CONFIG_DRAM_CLK <= 800) {
-+                      tfaw            = ns_to_t(50);
-+                      trcd            = ns_to_t(15);
-+                      trp             = ns_to_t(15);
-+                      trc             = ns_to_t(53);
-+                      tras            = ns_to_t(38);
-+
-+                      mr0             = 0x1c70;
-+                      mr2             = 0x18;
-+                      tcl             = 6;
-+                      wr_latency      = 2;
-+                      tcwl            = 4;
-+                      t_rdata_en      = 4;
-+              } else {
-+                      tfaw            = ns_to_t(35);
-+                      trcd            = ns_to_t(14);
-+                      trp             = ns_to_t(14);
-+                      trc             = ns_to_t(48);
-+                      tras            = ns_to_t(34);
-+
-+                      mr0             = 0x1e14;
-+                      mr2             = 0x20;
-+                      tcl             = 7;
-+                      wr_latency      = 3;
-+                      tcwl            = 5;
-+                      t_rdata_en      = 5;
-+              }
-+
-+              trasmax         = CONFIG_DRAM_CLK / 30;
-+              twtp            = tcwl + 2 + twtr;              // WL+BL/2+tWTR
-+              /* Gets overwritten below */
-+//            trd2wr          = tcwl + 2 + twr;               // WL+BL/2+tWR
-+              twr2rd          = tcwl + twtr;                  // WL+tWTR
-+
-+              tdinit0         = 500 * CONFIG_DRAM_CLK + 1;    // 500 us
-+              tdinit1         = 360 * CONFIG_DRAM_CLK / 1000 + 1;   // 360 ns
-+              tdinit2         = 200 * CONFIG_DRAM_CLK + 1;    // 200 us
-+              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;      //   1 us
-+
-+              mr1             = para->dram_mr1;
-+              mr3             = 0;
-+              tcke            = 3;
-+              tcksrx          = 5;
-+              tckesr          = 4;
-+              if (((para->dram_tpr13 & 0xc) == 0x04) || CONFIG_DRAM_CLK < 912)
-+                      trd2wr     = 5;
-+              else
-+                      trd2wr     = 6;
-+
-+              tmod            = 12;
-+              tmrd            = 4;
-+              tmrw            = 0;
-+
-+              break;
-+      case SUNXI_DRAM_TYPE_LPDDR2:
-+              tfaw            = max(ns_to_t(50), 4);
-+              trrd            = max(ns_to_t(10), 1);
-+              trcd            = max(ns_to_t(24), 2);
-+              trc             = ns_to_t(70);
-+              txp             = ns_to_t(8);
-+              if (txp < 2) {
-+                      txp++;
-+                      twtr    = 2;
-+              } else {
-+                      twtr    = txp;
-+              }
-+              twr             = max(ns_to_t(15), 2);
-+              trp             = ns_to_t(17);
-+              tras            = ns_to_t(42);
-+              trefi           = ns_to_t(3900) / 32;
-+              trfc            = ns_to_t(210);
-+
-+              trasmax         = CONFIG_DRAM_CLK / 60;
-+              mr3             = para->dram_mr3;
-+              twtp            = twr + 5;
-+              mr2             = 6;
-+              mr1             = 5;
-+              tcksrx          = 5;
-+              tckesr          = 5;
-+              trd2wr          = 10;
-+              tcke            = 2;
-+              tmod            = 5;
-+              tmrd            = 5;
-+              tmrw            = 3;
-+              tcl             = 4;
-+              wr_latency      = 1;
-+              t_rdata_en      = 1;
-+
-+              tdinit0         = 200 * CONFIG_DRAM_CLK + 1;
-+              tdinit1         = 100 * CONFIG_DRAM_CLK / 1000 + 1;
-+              tdinit2         = 11 * CONFIG_DRAM_CLK + 1;
-+              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;
-+              twr2rd          = twtr + 5;
-+              tcwl            = 2;
-+              mr1             = 195;
-+              mr0             = 0;
-+
-+              break;
-+      case SUNXI_DRAM_TYPE_LPDDR3:
-+              tfaw            = max(ns_to_t(50), 4);
-+              trrd            = max(ns_to_t(10), 1);
-+              trcd            = max(ns_to_t(24), 2);
-+              trc             = ns_to_t(70);
-+              twtr            = max(ns_to_t(8), 2);
-+              twr             = max(ns_to_t(15), 2);
-+              trp             = ns_to_t(17);
-+              tras            = ns_to_t(42);
-+              trefi           = ns_to_t(3900) / 32;
-+              trfc            = ns_to_t(210);
-+              txp             = twtr;
-+
-+              trasmax         = CONFIG_DRAM_CLK / 60;
-+              if (CONFIG_DRAM_CLK < 800) {
-+                      tcwl       = 4;
-+                      wr_latency = 3;
-+                      t_rdata_en = 6;
-+                      mr2                = 12;
-+              } else {
-+                      tcwl       = 3;
-+                      tcke       = 6;
-+                      wr_latency = 2;
-+                      t_rdata_en = 5;
-+                      mr2                = 10;
-+              }
-+              twtp            = tcwl + 5;
-+              tcl             = 7;
-+              mr3             = para->dram_mr3;
-+              tcksrx          = 5;
-+              tckesr          = 5;
-+              trd2wr          = 13;
-+              tcke            = 3;
-+              tmod            = 12;
-+              tdinit0         = 400 * CONFIG_DRAM_CLK + 1;
-+              tdinit1         = 500 * CONFIG_DRAM_CLK / 1000 + 1;
-+              tdinit2         = 11 * CONFIG_DRAM_CLK + 1;
-+              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;
-+              tmrd            = 5;
-+              tmrw            = 5;
-+              twr2rd          = tcwl + twtr + 5;
-+              mr1             = 195;
-+              mr0             = 0;
-+
-+              break;
-+      default:
-+              trfc            = 128;
-+              trp             = 6;
-+              trefi           = 98;
-+              txp             = 10;
-+              twr             = 8;
-+              twtr            = 3;
-+              tras            = 14;
-+              tfaw            = 16;
-+              trc             = 20;
-+              trcd            = 6;
-+              trrd            = 3;
-+
-+              twr2rd          = 8;
-+              tcksrx          = 4;
-+              tckesr          = 3;
-+              trd2wr          = 4;
-+              trasmax         = 27;
-+              twtp            = 12;
-+              tcke            = 2;
-+              tmod            = 6;
-+              tmrd            = 2;
-+              tmrw            = 0;
-+              tcwl            = 3;
-+              tcl             = 3;
-+              wr_latency      = 1;
-+              t_rdata_en      = 1;
-+              mr3             = 0;
-+              mr2             = 0;
-+              mr1             = 0;
-+              mr0             = 0;
-+              tdinit3         = 0;
-+              tdinit2         = 0;
-+              tdinit1         = 0;
-+              tdinit0         = 0;
-+
-+              break;
-+      }
-+
-+      /* Set mode registers */
-+      writel(mr0, 0x3103030);
-+      writel(mr1, 0x3103034);
-+      writel(mr2, 0x3103038);
-+      writel(mr3, 0x310303c);
-+      /* TODO: dram_odt_en is either 0x0 or 0x1, so right shift looks weird */
-+      writel((para->dram_odt_en >> 4) & 0x3, 0x310302c);
-+
-+      /* Set dram timing DRAMTMG0 - DRAMTMG5 */
-+      writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0),
-+              0x3103058);
-+      writel((txp << 16) | (trtp << 8) | (trc << 0),
-+              0x310305c);
-+      writel((tcwl << 24) | (tcl << 16) | (trd2wr << 8) | (twr2rd << 0),
-+              0x3103060);
-+      writel((tmrw << 16) | (tmrd << 12) | (tmod << 0),
-+              0x3103064);
-+      writel((trcd << 24) | (tccd << 16) | (trrd << 8) | (trp << 0),
-+              0x3103068);
-+      writel((tcksrx << 24) | (tcksrx << 16) | (tckesr << 8) | (tcke << 0),
-+              0x310306c);
-+
-+      /* Set dual rank timing */
-+      clrsetbits_le32(0x3103078, 0xf000ffff,
-+                      (CONFIG_DRAM_CLK < 800) ? 0xf0006610 : 0xf0007610);
-+
-+      /* Set phy interface time PITMG0, PTR3, PTR4 */
-+      writel((0x2 << 24) | (t_rdata_en << 16) | BIT(8) | (wr_latency << 0),
-+              0x3103080);
-+      writel(((tdinit0 << 0) | (tdinit1 << 20)), 0x3103050);
-+      writel(((tdinit2 << 0) | (tdinit3 << 20)), 0x3103054);
-+
-+      /* Set refresh timing and mode */
-+      writel((trefi << 16) | (trfc << 0), 0x3103090);
-+      writel((trefi << 15) & 0x0fff0000, 0x3103094);
-+}
-+
-+// Purpose of this routine seems to be to initialize the PLL driving
-+// the MBUS and sdram.
-+//
-+static int ccu_set_pll_ddr_clk(int index, dram_para_t *para)
-+{
-+      unsigned int val, clk, n;
-+
-+      if (para->dram_tpr13 & BIT(6))
-+              clk = para->dram_tpr9;
-+      else
-+              clk = para->dram_clk;
-+
-+      // set VCO clock divider
-+      n = (clk * 2) / 24;
-+
-+      val = readl(0x2001010);
-+      val &= 0xfff800fc; // clear dividers
-+      val |= (n - 1) << 8; // set PLL division
-+      val |= 0xc0000000; // enable PLL and LDO
-+      val &= 0xdfffffff;
-+      writel(val | 0x20000000, 0x2001010);
-+
-+      // wait for PLL to lock
-+      while ((readl(0x2001010) & 0x10000000) == 0) {
-+              ;
-+      }
-+
-+      udelay(20);
-+
-+      // enable PLL output
-+      val = readl(0x2001000);
-+      val |= 0x08000000;
-+      writel(val, 0x2001000);
-+
-+      // turn clock gate on
-+      val = readl(0x2001800);
-+      val &= 0xfcfffcfc; // select DDR clk source, n=1, m=1
-+      val |= 0x80000000; // turn clock on
-+      writel(val, 0x2001800);
-+
-+      return n * 24;
-+}
-+
-+// Main purpose of sys_init seems to be to initalise the clocks for
-+// the sdram controller.
-+//
-+static void mctl_sys_init(dram_para_t *para)
-+{
-+      // assert MBUS reset
-+      clrbits_le32(0x2001540, BIT(30));
-+
-+      // turn off sdram clock gate, assert sdram reset
-+      clrbits_le32(0x200180c, 0x10001);
-+      clrsetbits_le32(0x2001800, BIT(31) | BIT(30), BIT(27));
-+      udelay(10);
-+
-+      // set ddr pll clock
-+      para->dram_clk = ccu_set_pll_ddr_clk(0, para) / 2;
-+      udelay(100);
-+      dram_disable_all_master();
-+
-+      // release sdram reset
-+      setbits_le32(0x200180c, BIT(16));
-+
-+      // release MBUS reset
-+      setbits_le32(0x2001540, BIT(30));
-+      setbits_le32(0x2001800, BIT(30));
-+
-+      udelay(5);
-+
-+      // turn on sdram clock gate
-+      setbits_le32(0x200180c, BIT(0));
-+
-+      // turn dram clock gate on, trigger sdr clock update
-+      setbits_le32(0x2001800, BIT(31) | BIT(27));
-+      udelay(5);
-+
-+      // mCTL clock enable
-+      writel(0x8000, 0x310300c);
-+      udelay(10);
-+}
-+
-+// The main purpose of this routine seems to be to copy an address configuration
-+// from the dram_para1 and dram_para2 fields to the PHY configuration registers
-+// (0x3102000, 0x3102004).
-+//
-+static void mctl_com_init(dram_para_t *para)
-+{
-+      uint32_t val, width;
-+      unsigned long ptr;
-+      int i;
-+
-+      // purpose ??
-+      clrsetbits_le32(0x3102008, 0x3f00, 0x2000);
-+
-+      // set SDRAM type and word width
-+      val  = readl(0x3102000) & ~0x00fff000;
-+      val |= (para->dram_type & 0x7) << 16;           // DRAM type
-+      val |= (~para->dram_para2 & 0x1) << 12;         // DQ width
-+      val |= BIT(22);                                 // ??
-+      if (para->dram_type == SUNXI_DRAM_TYPE_LPDDR2 ||
-+          para->dram_type == SUNXI_DRAM_TYPE_LPDDR3) {
-+              val |= BIT(19);         // type 6 and 7 must use 1T
-+      } else {
-+              if (para->dram_tpr13 & BIT(5))
-+                      val |= BIT(19);
-+      }
-+      writel(val, 0x3102000);
-+
-+      // init rank / bank / row for single/dual or two different ranks
-+      if ((para->dram_para2 & BIT(8)) &&
-+          ((para->dram_para2 & 0xf000) != 0x1000))
-+              width = 32;
-+      else
-+              width = 16;
-+
-+      ptr = 0x3102000;
-+      for (i = 0; i < width; i += 16) {
-+              val = readl(ptr) & 0xfffff000;
-+
-+              val |= (para->dram_para2 >> 12) & 0x3; // rank
-+              val |= ((para->dram_para1 >> (i + 12)) << 2) & 0x4; // bank - 2
-+              val |= (((para->dram_para1 >> (i + 4)) - 1) << 4) & 0xff; // row - 1
-+
-+              // convert from page size to column addr width - 3
-+              switch ((para->dram_para1 >> i) & 0xf) {
-+              case 8: val |= 0xa00; break;
-+              case 4: val |= 0x900; break;
-+              case 2: val |= 0x800; break;
-+              case 1: val |= 0x700; break;
-+              default: val |= 0x600; break;
-+              }
-+              writel(val, ptr);
-+              ptr += 4;
-+      }
-+
-+      // set ODTMAP based on number of ranks in use
-+      val = (readl(0x3102000) & 0x1) ? 0x303 : 0x201;
-+      writel(val, 0x3103120);
-+
-+      // set mctl reg 3c4 to zero when using half DQ
-+      if (para->dram_para2 & BIT(0))
-+              writel(0, 0x31033c4);
-+
-+      // purpose ??
-+      if (para->dram_tpr4) {
-+                setbits_le32(0x3102000, (para->dram_tpr4 & 0x3) << 25);
-+                setbits_le32(0x3102004, (para->dram_tpr4 & 0x7fc) << 10);
-+      }
-+}
-+
-+static const uint8_t ac_remapping_tables[][22] = {
-+      [0] = { 0 },
-+      [1] = {  1,  9,  3,  7,  8, 18,  4, 13,  5,  6, 10,
-+               2, 14, 12,  0,  0, 21, 17, 20, 19, 11, 22 },
-+      [2] = {  4,  9,  3,  7,  8, 18,  1, 13,  2,  6, 10,
-+               5, 14, 12,  0,  0, 21, 17, 20, 19, 11, 22 },
-+      [3] = {  1,  7,  8, 12, 10, 18,  4, 13,  5,  6,  3,
-+               2,  9,  0,  0,  0, 21, 17, 20, 19, 11, 22 },
-+      [4] = {  4, 12, 10,  7,  8, 18,  1, 13,  2,  6,  3,
-+               5,  9,  0,  0,  0, 21, 17, 20, 19, 11, 22 },
-+      [5] = { 13,  2,  7,  9, 12, 19,  5,  1,  6,  3,  4,
-+               8, 10,  0,  0,  0, 21, 22, 18, 17, 11, 20 },
-+      [6] = {  3, 10,  7, 13,  9, 11,  1,  2,  4,  6,  8,
-+               5, 12,  0,  0,  0, 20,  1,  0, 21, 22, 17 },
-+      [7] = {  3,  2,  4,  7,  9,  1, 17, 12, 18, 14, 13,
-+               8, 15,  6, 10,  5, 19, 22, 16, 21, 20, 11 },
-+};
-+
-+/*
-+ * This routine chooses one of several remapping tables for 22 lines.
-+ * It is unclear which lines are being remapped. It seems to pick
-+ * table cfg7 for the Nezha board.
-+ */
-+static void mctl_phy_ac_remapping(dram_para_t *para)
-+{
-+      const uint8_t *cfg;
-+      uint32_t fuse, val;
-+
-+      /*
-+       * It is unclear whether the LPDDRx types don't need any remapping,
-+       * or whether the original code just didn't provide tables.
-+       */
-+      if (para->dram_type != SUNXI_DRAM_TYPE_DDR2 &&
-+          para->dram_type != SUNXI_DRAM_TYPE_DDR3)
-+              return;
-+
-+      fuse = (readl(SUNXI_SID_BASE + 0x28) & 0xf00) >> 8;
-+      debug("DDR efuse: 0x%x\n", fuse);
-+
-+      if (para->dram_type == SUNXI_DRAM_TYPE_DDR2) {
-+              if (fuse == 15)
-+                      return;
-+              cfg = ac_remapping_tables[6];
-+      } else {
-+              if (para->dram_tpr13 & 0xc0000) {
-+                      cfg = ac_remapping_tables[7];
-+              } else {
-+                      switch (fuse) {
-+                      case 8: cfg = ac_remapping_tables[2]; break;
-+                      case 9: cfg = ac_remapping_tables[3]; break;
-+                      case 10: cfg = ac_remapping_tables[5]; break;
-+                      case 11: cfg = ac_remapping_tables[4]; break;
-+                      default:
-+                      case 12: cfg = ac_remapping_tables[1]; break;
-+                      case 13:
-+                      case 14: cfg = ac_remapping_tables[0]; break;
-+                      }
-+              }
-+      }
-+
-+      val = (cfg[4] << 25) | (cfg[3] << 20) | (cfg[2] << 15) |
-+            (cfg[1] << 10) | (cfg[0] << 5);
-+      writel(val, 0x3102500);
-+
-+      val = (cfg[10] << 25) | (cfg[9] << 20) | (cfg[8] << 15) |
-+            (cfg[ 7] << 10) | (cfg[6] <<  5) | cfg[5];
-+      writel(val, 0x3102504);
-+
-+      val = (cfg[15] << 20) | (cfg[14] << 15) | (cfg[13] << 10) |
-+            (cfg[12] <<  5) | cfg[11];
-+      writel(val, 0x3102508);
-+
-+      val = (cfg[21] << 25) | (cfg[20] << 20) | (cfg[19] << 15) |
-+            (cfg[18] << 10) | (cfg[17] <<  5) | cfg[16];
-+      writel(val, 0x310250c);
-+
-+      val = (cfg[4] << 25) | (cfg[3] << 20) | (cfg[2] << 15) |
-+            (cfg[1] << 10) | (cfg[0] <<  5) | 1;
-+      writel(val, 0x3102500);
-+}
-+
-+// Init the controller channel. The key part is placing commands in the main
-+// command register (PIR, 0x3103000) and checking command status (PGSR0, 0x3103010).
-+//
-+static unsigned int mctl_channel_init(unsigned int ch_index, dram_para_t *para)
-+{
-+      unsigned int val, dqs_gating_mode;
-+
-+      dqs_gating_mode = (para->dram_tpr13 & 0xc) >> 2;
-+
-+      // set DDR clock to half of CPU clock
-+      clrsetbits_le32(0x310200c, 0xfff, (para->dram_clk / 2) - 1);
-+
-+      // MRCTRL0 nibble 3 undocumented
-+      clrsetbits_le32(0x3103108, 0xf00, 0x300);
-+
-+      if (para->dram_odt_en)
-+              val = 0;
-+      else
-+              val = BIT(5);
-+
-+      // DX0GCR0
-+      if (para->dram_clk > 672)
-+              clrsetbits_le32(0x3103344, 0xf63e, val);
-+      else
-+              clrsetbits_le32(0x3103344, 0xf03e, val);
-+
-+      // DX1GCR0
-+      if (para->dram_clk > 672) {
-+                setbits_le32(0x3103344, 0x400);
-+              clrsetbits_le32(0x31033c4, 0xf63e, val);
-+      } else {
-+              clrsetbits_le32(0x31033c4, 0xf03e, val);
-+      }
-+
-+      // 0x3103208 undocumented
-+      setbits_le32(0x3103208, BIT(1));
-+
-+      eye_delay_compensation(para);
-+
-+      // set PLL SSCG ?
-+      val = readl(0x3103108);
-+      if (dqs_gating_mode == 1) {
-+              clrsetbits_le32(0x3103108, 0xc0, 0);
-+              clrbits_le32(0x31030bc, 0x107);
-+      } else if (dqs_gating_mode == 2) {
-+              clrsetbits_le32(0x3103108, 0xc0, 0x80);
-+
-+              clrsetbits_le32(0x31030bc, 0x107,
-+                              (((para->dram_tpr13 >> 16) & 0x1f) - 2) | 0x100);
-+              clrsetbits_le32(0x310311c, BIT(31), BIT(27));
-+      } else {
-+              clrbits_le32(0x3103108, 0x40);
-+              udelay(10);
-+              setbits_le32(0x3103108, 0xc0);
-+      }
-+
-+      if (para->dram_type == SUNXI_DRAM_TYPE_LPDDR2 ||
-+          para->dram_type == SUNXI_DRAM_TYPE_LPDDR3) {
-+              if (dqs_gating_mode == 1)
-+                      clrsetbits_le32(0x310311c, 0x080000c0, 0x80000000);
-+              else
-+                      clrsetbits_le32(0x310311c, 0x77000000, 0x22000000);
-+      }
-+
-+      clrsetbits_le32(0x31030c0, 0x0fffffff,
-+                      (para->dram_para2 & BIT(12)) ? 0x03000001 : 0x01000007);
-+
-+      if (readl(0x70005d4) & (1 << 16)) {
-+              clrbits_le32(0x7010250, 0x2);
-+              udelay(10);
-+      }
-+
-+      // Set ZQ config
-+      clrsetbits_le32(0x3103140, 0x3ffffff,
-+                      (para->dram_zq & 0x00ffffff) | BIT(25));
-+
-+      // Initialise DRAM controller
-+      if (dqs_gating_mode == 1) {
-+              //writel(0x52, 0x3103000); // prep PHY reset + PLL init + z-cal
-+              writel(0x53, 0x3103000); // Go
-+
-+              while ((readl(0x3103010) & 0x1) == 0) {
-+              } // wait for IDONE
-+              udelay(10);
-+
-+              // 0x520 = prep DQS gating + DRAM init + d-cal
-+              if (para->dram_type == SUNXI_DRAM_TYPE_DDR3)
-+                      writel(0x5a0, 0x3103000);               // + DRAM reset
-+              else
-+                      writel(0x520, 0x3103000);
-+      } else {
-+              if ((readl(0x70005d4) & (1 << 16)) == 0) {
-+                      // prep DRAM init + PHY reset + d-cal + PLL init + z-cal
-+                      if (para->dram_type == SUNXI_DRAM_TYPE_DDR3)
-+                              writel(0x1f2, 0x3103000);       // + DRAM reset
-+                      else
-+                              writel(0x172, 0x3103000);
-+              } else {
-+                      // prep PHY reset + d-cal + z-cal
-+                      writel(0x62, 0x3103000);
-+              }
-+      }
-+
-+      setbits_le32(0x3103000, 0x1);            // GO
-+
-+      udelay(10);
-+      while ((readl(0x3103010) & 0x1) == 0) {
-+      } // wait for IDONE
-+
-+      if (readl(0x70005d4) & (1 << 16)) {
-+              clrsetbits_le32(0x310310c, 0x06000000, 0x04000000);
-+              udelay(10);
-+
-+              setbits_le32(0x3103004, 0x1);
-+
-+              while ((readl(0x3103018) & 0x7) != 0x3) {
-+              }
-+
-+              clrbits_le32(0x7010250, 0x1);
-+              udelay(10);
-+
-+              clrbits_le32(0x3103004, 0x1);
-+
-+              while ((readl(0x3103018) & 0x7) != 0x1) {
-+              }
-+
-+              udelay(15);
-+
-+              if (dqs_gating_mode == 1) {
-+                      clrbits_le32(0x3103108, 0xc0);
-+                      clrsetbits_le32(0x310310c, 0x06000000, 0x02000000);
-+                      udelay(1);
-+                      writel(0x401, 0x3103000);
-+
-+                      while ((readl(0x3103010) & 0x1) == 0) {
-+                      }
-+              }
-+      }
-+
-+      // Check for training error
-+      if (readl(0x3103010) & BIT(20)) {
-+              printf("ZQ calibration error, check external 240 ohm resistor\n");
-+              return 0;
-+      }
-+
-+      // STATR = Zynq STAT? Wait for status 'normal'?
-+      while ((readl(0x3103018) & 0x1) == 0) {
-+      }
-+
-+      setbits_le32(0x310308c, BIT(31));
-+      udelay(10);
-+      clrbits_le32(0x310308c, BIT(31));
-+      udelay(10);
-+      setbits_le32(0x3102014, BIT(31));
-+      udelay(10);
-+
-+      clrbits_le32(0x310310c, 0x06000000);
-+
-+      if (dqs_gating_mode == 1)
-+              clrsetbits_le32(0x310311c, 0xc0, 0x40);
-+
-+      return 1;
-+}
-+
-+static unsigned int calculate_rank_size(uint32_t regval)
-+{
-+      unsigned int bits;
-+
-+      bits = (regval >> 8) & 0xf;     /* page size - 3 */
-+      bits += (regval >> 4) & 0xf;    /* row width - 1 */
-+      bits += (regval >> 2) & 0x3;    /* bank count - 2 */
-+      bits -= 14;                     /* 1MB = 20 bits, minus above 6 = 14 */
-+
-+      return 1U << bits;
-+}
-+
-+/*
-+ * The below routine reads the dram config registers and extracts
-+ * the number of address bits in each rank available. It then calculates
-+ * total memory size in MB.
-+ */
-+static unsigned int DRAMC_get_dram_size(void)
-+{
-+      uint32_t val;
-+      unsigned int size;
-+
-+      val = readl(0x3102000);         /* MC_WORK_MODE0 */
-+      size = calculate_rank_size(val);
-+      if ((val & 0x3) == 0)           /* single rank? */
-+              return size;
-+
-+      val = readl(0x3102004);         /* MC_WORK_MODE1 */
-+      if ((val & 0x3) == 0)           /* two identical ranks? */
-+              return size * 2;
-+
-+      /* add sizes of both ranks */
-+      return size + calculate_rank_size(val);
-+}
-+
-+/*
-+ * The below routine reads the command status register to extract
-+ * DQ width and rank count. This follows the DQS training command in
-+ * channel_init. If error bit 22 is reset, we have two ranks and full DQ.
-+ * If there was an error, figure out whether it was half DQ, single rank,
-+ * or both. Set bit 12 and 0 in dram_para2 with the results.
-+ */
-+static int dqs_gate_detect(dram_para_t *para)
-+{
-+      uint32_t dx0, dx1;
-+
-+      if ((readl(0x3103010) & BIT(22)) == 0) {
-+              para->dram_para2 = (para->dram_para2 & ~0xf) | BIT(12);
-+              debug("dual rank and full DQ\n");
-+
-+              return 1;
-+      }
-+
-+      dx0 = (readl(0x03103348) & 0x3000000) >> 24;
-+      if (dx0 == 0) {
-+              para->dram_para2 = (para->dram_para2 & ~0xf) | 0x1001;
-+              debug("dual rank and half DQ\n");
-+
-+              return 1;
-+      }
-+
-+      if (dx0 == 2) {
-+              dx1 = (readl(0x031033c8) & 0x3000000) >> 24;
-+              if (dx1 == 2) {
-+                      para->dram_para2 = para->dram_para2 & ~0xf00f;
-+                      debug("single rank and full DQ\n");
-+              } else {
-+                      para->dram_para2 = (para->dram_para2 & ~0xf00f) | BIT(0);
-+                      debug("single rank and half DQ\n");
-+              }
-+
-+              return 1;
-+      }
-+
-+      if ((para->dram_tpr13 & BIT(29)) == 0)
-+              return 0;
-+
-+      debug("DX0 state: %d\n", dx0);
-+      debug("DX1 state: %d\n", dx1);
-+
-+      return 0;
-+}
-+
-+static int dramc_simple_wr_test(unsigned int mem_mb, int len)
-+{
-+      unsigned int  offs      = (mem_mb / 2) << 18; // half of memory size
-+      unsigned int  patt1 = 0x01234567;
-+      unsigned int  patt2 = 0xfedcba98;
-+      unsigned int *addr, v1, v2, i;
-+
-+      addr = (unsigned int *)CFG_SYS_SDRAM_BASE;
-+      for (i = 0; i != len; i++, addr++) {
-+              writel(patt1 + i, (unsigned long)addr);
-+              writel(patt2 + i, (unsigned long)(addr + offs));
-+      }
-+
-+      addr = (unsigned int *)CFG_SYS_SDRAM_BASE;
-+      for (i = 0; i != len; i++) {
-+              v1 = readl((unsigned long)(addr + i));
-+              v2 = patt1 + i;
-+              if (v1 != v2) {
-+                      printf("DRAM: simple test FAIL\n");
-+                      printf("%x != %x at address %p\n", v1, v2, addr + i);
-+                      return 1;
-+              }
-+              v1 = readl((unsigned long)(addr + offs + i));
-+              v2 = patt2 + i;
-+              if (v1 != v2) {
-+                      printf("DRAM: simple test FAIL\n");
-+                      printf("%x != %x at address %p\n", v1, v2, addr + offs + i);
-+                      return 1;
-+              }
-+      }
-+
-+      debug("DRAM: simple test OK\n");
-+      return 0;
-+}
-+
-+// Set the Vref mode for the controller
-+//
-+static void mctl_vrefzq_init(dram_para_t *para)
-+{
-+      if (para->dram_tpr13 & BIT(17))
-+              return;
-+
-+      clrsetbits_le32(0x3103110, 0x7f7f7f7f, para->dram_tpr5);
-+
-+      // IOCVR1
-+      if ((para->dram_tpr13 & BIT(16)) == 0)
-+              clrsetbits_le32(0x3103114, 0x7f, para->dram_tpr6 & 0x7f);
-+}
-+
-+// Perform an init of the controller. This is actually done 3 times. The first
-+// time to establish the number of ranks and DQ width. The second time to
-+// establish the actual ram size. The third time is final one, with the final
-+// settings.
-+//
-+static int mctl_core_init(dram_para_t *para)
-+{
-+      mctl_sys_init(para);
-+
-+      mctl_vrefzq_init(para);
-+
-+      mctl_com_init(para);
-+
-+      mctl_phy_ac_remapping(para);
-+
-+      mctl_set_timing_params(para);
-+
-+      return mctl_channel_init(0, para);
-+}
-+
-+/*
-+ * This routine sizes a DRAM device by cycling through address lines and
-+ * figuring out if they are connected to a real address line, or if the
-+ * address is a mirror.
-+ * First the column and bank bit allocations are set to low values (2 and 9
-+ * address lines). Then a maximum allocation (16 lines) is set for rows and
-+ * this is tested.
-+ * Next the BA2 line is checked. This seems to be placed above the column,
-+ * BA0-1 and row addresses. Finally, the column address is allocated 13 lines
-+ * and these are tested. The results are placed in dram_para1 and dram_para2.
-+ */
-+static int auto_scan_dram_size(dram_para_t *para)
-+{
-+      unsigned int rval, i, j, rank, maxrank, offs;
-+      unsigned int shft;
-+      unsigned long ptr, mc_work_mode, chk;
-+
-+      if (mctl_core_init(para) == 0) {
-+              printf("DRAM initialisation error : 0\n");
-+              return 0;
-+      }
-+
-+      maxrank = (para->dram_para2 & 0xf000) ? 2 : 1;
-+      mc_work_mode = 0x3102000;
-+      offs = 0;
-+
-+      /* write test pattern */
-+      for (i = 0, ptr = CFG_SYS_SDRAM_BASE; i < 64; i++, ptr += 4)
-+              writel((i & 0x1) ? ptr : ~ptr, ptr);
-+
-+      for (rank = 0; rank < maxrank;) {
-+              /* set row mode */
-+              clrsetbits_le32(mc_work_mode, 0xf0c, 0x6f0);
-+              udelay(1);
-+
-+              // Scan per address line, until address wraps (i.e. see shadow)
-+              for (i = 11; i < 17; i++) {
-+                      chk = CFG_SYS_SDRAM_BASE + (1U << (i + 11));
-+                      ptr = CFG_SYS_SDRAM_BASE;
-+                      for (j = 0; j < 64; j++) {
-+                              if (readl(chk) != ((j & 1) ? ptr : ~ptr))
-+                                      break;
-+                              ptr += 4;
-+                              chk += 4;
-+                      }
-+                      if (j == 64)
-+                              break;
-+              }
-+              if (i > 16)
-+                      i = 16;
-+              debug("rank %d row = %d\n", rank, i);
-+
-+              /* Store rows in para 1 */
-+              shft = offs + 4;
-+              rval = para->dram_para1;
-+              rval &= ~(0xff << shft);
-+              rval |= i << shft;
-+              para->dram_para1 = rval;
-+
-+              if (rank == 1)          /* Set bank mode for rank0 */
-+                      clrsetbits_le32(0x3102000, 0xffc, 0x6a4);
-+
-+              /* Set bank mode for current rank */
-+              clrsetbits_le32(mc_work_mode, 0xffc, 0x6a4);
-+              udelay(1);
-+
-+              // Test if bit A23 is BA2 or mirror XXX A22?
-+              chk = CFG_SYS_SDRAM_BASE + (1U << 22);
-+              ptr = CFG_SYS_SDRAM_BASE;
-+              for (i = 0, j = 0; i < 64; i++) {
-+                      if (readl(chk) != ((i & 1) ? ptr : ~ptr)) {
-+                              j = 1;
-+                              break;
-+                      }
-+                      ptr += 4;
-+                      chk += 4;
-+              }
-+
-+              debug("rank %d bank = %d\n", rank, (j + 1) << 2); /* 4 or 8 */
-+
-+              /* Store banks in para 1 */
-+              shft = 12 + offs;
-+              rval = para->dram_para1;
-+              rval &= ~(0xf << shft);
-+              rval |= j << shft;
-+              para->dram_para1 = rval;
-+
-+              if (rank == 1)          /* Set page mode for rank0 */
-+                      clrsetbits_le32(0x3102000, 0xffc, 0xaa0);
-+
-+              /* Set page mode for current rank */
-+              clrsetbits_le32(mc_work_mode, 0xffc, 0xaa0);
-+              udelay(1);
-+
-+              // Scan per address line, until address wraps (i.e. see shadow)
-+              for (i = 9; i < 14; i++) {
-+                      chk = CFG_SYS_SDRAM_BASE + (1U << i);
-+                      ptr = CFG_SYS_SDRAM_BASE;
-+                      for (j = 0; j < 64; j++) {
-+                              if (readl(chk) != ((j & 1) ? ptr : ~ptr))
-+                                      break;
-+                              ptr += 4;
-+                              chk += 4;
-+                      }
-+                      if (j == 64)
-+                              break;
-+              }
-+              if (i > 13)
-+                      i = 13;
-+
-+              unsigned int pgsize = (i == 9) ? 0 : (1 << (i - 10));
-+              debug("rank %d page size = %d KB\n", rank, pgsize);
-+
-+              /* Store page size */
-+              shft = offs;
-+              rval = para->dram_para1;
-+              rval &= ~(0xf << shft);
-+              rval |= pgsize << shft;
-+              para->dram_para1 = rval;
-+
-+              // Move to next rank
-+              rank++;
-+              if (rank != maxrank) {
-+                      if (rank == 1) {
-+                              /* MC_WORK_MODE */
-+                              clrsetbits_le32(0x3202000, 0xffc, 0x6f0);
-+
-+                              /* MC_WORK_MODE2 */
-+                              clrsetbits_le32(0x3202004, 0xffc, 0x6f0);
-+                      }
-+                      /* store rank1 config in upper half of para1 */
-+                      offs += 16;
-+                      mc_work_mode += 4;      /* move to MC_WORK_MODE2 */
-+              }
-+      }
-+      if (maxrank == 2) {
-+              para->dram_para2 &= 0xfffff0ff;
-+              /* note: rval is equal to para->dram_para1 here */
-+              if ((rval & 0xffff) == (rval >> 16)) {
-+                      debug("rank1 config same as rank0\n");
-+              } else {
-+                      para->dram_para2 |= BIT(8);
-+                      debug("rank1 config different from rank0\n");
-+              }
-+      }
-+
-+      return 1;
-+}
-+
-+/*
-+ * This routine sets up parameters with dqs_gating_mode equal to 1 and two
-+ * ranks enabled. It then configures the core and tests for 1 or 2 ranks and
-+ * full or half DQ width. It then resets the parameters to the original values.
-+ * dram_para2 is updated with the rank and width findings.
-+ */
-+static int auto_scan_dram_rank_width(dram_para_t *para)
-+{
-+      unsigned int s1 = para->dram_tpr13;
-+      unsigned int s2 = para->dram_para1;
-+
-+      para->dram_para1 = 0x00b000b0;
-+      para->dram_para2 = (para->dram_para2 & ~0xf) | BIT(12);
-+
-+      /* set DQS probe mode */
-+      para->dram_tpr13 = (para->dram_tpr13 & ~0x8) | BIT(2) | BIT(0);
-+
-+      mctl_core_init(para);
-+
-+      if (readl(0x3103010) & BIT(20))
-+              return 0;
-+
-+      if (dqs_gate_detect(para) == 0)
-+              return 0;
-+
-+      para->dram_tpr13 = s1;
-+      para->dram_para1 = s2;
-+
-+      return 1;
-+}
-+
-+/*
-+ * This routine determines the SDRAM topology. It first establishes the number
-+ * of ranks and the DQ width. Then it scans the SDRAM address lines to establish
-+ * the size of each rank. It then updates dram_tpr13 to reflect that the sizes
-+ * are now known: a re-init will not repeat the autoscan.
-+ */
-+static int auto_scan_dram_config(dram_para_t *para)
-+{
-+      if (((para->dram_tpr13 & BIT(14)) == 0) &&
-+          (auto_scan_dram_rank_width(para) == 0)) {
-+              printf("ERROR: auto scan dram rank & width failed\n");
-+              return 0;
-+      }
-+
-+      if (((para->dram_tpr13 & BIT(0)) == 0) &&
-+          (auto_scan_dram_size(para) == 0)) {
-+              printf("ERROR: auto scan dram size failed\n");
-+              return 0;
-+      }
-+
-+      if ((para->dram_tpr13 & BIT(15)) == 0)
-+              para->dram_tpr13 |= BIT(14) | BIT(13) | BIT(1) | BIT(0);
-+
-+      return 1;
-+}
-+
-+int init_DRAM(int type, dram_para_t *para)
-+{
-+      u32 rc, mem_size_mb;
-+
-+      debug("DRAM BOOT DRIVE INFO: %s\n", "V0.24");
-+      debug("DRAM CLK = %d MHz\n", para->dram_clk);
-+      debug("DRAM Type = %d (2:DDR2,3:DDR3)\n", para->dram_type);
-+      if ((para->dram_odt_en & 0x1) == 0)
-+              debug("DRAMC read ODT off\n");
-+      else
-+              debug("DRAMC ZQ value: 0x%x\n", para->dram_zq);
-+
-+      /* Test ZQ status */
-+      if (para->dram_tpr13 & BIT(16)) {
-+              debug("DRAM only have internal ZQ\n");
-+              setbits_le32(0x3000160, BIT(8));
-+              writel(0, 0x3000168);
-+              udelay(10);
-+      } else {
-+              clrbits_le32(0x3000160, 0x3);
-+              writel(para->dram_tpr13 & BIT(16), 0x7010254);
-+              udelay(10);
-+              clrsetbits_le32(0x3000160, 0x108, BIT(1));
-+              udelay(10);
-+              setbits_le32(0x3000160, BIT(0));
-+              udelay(20);
-+              debug("ZQ value = 0x%x\n", readl(0x300016c));
-+      }
-+
-+      dram_voltage_set(para);
-+
-+      /* Set SDRAM controller auto config */
-+      if ((para->dram_tpr13 & BIT(0)) == 0) {
-+              if (auto_scan_dram_config(para) == 0) {
-+                      printf("auto_scan_dram_config() FAILED\n");
-+                      return 0;
-+              }
-+      }
-+
-+      /* report ODT */
-+      rc = para->dram_mr1;
-+      if ((rc & 0x44) == 0)
-+              debug("DRAM ODT off\n");
-+      else
-+              debug("DRAM ODT value: 0x%x\n", rc);
-+
-+      /* Init core, final run */
-+      if (mctl_core_init(para) == 0) {
-+              printf("DRAM initialisation error: 1\n");
-+              return 0;
-+      }
-+
-+      /* Get SDRAM size */
-+      /* TODO: who ever puts a negative number in the top half? */
-+      rc = para->dram_para2;
-+      if (rc & BIT(31)) {
-+              rc = (rc >> 16) & ~BIT(15);
-+      } else {
-+              rc = DRAMC_get_dram_size();
-+              debug("DRAM: size = %dMB\n", rc);
-+              para->dram_para2 = (para->dram_para2 & 0xffffU) | rc << 16;
-+      }
-+      mem_size_mb = rc;
-+
-+      /* Purpose ?? */
-+      if (para->dram_tpr13 & BIT(30)) {
-+              rc = para->dram_tpr8;
-+              if (rc == 0)
-+                      rc = 0x10000200;
-+              writel(rc, 0x31030a0);
-+              writel(0x40a, 0x310309c);
-+              setbits_le32(0x3103004, BIT(0));
-+              debug("Enable Auto SR\n");
-+      } else {
-+              clrbits_le32(0x31030a0, 0xffff);
-+              clrbits_le32(0x3103004, 0x1);
-+      }
-+
-+      /* Purpose ?? */
-+      if (para->dram_tpr13 & BIT(9)) {
-+              clrsetbits_le32(0x3103100, 0xf000, 0x5000);
-+      } else {
-+              if (para->dram_type != SUNXI_DRAM_TYPE_LPDDR2)
-+                      clrbits_le32(0x3103100, 0xf000);
-+      }
-+
-+      setbits_le32(0x3103140, BIT(31));
-+
-+      /* CHECK: is that really writing to a different register? */
-+      if (para->dram_tpr13 & BIT(8))
-+              writel(readl(0x3103140) | 0x300, 0x31030b8);
-+
-+      if (para->dram_tpr13 & BIT(16))
-+              clrbits_le32(0x3103108, BIT(13));
-+      else
-+              setbits_le32(0x3103108, BIT(13));
-+
-+      /* Purpose ?? */
-+      if (para->dram_type == SUNXI_DRAM_TYPE_LPDDR3)
-+              clrsetbits_le32(0x310307c, 0xf0000, 0x1000);
-+
-+      dram_enable_all_master();
-+      if (para->dram_tpr13 & BIT(28)) {
-+              if ((readl(0x70005d4) & BIT(16)) ||
-+                  dramc_simple_wr_test(mem_size_mb, 4096))
-+                      return 0;
-+      }
-+
-+      return mem_size_mb;
-+}
-+
-+unsigned long sunxi_dram_init(void)
-+{
-+      dram_para_t para = {
-+              .dram_clk       = CONFIG_DRAM_CLK,
-+              .dram_type      = CONFIG_SUNXI_DRAM_TYPE,
-+              .dram_zq        = CONFIG_DRAM_ZQ,
-+              .dram_odt_en    = CONFIG_DRAM_SUNXI_ODT_EN,
-+              .dram_para1     = 0x000010d2,
-+              .dram_para2     = 0,
-+              .dram_mr0       = 0x1c70,
-+              .dram_mr1       = 0x42,
-+              .dram_mr2       = 0x18,
-+              .dram_mr3       = 0,
-+              .dram_tpr0      = 0x004a2195,
-+              .dram_tpr1      = 0x02423190,
-+              .dram_tpr2      = 0x0008b061,
-+              .dram_tpr3      = 0xb4787896, // unused
-+              .dram_tpr4      = 0,
-+              .dram_tpr5      = 0x48484848,
-+              .dram_tpr6      = 0x00000048,
-+              .dram_tpr7      = 0x1620121e, // unused
-+              .dram_tpr8      = 0,
-+              .dram_tpr9      = 0, // clock?
-+              .dram_tpr10     = 0,
-+              .dram_tpr11     = CONFIG_DRAM_SUNXI_TPR11,
-+              .dram_tpr12     = CONFIG_DRAM_SUNXI_TPR12,
-+              .dram_tpr13     = CONFIG_DRAM_SUNXI_TPR13,
-+      };
-+
-+      return init_DRAM(0, &para) * 1024UL * 1024;
-+};
-+
-+#ifdef CONFIG_RAM             /* using the driver model */
-+struct sunxi_ram_priv {
-+      size_t size;
-+};
-+
-+static int sunxi_ram_probe(struct udevice *dev)
-+{
-+      struct sunxi_ram_priv *priv = dev_get_priv(dev);
-+      unsigned long dram_size;
-+
-+      debug("%s: %s: probing\n", __func__, dev->name);
-+
-+      dram_size = sunxi_dram_init();
-+      if (!dram_size) {
-+              printf("DRAM init failed: %d\n", ret);
-+              return -ENODEV;
-+      }
-+
-+      priv->size = dram_size;
-+
-+      return 0;
-+}
-+
-+static int sunxi_ram_get_info(struct udevice *dev, struct ram_info *info)
-+{
-+      struct sunxi_ram_priv *priv = dev_get_priv(dev);
-+
-+      debug("%s: %s: getting info\n", __func__, dev->name);
-+
-+      info->base = CFG_SYS_SDRAM_BASE;
-+      info->size = priv->size;
-+
-+      return 0;
-+}
-+
-+static struct ram_ops sunxi_ram_ops = {
-+      .get_info = sunxi_ram_get_info,
-+};
-+
-+static const struct udevice_id sunxi_ram_ids[] = {
-+      { .compatible = "allwinner,sun20i-d1-mbus" },
-+      { }
-+};
-+
-+U_BOOT_DRIVER(sunxi_ram) = {
-+      .name = "sunxi_ram",
-+      .id = UCLASS_RAM,
-+      .of_match = sunxi_ram_ids,
-+      .ops = &sunxi_ram_ops,
-+      .probe = sunxi_ram_probe,
-+      .priv_auto = sizeof(struct sunxi_ram_priv),
-+};
-+#endif                                /* CONFIG_RAM (using driver model) */
-diff --git a/drivers/ram/sunxi/dram_sun20i_d1.h b/drivers/ram/sunxi/dram_sun20i_d1.h
-new file mode 100644
-index 0000000000..89aac9dade
---- /dev/null
-+++ b/drivers/ram/sunxi/dram_sun20i_d1.h
-@@ -0,0 +1,70 @@
-+// SPDX-License-Identifier:   GPL-2.0+
-+/*
-+ * D1/R528/T113 DRAM controller register and constant defines
-+ *
-+ * (C) Copyright 2022 Arm Ltd.
-+ * Based on H6 and H616 header, which are:
-+ * (C) Copyright 2017  Icenowy Zheng <icenowy@aosc.io>
-+ * (C) Copyright 2020  Jernej Skrabec <jernej.skrabec@siol.net>
-+ *
-+ */
-+
-+#ifndef _SUNXI_DRAM_SUN20I_D1_H
-+#define _SUNXI_DRAM_SUN20I_D1_H
-+
-+enum sunxi_dram_type {
-+      SUNXI_DRAM_TYPE_DDR2 = 2,
-+      SUNXI_DRAM_TYPE_DDR3 = 3,
-+      SUNXI_DRAM_TYPE_LPDDR2 = 6,
-+      SUNXI_DRAM_TYPE_LPDDR3 = 7,
-+};
-+
-+/*
-+ * This structure contains a mixture of fixed configuration settings,
-+ * variables that are used at runtime to communicate settings between
-+ * different stages and functions, and unused values.
-+ * This is copied from Allwinner's boot0 data structure, which can be
-+ * found at offset 0x38 in any boot0 binary. To allow matching up some
-+ * board specific settings, this struct is kept compatible, even though
-+ * we don't need all members in our code.
-+ */
-+typedef struct dram_para {
-+      /* normal configuration */
-+      u32     dram_clk;
-+      u32     dram_type;
-+      u32     dram_zq;
-+      u32     dram_odt_en;
-+
-+      /* control configuration */
-+      u32     dram_para1;
-+      u32     dram_para2;
-+
-+      /* timing configuration */
-+      u32     dram_mr0;
-+      u32     dram_mr1;
-+      u32     dram_mr2;
-+      u32     dram_mr3;
-+      u32     dram_tpr0;      //DRAMTMG0
-+      u32     dram_tpr1;      //DRAMTMG1
-+      u32     dram_tpr2;      //DRAMTMG2
-+      u32     dram_tpr3;      //DRAMTMG3
-+      u32     dram_tpr4;      //DRAMTMG4
-+      u32     dram_tpr5;      //DRAMTMG5
-+      u32     dram_tpr6;      //DRAMTMG8
-+      u32     dram_tpr7;
-+      u32     dram_tpr8;
-+      u32     dram_tpr9;
-+      u32     dram_tpr10;
-+      u32     dram_tpr11;
-+      u32     dram_tpr12;
-+      u32     dram_tpr13;     /* contains a bitfield of DRAM setup settings */
-+} dram_para_t;
-+
-+static inline int ns_to_t(int nanoseconds)
-+{
-+      const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
-+
-+      return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
-+}
-+
-+#endif /* _SUNXI_DRAM_SUN20I_D1_H */
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4014-sunxi-introduce-NCAT2-generation-model.patch b/package/boot/uboot-sunxi/patches/4014-sunxi-introduce-NCAT2-generation-model.patch
new file mode 100644 (file)
index 0000000..0528970
--- /dev/null
@@ -0,0 +1,347 @@
+From abdc00eee12eed6db2a5e6fb7d72aae6be1d4193 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:54 +0100
+Subject: [PATCH 4014/4044] sunxi: introduce NCAT2 generation model
+
+Allwinner seems to typically stick to a common MMIO memory map for
+several SoCs, but from time to time does some breaking changes, which
+also introduce new generations of some peripherals. The last time this
+happened with the H6, which apart from re-organising the base addresses
+also changed the clock controller significantly. We added a
+CONFIG_SUN50I_GEN_H6 symbol back then to mark SoCs sharing those traits.
+
+Now the Allwinner D1 changes the memory map again, and also extends the
+pincontroller, among other peripherals.
+To mark this generation of SoCs, add a CONFIG_SUNXI_GEN_NCAT2 symbol,
+this name is reportedly used in the Allwinner BSP code, and prevents us
+from inventing our own name.
+
+Add this new symbol to some guards that were already checking for the H6
+generation, since many features are shared between the two (like the
+renovated clock controller).
+
+This paves the way to introduce a first user of this generation.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Sam Edwards <CFSworks@gmail.com>
+Tested-by: Sam Edwards <CFSworks@gmail.com>
+---
+ arch/arm/include/asm/arch-sunxi/clock.h       |  2 +-
+ arch/arm/include/asm/arch-sunxi/cpu.h         |  2 +
+ .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h  | 43 +++++++++++++++++++
+ arch/arm/include/asm/arch-sunxi/mmc.h         |  2 +-
+ arch/arm/include/asm/arch-sunxi/prcm.h        |  2 +-
+ arch/arm/include/asm/arch-sunxi/timer.h       |  2 +-
+ arch/arm/mach-sunxi/Kconfig                   | 12 +++++-
+ arch/arm/mach-sunxi/Makefile                  |  1 +
+ arch/arm/mach-sunxi/board.c                   | 22 ++++++----
+ common/spl/Kconfig                            |  2 +-
+ drivers/i2c/mvtwsi.c                          |  3 +-
+ drivers/mmc/sunxi_mmc.c                       | 10 +++--
+ include/sunxi_gpio.h                          |  3 ++
+ 13 files changed, 87 insertions(+), 19 deletions(-)
+ create mode 100644 arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
+
+diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
+index 2cfd540742..3d34261b0e 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock.h
++++ b/arch/arm/include/asm/arch-sunxi/clock.h
+@@ -16,7 +16,7 @@
+ /* clock control module regs definition */
+ #if defined(CONFIG_MACH_SUN8I_A83T)
+ #include <asm/arch/clock_sun8i_a83t.h>
+-#elif defined(CONFIG_SUN50I_GEN_H6)
++#elif defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
+ #include <asm/arch/clock_sun50i_h6.h>
+ #elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
+       defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
+index b08f202374..768c6572d6 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu.h
+@@ -10,6 +10,8 @@
+ #include <asm/arch/cpu_sun9i.h>
+ #elif defined(CONFIG_SUN50I_GEN_H6)
+ #include <asm/arch/cpu_sun50i_h6.h>
++#elif defined(CONFIG_SUNXI_GEN_NCAT2)
++#include <asm/arch/cpu_sunxi_ncat2.h>
+ #else
+ #include <asm/arch/cpu_sun4i.h>
+ #endif
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
+new file mode 100644
+index 0000000000..b13be2c4e8
+--- /dev/null
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
+@@ -0,0 +1,43 @@
++/*
++ * (C) Copyright 2022 Arm Limited
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#ifndef _SUNXI_CPU_SUNXI_NCAT2_H
++#define _SUNXI_CPU_SUNXI_NCAT2_H
++
++#define SUNXI_CCM_BASE                        0x02001000
++#define SUNXI_TIMER_BASE              0x02050000
++
++#define SUNXI_UART0_BASE              0x02500000
++#define SUNXI_UART1_BASE              0x02500400
++#define SUNXI_UART2_BASE              0x02500800
++#define SUNXI_UART3_BASE              0x02500C00
++#define SUNXI_TWI0_BASE                       0x02502000
++#define SUNXI_TWI1_BASE                       0x02502400
++#define SUNXI_TWI2_BASE                       0x02502800
++#define SUNXI_TWI3_BASE                       0x02502C00
++
++#define SUNXI_SRAMC_BASE              0x03000000
++/* SID address space starts at 0x03006000, but e-fuse is at offset 0x200 */
++#define SUNXI_SIDC_BASE                       0x03006000
++#define SUNXI_SID_BASE                        0x03006200
++#define SUNXI_GIC400_BASE             0x03020000
++
++#define SUNXI_MMC0_BASE                       0x04020000
++#define SUNXI_MMC1_BASE                       0x04021000
++#define SUNXI_MMC2_BASE                       0x04022000
++
++#define SUNXI_R_CPUCFG_BASE           0x07000400
++
++#define SUNXI_CPUX_BASE                       0x09010000
++#define SUNXI_CPUCFG_BASE             0
++
++#ifndef __ASSEMBLY__
++void sunxi_board_init(void);
++void sunxi_reset(void);
++int sunxi_get_sid(unsigned int *sid);
++#endif
++
++#endif /* _SUNXI_CPU_SUNXI_NCAT2_H */
+diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
+index 5daacf10eb..8ed3e0459c 100644
+--- a/arch/arm/include/asm/arch-sunxi/mmc.h
++++ b/arch/arm/include/asm/arch-sunxi/mmc.h
+@@ -45,7 +45,7 @@ struct sunxi_mmc {
+       u32 chda;               /* 0x90 */
+       u32 cbda;               /* 0x94 */
+       u32 res2[26];
+-#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
++#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
+       u32 res3[17];
+       u32 samp_dl;
+       u32 res4[46];
+diff --git a/arch/arm/include/asm/arch-sunxi/prcm.h b/arch/arm/include/asm/arch-sunxi/prcm.h
+index 5106076f5e..c5418cfd28 100644
+--- a/arch/arm/include/asm/arch-sunxi/prcm.h
++++ b/arch/arm/include/asm/arch-sunxi/prcm.h
+@@ -9,7 +9,7 @@
+ #define _SUNXI_PRCM_H
+ /* prcm regs definition */
+-#if defined(CONFIG_SUN50I_GEN_H6)
++#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
+ #include <asm/arch/prcm_sun50i.h>
+ #else
+ #include <asm/arch/prcm_sun6i.h>
+diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h
+index bb5626d893..e17db8588e 100644
+--- a/arch/arm/include/asm/arch-sunxi/timer.h
++++ b/arch/arm/include/asm/arch-sunxi/timer.h
+@@ -76,7 +76,7 @@ struct sunxi_timer_reg {
+       struct sunxi_tgp tgp[4];
+       u8 res5[8];
+       u32 cpu_cfg;
+-#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
++#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
+       u8 res3[16];
+       struct sunxi_wdog wdog[5];      /* We have 5 watchdogs */
+ #endif
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index b328ce8960..60ca1239dd 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -102,7 +102,7 @@ config AXP_PMIC_BUS
+ config SUNXI_SRAM_ADDRESS
+       hex
+       default 0x10000 if MACH_SUN9I || MACH_SUN50I || MACH_SUN50I_H5
+-      default 0x20000 if SUN50I_GEN_H6
++      default 0x20000 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
+       default 0x0
+       ---help---
+       Older Allwinner SoCs have their mask boot ROM mapped just below 4GB,
+@@ -144,6 +144,14 @@ config SUN50I_GEN_H6
+       Select this for sunxi SoCs which have H6 like peripherals, clocks
+       and memory map.
++config SUNXI_GEN_NCAT2
++      bool
++      select MMC_SUNXI_HAS_NEW_MODE
++      select SUPPORT_SPL
++      ---help---
++      Select this for sunxi SoCs which have D1 like peripherals, clocks
++      and memory map.
++
+ config SUNXI_DRAM_DW
+       bool
+       ---help---
+@@ -760,6 +768,7 @@ config VIDEO_SUNXI
+       depends on !MACH_SUN9I
+       depends on !MACH_SUN50I
+       depends on !SUN50I_GEN_H6
++      depends on !SUNXI_GEN_NCAT2
+       select VIDEO
+       select DISPLAY
+       imply VIDEO_DT_SIMPLEFB
+@@ -973,6 +982,7 @@ config SPL_STACK_R_ADDR
+       default 0x2fe00000 if MACH_SUN9I
+       default 0x4fe00000 if MACH_SUN50I
+       default 0x4fe00000 if SUN50I_GEN_H6
++      default 0x4fe00000 if SUNXI_GEN_NCAT2
+ config SPL_SPI_SUNXI
+       bool "Support for SPI Flash on Allwinner SoCs in SPL"
+diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
+index 671211e932..1d4c70ec35 100644
+--- a/arch/arm/mach-sunxi/Makefile
++++ b/arch/arm/mach-sunxi/Makefile
+@@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_SUN8I)     += clock_sun6i.o
+ endif
+ obj-$(CONFIG_MACH_SUN9I)      += clock_sun9i.o gtbus_sun9i.o
+ obj-$(CONFIG_SUN50I_GEN_H6)   += clock_sun50i_h6.o
++obj-$(CONFIG_SUNXI_GEN_NCAT2) += clock_sun50i_h6.o
+ ifndef CONFIG_ARM64
+ obj-y += timer.o
+ endif
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index ec46ab9279..51b8e708b0 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -176,13 +176,19 @@ static int gpio_init(void)
+ #error Unsupported console port number. Please fix pin mux settings in board.c
+ #endif
+-#ifdef CONFIG_SUN50I_GEN_H6
+-      /* Update PIO power bias configuration by copy hardware detected value */
+-      val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+-      writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+-      val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
+-      writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
+-#endif
++      /*
++       * Update PIO power bias configuration by copying the hardware
++       * detected value.
++       */
++      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
++          IS_ENABLED(CONFIG_SUN50I_GEN_NCAT2)) {
++              val = readl(SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
++              writel(val, SUNXI_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
++      }
++      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6)) {
++              val = readl(SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_VAL);
++              writel(val, SUNXI_R_PIO_BASE + SUN50I_H6_GPIO_POW_MOD_SEL);
++      }
+       return 0;
+ }
+@@ -481,7 +487,7 @@ void reset_cpu(void)
+               /* sun5i sometimes gets stuck without this */
+               writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode);
+       }
+-#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
++#elif defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
+ #if defined(CONFIG_MACH_SUN50I_H6)
+       /* WDOG is broken for some H6 rev. use the R_WDOG instead */
+       static const struct sunxi_wdog *wdog =
+diff --git a/common/spl/Kconfig b/common/spl/Kconfig
+index 3c2af453ab..06bcedca7d 100644
+--- a/common/spl/Kconfig
++++ b/common/spl/Kconfig
+@@ -265,7 +265,7 @@ config SPL_TEXT_BASE
+       default 0x402F0400 if AM33XX
+       default 0x40301350 if OMAP54XX
+       default 0x10060 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN9I
+-      default 0x20060 if SUN50I_GEN_H6
++      default 0x20060 if SUN50I_GEN_H6 || SUNXI_GEN_NCAT2
+       default 0x00060 if ARCH_SUNXI
+       default 0xfffc0000 if ARCH_ZYNQMP
+       default 0x0
+diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
+index 93bbc6916e..5c9b92ccf9 100644
+--- a/drivers/i2c/mvtwsi.c
++++ b/drivers/i2c/mvtwsi.c
+@@ -124,7 +124,8 @@ enum mvtwsi_ctrl_register_fields {
+  * on other platforms, it is a normal r/w bit, which is cleared by writing 0.
+  */
+-#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
++#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || \
++    defined(CONFIG_SUNXI_GEN_NCAT2)
+ #define       MVTWSI_CONTROL_CLEAR_IFLG       0x00000008
+ #else
+ #define       MVTWSI_CONTROL_CLEAR_IFLG       0x00000000
+diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
+index 03e33753fc..a8e590561c 100644
+--- a/drivers/mmc/sunxi_mmc.c
++++ b/drivers/mmc/sunxi_mmc.c
+@@ -57,6 +57,7 @@ static bool sunxi_mmc_can_calibrate(void)
+       return IS_ENABLED(CONFIG_MACH_SUN50I) ||
+              IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
+              IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
++             IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) ||
+              IS_ENABLED(CONFIG_MACH_SUN8I_R40);
+ }
+@@ -191,7 +192,7 @@ static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
+       rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
+       writel(rval, &priv->reg->clkcr);
+-#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
++#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
+       /* A64 supports calibration of delays on MMC controller and we
+        * have to set delay of zero before starting calibration.
+        * Allwinner BSP driver sets a delay only in the case of
+@@ -530,7 +531,8 @@ struct mmc *sunxi_mmc_init(int sdc_no)
+       cfg->host_caps = MMC_MODE_4BIT;
+       if ((IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_MACH_SUN8I) ||
+-          IS_ENABLED(CONFIG_SUN50I_GEN_H6)) && (sdc_no == 2))
++          IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
++          IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) && (sdc_no == 2))
+               cfg->host_caps = MMC_MODE_8BIT;
+       cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+@@ -544,7 +546,7 @@ struct mmc *sunxi_mmc_init(int sdc_no)
+       /* config ahb clock */
+       debug("init mmc %d clock and io\n", sdc_no);
+-#if !defined(CONFIG_SUN50I_GEN_H6)
++#if !defined(CONFIG_SUN50I_GEN_H6) && !defined(CONFIG_SUNXI_GEN_NCAT2)
+       setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
+ #ifdef CONFIG_SUNXI_GEN_SUN6I
+@@ -619,7 +621,7 @@ static unsigned get_mclk_offset(void)
+       if (IS_ENABLED(CONFIG_MACH_SUN9I_A80))
+               return 0x410;
+-      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
++      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
+               return 0x830;
+       return 0x88;
+diff --git a/include/sunxi_gpio.h b/include/sunxi_gpio.h
+index 61978db6db..8cf9047ff9 100644
+--- a/include/sunxi_gpio.h
++++ b/include/sunxi_gpio.h
+@@ -16,6 +16,9 @@
+ #elif defined(CONFIG_SUN50I_GEN_H6)
+ #define SUNXI_PIO_BASE                0x0300b000
+ #define SUNXI_R_PIO_BASE      0x07022000
++#elif defined(CONFIG_SUNXI_GEN_NCAT2)
++#define SUNXI_PIO_BASE                0x02000000
++#define SUNXI_R_PIO_BASE      0
+ #else
+ #define SUNXI_PIO_BASE                0x01c20800
+ #define SUNXI_R_PIO_BASE      0x01f02c00
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4015-pinctrl-sunxi-add-Allwinner-D1-pinctrl-description.patch b/package/boot/uboot-sunxi/patches/4015-pinctrl-sunxi-add-Allwinner-D1-pinctrl-description.patch
new file mode 100644 (file)
index 0000000..6dc13a3
--- /dev/null
@@ -0,0 +1,80 @@
+From 8221f71488b4fb448af0c23d2c9c56bea230584d Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:55 +0100
+Subject: [PATCH 4015/4044] pinctrl: sunxi: add Allwinner D1 pinctrl
+ description
+
+Apart from using the new pinctrl MMIO register layout, the Allwinner D1
+and related SoCs still need to usual set of mux values hardcoded in
+U-Boot's pinctrl driver.
+Add the values we need so far to this list, so that DM based drivers
+will just work without further ado.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ drivers/pinctrl/sunxi/Kconfig         |  4 ++++
+ drivers/pinctrl/sunxi/pinctrl-sunxi.c | 28 +++++++++++++++++++++++++++
+ 2 files changed, 32 insertions(+)
+
+diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
+index 77da90836b..c8f937d91e 100644
+--- a/drivers/pinctrl/sunxi/Kconfig
++++ b/drivers/pinctrl/sunxi/Kconfig
+@@ -124,4 +124,8 @@ config PINCTRL_SUN50I_H616_R
+       default MACH_SUN50I_H616
+       select PINCTRL_SUNXI
++config PINCTRL_SUN20I_D1
++      bool "Support for the Allwinner D1/R528 PIO"
++      select PINCTRL_SUNXI
++
+ endif
+diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+index 4c52e3fa74..614cfe6b73 100644
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -735,6 +735,28 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc
+       .num_banks      = 1,
+ };
++static const struct sunxi_pinctrl_function sun20i_d1_pinctrl_functions[] = {
++      { "emac",       8 },    /* PE0-PE15 */
++      { "gpio_in",    0 },
++      { "gpio_out",   1 },
++      { "mmc0",       2 },    /* PF0-PF5 */
++      { "mmc2",       3 },    /* PC1-PC7 */
++      { "spi0",       2 },    /* PC2-PC7 */
++#if IS_ENABLED(CONFIG_UART0_PORT_F)
++      { "uart0",      3 },    /* PF2-PF4 */
++#else
++      { "uart0",      6 },    /* PB2-PB3 */
++#endif
++      { "uart3",      7 },    /* PB6-PB9 */
++};
++
++static const struct sunxi_pinctrl_desc __maybe_unused sun20i_d1_pinctrl_desc = {
++      .functions      = sun20i_d1_pinctrl_functions,
++      .num_functions  = ARRAY_SIZE(sun20i_d1_pinctrl_functions),
++      .first_bank     = SUNXI_GPIO_A,
++      .num_banks      = 7,
++};
++
+ static const struct udevice_id sunxi_pinctrl_ids[] = {
+ #ifdef CONFIG_PINCTRL_SUNIV_F1C100S
+       {
+@@ -891,6 +913,12 @@ static const struct udevice_id sunxi_pinctrl_ids[] = {
+               .compatible = "allwinner,sun50i-h616-r-pinctrl",
+               .data = (ulong)&sun50i_h616_r_pinctrl_desc,
+       },
++#endif
++#ifdef CONFIG_PINCTRL_SUN20I_D1
++      {
++              .compatible = "allwinner,sun20i-d1-pinctrl",
++              .data = (ulong)&sun20i_d1_pinctrl_desc,
++      },
+ #endif
+       {}
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4015-sunxi-add-early-Allwinner-R528-T113-SoC-support.patch b/package/boot/uboot-sunxi/patches/4015-sunxi-add-early-Allwinner-R528-T113-SoC-support.patch
deleted file mode 100644 (file)
index 32eb73b..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-From bc8f569427d231f9cd0f483474af870cafa857e4 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Tue, 6 Sep 2022 15:59:57 +0100
-Subject: [PATCH 4015/4031] sunxi: add early Allwinner R528/T113 SoC support
-
-This adds the remaining code bits to teach U-Boot about Allwinner's
-newest SoC generation. This was introduced with the RISC-V based
-Allwinner D1 SoC, which actually shares a die with the ARM cores versions
-called R528 (BGA, without DRAM) and T113s (QFP, with embedded DRAM).
-
-This adds the new Kconfig stanza, using the two newly introduced symbols
-for the new SoC generation and pincontroller. It also adds the new symbols
-to the relavent code places, to set all the hardcoded bits directly.
-
-We just chicken out the DRAM controller code for now with a stub to make
-it compile. There is GPLed code out there that can be used, although that
-still looks very much like the disassembly/decompile it came from.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h |  9 +++++++--
- arch/arm/mach-sunxi/Kconfig                       | 10 ++++++++++
- arch/arm/mach-sunxi/board.c                       |  8 ++++++++
- arch/arm/mach-sunxi/clock_sun50i_h6.c             |  2 ++
- arch/arm/mach-sunxi/cpu_info.c                    |  2 ++
- common/spl/Kconfig                                |  1 +
- drivers/mmc/sunxi_mmc.c                           |  1 +
- drivers/pinctrl/sunxi/Kconfig                     |  1 +
- 8 files changed, 32 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-index 8471e11aa0..a84a57e5b4 100644
---- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-+++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
-@@ -266,7 +266,7 @@ struct sunxi_ccm_reg {
- #define CCM_CPU_AXI_AXI_MASK          0x3
- #define CCM_CPU_AXI_DEFAULT_FACTORS   0x301
--#ifdef CONFIG_MACH_SUN50I_H6
-+#ifdef CONFIG_MACH_SUN50I_H6                          /* H6 */
- #define CCM_PLL6_DEFAULT              0xa0006300
- /* psi_ahb1_ahb2 bit field */
-@@ -277,7 +277,7 @@ struct sunxi_ccm_reg {
- /* apb1 bit field */
- #define CCM_APB1_DEFAULT              0x03000102
--#elif CONFIG_MACH_SUN50I_H616
-+#elif CONFIG_MACH_SUN50I_H616                         /* H616 */
- #define CCM_PLL6_DEFAULT              0xa8003100
- /* psi_ahb1_ahb2 bit field */
-@@ -288,6 +288,11 @@ struct sunxi_ccm_reg {
- /* apb1 bit field */
- #define CCM_APB1_DEFAULT              0x03000102
-+#elif CONFIG_MACH_SUN8I_R528                          /* R528 */
-+#define CCM_PLL6_DEFAULT              0xe8216300
-+#define CCM_PSI_AHB1_AHB2_DEFAULT     0x03000002
-+//#define CCM_AHB3_DEFAULT            0x03000002
-+#define CCM_APB1_DEFAULT              0x03000102
- #endif
- /* apb2 bit field */
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index 057b0ccd33..142d86afc6 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -318,6 +318,15 @@ config MACH_SUN8I_R40
-       select PHY_SUN4I_USB
-       imply SPL_SYS_I2C_LEGACY
-+config MACH_SUN8I_R528
-+      bool "sun8i (Allwinner R528)"
-+      select CPU_V7A
-+      select SUNXI_GEN_NCAT2
-+      select SUNXI_NEW_PINCTRL
-+      select MMC_SUNXI_HAS_NEW_MODE
-+      select SUPPORT_SPL
-+      select DRAM_SUN8I_R528
-+
- config MACH_SUN8I_V3S
-       bool "sun8i (Allwinner V3/V3s/S3/S3L)"
-       select CPU_V7A
-@@ -622,6 +631,7 @@ config SYS_CONFIG_NAME
-       default "sun6i" if MACH_SUN6I
-       default "sun7i" if MACH_SUN7I
-       default "sun8i" if MACH_SUN8I
-+      default "sun8i" if MACH_SUN8I_R528
-       default "sun9i" if MACH_SUN9I
-       default "sun50i" if MACH_SUN50I
-       default "sun50i" if MACH_SUN50I_H6
-diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
-index 6d96182226..df4f32d10c 100644
---- a/arch/arm/mach-sunxi/board.c
-+++ b/arch/arm/mach-sunxi/board.c
-@@ -147,6 +147,10 @@ static int gpio_init(void)
-       sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0);
-       sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0);
-       sunxi_gpio_set_pull(SUNXI_GPH(13), SUNXI_GPIO_PULL_UP);
-+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_R528)
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(2), 6);
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(3), 6);
-+      sunxi_gpio_set_pull(SUNXI_GPE(3), SUNXI_GPIO_PULL_UP);
- #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUNIV)
-       sunxi_gpio_set_cfgpin(SUNXI_GPA(2), SUNIV_GPE_UART0);
-       sunxi_gpio_set_cfgpin(SUNXI_GPA(3), SUNIV_GPE_UART0);
-@@ -163,6 +167,10 @@ static int gpio_init(void)
-       sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_GPB_UART2);
-       sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
-       sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
-+#elif CONFIG_CONS_INDEX == 4 && defined(CONFIG_MACH_SUN8I_R528)
-+      sunxi_gpio_set_cfgpin(SUNXI_GPB(6), 7);
-+      sunxi_gpio_set_cfgpin(SUNXI_GPB(7), 7);
-+      sunxi_gpio_set_pull(SUNXI_GPB(7), SUNXI_GPIO_PULL_UP);
- #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
-       sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
-       sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
-diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
-index 607efe6a9c..4d5e23a9af 100644
---- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
-+++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
-@@ -38,7 +38,9 @@ void clock_init_safe(void)
-                       CCM_CPU_AXI_DEFAULT_FACTORS);
-       writel(CCM_PSI_AHB1_AHB2_DEFAULT, &ccm->psi_ahb1_ahb2_cfg);
-+#ifdef CCM_AHB3_DEFAULT
-       writel(CCM_AHB3_DEFAULT, &ccm->ahb3_cfg);
-+#endif
-       writel(CCM_APB1_DEFAULT, &ccm->apb1_cfg);
-       /*
-diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
-index 7eef178859..7fecc3b88d 100644
---- a/arch/arm/mach-sunxi/cpu_info.c
-+++ b/arch/arm/mach-sunxi/cpu_info.c
-@@ -93,6 +93,8 @@ int print_cpuinfo(void)
-       printf("CPU:   Allwinner R40 (SUN8I %04x)\n", sunxi_get_sram_id());
- #elif defined CONFIG_MACH_SUN8I_V3S
-       printf("CPU:   Allwinner V3s (SUN8I %04x)\n", sunxi_get_sram_id());
-+#elif defined CONFIG_MACH_SUN8I_R528
-+      puts("CPU:   Allwinner R528 (SUN8I)\n");
- #elif defined CONFIG_MACH_SUN9I
-       puts("CPU:   Allwinner A80 (SUN9I)\n");
- #elif defined CONFIG_MACH_SUN50I
-diff --git a/common/spl/Kconfig b/common/spl/Kconfig
-index 06bcedca7d..196a250ef9 100644
---- a/common/spl/Kconfig
-+++ b/common/spl/Kconfig
-@@ -357,6 +357,7 @@ config SPL_STACK
-       default 0x91ffb8 if ARCH_MX6 && !MX6_OCRAM_256KB
-       default 0x118000 if MACH_SUN50I_H6
-       default 0x58000 if MACH_SUN50I_H616
-+      default 0x40000 if MACH_SUN8I_R528
-       default 0x54000 if MACH_SUN50I || MACH_SUN50I_H5
-       default 0x18000 if MACH_SUN9I
-       default 0x8000 if ARCH_SUNXI
-diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
-index a8e590561c..0837e8bb30 100644
---- a/drivers/mmc/sunxi_mmc.c
-+++ b/drivers/mmc/sunxi_mmc.c
-@@ -708,6 +708,7 @@ static const struct udevice_id sunxi_mmc_ids[] = {
-       { .compatible = "allwinner,sun50i-h6-emmc" },
-       { .compatible = "allwinner,sun50i-a100-mmc" },
-       { .compatible = "allwinner,sun50i-a100-emmc" },
-+      { .compatible = "allwinner,sun20i-d1-mmc" },
-       { /* sentinel */ }
- };
-diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
-index c8f937d91e..cbd6179598 100644
---- a/drivers/pinctrl/sunxi/Kconfig
-+++ b/drivers/pinctrl/sunxi/Kconfig
-@@ -126,6 +126,7 @@ config PINCTRL_SUN50I_H616_R
- config PINCTRL_SUN20I_D1
-       bool "Support for the Allwinner D1/R528 PIO"
-+      default MACH_SUN8I_R528
-       select PINCTRL_SUNXI
- endif
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4016-clk-sunxi-Add-support-for-the-D1-CCU.patch b/package/boot/uboot-sunxi/patches/4016-clk-sunxi-Add-support-for-the-D1-CCU.patch
new file mode 100644 (file)
index 0000000..dc40f5e
--- /dev/null
@@ -0,0 +1,418 @@
+From 716a59d3d21ebb997f345b28b972d8f6e627fe34 Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Fri, 21 Jul 2023 14:45:56 +0100
+Subject: [PATCH 4016/4044] clk: sunxi: Add support for the D1 CCU
+
+Since the D1 CCU binding is defined, we can add support for its
+gates/resets, following the pattern of the existing drivers.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Sean Anderson <seanga2@gmail.com>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ drivers/clk/sunxi/Kconfig                 |   6 +
+ drivers/clk/sunxi/Makefile                |   1 +
+ drivers/clk/sunxi/clk_d1.c                |  84 ++++++++++++
+ drivers/clk/sunxi/clk_sunxi.c             |   5 +
+ include/dt-bindings/clock/sun20i-d1-ccu.h | 158 ++++++++++++++++++++++
+ include/dt-bindings/reset/sun20i-d1-ccu.h |  79 +++++++++++
+ 6 files changed, 333 insertions(+)
+ create mode 100644 drivers/clk/sunxi/clk_d1.c
+ create mode 100644 include/dt-bindings/clock/sun20i-d1-ccu.h
+ create mode 100644 include/dt-bindings/reset/sun20i-d1-ccu.h
+
+diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
+index bf11fad6ee..f65e482ba4 100644
+--- a/drivers/clk/sunxi/Kconfig
++++ b/drivers/clk/sunxi/Kconfig
+@@ -87,6 +87,12 @@ config CLK_SUN8I_H3
+         This enables common clock driver support for platforms based
+         on Allwinner H3/H5 SoC.
++config CLK_SUN20I_D1
++      bool "Clock driver for Allwinner D1"
++      help
++        This enables common clock driver support for platforms based
++        on Allwinner D1 SoC.
++
+ config CLK_SUN50I_H6
+       bool "Clock driver for Allwinner H6"
+       default MACH_SUN50I_H6
+diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
+index 895da02ebe..90a277489d 100644
+--- a/drivers/clk/sunxi/Makefile
++++ b/drivers/clk/sunxi/Makefile
+@@ -19,6 +19,7 @@ obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o
+ obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o
+ obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o
+ obj-$(CONFIG_CLK_SUN8I_H3) += clk_h3.o
++obj-$(CONFIG_CLK_SUN20I_D1) += clk_d1.o
+ obj-$(CONFIG_CLK_SUN50I_H6) += clk_h6.o
+ obj-$(CONFIG_CLK_SUN50I_H6_R) += clk_h6_r.o
+ obj-$(CONFIG_CLK_SUN50I_H616) += clk_h616.o
+diff --git a/drivers/clk/sunxi/clk_d1.c b/drivers/clk/sunxi/clk_d1.c
+new file mode 100644
+index 0000000000..9dae761de8
+--- /dev/null
++++ b/drivers/clk/sunxi/clk_d1.c
+@@ -0,0 +1,84 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
++ */
++
++#include <common.h>
++#include <clk-uclass.h>
++#include <dm.h>
++#include <errno.h>
++#include <clk/sunxi.h>
++#include <dt-bindings/clock/sun20i-d1-ccu.h>
++#include <dt-bindings/reset/sun20i-d1-ccu.h>
++#include <linux/bitops.h>
++
++static struct ccu_clk_gate d1_gates[] = {
++      [CLK_APB0]              = GATE_DUMMY,
++
++      [CLK_BUS_MMC0]          = GATE(0x84c, BIT(0)),
++      [CLK_BUS_MMC1]          = GATE(0x84c, BIT(1)),
++      [CLK_BUS_MMC2]          = GATE(0x84c, BIT(2)),
++      [CLK_BUS_UART0]         = GATE(0x90c, BIT(0)),
++      [CLK_BUS_UART1]         = GATE(0x90c, BIT(1)),
++      [CLK_BUS_UART2]         = GATE(0x90c, BIT(2)),
++      [CLK_BUS_UART3]         = GATE(0x90c, BIT(3)),
++      [CLK_BUS_UART4]         = GATE(0x90c, BIT(4)),
++      [CLK_BUS_UART5]         = GATE(0x90c, BIT(5)),
++      [CLK_BUS_I2C0]          = GATE(0x91c, BIT(0)),
++      [CLK_BUS_I2C1]          = GATE(0x91c, BIT(1)),
++      [CLK_BUS_I2C2]          = GATE(0x91c, BIT(2)),
++      [CLK_BUS_I2C3]          = GATE(0x91c, BIT(3)),
++      [CLK_SPI0]              = GATE(0x940, BIT(31)),
++      [CLK_SPI1]              = GATE(0x944, BIT(31)),
++      [CLK_BUS_SPI0]          = GATE(0x96c, BIT(0)),
++      [CLK_BUS_SPI1]          = GATE(0x96c, BIT(1)),
++
++      [CLK_BUS_EMAC]          = GATE(0x97c, BIT(0)),
++
++      [CLK_USB_OHCI0]         = GATE(0xa70, BIT(31)),
++      [CLK_USB_OHCI1]         = GATE(0xa74, BIT(31)),
++      [CLK_BUS_OHCI0]         = GATE(0xa8c, BIT(0)),
++      [CLK_BUS_OHCI1]         = GATE(0xa8c, BIT(1)),
++      [CLK_BUS_EHCI0]         = GATE(0xa8c, BIT(4)),
++      [CLK_BUS_EHCI1]         = GATE(0xa8c, BIT(5)),
++      [CLK_BUS_OTG]           = GATE(0xa8c, BIT(8)),
++      [CLK_BUS_LRADC]         = GATE(0xa9c, BIT(0)),
++
++      [CLK_RISCV]             = GATE(0xd04, BIT(31)),
++};
++
++static struct ccu_reset d1_resets[] = {
++      [RST_BUS_MMC0]          = RESET(0x84c, BIT(16)),
++      [RST_BUS_MMC1]          = RESET(0x84c, BIT(17)),
++      [RST_BUS_MMC2]          = RESET(0x84c, BIT(18)),
++      [RST_BUS_UART0]         = RESET(0x90c, BIT(16)),
++      [RST_BUS_UART1]         = RESET(0x90c, BIT(17)),
++      [RST_BUS_UART2]         = RESET(0x90c, BIT(18)),
++      [RST_BUS_UART3]         = RESET(0x90c, BIT(19)),
++      [RST_BUS_UART4]         = RESET(0x90c, BIT(20)),
++      [RST_BUS_UART5]         = RESET(0x90c, BIT(21)),
++      [RST_BUS_I2C0]          = RESET(0x91c, BIT(16)),
++      [RST_BUS_I2C1]          = RESET(0x91c, BIT(17)),
++      [RST_BUS_I2C2]          = RESET(0x91c, BIT(18)),
++      [RST_BUS_I2C3]          = RESET(0x91c, BIT(19)),
++      [RST_BUS_SPI0]          = RESET(0x96c, BIT(16)),
++      [RST_BUS_SPI1]          = RESET(0x96c, BIT(17)),
++
++      [RST_BUS_EMAC]          = RESET(0x97c, BIT(16)),
++
++      [RST_USB_PHY0]          = RESET(0xa70, BIT(30)),
++      [RST_USB_PHY1]          = RESET(0xa74, BIT(30)),
++      [RST_BUS_OHCI0]         = RESET(0xa8c, BIT(16)),
++      [RST_BUS_OHCI1]         = RESET(0xa8c, BIT(17)),
++      [RST_BUS_EHCI0]         = RESET(0xa8c, BIT(20)),
++      [RST_BUS_EHCI1]         = RESET(0xa8c, BIT(21)),
++      [RST_BUS_OTG]           = RESET(0xa8c, BIT(24)),
++      [RST_BUS_LRADC]         = RESET(0xa9c, BIT(16)),
++};
++
++const struct ccu_desc d1_ccu_desc = {
++      .gates  = d1_gates,
++      .resets = d1_resets,
++      .num_gates = ARRAY_SIZE(d1_gates),
++      .num_resets = ARRAY_SIZE(d1_resets),
++};
+diff --git a/drivers/clk/sunxi/clk_sunxi.c b/drivers/clk/sunxi/clk_sunxi.c
+index ec02a2d037..a0011a35d9 100644
+--- a/drivers/clk/sunxi/clk_sunxi.c
++++ b/drivers/clk/sunxi/clk_sunxi.c
+@@ -118,6 +118,7 @@ extern const struct ccu_desc a64_ccu_desc;
+ extern const struct ccu_desc a80_ccu_desc;
+ extern const struct ccu_desc a80_mmc_clk_desc;
+ extern const struct ccu_desc a83t_ccu_desc;
++extern const struct ccu_desc d1_ccu_desc;
+ extern const struct ccu_desc f1c100s_ccu_desc;
+ extern const struct ccu_desc h3_ccu_desc;
+ extern const struct ccu_desc h6_ccu_desc;
+@@ -214,6 +215,10 @@ static const struct udevice_id sunxi_clk_ids[] = {
+ #ifdef CONFIG_CLK_SUNIV_F1C100S
+       { .compatible = "allwinner,suniv-f1c100s-ccu",
+         .data = (ulong)&f1c100s_ccu_desc },
++#endif
++#ifdef CONFIG_CLK_SUN20I_D1
++      { .compatible = "allwinner,sun20i-d1-ccu",
++        .data = (ulong)&d1_ccu_desc },
+ #endif
+       { }
+ };
+diff --git a/include/dt-bindings/clock/sun20i-d1-ccu.h b/include/dt-bindings/clock/sun20i-d1-ccu.h
+new file mode 100644
+index 0000000000..e143b99297
+--- /dev/null
++++ b/include/dt-bindings/clock/sun20i-d1-ccu.h
+@@ -0,0 +1,158 @@
++/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
++/*
++ * Copyright (C) 2020 huangzhenwei@allwinnertech.com
++ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
++ */
++
++#ifndef _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
++#define _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
++
++#define CLK_PLL_CPUX          0
++#define CLK_PLL_DDR0          1
++#define CLK_PLL_PERIPH0_4X    2
++#define CLK_PLL_PERIPH0_2X    3
++#define CLK_PLL_PERIPH0_800M  4
++#define CLK_PLL_PERIPH0               5
++#define CLK_PLL_PERIPH0_DIV3  6
++#define CLK_PLL_VIDEO0_4X     7
++#define CLK_PLL_VIDEO0_2X     8
++#define CLK_PLL_VIDEO0                9
++#define CLK_PLL_VIDEO1_4X     10
++#define CLK_PLL_VIDEO1_2X     11
++#define CLK_PLL_VIDEO1                12
++#define CLK_PLL_VE            13
++#define CLK_PLL_AUDIO0_4X     14
++#define CLK_PLL_AUDIO0_2X     15
++#define CLK_PLL_AUDIO0                16
++#define CLK_PLL_AUDIO1                17
++#define CLK_PLL_AUDIO1_DIV2   18
++#define CLK_PLL_AUDIO1_DIV5   19
++#define CLK_CPUX              20
++#define CLK_CPUX_AXI          21
++#define CLK_CPUX_APB          22
++#define CLK_PSI_AHB           23
++#define CLK_APB0              24
++#define CLK_APB1              25
++#define CLK_MBUS              26
++#define CLK_DE                        27
++#define CLK_BUS_DE            28
++#define CLK_DI                        29
++#define CLK_BUS_DI            30
++#define CLK_G2D                       31
++#define CLK_BUS_G2D           32
++#define CLK_CE                        33
++#define CLK_BUS_CE            34
++#define CLK_VE                        35
++#define CLK_BUS_VE            36
++#define CLK_BUS_DMA           37
++#define CLK_BUS_MSGBOX0               38
++#define CLK_BUS_MSGBOX1               39
++#define CLK_BUS_MSGBOX2               40
++#define CLK_BUS_SPINLOCK      41
++#define CLK_BUS_HSTIMER               42
++#define CLK_AVS                       43
++#define CLK_BUS_DBG           44
++#define CLK_BUS_PWM           45
++#define CLK_BUS_IOMMU         46
++#define CLK_DRAM              47
++#define CLK_MBUS_DMA          48
++#define CLK_MBUS_VE           49
++#define CLK_MBUS_CE           50
++#define CLK_MBUS_TVIN         51
++#define CLK_MBUS_CSI          52
++#define CLK_MBUS_G2D          53
++#define CLK_MBUS_RISCV                54
++#define CLK_BUS_DRAM          55
++#define CLK_MMC0              56
++#define CLK_MMC1              57
++#define CLK_MMC2              58
++#define CLK_BUS_MMC0          59
++#define CLK_BUS_MMC1          60
++#define CLK_BUS_MMC2          61
++#define CLK_BUS_UART0         62
++#define CLK_BUS_UART1         63
++#define CLK_BUS_UART2         64
++#define CLK_BUS_UART3         65
++#define CLK_BUS_UART4         66
++#define CLK_BUS_UART5         67
++#define CLK_BUS_I2C0          68
++#define CLK_BUS_I2C1          69
++#define CLK_BUS_I2C2          70
++#define CLK_BUS_I2C3          71
++#define CLK_SPI0              72
++#define CLK_SPI1              73
++#define CLK_BUS_SPI0          74
++#define CLK_BUS_SPI1          75
++#define CLK_EMAC_25M          76
++#define CLK_BUS_EMAC          77
++#define CLK_IR_TX             78
++#define CLK_BUS_IR_TX         79
++#define CLK_BUS_GPADC         80
++#define CLK_BUS_THS           81
++#define CLK_I2S0              82
++#define CLK_I2S1              83
++#define CLK_I2S2              84
++#define CLK_I2S2_ASRC         85
++#define CLK_BUS_I2S0          86
++#define CLK_BUS_I2S1          87
++#define CLK_BUS_I2S2          88
++#define CLK_SPDIF_TX          89
++#define CLK_SPDIF_RX          90
++#define CLK_BUS_SPDIF         91
++#define CLK_DMIC              92
++#define CLK_BUS_DMIC          93
++#define CLK_AUDIO_DAC         94
++#define CLK_AUDIO_ADC         95
++#define CLK_BUS_AUDIO         96
++#define CLK_USB_OHCI0         97
++#define CLK_USB_OHCI1         98
++#define CLK_BUS_OHCI0         99
++#define CLK_BUS_OHCI1         100
++#define CLK_BUS_EHCI0         101
++#define CLK_BUS_EHCI1         102
++#define CLK_BUS_OTG           103
++#define CLK_BUS_LRADC         104
++#define CLK_BUS_DPSS_TOP      105
++#define CLK_HDMI_24M          106
++#define CLK_HDMI_CEC_32K      107
++#define CLK_HDMI_CEC          108
++#define CLK_BUS_HDMI          109
++#define CLK_MIPI_DSI          110
++#define CLK_BUS_MIPI_DSI      111
++#define CLK_TCON_LCD0         112
++#define CLK_BUS_TCON_LCD0     113
++#define CLK_TCON_TV           114
++#define CLK_BUS_TCON_TV               115
++#define CLK_TVE                       116
++#define CLK_BUS_TVE_TOP               117
++#define CLK_BUS_TVE           118
++#define CLK_TVD                       119
++#define CLK_BUS_TVD_TOP               120
++#define CLK_BUS_TVD           121
++#define CLK_LEDC              122
++#define CLK_BUS_LEDC          123
++#define CLK_CSI_TOP           124
++#define CLK_CSI_MCLK          125
++#define CLK_BUS_CSI           126
++#define CLK_TPADC             127
++#define CLK_BUS_TPADC         128
++#define CLK_BUS_TZMA          129
++#define CLK_DSP                       130
++#define CLK_BUS_DSP_CFG               131
++#define CLK_RISCV             132
++#define CLK_RISCV_AXI         133
++#define CLK_BUS_RISCV_CFG     134
++#define CLK_FANOUT_24M                135
++#define CLK_FANOUT_12M                136
++#define CLK_FANOUT_16M                137
++#define CLK_FANOUT_25M                138
++#define CLK_FANOUT_32K                139
++#define CLK_FANOUT_27M                140
++#define CLK_FANOUT_PCLK               141
++#define CLK_FANOUT0           142
++#define CLK_FANOUT1           143
++#define CLK_FANOUT2           144
++#define CLK_BUS_CAN0          145
++#define CLK_BUS_CAN1          146
++
++#endif /* _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_ */
+diff --git a/include/dt-bindings/reset/sun20i-d1-ccu.h b/include/dt-bindings/reset/sun20i-d1-ccu.h
+new file mode 100644
+index 0000000000..f8001cf50b
+--- /dev/null
++++ b/include/dt-bindings/reset/sun20i-d1-ccu.h
+@@ -0,0 +1,79 @@
++/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
++/*
++ * Copyright (c) 2020 huangzhenwei@allwinnertech.com
++ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
++ */
++
++#ifndef _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
++#define _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
++
++#define RST_MBUS              0
++#define RST_BUS_DE            1
++#define RST_BUS_DI            2
++#define RST_BUS_G2D           3
++#define RST_BUS_CE            4
++#define RST_BUS_VE            5
++#define RST_BUS_DMA           6
++#define RST_BUS_MSGBOX0               7
++#define RST_BUS_MSGBOX1               8
++#define RST_BUS_MSGBOX2               9
++#define RST_BUS_SPINLOCK      10
++#define RST_BUS_HSTIMER               11
++#define RST_BUS_DBG           12
++#define RST_BUS_PWM           13
++#define RST_BUS_DRAM          14
++#define RST_BUS_MMC0          15
++#define RST_BUS_MMC1          16
++#define RST_BUS_MMC2          17
++#define RST_BUS_UART0         18
++#define RST_BUS_UART1         19
++#define RST_BUS_UART2         20
++#define RST_BUS_UART3         21
++#define RST_BUS_UART4         22
++#define RST_BUS_UART5         23
++#define RST_BUS_I2C0          24
++#define RST_BUS_I2C1          25
++#define RST_BUS_I2C2          26
++#define RST_BUS_I2C3          27
++#define RST_BUS_SPI0          28
++#define RST_BUS_SPI1          29
++#define RST_BUS_EMAC          30
++#define RST_BUS_IR_TX         31
++#define RST_BUS_GPADC         32
++#define RST_BUS_THS           33
++#define RST_BUS_I2S0          34
++#define RST_BUS_I2S1          35
++#define RST_BUS_I2S2          36
++#define RST_BUS_SPDIF         37
++#define RST_BUS_DMIC          38
++#define RST_BUS_AUDIO         39
++#define RST_USB_PHY0          40
++#define RST_USB_PHY1          41
++#define RST_BUS_OHCI0         42
++#define RST_BUS_OHCI1         43
++#define RST_BUS_EHCI0         44
++#define RST_BUS_EHCI1         45
++#define RST_BUS_OTG           46
++#define RST_BUS_LRADC         47
++#define RST_BUS_DPSS_TOP      48
++#define RST_BUS_HDMI_SUB      49
++#define RST_BUS_HDMI_MAIN     50
++#define RST_BUS_MIPI_DSI      51
++#define RST_BUS_TCON_LCD0     52
++#define RST_BUS_TCON_TV               53
++#define RST_BUS_LVDS0         54
++#define RST_BUS_TVE           55
++#define RST_BUS_TVE_TOP               56
++#define RST_BUS_TVD           57
++#define RST_BUS_TVD_TOP               58
++#define RST_BUS_LEDC          59
++#define RST_BUS_CSI           60
++#define RST_BUS_TPADC         61
++#define RST_DSP                       62
++#define RST_BUS_DSP_CFG               63
++#define RST_BUS_DSP_DBG               64
++#define RST_BUS_RISCV_CFG     65
++#define RST_BUS_CAN0          66
++#define RST_BUS_CAN1          67
++
++#endif /* _DT_BINDINGS_RST_SUN20I_D1_CCU_H_ */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4016-sunxi-refactor-serial-base-addresses-to-avoid-asm-ar.patch b/package/boot/uboot-sunxi/patches/4016-sunxi-refactor-serial-base-addresses-to-avoid-asm-ar.patch
deleted file mode 100644 (file)
index 6b9f8fa..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-From 733d8e8ac84a4936cdd55a688f41dd8de10d870c Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Sun, 3 Jul 2022 00:14:24 +0100
-Subject: [PATCH 4016/4031] sunxi: refactor serial base addresses to avoid
- asm/arch/cpu.h
-
-At the moment we have each SoC's memory map defined in its own cpu.h,
-which is included in include/configs/sunxi_common.h. This will be a
-problem with the introduction of Allwinner RISC-V support.
-
-Remove the inclusion of that header file from the common config header,
-instead move the required serial base addresses (for the SPL) into a
-separate header file. Then include the original cpu.h file only where
-we really need it, which is only under arch/arm now.
-
-This disentangles the architecture specific header files from the
-generic code.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/cpu/armv7/sunxi/sram.c               |  1 +
- arch/arm/cpu/armv8/fel_utils.S                |  1 +
- arch/arm/include/asm/arch-sunxi/clock.h       |  1 +
- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h   | 15 ---------
- .../include/asm/arch-sunxi/cpu_sun50i_h6.h    |  5 ---
- arch/arm/include/asm/arch-sunxi/cpu_sun9i.h   |  7 ----
- .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h  |  5 ---
- arch/arm/include/asm/arch-sunxi/serial.h      | 32 +++++++++++++++++++
- arch/arm/mach-sunxi/gtbus_sun9i.c             |  1 +
- arch/arm/mach-sunxi/timer.c                   |  1 +
- include/configs/sunxi-common.h                |  2 +-
- 11 files changed, 38 insertions(+), 33 deletions(-)
- create mode 100644 arch/arm/include/asm/arch-sunxi/serial.h
-
-diff --git a/arch/arm/cpu/armv7/sunxi/sram.c b/arch/arm/cpu/armv7/sunxi/sram.c
-index 28564c2846..28ff6a1b7c 100644
---- a/arch/arm/cpu/armv7/sunxi/sram.c
-+++ b/arch/arm/cpu/armv7/sunxi/sram.c
-@@ -12,6 +12,7 @@
- #include <common.h>
- #include <init.h>
- #include <asm/io.h>
-+#include <asm/arch/cpu.h>
- void sunxi_sram_init(void)
- {
-diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S
-index 2fe38a1a04..939869b9ff 100644
---- a/arch/arm/cpu/armv8/fel_utils.S
-+++ b/arch/arm/cpu/armv8/fel_utils.S
-@@ -10,6 +10,7 @@
- #include <config.h>
- #include <asm/system.h>
- #include <linux/linkage.h>
-+#include <asm/arch/cpu.h>
- /*
-  * We don't overwrite save_boot_params() here, to save the FEL state upon
-diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
-index 3d34261b0e..fcc8966cb0 100644
---- a/arch/arm/include/asm/arch-sunxi/clock.h
-+++ b/arch/arm/include/asm/arch-sunxi/clock.h
-@@ -9,6 +9,7 @@
- #define _SUNXI_CLOCK_H
- #include <linux/types.h>
-+#include <asm/arch/cpu.h>
- #define CLK_GATE_OPEN                 0x1
- #define CLK_GATE_CLOSE                        0x0
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
-index d6fe51f24b..3daee2f574 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
-@@ -128,20 +128,6 @@ defined(CONFIG_MACH_SUN50I)
- #define SUNXI_CPUCFG_BASE             0x01c25c00
- #endif
--#ifdef CONFIG_MACH_SUNIV
--#define SUNXI_UART0_BASE              0x01c25000
--#define SUNXI_UART1_BASE              0x01c25400
--#define SUNXI_UART2_BASE              0x01c25800
--#else
--#define SUNXI_UART0_BASE              0x01c28000
--#define SUNXI_UART1_BASE              0x01c28400
--#define SUNXI_UART2_BASE              0x01c28800
--#endif
--#define SUNXI_UART3_BASE              0x01c28c00
--#define SUNXI_UART4_BASE              0x01c29000
--#define SUNXI_UART5_BASE              0x01c29400
--#define SUNXI_UART6_BASE              0x01c29800
--#define SUNXI_UART7_BASE              0x01c29c00
- #define SUNXI_PS2_0_BASE              0x01c2a000
- #define SUNXI_PS2_1_BASE              0x01c2a400
-@@ -208,7 +194,6 @@ defined(CONFIG_MACH_SUN50I)
- #endif
- #define SUNXI_R_TWI_BASE              0x01f02400
--#define SUNXI_R_UART_BASE             0x01f02800
- #define SUN6I_P2WI_BASE                       0x01f03400
- #define SUNXI_RSB_BASE                        0x01f03400
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
-index 9b6bf84360..15ee092d35 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
-@@ -42,10 +42,6 @@
- #define SUNXI_DRAM_PHY0_BASE          0x04800000
- #endif
--#define SUNXI_UART0_BASE              0x05000000
--#define SUNXI_UART1_BASE              0x05000400
--#define SUNXI_UART2_BASE              0x05000800
--#define SUNXI_UART3_BASE              0x05000C00
- #define SUNXI_TWI0_BASE                       0x05002000
- #define SUNXI_TWI1_BASE                       0x05002400
- #define SUNXI_TWI2_BASE                       0x05002800
-@@ -67,7 +63,6 @@
- #define SUNXI_R_CPUCFG_BASE           0x07000400
- #define SUNXI_PRCM_BASE                       0x07010000
- #define SUNXI_R_WDOG_BASE             0x07020400
--#define SUNXI_R_UART_BASE             0x07080000
- #define SUNXI_R_TWI_BASE              0x07081400
- #ifndef __ASSEMBLY__
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
-index 20025be231..2bf2675d5c 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
-@@ -86,12 +86,6 @@
- #define SUNXI_LRADC_BASE              (REGS_APB0_BASE + 0x1800)
- /* APB1 Module */
--#define SUNXI_UART0_BASE              (REGS_APB1_BASE + 0x0000)
--#define SUNXI_UART1_BASE              (REGS_APB1_BASE + 0x0400)
--#define SUNXI_UART2_BASE              (REGS_APB1_BASE + 0x0800)
--#define SUNXI_UART3_BASE              (REGS_APB1_BASE + 0x0C00)
--#define SUNXI_UART4_BASE              (REGS_APB1_BASE + 0x1000)
--#define SUNXI_UART5_BASE              (REGS_APB1_BASE + 0x1400)
- #define SUNXI_TWI0_BASE                       (REGS_APB1_BASE + 0x2800)
- #define SUNXI_TWI1_BASE                       (REGS_APB1_BASE + 0x2C00)
- #define SUNXI_TWI2_BASE                       (REGS_APB1_BASE + 0x3000)
-@@ -100,7 +94,6 @@
- /* RCPUS Module */
- #define SUNXI_PRCM_BASE                       (REGS_RCPUS_BASE + 0x1400)
--#define SUNXI_R_UART_BASE             (REGS_RCPUS_BASE + 0x2800)
- #define SUNXI_RSB_BASE                        (REGS_RCPUS_BASE + 0x3400)
- /* Misc. */
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-index 13093085a5..d01508517c 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-@@ -27,10 +27,6 @@
- #define SUNXI_MMC1_BASE                       0x04021000
- #define SUNXI_MMC2_BASE                       0x04022000
--#define SUNXI_UART0_BASE              0x02500000
--#define SUNXI_UART1_BASE              0x02500400
--#define SUNXI_UART2_BASE              0x02500800
--#define SUNXI_UART3_BASE              0x02500C00
- #define SUNXI_TWI0_BASE                       0x02502000
- #define SUNXI_TWI1_BASE                       0x02502400
- #define SUNXI_TWI2_BASE                       0x02502800
-@@ -42,7 +38,6 @@
- #define SUNXI_R_CPUCFG_BASE           0x07000400
- #define SUNXI_PRCM_BASE                       0x07010000
- #define SUNXI_R_WDOG_BASE             0x07020400
--#define SUNXI_R_UART_BASE             0x07080000
- #define SUNXI_R_TWI_BASE              0x07081400
- #ifndef __ASSEMBLY__
-diff --git a/arch/arm/include/asm/arch-sunxi/serial.h b/arch/arm/include/asm/arch-sunxi/serial.h
-new file mode 100644
-index 0000000000..9386287b65
---- /dev/null
-+++ b/arch/arm/include/asm/arch-sunxi/serial.h
-@@ -0,0 +1,32 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ *  hardcoded UART base addresses for early SPL use
-+ *
-+ *  Copyright (c) 2022  Arm Ltd.
-+ */
-+
-+#ifndef SUNXI_SERIAL_MEMMAP_H
-+#define SUNXI_SERIAL_MEMMAP_H
-+
-+#if defined(CONFIG_MACH_SUN9I)
-+#define SUNXI_UART0_BASE              0x07000000
-+#define SUNXI_R_UART_BASE             0x08002800
-+#elif defined(CONFIG_SUN50I_GEN_H6)
-+#define SUNXI_UART0_BASE              0x05000000
-+#define SUNXI_R_UART_BASE             0x07080000
-+#elif defined(CONFIG_MACH_SUNIV)
-+#define SUNXI_UART0_BASE              0x01c25000
-+#define SUNXI_R_UART_BASE             0
-+#elif defined(CONFIG_SUNXI_GEN_NCAT2)
-+#define SUNXI_UART0_BASE              0x02500000
-+#define SUNXI_R_UART_BASE             0               // 0x07080000 (?>
-+#else
-+#define SUNXI_UART0_BASE              0x01c28000
-+#define SUNXI_R_UART_BASE             0x01f02800
-+#endif
-+
-+#define SUNXI_UART1_BASE              (SUNXI_UART0_BASE + 0x400)
-+#define SUNXI_UART2_BASE              (SUNXI_UART0_BASE + 0x800)
-+#define SUNXI_UART3_BASE              (SUNXI_UART0_BASE + 0xc00)
-+
-+#endif /* SUNXI_SERIAL_MEMMAP_H */
-diff --git a/arch/arm/mach-sunxi/gtbus_sun9i.c b/arch/arm/mach-sunxi/gtbus_sun9i.c
-index cf011c4cfa..5624621b50 100644
---- a/arch/arm/mach-sunxi/gtbus_sun9i.c
-+++ b/arch/arm/mach-sunxi/gtbus_sun9i.c
-@@ -8,6 +8,7 @@
- #include <common.h>
- #include <asm/io.h>
-+#include <asm/arch/cpu.h>
- #include <asm/arch/gtbus_sun9i.h>
- #include <asm/arch/sys_proto.h>
-diff --git a/arch/arm/mach-sunxi/timer.c b/arch/arm/mach-sunxi/timer.c
-index fc9d419a25..9a6f6c06d8 100644
---- a/arch/arm/mach-sunxi/timer.c
-+++ b/arch/arm/mach-sunxi/timer.c
-@@ -10,6 +10,7 @@
- #include <time.h>
- #include <asm/global_data.h>
- #include <asm/io.h>
-+#include <asm/arch/cpu.h>
- #include <asm/arch/timer.h>
- #include <linux/delay.h>
-diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
-index d2d70f0fc2..b8ca77d031 100644
---- a/include/configs/sunxi-common.h
-+++ b/include/configs/sunxi-common.h
-@@ -12,7 +12,6 @@
- #ifndef _SUNXI_COMMON_CONFIG_H
- #define _SUNXI_COMMON_CONFIG_H
--#include <asm/arch/cpu.h>
- #include <linux/stringify.h>
- /* Serial & console */
-@@ -24,6 +23,7 @@
- #define CFG_SYS_NS16550_CLK           24000000
- #endif
- #if !CONFIG_IS_ENABLED(DM_SERIAL)
-+#include <asm/arch/serial.h>
- # define CFG_SYS_NS16550_COM1         SUNXI_UART0_BASE
- # define CFG_SYS_NS16550_COM2         SUNXI_UART1_BASE
- # define CFG_SYS_NS16550_COM3         SUNXI_UART2_BASE
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4017-riscv-dts-allwinner-Add-the-D1-D1s-SoC-devicetree.patch b/package/boot/uboot-sunxi/patches/4017-riscv-dts-allwinner-Add-the-D1-D1s-SoC-devicetree.patch
deleted file mode 100644 (file)
index a08a6d1..0000000
+++ /dev/null
@@ -1,1144 +0,0 @@
-From d25ac8934d210132b1df15bd63301646eb43d57e Mon Sep 17 00:00:00 2001
-From: Samuel Holland <samuel@sholland.org>
-Date: Wed, 25 Jan 2023 22:57:31 -0600
-Subject: [PATCH 4017/4031] riscv: dts: allwinner: Add the D1/D1s SoC
- devicetree
-
-D1 (aka D1-H), D1s (aka F133), R528, and T113 are a family of SoCs based
-on a single die, or at a pair of dies derived from the same design.
-
-D1 and D1s contain a single T-HEAD Xuantie C906 CPU, whereas R528 and
-T113 contain a pair of Cortex-A7's. D1 and R528 are the full version of
-the chip with a BGA package, whereas D1s and T113 are low-pin-count QFP
-variants.
-
-Because the original design supported both ARM and RISC-V CPUs, some
-peripherals are duplicated. In addition, all variants except D1s contain
-a HiFi 4 DSP with its own set of peripherals.
-
-The devicetrees are organized to minimize duplication:
- - Common perhiperals are described in sunxi-d1s-t113.dtsi
- - DSP-related peripherals are described in sunxi-d1-t113.dtsi
- - RISC-V specific hardware is described in sun20i-d1s.dtsi
- - Functionality unique to the D1 variant is described in sun20i-d1.dtsi
-
-The SOC_PERIPHERAL_IRQ macro handles the different #interrupt-cells
-values between the ARM (GIC) and RISC-V (PLIC) versions of the SoC.
-
-Signed-off-by: Samuel Holland <samuel@sholland.org>
----
- arch/riscv/dts/sun20i-common-regulators.dtsi |  28 +
- arch/riscv/dts/sun20i-d1.dtsi                |  66 ++
- arch/riscv/dts/sun20i-d1s.dtsi               |  76 ++
- arch/riscv/dts/sunxi-d1-t113.dtsi            |  15 +
- arch/riscv/dts/sunxi-d1s-t113.dtsi           | 834 +++++++++++++++++++
- include/dt-bindings/clock/sun20i-d1-r-ccu.h  |  19 +
- include/dt-bindings/reset/sun20i-d1-r-ccu.h  |  16 +
- 7 files changed, 1054 insertions(+)
- create mode 100644 arch/riscv/dts/sun20i-common-regulators.dtsi
- create mode 100644 arch/riscv/dts/sun20i-d1.dtsi
- create mode 100644 arch/riscv/dts/sun20i-d1s.dtsi
- create mode 100644 arch/riscv/dts/sunxi-d1-t113.dtsi
- create mode 100644 arch/riscv/dts/sunxi-d1s-t113.dtsi
- create mode 100644 include/dt-bindings/clock/sun20i-d1-r-ccu.h
- create mode 100644 include/dt-bindings/reset/sun20i-d1-r-ccu.h
-
-diff --git a/arch/riscv/dts/sun20i-common-regulators.dtsi b/arch/riscv/dts/sun20i-common-regulators.dtsi
-new file mode 100644
-index 0000000000..9b03fca244
---- /dev/null
-+++ b/arch/riscv/dts/sun20i-common-regulators.dtsi
-@@ -0,0 +1,28 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
-+
-+/ {
-+      reg_vcc: vcc {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc";
-+              regulator-min-microvolt = <5000000>;
-+              regulator-max-microvolt = <5000000>;
-+      };
-+
-+      reg_vcc_3v3: vcc-3v3 {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc-3v3";
-+              regulator-min-microvolt = <3300000>;
-+              regulator-max-microvolt = <3300000>;
-+              vin-supply = <&reg_vcc>;
-+      };
-+};
-+
-+&pio {
-+      vcc-pb-supply = <&reg_vcc_3v3>;
-+      vcc-pc-supply = <&reg_vcc_3v3>;
-+      vcc-pd-supply = <&reg_vcc_3v3>;
-+      vcc-pe-supply = <&reg_vcc_3v3>;
-+      vcc-pf-supply = <&reg_vcc_3v3>;
-+      vcc-pg-supply = <&reg_vcc_3v3>;
-+};
-diff --git a/arch/riscv/dts/sun20i-d1.dtsi b/arch/riscv/dts/sun20i-d1.dtsi
-new file mode 100644
-index 0000000000..97e7cbb325
---- /dev/null
-+++ b/arch/riscv/dts/sun20i-d1.dtsi
-@@ -0,0 +1,66 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
-+
-+#include "sun20i-d1s.dtsi"
-+#include "sunxi-d1-t113.dtsi"
-+
-+/ {
-+      soc {
-+              lradc: keys@2009800 {
-+                      compatible = "allwinner,sun20i-d1-lradc",
-+                                   "allwinner,sun50i-r329-lradc";
-+                      reg = <0x2009800 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(61) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_LRADC>;
-+                      resets = <&ccu RST_BUS_LRADC>;
-+                      status = "disabled";
-+              };
-+
-+              i2s0: i2s@2032000 {
-+                      compatible = "allwinner,sun20i-d1-i2s",
-+                                   "allwinner,sun50i-r329-i2s";
-+                      reg = <0x2032000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(26) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_I2S0>,
-+                               <&ccu CLK_I2S0>;
-+                      clock-names = "apb", "mod";
-+                      resets = <&ccu RST_BUS_I2S0>;
-+                      dmas = <&dma 3>, <&dma 3>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+                      #sound-dai-cells = <0>;
-+              };
-+      };
-+};
-+
-+&pio {
-+      /omit-if-no-ref/
-+      dmic_pb11_d0_pin: dmic-pb11-d0-pin {
-+              pins = "PB11";
-+              function = "dmic";
-+      };
-+
-+      /omit-if-no-ref/
-+      dmic_pe17_clk_pin: dmic-pe17-clk-pin {
-+              pins = "PE17";
-+              function = "dmic";
-+      };
-+
-+      /omit-if-no-ref/
-+      i2c0_pb10_pins: i2c0-pb10-pins {
-+              pins = "PB10", "PB11";
-+              function = "i2c0";
-+      };
-+
-+      /omit-if-no-ref/
-+      i2c2_pb0_pins: i2c2-pb0-pins {
-+              pins = "PB0", "PB1";
-+              function = "i2c2";
-+      };
-+
-+      /omit-if-no-ref/
-+      uart0_pb8_pins: uart0-pb8-pins {
-+              pins = "PB8", "PB9";
-+              function = "uart0";
-+      };
-+};
-diff --git a/arch/riscv/dts/sun20i-d1s.dtsi b/arch/riscv/dts/sun20i-d1s.dtsi
-new file mode 100644
-index 0000000000..8275630af9
---- /dev/null
-+++ b/arch/riscv/dts/sun20i-d1s.dtsi
-@@ -0,0 +1,76 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
-+
-+#define SOC_PERIPHERAL_IRQ(nr)        (nr + 16)
-+
-+#include "sunxi-d1s-t113.dtsi"
-+
-+/ {
-+      cpus {
-+              timebase-frequency = <24000000>;
-+              #address-cells = <1>;
-+              #size-cells = <0>;
-+
-+              cpu0: cpu@0 {
-+                      compatible = "thead,c906", "riscv";
-+                      device_type = "cpu";
-+                      reg = <0>;
-+                      clocks = <&ccu CLK_RISCV>;
-+                      d-cache-block-size = <64>;
-+                      d-cache-sets = <256>;
-+                      d-cache-size = <32768>;
-+                      i-cache-block-size = <64>;
-+                      i-cache-sets = <128>;
-+                      i-cache-size = <32768>;
-+                      mmu-type = "riscv,sv39";
-+                      operating-points-v2 = <&opp_table_cpu>;
-+                      riscv,isa = "rv64imafdc";
-+                      #cooling-cells = <2>;
-+
-+                      cpu0_intc: interrupt-controller {
-+                              compatible = "riscv,cpu-intc";
-+                              interrupt-controller;
-+                              #address-cells = <0>;
-+                              #interrupt-cells = <1>;
-+                      };
-+              };
-+      };
-+
-+      opp_table_cpu: opp-table-cpu {
-+              compatible = "operating-points-v2";
-+
-+              opp-408000000 {
-+                      opp-hz = /bits/ 64 <408000000>;
-+                      opp-microvolt = <900000 900000 1100000>;
-+              };
-+
-+              opp-1080000000 {
-+                      opp-hz = /bits/ 64 <1008000000>;
-+                      opp-microvolt = <900000 900000 1100000>;
-+              };
-+      };
-+
-+      soc {
-+              interrupt-parent = <&plic>;
-+
-+              riscv_wdt: watchdog@6011000 {
-+                      compatible = "allwinner,sun20i-d1-wdt";
-+                      reg = <0x6011000 0x20>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(131) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&dcxo>, <&rtc CLK_OSC32K>;
-+                      clock-names = "hosc", "losc";
-+              };
-+
-+              plic: interrupt-controller@10000000 {
-+                      compatible = "allwinner,sun20i-d1-plic",
-+                                   "thead,c900-plic";
-+                      reg = <0x10000000 0x4000000>;
-+                      interrupts-extended = <&cpu0_intc 11>,
-+                                            <&cpu0_intc 9>;
-+                      interrupt-controller;
-+                      riscv,ndev = <175>;
-+                      #address-cells = <0>;
-+                      #interrupt-cells = <2>;
-+              };
-+      };
-+};
-diff --git a/arch/riscv/dts/sunxi-d1-t113.dtsi b/arch/riscv/dts/sunxi-d1-t113.dtsi
-new file mode 100644
-index 0000000000..b7156123df
---- /dev/null
-+++ b/arch/riscv/dts/sunxi-d1-t113.dtsi
-@@ -0,0 +1,15 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
-+
-+/ {
-+      soc {
-+              dsp_wdt: watchdog@1700400 {
-+                      compatible = "allwinner,sun20i-d1-wdt";
-+                      reg = <0x1700400 0x20>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(122) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&dcxo>, <&rtc CLK_OSC32K>;
-+                      clock-names = "hosc", "losc";
-+                      status = "reserved";
-+              };
-+      };
-+};
-diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-new file mode 100644
-index 0000000000..6fadcee780
---- /dev/null
-+++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-@@ -0,0 +1,834 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
-+
-+#include <dt-bindings/clock/sun6i-rtc.h>
-+#include <dt-bindings/clock/sun8i-de2.h>
-+#include <dt-bindings/clock/sun8i-tcon-top.h>
-+#include <dt-bindings/clock/sun20i-d1-ccu.h>
-+#include <dt-bindings/clock/sun20i-d1-r-ccu.h>
-+#include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/reset/sun8i-de2.h>
-+#include <dt-bindings/reset/sun20i-d1-ccu.h>
-+#include <dt-bindings/reset/sun20i-d1-r-ccu.h>
-+
-+/ {
-+      #address-cells = <1>;
-+      #size-cells = <1>;
-+
-+      dcxo: dcxo-clk {
-+              compatible = "fixed-clock";
-+              clock-output-names = "dcxo";
-+              #clock-cells = <0>;
-+      };
-+
-+      de: display-engine {
-+              compatible = "allwinner,sun20i-d1-display-engine";
-+              allwinner,pipelines = <&mixer0>, <&mixer1>;
-+              status = "disabled";
-+      };
-+
-+      soc {
-+              compatible = "simple-bus";
-+              ranges;
-+              dma-noncoherent;
-+              #address-cells = <1>;
-+              #size-cells = <1>;
-+
-+              pio: pinctrl@2000000 {
-+                      compatible = "allwinner,sun20i-d1-pinctrl";
-+                      reg = <0x2000000 0x800>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(69) IRQ_TYPE_LEVEL_HIGH>,
-+                                   <SOC_PERIPHERAL_IRQ(71) IRQ_TYPE_LEVEL_HIGH>,
-+                                   <SOC_PERIPHERAL_IRQ(73) IRQ_TYPE_LEVEL_HIGH>,
-+                                   <SOC_PERIPHERAL_IRQ(75) IRQ_TYPE_LEVEL_HIGH>,
-+                                   <SOC_PERIPHERAL_IRQ(77) IRQ_TYPE_LEVEL_HIGH>,
-+                                   <SOC_PERIPHERAL_IRQ(79) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_APB0>,
-+                               <&dcxo>,
-+                               <&rtc CLK_OSC32K>;
-+                      clock-names = "apb", "hosc", "losc";
-+                      gpio-controller;
-+                      interrupt-controller;
-+                      #gpio-cells = <3>;
-+                      #interrupt-cells = <3>;
-+
-+                      /omit-if-no-ref/
-+                      clk_pg11_pin: clk-pg11-pin {
-+                              pins = "PG11";
-+                              function = "clk";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      dsi_4lane_pins: dsi-4lane-pins {
-+                              pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5",
-+                                     "PD6", "PD7", "PD8", "PD9";
-+                              drive-strength = <30>;
-+                              function = "dsi";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      lcd_rgb666_pins: lcd-rgb666-pins {
-+                              pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5",
-+                                     "PD6", "PD7", "PD8", "PD9", "PD10", "PD11",
-+                                     "PD12", "PD13", "PD14", "PD15", "PD16", "PD17",
-+                                     "PD18", "PD19", "PD20", "PD21";
-+                              function = "lcd0";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      mmc0_pins: mmc0-pins {
-+                              pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
-+                              function = "mmc0";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      mmc1_pins: mmc1-pins {
-+                              pins = "PG0", "PG1", "PG2", "PG3", "PG4", "PG5";
-+                              function = "mmc1";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      mmc2_pins: mmc2-pins {
-+                              pins = "PC2", "PC3", "PC4", "PC5", "PC6", "PC7";
-+                              function = "mmc2";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      rgmii_pe_pins: rgmii-pe-pins {
-+                              pins = "PE0", "PE1", "PE2", "PE3", "PE4",
-+                                     "PE5", "PE6", "PE7", "PE8", "PE9",
-+                                     "PE11", "PE12", "PE13", "PE14", "PE15";
-+                              function = "emac";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      rmii_pe_pins: rmii-pe-pins {
-+                              pins = "PE0", "PE1", "PE2", "PE3", "PE4",
-+                                     "PE5", "PE6", "PE7", "PE8", "PE9";
-+                              function = "emac";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      uart1_pg6_pins: uart1-pg6-pins {
-+                              pins = "PG6", "PG7";
-+                              function = "uart1";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      uart1_pg8_rts_cts_pins: uart1-pg8-rts-cts-pins {
-+                              pins = "PG8", "PG9";
-+                              function = "uart1";
-+                      };
-+
-+                      /omit-if-no-ref/
-+                      uart3_pb_pins: uart3-pb-pins {
-+                              pins = "PB6", "PB7";
-+                              function = "uart3";
-+                      };
-+              };
-+
-+              ccu: clock-controller@2001000 {
-+                      compatible = "allwinner,sun20i-d1-ccu";
-+                      reg = <0x2001000 0x1000>;
-+                      clocks = <&dcxo>,
-+                               <&rtc CLK_OSC32K>,
-+                               <&rtc CLK_IOSC>;
-+                      clock-names = "hosc", "losc", "iosc";
-+                      #clock-cells = <1>;
-+                      #reset-cells = <1>;
-+              };
-+
-+              dmic: dmic@2031000 {
-+                      compatible = "allwinner,sun20i-d1-dmic",
-+                                   "allwinner,sun50i-h6-dmic";
-+                      reg = <0x2031000 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(24) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_DMIC>,
-+                               <&ccu CLK_DMIC>;
-+                      clock-names = "bus", "mod";
-+                      resets = <&ccu RST_BUS_DMIC>;
-+                      dmas = <&dma 8>;
-+                      dma-names = "rx";
-+                      status = "disabled";
-+                      #sound-dai-cells = <0>;
-+              };
-+
-+              i2s1: i2s@2033000 {
-+                      compatible = "allwinner,sun20i-d1-i2s",
-+                                   "allwinner,sun50i-r329-i2s";
-+                      reg = <0x2033000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(27) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_I2S1>,
-+                               <&ccu CLK_I2S1>;
-+                      clock-names = "apb", "mod";
-+                      resets = <&ccu RST_BUS_I2S1>;
-+                      dmas = <&dma 4>, <&dma 4>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+                      #sound-dai-cells = <0>;
-+              };
-+
-+              i2s2: i2s@2034000 {
-+                      compatible = "allwinner,sun20i-d1-i2s",
-+                                   "allwinner,sun50i-r329-i2s";
-+                      reg = <0x2034000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(28) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_I2S2>,
-+                               <&ccu CLK_I2S2>;
-+                      clock-names = "apb", "mod";
-+                      resets = <&ccu RST_BUS_I2S2>;
-+                      dmas = <&dma 5>, <&dma 5>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+                      #sound-dai-cells = <0>;
-+              };
-+
-+              timer: timer@2050000 {
-+                      compatible = "allwinner,sun20i-d1-timer",
-+                                   "allwinner,sun8i-a23-timer";
-+                      reg = <0x2050000 0xa0>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(59) IRQ_TYPE_LEVEL_HIGH>,
-+                                   <SOC_PERIPHERAL_IRQ(60) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&dcxo>;
-+              };
-+
-+              wdt: watchdog@20500a0 {
-+                      compatible = "allwinner,sun20i-d1-wdt-reset",
-+                                   "allwinner,sun20i-d1-wdt";
-+                      reg = <0x20500a0 0x20>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(63) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&dcxo>, <&rtc CLK_OSC32K>;
-+                      clock-names = "hosc", "losc";
-+                      status = "reserved";
-+              };
-+
-+              uart0: serial@2500000 {
-+                      compatible = "snps,dw-apb-uart";
-+                      reg = <0x2500000 0x400>;
-+                      reg-io-width = <4>;
-+                      reg-shift = <2>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(2) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_UART0>;
-+                      resets = <&ccu RST_BUS_UART0>;
-+                      dmas = <&dma 14>, <&dma 14>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+              };
-+
-+              uart1: serial@2500400 {
-+                      compatible = "snps,dw-apb-uart";
-+                      reg = <0x2500400 0x400>;
-+                      reg-io-width = <4>;
-+                      reg-shift = <2>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(3) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_UART1>;
-+                      resets = <&ccu RST_BUS_UART1>;
-+                      dmas = <&dma 15>, <&dma 15>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+              };
-+
-+              uart2: serial@2500800 {
-+                      compatible = "snps,dw-apb-uart";
-+                      reg = <0x2500800 0x400>;
-+                      reg-io-width = <4>;
-+                      reg-shift = <2>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(4) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_UART2>;
-+                      resets = <&ccu RST_BUS_UART2>;
-+                      dmas = <&dma 16>, <&dma 16>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+              };
-+
-+              uart3: serial@2500c00 {
-+                      compatible = "snps,dw-apb-uart";
-+                      reg = <0x2500c00 0x400>;
-+                      reg-io-width = <4>;
-+                      reg-shift = <2>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(5) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_UART3>;
-+                      resets = <&ccu RST_BUS_UART3>;
-+                      dmas = <&dma 17>, <&dma 17>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+              };
-+
-+              uart4: serial@2501000 {
-+                      compatible = "snps,dw-apb-uart";
-+                      reg = <0x2501000 0x400>;
-+                      reg-io-width = <4>;
-+                      reg-shift = <2>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(6) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_UART4>;
-+                      resets = <&ccu RST_BUS_UART4>;
-+                      dmas = <&dma 18>, <&dma 18>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+              };
-+
-+              uart5: serial@2501400 {
-+                      compatible = "snps,dw-apb-uart";
-+                      reg = <0x2501400 0x400>;
-+                      reg-io-width = <4>;
-+                      reg-shift = <2>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(7) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_UART5>;
-+                      resets = <&ccu RST_BUS_UART5>;
-+                      dmas = <&dma 19>, <&dma 19>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+              };
-+
-+              i2c0: i2c@2502000 {
-+                      compatible = "allwinner,sun20i-d1-i2c",
-+                                   "allwinner,sun8i-v536-i2c",
-+                                   "allwinner,sun6i-a31-i2c";
-+                      reg = <0x2502000 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(9) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_I2C0>;
-+                      resets = <&ccu RST_BUS_I2C0>;
-+                      dmas = <&dma 43>, <&dma 43>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              i2c1: i2c@2502400 {
-+                      compatible = "allwinner,sun20i-d1-i2c",
-+                                   "allwinner,sun8i-v536-i2c",
-+                                   "allwinner,sun6i-a31-i2c";
-+                      reg = <0x2502400 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(10) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_I2C1>;
-+                      resets = <&ccu RST_BUS_I2C1>;
-+                      dmas = <&dma 44>, <&dma 44>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              i2c2: i2c@2502800 {
-+                      compatible = "allwinner,sun20i-d1-i2c",
-+                                   "allwinner,sun8i-v536-i2c",
-+                                   "allwinner,sun6i-a31-i2c";
-+                      reg = <0x2502800 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(11) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_I2C2>;
-+                      resets = <&ccu RST_BUS_I2C2>;
-+                      dmas = <&dma 45>, <&dma 45>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              i2c3: i2c@2502c00 {
-+                      compatible = "allwinner,sun20i-d1-i2c",
-+                                   "allwinner,sun8i-v536-i2c",
-+                                   "allwinner,sun6i-a31-i2c";
-+                      reg = <0x2502c00 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(12) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_I2C3>;
-+                      resets = <&ccu RST_BUS_I2C3>;
-+                      dmas = <&dma 46>, <&dma 46>;
-+                      dma-names = "rx", "tx";
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              syscon: syscon@3000000 {
-+                      compatible = "allwinner,sun20i-d1-system-control";
-+                      reg = <0x3000000 0x1000>;
-+                      ranges;
-+                      #address-cells = <1>;
-+                      #size-cells = <1>;
-+              };
-+
-+              dma: dma-controller@3002000 {
-+                      compatible = "allwinner,sun20i-d1-dma";
-+                      reg = <0x3002000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(50) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>;
-+                      clock-names = "bus", "mbus";
-+                      resets = <&ccu RST_BUS_DMA>;
-+                      dma-channels = <16>;
-+                      dma-requests = <48>;
-+                      #dma-cells = <1>;
-+              };
-+
-+              sid: efuse@3006000 {
-+                      compatible = "allwinner,sun20i-d1-sid";
-+                      reg = <0x3006000 0x1000>;
-+                      #address-cells = <1>;
-+                      #size-cells = <1>;
-+              };
-+
-+              mbus: dram-controller@3102000 {
-+                      compatible = "allwinner,sun20i-d1-mbus";
-+                      reg = <0x3102000 0x1000>,
-+                            <0x3103000 0x1000>;
-+                      reg-names = "mbus", "dram";
-+                      interrupts = <SOC_PERIPHERAL_IRQ(43) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_MBUS>,
-+                               <&ccu CLK_DRAM>,
-+                               <&ccu CLK_BUS_DRAM>;
-+                      clock-names = "mbus", "dram", "bus";
-+                      dma-ranges = <0 0x40000000 0x80000000>;
-+                      #address-cells = <1>;
-+                      #size-cells = <1>;
-+                      #interconnect-cells = <1>;
-+              };
-+
-+              mmc0: mmc@4020000 {
-+                      compatible = "allwinner,sun20i-d1-mmc";
-+                      reg = <0x4020000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(40) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
-+                      clock-names = "ahb", "mmc";
-+                      resets = <&ccu RST_BUS_MMC0>;
-+                      reset-names = "ahb";
-+                      cap-sd-highspeed;
-+                      max-frequency = <150000000>;
-+                      no-mmc;
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              mmc1: mmc@4021000 {
-+                      compatible = "allwinner,sun20i-d1-mmc";
-+                      reg = <0x4021000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(41) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
-+                      clock-names = "ahb", "mmc";
-+                      resets = <&ccu RST_BUS_MMC1>;
-+                      reset-names = "ahb";
-+                      cap-sd-highspeed;
-+                      max-frequency = <150000000>;
-+                      no-mmc;
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              mmc2: mmc@4022000 {
-+                      compatible = "allwinner,sun20i-d1-emmc",
-+                                   "allwinner,sun50i-a100-emmc";
-+                      reg = <0x4022000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(42) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
-+                      clock-names = "ahb", "mmc";
-+                      resets = <&ccu RST_BUS_MMC2>;
-+                      reset-names = "ahb";
-+                      cap-mmc-highspeed;
-+                      max-frequency = <150000000>;
-+                      mmc-ddr-1_8v;
-+                      mmc-ddr-3_3v;
-+                      no-sd;
-+                      no-sdio;
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              usb_otg: usb@4100000 {
-+                      compatible = "allwinner,sun20i-d1-musb",
-+                                   "allwinner,sun8i-a33-musb";
-+                      reg = <0x4100000 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(29) IRQ_TYPE_LEVEL_HIGH>;
-+                      interrupt-names = "mc";
-+                      clocks = <&ccu CLK_BUS_OTG>;
-+                      resets = <&ccu RST_BUS_OTG>;
-+                      extcon = <&usbphy 0>;
-+                      phys = <&usbphy 0>;
-+                      phy-names = "usb";
-+                      status = "disabled";
-+              };
-+
-+              usbphy: phy@4100400 {
-+                      compatible = "allwinner,sun20i-d1-usb-phy";
-+                      reg = <0x4100400 0x100>,
-+                            <0x4101800 0x100>,
-+                            <0x4200800 0x100>;
-+                      reg-names = "phy_ctrl",
-+                                  "pmu0",
-+                                  "pmu1";
-+                      clocks = <&dcxo>,
-+                               <&dcxo>;
-+                      clock-names = "usb0_phy",
-+                                    "usb1_phy";
-+                      resets = <&ccu RST_USB_PHY0>,
-+                               <&ccu RST_USB_PHY1>;
-+                      reset-names = "usb0_reset",
-+                                    "usb1_reset";
-+                      status = "disabled";
-+                      #phy-cells = <1>;
-+              };
-+
-+              ehci0: usb@4101000 {
-+                      compatible = "allwinner,sun20i-d1-ehci",
-+                                   "generic-ehci";
-+                      reg = <0x4101000 0x100>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(30) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_OHCI0>,
-+                               <&ccu CLK_BUS_EHCI0>,
-+                               <&ccu CLK_USB_OHCI0>;
-+                      resets = <&ccu RST_BUS_OHCI0>,
-+                               <&ccu RST_BUS_EHCI0>;
-+                      phys = <&usbphy 0>;
-+                      phy-names = "usb";
-+                      status = "disabled";
-+              };
-+
-+              ohci0: usb@4101400 {
-+                      compatible = "allwinner,sun20i-d1-ohci",
-+                                   "generic-ohci";
-+                      reg = <0x4101400 0x100>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(31) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_OHCI0>,
-+                               <&ccu CLK_USB_OHCI0>;
-+                      resets = <&ccu RST_BUS_OHCI0>;
-+                      phys = <&usbphy 0>;
-+                      phy-names = "usb";
-+                      status = "disabled";
-+              };
-+
-+              ehci1: usb@4200000 {
-+                      compatible = "allwinner,sun20i-d1-ehci",
-+                                   "generic-ehci";
-+                      reg = <0x4200000 0x100>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(33) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_OHCI1>,
-+                               <&ccu CLK_BUS_EHCI1>,
-+                               <&ccu CLK_USB_OHCI1>;
-+                      resets = <&ccu RST_BUS_OHCI1>,
-+                               <&ccu RST_BUS_EHCI1>;
-+                      phys = <&usbphy 1>;
-+                      phy-names = "usb";
-+                      status = "disabled";
-+              };
-+
-+              ohci1: usb@4200400 {
-+                      compatible = "allwinner,sun20i-d1-ohci",
-+                                   "generic-ohci";
-+                      reg = <0x4200400 0x100>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(34) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_OHCI1>,
-+                               <&ccu CLK_USB_OHCI1>;
-+                      resets = <&ccu RST_BUS_OHCI1>;
-+                      phys = <&usbphy 1>;
-+                      phy-names = "usb";
-+                      status = "disabled";
-+              };
-+
-+              emac: ethernet@4500000 {
-+                      compatible = "allwinner,sun20i-d1-emac",
-+                                   "allwinner,sun50i-a64-emac";
-+                      reg = <0x4500000 0x10000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(46) IRQ_TYPE_LEVEL_HIGH>;
-+                      interrupt-names = "macirq";
-+                      clocks = <&ccu CLK_BUS_EMAC>;
-+                      clock-names = "stmmaceth";
-+                      resets = <&ccu RST_BUS_EMAC>;
-+                      reset-names = "stmmaceth";
-+                      syscon = <&syscon>;
-+                      status = "disabled";
-+
-+                      mdio: mdio {
-+                              compatible = "snps,dwmac-mdio";
-+                              #address-cells = <1>;
-+                              #size-cells = <0>;
-+                      };
-+              };
-+
-+              display_clocks: clock-controller@5000000 {
-+                      compatible = "allwinner,sun20i-d1-de2-clk",
-+                                   "allwinner,sun50i-h5-de2-clk";
-+                      reg = <0x5000000 0x10000>;
-+                      clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>;
-+                      clock-names = "bus", "mod";
-+                      resets = <&ccu RST_BUS_DE>;
-+                      #clock-cells = <1>;
-+                      #reset-cells = <1>;
-+              };
-+
-+              mixer0: mixer@5100000 {
-+                      compatible = "allwinner,sun20i-d1-de2-mixer-0";
-+                      reg = <0x5100000 0x100000>;
-+                      clocks = <&display_clocks CLK_BUS_MIXER0>,
-+                               <&display_clocks CLK_MIXER0>;
-+                      clock-names = "bus", "mod";
-+                      resets = <&display_clocks RST_MIXER0>;
-+
-+                      ports {
-+                              #address-cells = <1>;
-+                              #size-cells = <0>;
-+
-+                              mixer0_out: port@1 {
-+                                      reg = <1>;
-+
-+                                      mixer0_out_tcon_top_mixer0: endpoint {
-+                                              remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
-+                                      };
-+                              };
-+                      };
-+              };
-+
-+              mixer1: mixer@5200000 {
-+                      compatible = "allwinner,sun20i-d1-de2-mixer-1";
-+                      reg = <0x5200000 0x100000>;
-+                      clocks = <&display_clocks CLK_BUS_MIXER1>,
-+                               <&display_clocks CLK_MIXER1>;
-+                      clock-names = "bus", "mod";
-+                      resets = <&display_clocks RST_MIXER1>;
-+
-+                      ports {
-+                              #address-cells = <1>;
-+                              #size-cells = <0>;
-+
-+                              mixer1_out: port@1 {
-+                                      reg = <1>;
-+
-+                                      mixer1_out_tcon_top_mixer1: endpoint {
-+                                              remote-endpoint = <&tcon_top_mixer1_in_mixer1>;
-+                                      };
-+                              };
-+                      };
-+              };
-+
-+              dsi: dsi@5450000 {
-+                      compatible = "allwinner,sun20i-d1-mipi-dsi",
-+                                   "allwinner,sun50i-a100-mipi-dsi";
-+                      reg = <0x5450000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(92) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_MIPI_DSI>,
-+                               <&tcon_top CLK_TCON_TOP_DSI>;
-+                      clock-names = "bus", "mod";
-+                      resets = <&ccu RST_BUS_MIPI_DSI>;
-+                      phys = <&dphy>;
-+                      phy-names = "dphy";
-+                      status = "disabled";
-+
-+                      port {
-+                              dsi_in_tcon_lcd0: endpoint {
-+                                      remote-endpoint = <&tcon_lcd0_out_dsi>;
-+                              };
-+                      };
-+              };
-+
-+              dphy: phy@5451000 {
-+                      compatible = "allwinner,sun20i-d1-mipi-dphy",
-+                                   "allwinner,sun50i-a100-mipi-dphy";
-+                      reg = <0x5451000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(92) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_MIPI_DSI>,
-+                               <&ccu CLK_MIPI_DSI>;
-+                      clock-names = "bus", "mod";
-+                      resets = <&ccu RST_BUS_MIPI_DSI>;
-+                      #phy-cells = <0>;
-+              };
-+
-+              tcon_top: tcon-top@5460000 {
-+                      compatible = "allwinner,sun20i-d1-tcon-top";
-+                      reg = <0x5460000 0x1000>;
-+                      clocks = <&ccu CLK_BUS_DPSS_TOP>,
-+                               <&ccu CLK_TCON_TV>,
-+                               <&ccu CLK_TVE>,
-+                               <&ccu CLK_TCON_LCD0>;
-+                      clock-names = "bus", "tcon-tv0", "tve0", "dsi";
-+                      clock-output-names = "tcon-top-tv0", "tcon-top-dsi";
-+                      resets = <&ccu RST_BUS_DPSS_TOP>;
-+                      #clock-cells = <1>;
-+
-+                      ports {
-+                              #address-cells = <1>;
-+                              #size-cells = <0>;
-+
-+                              tcon_top_mixer0_in: port@0 {
-+                                      reg = <0>;
-+
-+                                      tcon_top_mixer0_in_mixer0: endpoint {
-+                                              remote-endpoint = <&mixer0_out_tcon_top_mixer0>;
-+                                      };
-+                              };
-+
-+                              tcon_top_mixer0_out: port@1 {
-+                                      reg = <1>;
-+                                      #address-cells = <1>;
-+                                      #size-cells = <0>;
-+
-+                                      tcon_top_mixer0_out_tcon_lcd0: endpoint@0 {
-+                                              reg = <0>;
-+                                              remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer0>;
-+                                      };
-+
-+                                      tcon_top_mixer0_out_tcon_tv0: endpoint@2 {
-+                                              reg = <2>;
-+                                              remote-endpoint = <&tcon_tv0_in_tcon_top_mixer0>;
-+                                      };
-+                              };
-+
-+                              tcon_top_mixer1_in: port@2 {
-+                                      reg = <2>;
-+                                      #address-cells = <1>;
-+                                      #size-cells = <0>;
-+
-+                                      tcon_top_mixer1_in_mixer1: endpoint@1 {
-+                                              reg = <1>;
-+                                              remote-endpoint = <&mixer1_out_tcon_top_mixer1>;
-+                                      };
-+                              };
-+
-+                              tcon_top_mixer1_out: port@3 {
-+                                      reg = <3>;
-+                                      #address-cells = <1>;
-+                                      #size-cells = <0>;
-+
-+                                      tcon_top_mixer1_out_tcon_lcd0: endpoint@0 {
-+                                              reg = <0>;
-+                                              remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer1>;
-+                                      };
-+
-+                                      tcon_top_mixer1_out_tcon_tv0: endpoint@2 {
-+                                              reg = <2>;
-+                                              remote-endpoint = <&tcon_tv0_in_tcon_top_mixer1>;
-+                                      };
-+                              };
-+
-+                              tcon_top_hdmi_in: port@4 {
-+                                      reg = <4>;
-+
-+                                      tcon_top_hdmi_in_tcon_tv0: endpoint {
-+                                              remote-endpoint = <&tcon_tv0_out_tcon_top_hdmi>;
-+                                      };
-+                              };
-+
-+                              tcon_top_hdmi_out: port@5 {
-+                                      reg = <5>;
-+                              };
-+                      };
-+              };
-+
-+              tcon_lcd0: lcd-controller@5461000 {
-+                      compatible = "allwinner,sun20i-d1-tcon-lcd";
-+                      reg = <0x5461000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(90) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_TCON_LCD0>,
-+                               <&ccu CLK_TCON_LCD0>;
-+                      clock-names = "ahb", "tcon-ch0";
-+                      clock-output-names = "tcon-pixel-clock";
-+                      resets = <&ccu RST_BUS_TCON_LCD0>,
-+                               <&ccu RST_BUS_LVDS0>;
-+                      reset-names = "lcd", "lvds";
-+                      #clock-cells = <0>;
-+
-+                      ports {
-+                              #address-cells = <1>;
-+                              #size-cells = <0>;
-+
-+                              tcon_lcd0_in: port@0 {
-+                                      reg = <0>;
-+                                      #address-cells = <1>;
-+                                      #size-cells = <0>;
-+
-+                                      tcon_lcd0_in_tcon_top_mixer0: endpoint@0 {
-+                                              reg = <0>;
-+                                              remote-endpoint = <&tcon_top_mixer0_out_tcon_lcd0>;
-+                                      };
-+
-+                                      tcon_lcd0_in_tcon_top_mixer1: endpoint@1 {
-+                                              reg = <1>;
-+                                              remote-endpoint = <&tcon_top_mixer1_out_tcon_lcd0>;
-+                                      };
-+                              };
-+
-+                              tcon_lcd0_out: port@1 {
-+                                      reg = <1>;
-+                                      #address-cells = <1>;
-+                                      #size-cells = <0>;
-+
-+                                      tcon_lcd0_out_dsi: endpoint@1 {
-+                                              reg = <1>;
-+                                              remote-endpoint = <&dsi_in_tcon_lcd0>;
-+                                      };
-+                              };
-+                      };
-+              };
-+
-+              tcon_tv0: lcd-controller@5470000 {
-+                      compatible = "allwinner,sun20i-d1-tcon-tv";
-+                      reg = <0x5470000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(91) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_TCON_TV>,
-+                               <&tcon_top CLK_TCON_TOP_TV0>;
-+                      clock-names = "ahb", "tcon-ch1";
-+                      resets = <&ccu RST_BUS_TCON_TV>;
-+                      reset-names = "lcd";
-+
-+                      ports {
-+                              #address-cells = <1>;
-+                              #size-cells = <0>;
-+
-+                              tcon_tv0_in: port@0 {
-+                                      reg = <0>;
-+                                      #address-cells = <1>;
-+                                      #size-cells = <0>;
-+
-+                                      tcon_tv0_in_tcon_top_mixer0: endpoint@0 {
-+                                              reg = <0>;
-+                                              remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>;
-+                                      };
-+
-+                                      tcon_tv0_in_tcon_top_mixer1: endpoint@1 {
-+                                              reg = <1>;
-+                                              remote-endpoint = <&tcon_top_mixer1_out_tcon_tv0>;
-+                                      };
-+                              };
-+
-+                              tcon_tv0_out: port@1 {
-+                                      reg = <1>;
-+
-+                                      tcon_tv0_out_tcon_top_hdmi: endpoint {
-+                                              remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>;
-+                                      };
-+                              };
-+                      };
-+              };
-+
-+              ppu: power-controller@7001000 {
-+                      compatible = "allwinner,sun20i-d1-ppu";
-+                      reg = <0x7001000 0x1000>;
-+                      clocks = <&r_ccu CLK_BUS_R_PPU>;
-+                      resets = <&r_ccu RST_BUS_R_PPU>;
-+                      #power-domain-cells = <1>;
-+              };
-+
-+              r_ccu: clock-controller@7010000 {
-+                      compatible = "allwinner,sun20i-d1-r-ccu";
-+                      reg = <0x7010000 0x400>;
-+                      clocks = <&dcxo>,
-+                               <&rtc CLK_OSC32K>,
-+                               <&rtc CLK_IOSC>,
-+                               <&ccu CLK_PLL_PERIPH0_DIV3>;
-+                      clock-names = "hosc", "losc", "iosc", "pll-periph";
-+                      #clock-cells = <1>;
-+                      #reset-cells = <1>;
-+              };
-+
-+              rtc: rtc@7090000 {
-+                      compatible = "allwinner,sun20i-d1-rtc",
-+                                   "allwinner,sun50i-r329-rtc";
-+                      reg = <0x7090000 0x400>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(144) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&r_ccu CLK_BUS_R_RTC>,
-+                               <&dcxo>,
-+                               <&r_ccu CLK_R_AHB>;
-+                      clock-names = "bus", "hosc", "ahb";
-+                      #clock-cells = <1>;
-+              };
-+      };
-+};
-diff --git a/include/dt-bindings/clock/sun20i-d1-r-ccu.h b/include/dt-bindings/clock/sun20i-d1-r-ccu.h
-new file mode 100644
-index 0000000000..4c2697fd32
---- /dev/null
-+++ b/include/dt-bindings/clock/sun20i-d1-r-ccu.h
-@@ -0,0 +1,19 @@
-+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
-+/*
-+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
-+#define _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
-+
-+#define CLK_R_AHB             0
-+
-+#define CLK_BUS_R_TIMER               2
-+#define CLK_BUS_R_TWD         3
-+#define CLK_BUS_R_PPU         4
-+#define CLK_R_IR_RX           5
-+#define CLK_BUS_R_IR_RX               6
-+#define CLK_BUS_R_RTC         7
-+#define CLK_BUS_R_CPUCFG      8
-+
-+#endif /* _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_ */
-diff --git a/include/dt-bindings/reset/sun20i-d1-r-ccu.h b/include/dt-bindings/reset/sun20i-d1-r-ccu.h
-new file mode 100644
-index 0000000000..d93d6423d2
---- /dev/null
-+++ b/include/dt-bindings/reset/sun20i-d1-r-ccu.h
-@@ -0,0 +1,16 @@
-+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
-+/*
-+ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
-+ */
-+
-+#ifndef _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
-+#define _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
-+
-+#define RST_BUS_R_TIMER               0
-+#define RST_BUS_R_TWD         1
-+#define RST_BUS_R_PPU         2
-+#define RST_BUS_R_IR_RX               3
-+#define RST_BUS_R_RTC         4
-+#define RST_BUS_R_CPUCFG      5
-+
-+#endif /* _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_ */
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4017-sunxi-clock-D1-R528-Enable-PLL-LDO-during-PLL1-setup.patch b/package/boot/uboot-sunxi/patches/4017-sunxi-clock-D1-R528-Enable-PLL-LDO-during-PLL1-setup.patch
new file mode 100644 (file)
index 0000000..9bc22dc
--- /dev/null
@@ -0,0 +1,53 @@
+From 8cd51196fec0b7544cb5842dac9f7209542a6a61 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:57 +0100
+Subject: [PATCH 4017/4044] sunxi: clock: D1/R528: Enable PLL LDO during PLL1
+ setup
+
+The D1/R528/T113s SoCs introduce a new "LDO enable" bit in the CPUX_PLL.
+Just enable that when we program that PLL.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h |  1 +
+ arch/arm/mach-sunxi/clock_sun50i_h6.c             | 12 +++++++-----
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+index 37df4410ea..9895c2c220 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+@@ -228,6 +228,7 @@ struct sunxi_ccm_reg {
+ /* pll1 bit field */
+ #define CCM_PLL1_CTRL_EN              BIT(31)
++#define CCM_PLL1_LDO_EN                       BIT(30)
+ #define CCM_PLL1_LOCK_EN              BIT(29)
+ #define CCM_PLL1_LOCK                 BIT(28)
+ #define CCM_PLL1_OUT_EN                       BIT(27)
+diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+index 7926394cf7..90110eab10 100644
+--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
++++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+@@ -86,11 +86,13 @@ void clock_set_pll1(unsigned int clk)
+       writel(val, &ccm->cpu_axi_cfg);
+       /* clk = 24*n/p, p is ignored if clock is >288MHz */
+-      writel(CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2 |
+-#ifdef CONFIG_MACH_SUN50I_H616
+-             CCM_PLL1_OUT_EN |
+-#endif
+-             CCM_PLL1_CTRL_N(clk / 24000000), &ccm->pll1_cfg);
++      val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2;
++      val |= CCM_PLL1_CTRL_N(clk / 24000000);
++      if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
++             val |= CCM_PLL1_OUT_EN;
++      if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
++             val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN;
++      writel(val, &ccm->pll1_cfg);
+       while (!(readl(&ccm->pll1_cfg) & CCM_PLL1_LOCK)) {}
+       /* Switch CPU to PLL1 */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4018-ARM-dts-sunxi-add-Allwinner-T113-s-SoC-.dtsi.patch b/package/boot/uboot-sunxi/patches/4018-ARM-dts-sunxi-add-Allwinner-T113-s-SoC-.dtsi.patch
deleted file mode 100644 (file)
index 9da865b..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-From 3db4754246274bc530d008f54fc686db8425479f Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Tue, 3 Jan 2023 16:04:47 +0000
-Subject: [PATCH 4018/4031] ARM: dts: sunxi: add Allwinner T113-s SoC .dtsi
-
-The Allwinner T113-s SoC is apparently using the same (or at least a very
-similar) die as the D1/D1s, but replaces the single RISC-V core with
-two Arm Cortex-A7 cores.
-Since the D1 core .dtsi already describes all common peripherals, we
-just need a DT describing the ARM specific peripherals: the CPU cores,
-the Generic Timer, the GIC and the PMU.
-We include the core .dtsi directly from the riscv DT directory.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/dts/sun8i-t113s.dtsi | 59 +++++++++++++++++++++++++++++++++++
- 1 file changed, 59 insertions(+)
- create mode 100644 arch/arm/dts/sun8i-t113s.dtsi
-
-diff --git a/arch/arm/dts/sun8i-t113s.dtsi b/arch/arm/dts/sun8i-t113s.dtsi
-new file mode 100644
-index 0000000000..ce00883130
---- /dev/null
-+++ b/arch/arm/dts/sun8i-t113s.dtsi
-@@ -0,0 +1,59 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2022 Arm Ltd.
-+
-+#define SOC_PERIPHERAL_IRQ(nr) GIC_SPI nr
-+
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include <../../riscv/dts/sunxi-d1s-t113.dtsi>
-+#include <../../riscv/dts/sunxi-d1-t113.dtsi>
-+
-+/ {
-+      interrupt-parent = <&gic>;
-+
-+      cpus {
-+              #address-cells = <1>;
-+              #size-cells = <0>;
-+
-+              cpu0: cpu@0 {
-+                      compatible = "arm,cortex-a7";
-+                      device_type = "cpu";
-+                      reg = <0>;
-+                      clocks = <&ccu CLK_CPUX>;
-+                      clock-names = "cpu";
-+              };
-+
-+              cpu1: cpu@1 {
-+                      compatible = "arm,cortex-a7";
-+                      device_type = "cpu";
-+                      reg = <1>;
-+                      clocks = <&ccu CLK_CPUX>;
-+                      clock-names = "cpu";
-+              };
-+      };
-+
-+      gic: interrupt-controller@1c81000 {
-+              compatible = "arm,gic-400";
-+              reg = <0x03021000 0x1000>,
-+                    <0x03022000 0x2000>,
-+                    <0x03024000 0x2000>,
-+                    <0x03026000 0x2000>;
-+              interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-+              interrupt-controller;
-+              #interrupt-cells = <3>;
-+      };
-+
-+      timer {
-+              compatible = "arm,armv7-timer";
-+              interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-+                           <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-+                           <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-+                           <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
-+      };
-+
-+      pmu {
-+              compatible = "arm,cortex-a7-pmu";
-+              interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
-+                           <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-+              interrupt-affinity = <&cpu0>, <&cpu1>;
-+      };
-+};
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4018-sunxi-clock-support-D1-R528-PLL6-clock.patch b/package/boot/uboot-sunxi/patches/4018-sunxi-clock-support-D1-R528-PLL6-clock.patch
new file mode 100644 (file)
index 0000000..c07f59e
--- /dev/null
@@ -0,0 +1,70 @@
+From 18b787a4cb4edc9b6aa38b55830c9f9f17716000 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:58 +0100
+Subject: [PATCH 4018/4044] sunxi: clock: support D1/R528 PLL6 clock
+
+The PLL_PERIPH0 clock changed a bit in the D1/R528/T113s SoCs: there is
+new P0 divider at bits [18:16], and the M divider is 1.
+
+Add code to support this version of "PLL6".
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ .../include/asm/arch-sunxi/clock_sun50i_h6.h  |  2 ++
+ arch/arm/mach-sunxi/clock_sun50i_h6.c         | 24 +++++++++++++------
+ 2 files changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+index 9895c2c220..8471e11aa0 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+@@ -249,6 +249,8 @@ struct sunxi_ccm_reg {
+ #define CCM_PLL6_CTRL_EN              BIT(31)
+ #define CCM_PLL6_LOCK_EN              BIT(29)
+ #define CCM_PLL6_LOCK                 BIT(28)
++#define CCM_PLL6_CTRL_P0_SHIFT                16
++#define CCM_PLL6_CTRL_P0_MASK         (0x7 << CCM_PLL6_CTRL_P0_SHIFT)
+ #define CCM_PLL6_CTRL_N_SHIFT         8
+ #define CCM_PLL6_CTRL_N_MASK          (0xff << CCM_PLL6_CTRL_N_SHIFT)
+ #define CCM_PLL6_CTRL_DIV1_SHIFT      0
+diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+index 90110eab10..607efe6a9c 100644
+--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
++++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+@@ -107,16 +107,26 @@ unsigned int clock_get_pll6(void)
+ {
+       struct sunxi_ccm_reg *const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+-      int m = IS_ENABLED(CONFIG_MACH_SUN50I_H6) ? 4 : 2;
+-
+       uint32_t rval = readl(&ccm->pll6_cfg);
+       int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1;
+-      int div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >>
+-                      CCM_PLL6_CTRL_DIV1_SHIFT) + 1;
+       int div2 = ((rval & CCM_PLL6_CTRL_DIV2_MASK) >>
+-                      CCM_PLL6_CTRL_DIV2_SHIFT) + 1;
+-      /* The register defines PLL6-2X or PLL6-4X, not plain PLL6 */
+-      return 24000000 / m * n / div1 / div2;
++                  CCM_PLL6_CTRL_DIV2_SHIFT) + 1;
++      int div1, m;
++
++      if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) {
++              div1 = ((rval & CCM_PLL6_CTRL_P0_MASK) >>
++                      CCM_PLL6_CTRL_P0_SHIFT) + 1;
++              m = 1;
++      } else {
++              div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >>
++                      CCM_PLL6_CTRL_DIV1_SHIFT) + 1;
++              if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
++                      m = 4;
++              else
++                      m = 2;
++      }
++
++      return 24000000U * n / m / div1 / div2;
+ }
+ int clock_twi_onoff(int port, int state)
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4019-sunxi-add-preliminary-MangoPi-MQ-R-board-support.patch b/package/boot/uboot-sunxi/patches/4019-sunxi-add-preliminary-MangoPi-MQ-R-board-support.patch
deleted file mode 100644 (file)
index 86bb2f3..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-From 61b9b6b87af8e7eed501155803620083f6dff849 Mon Sep 17 00:00:00 2001
-From: Andre Przywara <andre.przywara@arm.com>
-Date: Fri, 2 Dec 2022 16:11:36 +0000
-Subject: [PATCH 4019/4031] sunxi: add preliminary MangoPi MQ-R board support
-
-This includes a preliminary basic DT and a defconfig to get the board
-booted.
-
-Signed-off-by: Andre Przywara <andre.przywara@arm.com>
----
- arch/arm/dts/Makefile                         |   2 +
- .../arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts |  35 +++++
- arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi | 126 ++++++++++++++++++
- configs/mangopi_mq_r_defconfig                |  17 +++
- 4 files changed, 180 insertions(+)
- create mode 100644 arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts
- create mode 100644 arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi
- create mode 100644 configs/mangopi_mq_r_defconfig
-
-diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
-index c160e884bf..41ee9c4c65 100644
---- a/arch/arm/dts/Makefile
-+++ b/arch/arm/dts/Makefile
-@@ -710,6 +710,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
-       sun8i-s3-pinecube.dtb \
-       sun8i-v3-sl631-imx179.dtb \
-       sun8i-v3s-licheepi-zero.dtb
-+dtb-$(CONFIG_MACH_SUN8I_R528) += \
-+      sun8i-t113s-mangopi-mq-r-t113.dtb
- dtb-$(CONFIG_MACH_SUN50I_H5) += \
-       sun50i-h5-bananapi-m2-plus.dtb \
-       sun50i-h5-emlid-neutis-n5-devboard.dtb \
-diff --git a/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts b/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts
-new file mode 100644
-index 0000000000..94e24b5926
---- /dev/null
-+++ b/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts
-@@ -0,0 +1,35 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2022 Arm Ltd.
-+
-+#include <dt-bindings/interrupt-controller/irq.h>
-+
-+/dts-v1/;
-+
-+#include "sun8i-t113s.dtsi"
-+#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
-+
-+/ {
-+      model = "MangoPi MQ-R-T113";
-+      compatible = "widora,mangopi-mq-r-t113", "allwinner,sun8i-t113s";
-+
-+      aliases {
-+              ethernet0 = &rtl8189ftv;
-+      };
-+};
-+
-+&cpu0 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&cpu1 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&mmc1 {
-+      rtl8189ftv: wifi@1 {
-+              reg = <1>;
-+              interrupt-parent = <&pio>;
-+              interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 = WL_WAKE_AP */
-+              interrupt-names = "host-wake";
-+      };
-+};
-diff --git a/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi b/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi
-new file mode 100644
-index 0000000000..e9bc749488
---- /dev/null
-+++ b/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi
-@@ -0,0 +1,126 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2022 Arm Ltd.
-+/*
-+ * Common peripherals and configurations for MangoPi MQ-R boards.
-+ */
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+      aliases {
-+              serial3 = &uart3;
-+      };
-+
-+      chosen {
-+              stdout-path = "serial3:115200n8";
-+      };
-+
-+      leds {
-+              compatible = "gpio-leds";
-+
-+              led-0 {
-+                      color = <LED_COLOR_ID_BLUE>;
-+                      function = LED_FUNCTION_STATUS;
-+                      gpios = <&pio 3 22 GPIO_ACTIVE_LOW>; /* PD22 */
-+              };
-+      };
-+
-+      /* board wide 5V supply directly from the USB-C socket */
-+      reg_vcc5v: regulator-5v {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc-5v";
-+              regulator-min-microvolt = <5000000>;
-+              regulator-max-microvolt = <5000000>;
-+              regulator-always-on;
-+      };
-+
-+      /* SY8008 DC/DC regulator on the board */
-+      reg_3v3: regulator-3v3 {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc-3v3";
-+              regulator-min-microvolt = <3300000>;
-+              regulator-max-microvolt = <3300000>;
-+              vin-supply = <&reg_vcc5v>;
-+      };
-+
-+      /* SY8008 DC/DC regulator on the board, also supplying VDD-SYS */
-+      reg_vcc_core: regulator-core {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc-core";
-+              regulator-min-microvolt = <880000>;
-+              regulator-max-microvolt = <880000>;
-+              vin-supply = <&reg_vcc5v>;
-+      };
-+
-+      /* XC6206 LDO on the board */
-+      reg_avdd2v8: regulator-avdd {
-+              compatible = "regulator-fixed";
-+              regulator-name = "avdd2v8";
-+              regulator-min-microvolt = <2800000>;
-+              regulator-max-microvolt = <2800000>;
-+              vin-supply = <&reg_3v3>;
-+      };
-+
-+      wifi_pwrseq: wifi-pwrseq {
-+              compatible = "mmc-pwrseq-simple";
-+              reset-gpios = <&pio 6 12 GPIO_ACTIVE_LOW>; /* PG12 */
-+      };
-+};
-+
-+&dcxo {
-+      clock-frequency = <24000000>;
-+};
-+
-+&ehci1 {
-+      status = "okay";
-+};
-+
-+&mmc0 {
-+      pinctrl-0 = <&mmc0_pins>;
-+      pinctrl-names = "default";
-+      vmmc-supply = <&reg_3v3>;
-+      cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
-+      disable-wp;
-+      bus-width = <4>;
-+      status = "okay";
-+};
-+
-+&mmc1 {
-+      pinctrl-0 = <&mmc1_pins>;
-+      pinctrl-names = "default";
-+      vmmc-supply = <&reg_3v3>;
-+      non-removable;
-+      bus-width = <4>;
-+      mmc-pwrseq = <&wifi_pwrseq>;
-+      status = "okay";
-+};
-+
-+&ohci1 {
-+      status = "okay";
-+};
-+
-+&pio {
-+      vcc-pb-supply = <&reg_3v3>;
-+      vcc-pd-supply = <&reg_3v3>;
-+      vcc-pe-supply = <&reg_avdd2v8>;
-+      vcc-pf-supply = <&reg_3v3>;
-+      vcc-pg-supply = <&reg_3v3>;
-+};
-+
-+&uart3 {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&uart3_pb_pins>;
-+      status = "okay";
-+};
-+
-+/* The USB-C socket has its CC pins pulled to GND, so is hardwired as a UFP. */
-+&usb_otg {
-+      dr_mode = "peripheral";
-+      status = "okay";
-+};
-+
-+&usbphy {
-+      usb1_vbus-supply = <&reg_vcc5v>;
-+      status = "okay";
-+};
-diff --git a/configs/mangopi_mq_r_defconfig b/configs/mangopi_mq_r_defconfig
-new file mode 100644
-index 0000000000..28bbfde602
---- /dev/null
-+++ b/configs/mangopi_mq_r_defconfig
-@@ -0,0 +1,17 @@
-+CONFIG_ARM=y
-+CONFIG_ARCH_SUNXI=y
-+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-mangopi-mq-r-t113"
-+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
-+CONFIG_SPL=y
-+CONFIG_MACH_SUN8I_R528=y
-+CONFIG_CONS_INDEX=4
-+CONFIG_MMC0_CD_PIN="PF6"
-+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-+CONFIG_SYS_MONITOR_LEN=786432
-+CONFIG_DRAM_CLK=792
-+CONFIG_DRAM_ZQ=8092667
-+CONFIG_DRAM_SUNXI_ODT_EN=0
-+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
-+CONFIG_DRAM_SUNXI_TPR11=0x340000
-+CONFIG_DRAM_SUNXI_TPR12=0x46
-+CONFIG_DRAM_SUNXI_TPR13=0x34000100
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4019-sunxi-clock-h6-prepare-for-PRCM-less-SoCs.patch b/package/boot/uboot-sunxi/patches/4019-sunxi-clock-h6-prepare-for-PRCM-less-SoCs.patch
new file mode 100644 (file)
index 0000000..0ee1c1e
--- /dev/null
@@ -0,0 +1,75 @@
+From c691eece56bd26a66aeebe435dd5179c60073e43 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:45:59 +0100
+Subject: [PATCH 4019/4044] sunxi: clock: h6: prepare for PRCM less SoCs
+
+The Allwinner D1/R528/T113 SoCs have a very minimal separate
+"management" power plane, with almost no device attached to it (so
+no r_i2c or r_uart). This means we don't need to flip any clock gates in
+the PRCM block, which in fact those SoCs do not have.
+
+Prepare the code for those SoCs by making the PRCM block optional in the
+H6 SPL clock code, which we otherwise share to this new family of SoCs.
+If the memory map (cpu.h) does not define the PRCM address, we simply
+skip any attempt to program gates there.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/mach-sunxi/clock_sun50i_h6.c | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+index 607efe6a9c..c3a4623d34 100644
+--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
++++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+@@ -4,14 +4,20 @@
+ #include <asm/arch/clock.h>
+ #include <asm/arch/prcm.h>
++#ifndef SUNXI_PRCM_BASE
++#define SUNXI_PRCM_BASE 0
++#endif
++
+ #ifdef CONFIG_SPL_BUILD
+-void clock_init_safe(void)
++
++static void clock_init_safe_prcm(void)
+ {
+-      struct sunxi_ccm_reg *const ccm =
+-              (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+       struct sunxi_prcm_reg *const prcm =
+               (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
++      if (!prcm)
++              return;
++
+       if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) {
+               /* this seems to enable PLLs on H616 */
+               setbits_le32(&prcm->sys_pwroff_gating, 0x10);
+@@ -27,6 +33,14 @@ void clock_init_safe(void)
+               /* set PLL VDD LDO output to 1.14 V */
+               setbits_le32(&prcm->pll_ldo_cfg, 0x60000);
+       }
++}
++
++void clock_init_safe(void)
++{
++      struct sunxi_ccm_reg *const ccm =
++              (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
++
++      clock_init_safe_prcm();
+       clock_set_pll1(408000000);
+@@ -141,6 +155,8 @@ int clock_twi_onoff(int port, int state)
+       value = BIT(GATE_SHIFT) | BIT (RESET_SHIFT);
+       if (port == 5) {
++              if (!prcm)
++                      return -ENODEV;
+               shift = 0;
+               ptr = &prcm->twi_gate_reset;
+       } else {
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4020-Kconfig-sunxi-prepare-for-using-drivers-ram-sunxi.patch b/package/boot/uboot-sunxi/patches/4020-Kconfig-sunxi-prepare-for-using-drivers-ram-sunxi.patch
new file mode 100644 (file)
index 0000000..e949d69
--- /dev/null
@@ -0,0 +1,58 @@
+From b3afb64d19f297a9bddddaf75e67a88b1be96f90 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Sat, 26 Aug 2023 16:56:03 +0200
+Subject: [PATCH 4020/4044] Kconfig: sunxi: prepare for using drivers/ram/sunxi
+
+At the moment all Allwinner DRAM initialisation routines are stored in
+arch/arm/mach-sunxi, even though those "drivers" are just a giant
+collection of writel's, without any architectural dependency.
+
+The R528/T113-s SoC (with ARM cores) and the D1/D1s Soc (with RISC-V
+cores) share the same die, so should share the same DRAM init routines as
+well.
+
+To prepare for this, add a new sunxi directory inside drivers/ram, and
+add some stub entries to prepare for the addition of the share DRAM code
+for those SoCs.
+
+The RISC-V D1(s) SoCs will probably use SPL_DM, so make this entry
+depend on that already.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ drivers/ram/Kconfig       |  1 +
+ drivers/ram/sunxi/Kconfig | 13 +++++++++++++
+ 2 files changed, 14 insertions(+)
+ create mode 100644 drivers/ram/sunxi/Kconfig
+
+diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
+index e085119963..636374be59 100644
+--- a/drivers/ram/Kconfig
++++ b/drivers/ram/Kconfig
+@@ -112,3 +112,4 @@ source "drivers/ram/rockchip/Kconfig"
+ source "drivers/ram/sifive/Kconfig"
+ source "drivers/ram/stm32mp1/Kconfig"
+ source "drivers/ram/octeon/Kconfig"
++source "drivers/ram/sunxi/Kconfig"
+diff --git a/drivers/ram/sunxi/Kconfig b/drivers/ram/sunxi/Kconfig
+new file mode 100644
+index 0000000000..97e261de54
+--- /dev/null
++++ b/drivers/ram/sunxi/Kconfig
+@@ -0,0 +1,13 @@
++config DRAM_SUN20I_D1
++      bool "DM DRAM driver support for Allwinner D1"
++      depends on RAM && ARCH_SUNXI
++      default y
++      help
++        This enables support for DRAM drivers using the driver model
++        for Allwinner SoCs.
++
++config DRAM_SUN8I_R528
++      bool "DRAM driver support for Allwinner R528/T113s"
++      default y if MACH_SUN8I_R528
++      help
++        Select this DRAM controller driver for the R528/T113s SoCs.
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4020-sunxi-add-uart0_pins-on-Port-E-PE2-PE3-on-D1s-T133.patch b/package/boot/uboot-sunxi/patches/4020-sunxi-add-uart0_pins-on-Port-E-PE2-PE3-on-D1s-T133.patch
deleted file mode 100644 (file)
index 3c26b0d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From c20401da0fe90a790f47e70cf79f43551adf76b9 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Sat, 3 Jun 2023 00:52:04 +0200
-Subject: [PATCH 4020/4031] sunxi: add uart0_pins on Port E PE2/PE3 on D1s/T133
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/riscv/dts/sunxi-d1s-t113.dtsi | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-index 6fadcee780..2b7d54aab4 100644
---- a/arch/riscv/dts/sunxi-d1s-t113.dtsi
-+++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-@@ -125,6 +125,12 @@
-                               pins = "PB6", "PB7";
-                               function = "uart3";
-                       };
-+
-+                      /omit-if-no-ref/
-+                      uart0_pins: uart0-pins {
-+                              pins = "PE2", "PE3";
-+                              function = "uart0";
-+                      };
-               };
-               ccu: clock-controller@2001000 {
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4021-sunxi-add-R528-T113-s3-D1-s-DRAM-initialisation-code.patch b/package/boot/uboot-sunxi/patches/4021-sunxi-add-R528-T113-s3-D1-s-DRAM-initialisation-code.patch
new file mode 100644 (file)
index 0000000..288d5fd
--- /dev/null
@@ -0,0 +1,1660 @@
+From 96e17af5ca374af5e45422ca56d11f523437d2d2 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:46:01 +0100
+Subject: [PATCH 4021/4044] sunxi: add R528/T113-s3/D1(s) DRAM initialisation
+ code
+
+The Allwinner R528/T113-s/D1/D1s SoCs all share the same die, so use the
+same DRAM initialisation code.
+Make use of prior art here and lift some code from awboot[1], which
+carried init code based on earlier decompilation efforts, but with a
+GPL2 license tag.
+This code has been heavily reworked and cleaned up, to match previous
+DRAM routines for other SoCs, and also to be closer to U-Boot's coding
+style and support routines.
+The actual DRAM chip timing parameters are included in the main file,
+since they cover all DRAM types, and are protected by a new Kconfig
+CONFIG_SUNXI_DRAM_TYPE symbol, which allows the compiler to pick only
+the relevant settings, at build time.
+
+The relevant DRAM chips/board specific configuration parameters are
+delivered via Kconfig, so this code here should work for all supported
+SoCs and DRAM chips combinations.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Tested-by: Sam Edwards <CFSworks@gmail.com>
+---
+ drivers/Makefile                   |    1 +
+ drivers/ram/Makefile               |    3 +
+ drivers/ram/sunxi/Kconfig          |   59 ++
+ drivers/ram/sunxi/Makefile         |    4 +
+ drivers/ram/sunxi/dram_sun20i_d1.c | 1432 ++++++++++++++++++++++++++++
+ drivers/ram/sunxi/dram_sun20i_d1.h |   73 ++
+ 6 files changed, 1572 insertions(+)
+ create mode 100644 drivers/ram/sunxi/Makefile
+ create mode 100644 drivers/ram/sunxi/dram_sun20i_d1.c
+ create mode 100644 drivers/ram/sunxi/dram_sun20i_d1.h
+
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 15d19d0c8a..1542ce7caf 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -52,6 +52,7 @@ obj-$(CONFIG_$(SPL_)ALTERA_SDRAM) += ddr/altera/
+ obj-$(CONFIG_ARCH_IMX8M) += ddr/imx/imx8m/
+ obj-$(CONFIG_IMX8ULP_DRAM) += ddr/imx/imx8ulp/
+ obj-$(CONFIG_ARCH_IMX9) += ddr/imx/imx9/
++obj-$(CONFIG_DRAM_SUN8I_R528) += ram/
+ obj-$(CONFIG_SPL_DM_RESET) += reset/
+ obj-$(CONFIG_SPL_MUSB_NEW) += usb/musb-new/
+ obj-$(CONFIG_SPL_USB_GADGET) += usb/gadget/
+diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
+index 83948e2c43..ae3cf65fa4 100644
+--- a/drivers/ram/Makefile
++++ b/drivers/ram/Makefile
+@@ -10,6 +10,9 @@ obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
+ obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
+ obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o
++obj-$(CONFIG_DRAM_SUN8I_R528) += sunxi/
++
++
+ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
+ obj-$(CONFIG_K3_AM654_DDRSS) += k3-am654-ddrss.o
+diff --git a/drivers/ram/sunxi/Kconfig b/drivers/ram/sunxi/Kconfig
+index 97e261de54..657f47a870 100644
+--- a/drivers/ram/sunxi/Kconfig
++++ b/drivers/ram/sunxi/Kconfig
+@@ -11,3 +11,62 @@ config DRAM_SUN8I_R528
+       default y if MACH_SUN8I_R528
+       help
+         Select this DRAM controller driver for the R528/T113s SoCs.
++
++if DRAM_SUN20I_D1 || DRAM_SUN8I_R528
++
++config DRAM_SUNXI_ODT_EN
++      hex "DRAM ODT EN parameter"
++      default 0x1
++      help
++        ODT EN value from vendor DRAM settings.
++
++config DRAM_SUNXI_TPR0
++      hex "DRAM TPR0 parameter"
++      default 0x0
++      help
++        TPR0 value from vendor DRAM settings.
++
++config DRAM_SUNXI_TPR11
++      hex "DRAM TPR11 parameter"
++      default 0x0
++      help
++        TPR11 value from vendor DRAM settings.
++
++config DRAM_SUNXI_TPR12
++      hex "DRAM TPR12 parameter"
++      default 0x0
++      help
++        TPR12 value from vendor DRAM settings.
++
++config DRAM_SUNXI_TPR13
++      hex "DRAM TPR13 parameter"
++      default 0x0
++      help
++        TPR13 value from vendor DRAM settings. It tells which features
++        should be configured.
++
++choice
++      prompt "DRAM chip type"
++      default SUNXI_DRAM_TYPE_DDR3 if DRAM_SUN8I_R528 || DRAM_SUN20I_D1
++
++config SUNXI_DRAM_TYPE_DDR2
++        bool "DDR2 chips"
++
++config SUNXI_DRAM_TYPE_DDR3
++        bool "DDR3 chips"
++
++config SUNXI_DRAM_TYPE_LPDDR2
++        bool "LPDDR2 chips"
++
++config SUNXI_DRAM_TYPE_LPDDR3
++        bool "LPDDR3 chips"
++endchoice
++
++config SUNXI_DRAM_TYPE
++      int
++      default 2 if SUNXI_DRAM_TYPE_DDR2
++      default 3 if SUNXI_DRAM_TYPE_DDR3
++      default 6 if SUNXI_DRAM_TYPE_LPDDR2
++      default 7 if SUNXI_DRAM_TYPE_LPDDR3
++
++endif
+diff --git a/drivers/ram/sunxi/Makefile b/drivers/ram/sunxi/Makefile
+new file mode 100644
+index 0000000000..d6fb2cf0b6
+--- /dev/null
++++ b/drivers/ram/sunxi/Makefile
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0+
++
++obj-$(CONFIG_DRAM_SUN20I_D1) += dram_sun20i_d1.o
++obj-$(CONFIG_DRAM_SUN8I_R528) += dram_sun20i_d1.o
+diff --git a/drivers/ram/sunxi/dram_sun20i_d1.c b/drivers/ram/sunxi/dram_sun20i_d1.c
+new file mode 100644
+index 0000000000..c766fc2406
+--- /dev/null
++++ b/drivers/ram/sunxi/dram_sun20i_d1.c
+@@ -0,0 +1,1432 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Allwinner D1/D1s/R528/T113-sx DRAM initialisation
++ *
++ * As usual there is no documentation for the memory controller or PHY IP
++ * used here. The baseline of this code was lifted from awboot[1], which
++ * seems to be based on some form of de-compilation of some original Allwinner
++ * code bits (with a GPL2 license tag from the very beginning).
++ * This version here is a reworked version, to match the U-Boot coding style
++ * and style of the other Allwinner DRAM drivers.
++ *
++ * [1] https://github.com/szemzoa/awboot.git
++ */
++
++#include <asm/io.h>
++#include <common.h>
++#ifdef CONFIG_RAM
++  #include <dm.h>
++  #include <ram.h>
++#endif
++#include <linux/delay.h>
++
++#include "dram_sun20i_d1.h"
++
++#ifndef SUNXI_SID_BASE
++#define SUNXI_SID_BASE        0x3006200
++#endif
++
++#ifndef SUNXI_CCM_BASE
++#define SUNXI_CCM_BASE        0x2001000
++#endif
++
++static void sid_read_ldoB_cal(const dram_para_t *para)
++{
++      uint32_t reg;
++
++      reg = (readl(SUNXI_SID_BASE + 0x1c) & 0xff00) >> 8;
++
++      if (reg == 0)
++              return;
++
++      switch (para->dram_type) {
++      case SUNXI_DRAM_TYPE_DDR2:
++              break;
++      case SUNXI_DRAM_TYPE_DDR3:
++              if (reg > 0x20)
++                      reg -= 0x16;
++              break;
++      default:
++              reg = 0;
++              break;
++      }
++
++      clrsetbits_le32(0x3000150, 0xff00, reg << 8);
++}
++
++static void dram_voltage_set(const dram_para_t *para)
++{
++      int vol;
++
++      switch (para->dram_type) {
++      case SUNXI_DRAM_TYPE_DDR2:
++              vol = 47;
++              break;
++      case SUNXI_DRAM_TYPE_DDR3:
++              vol = 25;
++              break;
++      default:
++              vol = 0;
++              break;
++      }
++
++      clrsetbits_le32(0x3000150, 0x20ff00, vol << 8);
++
++      udelay(1);
++
++      sid_read_ldoB_cal(para);
++}
++
++static void dram_enable_all_master(void)
++{
++      writel(~0, 0x3102020);
++      writel(0xff, 0x3102024);
++      writel(0xffff, 0x3102028);
++      udelay(10);
++}
++
++static void dram_disable_all_master(void)
++{
++      writel(1, 0x3102020);
++      writel(0, 0x3102024);
++      writel(0, 0x3102028);
++      udelay(10);
++}
++
++static void eye_delay_compensation(const dram_para_t *para)
++{
++      uint32_t delay;
++      unsigned long ptr;
++
++      // DATn0IOCR, n =  0...7
++      delay = (para->dram_tpr11 & 0xf) << 9;
++      delay |= (para->dram_tpr12 & 0xf) << 1;
++      for (ptr = 0x3103310; ptr < 0x3103334; ptr += 4)
++              setbits_le32(ptr, delay);
++
++      // DATn1IOCR, n =  0...7
++      delay = (para->dram_tpr11 & 0xf0) << 5;
++      delay |= (para->dram_tpr12 & 0xf0) >> 3;
++      for (ptr = 0x3103390; ptr != 0x31033b4; ptr += 4)
++              setbits_le32(ptr, delay);
++
++      // PGCR0: assert AC loopback FIFO reset
++      clrbits_le32(0x3103100, 0x04000000);
++
++      // ??
++
++      delay = (para->dram_tpr11 & 0xf0000) >> 7;
++      delay |= (para->dram_tpr12 & 0xf0000) >> 15;
++      setbits_le32(0x3103334, delay);
++      setbits_le32(0x3103338, delay);
++
++      delay = (para->dram_tpr11 & 0xf00000) >> 11;
++      delay |= (para->dram_tpr12 & 0xf00000) >> 19;
++      setbits_le32(0x31033b4, delay);
++      setbits_le32(0x31033b8, delay);
++
++      setbits_le32(0x310333c, (para->dram_tpr11 & 0xf0000) << 9);
++      setbits_le32(0x31033bc, (para->dram_tpr11 & 0xf00000) << 5);
++
++      // PGCR0: release AC loopback FIFO reset
++      setbits_le32(0x3103100, BIT(26));
++
++      udelay(1);
++
++      delay = (para->dram_tpr10 & 0xf0) << 4;
++      for (ptr = 0x3103240; ptr != 0x310327c; ptr += 4)
++              setbits_le32(ptr, delay);
++      for (ptr = 0x3103228; ptr != 0x3103240; ptr += 4)
++              setbits_le32(ptr, delay);
++
++      setbits_le32(0x3103218, (para->dram_tpr10 & 0x0f) << 8);
++      setbits_le32(0x310321c, (para->dram_tpr10 & 0x0f) << 8);
++
++      setbits_le32(0x3103280, (para->dram_tpr10 & 0xf00) >> 4);
++}
++
++/*
++ * Main purpose of the auto_set_timing routine seems to be to calculate all
++ * timing settings for the specific type of sdram used. Read together with
++ * an sdram datasheet for context on the various variables.
++ */
++static void mctl_set_timing_params(const dram_para_t *para,
++                                 const dram_config_t *config)
++{
++      /* DRAM_TPR0 */
++      u8 tccd         = 2;
++      u8 tfaw;
++      u8 trrd;
++      u8 trcd;
++      u8 trc;
++
++      /* DRAM_TPR1 */
++      u8 txp;
++      u8 twtr;
++      u8 trtp         = 4;
++      u8 twr;
++      u8 trp;
++      u8 tras;
++
++      /* DRAM_TPR2 */
++      u16 trefi;
++      u16 trfc;
++
++      u8 tcksrx;
++      u8 tckesr;
++      u8 trd2wr;
++      u8 twr2rd;
++      u8 trasmax;
++      u8 twtp;
++      u8 tcke;
++      u8 tmod;
++      u8 tmrd;
++      u8 tmrw;
++
++      u8 tcl;
++      u8 tcwl;
++      u8 t_rdata_en;
++      u8 wr_latency;
++
++      u32 mr0;
++      u32 mr1;
++      u32 mr2;
++      u32 mr3;
++
++      u32 tdinit0;
++      u32 tdinit1;
++      u32 tdinit2;
++      u32 tdinit3;
++
++      switch (para->dram_type) {
++      case SUNXI_DRAM_TYPE_DDR2:
++              /* DRAM_TPR0 */
++              tfaw            = ns_to_t(50);
++              trrd            = ns_to_t(10);
++              trcd            = ns_to_t(20);
++              trc             = ns_to_t(65);
++
++              /* DRAM_TPR1 */
++              txp             = 2;
++              twtr            = ns_to_t(8);
++              twr             = ns_to_t(15);
++              trp             = ns_to_t(15);
++              tras            = ns_to_t(45);
++
++              /* DRAM_TRP2 */
++              trfc            = ns_to_t(328);
++              trefi           = ns_to_t(7800) / 32;
++
++              trasmax         = CONFIG_DRAM_CLK / 30;
++              if (CONFIG_DRAM_CLK < 409) {
++                      t_rdata_en      = 1;
++                      tcl             = 3;
++                      mr0             = 0x06a3;
++              } else {
++                      t_rdata_en      = 2;
++                      tcl             = 4;
++                      mr0             = 0x0e73;
++              }
++              tmrd            = 2;
++              twtp            = twr + 5;
++              tcksrx          = 5;
++              tckesr          = 4;
++              trd2wr          = 4;
++              tcke            = 3;
++              tmod            = 12;
++              wr_latency      = 1;
++              tmrw            = 0;
++              twr2rd          = twtr + 5;
++              tcwl            = 0;
++
++              mr1             = para->dram_mr1;
++              mr2             = 0;
++              mr3             = 0;
++
++              tdinit0         = 200 * CONFIG_DRAM_CLK + 1;
++              tdinit1         = 100 * CONFIG_DRAM_CLK / 1000 + 1;
++              tdinit2         = 200 * CONFIG_DRAM_CLK + 1;
++              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;
++
++              break;
++      case SUNXI_DRAM_TYPE_DDR3:
++              trfc            = ns_to_t(350);
++              trefi           = ns_to_t(7800) / 32 + 1;       // XXX
++
++              twtr            = ns_to_t(8) + 2;               // + 2 ? XXX
++              /* Only used by trd2wr calculation, which gets discard below */
++//            twr             = max(ns_to_t(15), 2);
++              trrd            = max(ns_to_t(10), 2);
++              txp             = max(ns_to_t(10), 2);
++
++              if (CONFIG_DRAM_CLK <= 800) {
++                      tfaw            = ns_to_t(50);
++                      trcd            = ns_to_t(15);
++                      trp             = ns_to_t(15);
++                      trc             = ns_to_t(53);
++                      tras            = ns_to_t(38);
++
++                      mr0             = 0x1c70;
++                      mr2             = 0x18;
++                      tcl             = 6;
++                      wr_latency      = 2;
++                      tcwl            = 4;
++                      t_rdata_en      = 4;
++              } else {
++                      tfaw            = ns_to_t(35);
++                      trcd            = ns_to_t(14);
++                      trp             = ns_to_t(14);
++                      trc             = ns_to_t(48);
++                      tras            = ns_to_t(34);
++
++                      mr0             = 0x1e14;
++                      mr2             = 0x20;
++                      tcl             = 7;
++                      wr_latency      = 3;
++                      tcwl            = 5;
++                      t_rdata_en      = 5;
++              }
++
++              trasmax         = CONFIG_DRAM_CLK / 30;
++              twtp            = tcwl + 2 + twtr;              // WL+BL/2+tWTR
++              /* Gets overwritten below */
++//            trd2wr          = tcwl + 2 + twr;               // WL+BL/2+tWR
++              twr2rd          = tcwl + twtr;                  // WL+tWTR
++
++              tdinit0         = 500 * CONFIG_DRAM_CLK + 1;    // 500 us
++              tdinit1         = 360 * CONFIG_DRAM_CLK / 1000 + 1;   // 360 ns
++              tdinit2         = 200 * CONFIG_DRAM_CLK + 1;    // 200 us
++              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;      //   1 us
++
++              mr1             = para->dram_mr1;
++              mr3             = 0;
++              tcke            = 3;
++              tcksrx          = 5;
++              tckesr          = 4;
++              if (((config->dram_tpr13 & 0xc) == 0x04) || CONFIG_DRAM_CLK < 912)
++                      trd2wr     = 5;
++              else
++                      trd2wr     = 6;
++
++              tmod            = 12;
++              tmrd            = 4;
++              tmrw            = 0;
++
++              break;
++      case SUNXI_DRAM_TYPE_LPDDR2:
++              tfaw            = max(ns_to_t(50), 4);
++              trrd            = max(ns_to_t(10), 1);
++              trcd            = max(ns_to_t(24), 2);
++              trc             = ns_to_t(70);
++              txp             = ns_to_t(8);
++              if (txp < 2) {
++                      txp++;
++                      twtr    = 2;
++              } else {
++                      twtr    = txp;
++              }
++              twr             = max(ns_to_t(15), 2);
++              trp             = ns_to_t(17);
++              tras            = ns_to_t(42);
++              trefi           = ns_to_t(3900) / 32;
++              trfc            = ns_to_t(210);
++
++              trasmax         = CONFIG_DRAM_CLK / 60;
++              mr3             = para->dram_mr3;
++              twtp            = twr + 5;
++              mr2             = 6;
++              mr1             = 5;
++              tcksrx          = 5;
++              tckesr          = 5;
++              trd2wr          = 10;
++              tcke            = 2;
++              tmod            = 5;
++              tmrd            = 5;
++              tmrw            = 3;
++              tcl             = 4;
++              wr_latency      = 1;
++              t_rdata_en      = 1;
++
++              tdinit0         = 200 * CONFIG_DRAM_CLK + 1;
++              tdinit1         = 100 * CONFIG_DRAM_CLK / 1000 + 1;
++              tdinit2         = 11 * CONFIG_DRAM_CLK + 1;
++              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;
++              twr2rd          = twtr + 5;
++              tcwl            = 2;
++              mr1             = 195;
++              mr0             = 0;
++
++              break;
++      case SUNXI_DRAM_TYPE_LPDDR3:
++              tfaw            = max(ns_to_t(50), 4);
++              trrd            = max(ns_to_t(10), 1);
++              trcd            = max(ns_to_t(24), 2);
++              trc             = ns_to_t(70);
++              twtr            = max(ns_to_t(8), 2);
++              twr             = max(ns_to_t(15), 2);
++              trp             = ns_to_t(17);
++              tras            = ns_to_t(42);
++              trefi           = ns_to_t(3900) / 32;
++              trfc            = ns_to_t(210);
++              txp             = twtr;
++
++              trasmax         = CONFIG_DRAM_CLK / 60;
++              if (CONFIG_DRAM_CLK < 800) {
++                      tcwl       = 4;
++                      wr_latency = 3;
++                      t_rdata_en = 6;
++                      mr2                = 12;
++              } else {
++                      tcwl       = 3;
++                      tcke       = 6;
++                      wr_latency = 2;
++                      t_rdata_en = 5;
++                      mr2                = 10;
++              }
++              twtp            = tcwl + 5;
++              tcl             = 7;
++              mr3             = para->dram_mr3;
++              tcksrx          = 5;
++              tckesr          = 5;
++              trd2wr          = 13;
++              tcke            = 3;
++              tmod            = 12;
++              tdinit0         = 400 * CONFIG_DRAM_CLK + 1;
++              tdinit1         = 500 * CONFIG_DRAM_CLK / 1000 + 1;
++              tdinit2         = 11 * CONFIG_DRAM_CLK + 1;
++              tdinit3         = 1 * CONFIG_DRAM_CLK + 1;
++              tmrd            = 5;
++              tmrw            = 5;
++              twr2rd          = tcwl + twtr + 5;
++              mr1             = 195;
++              mr0             = 0;
++
++              break;
++      default:
++              trfc            = 128;
++              trp             = 6;
++              trefi           = 98;
++              txp             = 10;
++              twr             = 8;
++              twtr            = 3;
++              tras            = 14;
++              tfaw            = 16;
++              trc             = 20;
++              trcd            = 6;
++              trrd            = 3;
++
++              twr2rd          = 8;
++              tcksrx          = 4;
++              tckesr          = 3;
++              trd2wr          = 4;
++              trasmax         = 27;
++              twtp            = 12;
++              tcke            = 2;
++              tmod            = 6;
++              tmrd            = 2;
++              tmrw            = 0;
++              tcwl            = 3;
++              tcl             = 3;
++              wr_latency      = 1;
++              t_rdata_en      = 1;
++              mr3             = 0;
++              mr2             = 0;
++              mr1             = 0;
++              mr0             = 0;
++              tdinit3         = 0;
++              tdinit2         = 0;
++              tdinit1         = 0;
++              tdinit0         = 0;
++
++              break;
++      }
++
++      /* Set mode registers */
++      writel(mr0, 0x3103030);
++      writel(mr1, 0x3103034);
++      writel(mr2, 0x3103038);
++      writel(mr3, 0x310303c);
++      /* TODO: dram_odt_en is either 0x0 or 0x1, so right shift looks weird */
++      writel((para->dram_odt_en >> 4) & 0x3, 0x310302c);
++
++      /* Set dram timing DRAMTMG0 - DRAMTMG5 */
++      writel((twtp << 24) | (tfaw << 16) | (trasmax << 8) | (tras << 0),
++              0x3103058);
++      writel((txp << 16) | (trtp << 8) | (trc << 0),
++              0x310305c);
++      writel((tcwl << 24) | (tcl << 16) | (trd2wr << 8) | (twr2rd << 0),
++              0x3103060);
++      writel((tmrw << 16) | (tmrd << 12) | (tmod << 0),
++              0x3103064);
++      writel((trcd << 24) | (tccd << 16) | (trrd << 8) | (trp << 0),
++              0x3103068);
++      writel((tcksrx << 24) | (tcksrx << 16) | (tckesr << 8) | (tcke << 0),
++              0x310306c);
++
++      /* Set dual rank timing */
++      clrsetbits_le32(0x3103078, 0xf000ffff,
++                      (CONFIG_DRAM_CLK < 800) ? 0xf0006610 : 0xf0007610);
++
++      /* Set phy interface time PITMG0, PTR3, PTR4 */
++      writel((0x2 << 24) | (t_rdata_en << 16) | BIT(8) | (wr_latency << 0),
++              0x3103080);
++      writel(((tdinit0 << 0) | (tdinit1 << 20)), 0x3103050);
++      writel(((tdinit2 << 0) | (tdinit3 << 20)), 0x3103054);
++
++      /* Set refresh timing and mode */
++      writel((trefi << 16) | (trfc << 0), 0x3103090);
++      writel((trefi << 15) & 0x0fff0000, 0x3103094);
++}
++
++// Purpose of this routine seems to be to initialize the PLL driving
++// the MBUS and sdram.
++//
++static int ccu_set_pll_ddr_clk(int index, const dram_para_t *para,
++                             const dram_config_t *config)
++{
++      unsigned int val, clk, n;
++
++      if (config->dram_tpr13 & BIT(6))
++              clk = para->dram_tpr9;
++      else
++              clk = para->dram_clk;
++
++      // set VCO clock divider
++      n = (clk * 2) / 24;
++
++      val = readl(SUNXI_CCM_BASE + 0x10);
++      val &= ~0x0007ff03;                     // clear dividers
++      val |= (n - 1) << 8;                    // set PLL division
++      val |= BIT(31) | BIT(30);               // enable PLL and LDO
++      writel(val | BIT(29), SUNXI_CCM_BASE + 0x10);
++
++      // wait for PLL to lock
++      while ((readl(SUNXI_CCM_BASE + 0x10) & BIT(28)) == 0)
++              ;
++
++      udelay(20);
++
++      // enable PLL output
++      setbits_le32(SUNXI_CCM_BASE + 0x0, BIT(27));
++
++      // turn clock gate on
++      val = readl(SUNXI_CCM_BASE + 0x800);
++      val &= ~0x03000303;             // select DDR clk source, n=1, m=1
++      val |= BIT(31);                 // turn clock on
++      writel(val, SUNXI_CCM_BASE + 0x800);
++
++      return n * 24;
++}
++
++/* Set up the PLL and clock gates for the DRAM controller and MBUS clocks. */
++static void mctl_sys_init(const dram_para_t *para, const dram_config_t *config)
++{
++      // assert MBUS reset
++      clrbits_le32(SUNXI_CCM_BASE + 0x540, BIT(30));
++
++      // turn off sdram clock gate, assert sdram reset
++      clrbits_le32(SUNXI_CCM_BASE + 0x80c, 0x10001);
++      clrsetbits_le32(SUNXI_CCM_BASE + 0x800, BIT(31) | BIT(30), BIT(27));
++      udelay(10);
++
++      // set ddr pll clock
++      ccu_set_pll_ddr_clk(0, para, config);
++      udelay(100);
++      dram_disable_all_master();
++
++      // release sdram reset
++      setbits_le32(SUNXI_CCM_BASE + 0x80c, BIT(16));
++
++      // release MBUS reset
++      setbits_le32(SUNXI_CCM_BASE + 0x540, BIT(30));
++      setbits_le32(SUNXI_CCM_BASE + 0x800, BIT(30));
++
++      udelay(5);
++
++      // turn on sdram clock gate
++      setbits_le32(SUNXI_CCM_BASE + 0x80c, BIT(0));
++
++      // turn dram clock gate on, trigger sdr clock update
++      setbits_le32(SUNXI_CCM_BASE + 0x800, BIT(31) | BIT(27));
++      udelay(5);
++
++      // mCTL clock enable
++      writel(0x8000, 0x310300c);
++      udelay(10);
++}
++
++// The main purpose of this routine seems to be to copy an address configuration
++// from the dram_para1 and dram_para2 fields to the PHY configuration registers
++// (0x3102000, 0x3102004).
++//
++static void mctl_com_init(const dram_para_t *para, const dram_config_t *config)
++{
++      uint32_t val, width;
++      unsigned long ptr;
++      int i;
++
++      // purpose ??
++      clrsetbits_le32(0x3102008, 0x3f00, 0x2000);
++
++      // set SDRAM type and word width
++      val  = readl(0x3102000) & ~0x00fff000;
++      val |= (para->dram_type & 0x7) << 16;           // DRAM type
++      val |= (~config->dram_para2 & 0x1) << 12;               // DQ width
++      val |= BIT(22);                                 // ??
++      if (para->dram_type == SUNXI_DRAM_TYPE_LPDDR2 ||
++          para->dram_type == SUNXI_DRAM_TYPE_LPDDR3) {
++              val |= BIT(19);         // type 6 and 7 must use 1T
++      } else {
++              if (config->dram_tpr13 & BIT(5))
++                      val |= BIT(19);
++      }
++      writel(val, 0x3102000);
++
++      // init rank / bank / row for single/dual or two different ranks
++      if ((config->dram_para2 & BIT(8)) &&
++          ((config->dram_para2 & 0xf000) != 0x1000))
++              width = 32;
++      else
++              width = 16;
++
++      ptr = 0x3102000;
++      for (i = 0; i < width; i += 16) {
++              val = readl(ptr) & 0xfffff000;
++
++              val |= (config->dram_para2 >> 12) & 0x3; // rank
++              val |= ((config->dram_para1 >> (i + 12)) << 2) & 0x4; // bank - 2
++              val |= (((config->dram_para1 >> (i + 4)) - 1) << 4) & 0xff; // row - 1
++
++              // convert from page size to column addr width - 3
++              switch ((config->dram_para1 >> i) & 0xf) {
++              case 8: val |= 0xa00; break;
++              case 4: val |= 0x900; break;
++              case 2: val |= 0x800; break;
++              case 1: val |= 0x700; break;
++              default: val |= 0x600; break;
++              }
++              writel(val, ptr);
++              ptr += 4;
++      }
++
++      // set ODTMAP based on number of ranks in use
++      val = (readl(0x3102000) & 0x1) ? 0x303 : 0x201;
++      writel(val, 0x3103120);
++
++      // set mctl reg 3c4 to zero when using half DQ
++      if (config->dram_para2 & BIT(0))
++              writel(0, 0x31033c4);
++
++      // purpose ??
++      if (para->dram_tpr4) {
++                setbits_le32(0x3102000, (para->dram_tpr4 & 0x3) << 25);
++                setbits_le32(0x3102004, (para->dram_tpr4 & 0x7fc) << 10);
++      }
++}
++
++static const uint8_t ac_remapping_tables[][22] = {
++      [0] = { 0 },
++      [1] = {  1,  9,  3,  7,  8, 18,  4, 13,  5,  6, 10,
++               2, 14, 12,  0,  0, 21, 17, 20, 19, 11, 22 },
++      [2] = {  4,  9,  3,  7,  8, 18,  1, 13,  2,  6, 10,
++               5, 14, 12,  0,  0, 21, 17, 20, 19, 11, 22 },
++      [3] = {  1,  7,  8, 12, 10, 18,  4, 13,  5,  6,  3,
++               2,  9,  0,  0,  0, 21, 17, 20, 19, 11, 22 },
++      [4] = {  4, 12, 10,  7,  8, 18,  1, 13,  2,  6,  3,
++               5,  9,  0,  0,  0, 21, 17, 20, 19, 11, 22 },
++      [5] = { 13,  2,  7,  9, 12, 19,  5,  1,  6,  3,  4,
++               8, 10,  0,  0,  0, 21, 22, 18, 17, 11, 20 },
++      [6] = {  3, 10,  7, 13,  9, 11,  1,  2,  4,  6,  8,
++               5, 12,  0,  0,  0, 20,  1,  0, 21, 22, 17 },
++      [7] = {  3,  2,  4,  7,  9,  1, 17, 12, 18, 14, 13,
++               8, 15,  6, 10,  5, 19, 22, 16, 21, 20, 11 },
++};
++
++/*
++ * This routine chooses one of several remapping tables for 22 lines.
++ * It is unclear which lines are being remapped. It seems to pick
++ * table cfg7 for the Nezha board.
++ */
++static void mctl_phy_ac_remapping(const dram_para_t *para,
++                                const dram_config_t *config)
++{
++      const uint8_t *cfg;
++      uint32_t fuse, val;
++
++      /*
++       * It is unclear whether the LPDDRx types don't need any remapping,
++       * or whether the original code just didn't provide tables.
++       */
++      if (para->dram_type != SUNXI_DRAM_TYPE_DDR2 &&
++          para->dram_type != SUNXI_DRAM_TYPE_DDR3)
++              return;
++
++      fuse = (readl(SUNXI_SID_BASE + 0x28) & 0xf00) >> 8;
++      debug("DDR efuse: 0x%x\n", fuse);
++
++      if (para->dram_type == SUNXI_DRAM_TYPE_DDR2) {
++              if (fuse == 15)
++                      return;
++              cfg = ac_remapping_tables[6];
++      } else {
++              if (config->dram_tpr13 & 0xc0000) {
++                      cfg = ac_remapping_tables[7];
++              } else {
++                      switch (fuse) {
++                      case 8: cfg = ac_remapping_tables[2]; break;
++                      case 9: cfg = ac_remapping_tables[3]; break;
++                      case 10: cfg = ac_remapping_tables[5]; break;
++                      case 11: cfg = ac_remapping_tables[4]; break;
++                      default:
++                      case 12: cfg = ac_remapping_tables[1]; break;
++                      case 13:
++                      case 14: cfg = ac_remapping_tables[0]; break;
++                      }
++              }
++      }
++
++      val = (cfg[4] << 25) | (cfg[3] << 20) | (cfg[2] << 15) |
++            (cfg[1] << 10) | (cfg[0] << 5);
++      writel(val, 0x3102500);
++
++      val = (cfg[10] << 25) | (cfg[9] << 20) | (cfg[8] << 15) |
++            (cfg[ 7] << 10) | (cfg[6] <<  5) | cfg[5];
++      writel(val, 0x3102504);
++
++      val = (cfg[15] << 20) | (cfg[14] << 15) | (cfg[13] << 10) |
++            (cfg[12] <<  5) | cfg[11];
++      writel(val, 0x3102508);
++
++      val = (cfg[21] << 25) | (cfg[20] << 20) | (cfg[19] << 15) |
++            (cfg[18] << 10) | (cfg[17] <<  5) | cfg[16];
++      writel(val, 0x310250c);
++
++      val = (cfg[4] << 25) | (cfg[3] << 20) | (cfg[2] << 15) |
++            (cfg[1] << 10) | (cfg[0] <<  5) | 1;
++      writel(val, 0x3102500);
++}
++
++// Init the controller channel. The key part is placing commands in the main
++// command register (PIR, 0x3103000) and checking command status (PGSR0, 0x3103010).
++//
++static unsigned int mctl_channel_init(unsigned int ch_index,
++                                    const dram_para_t *para,
++                                    const dram_config_t *config)
++{
++      unsigned int val, dqs_gating_mode;
++
++      dqs_gating_mode = (config->dram_tpr13 & 0xc) >> 2;
++
++      // set DDR clock to half of CPU clock
++      clrsetbits_le32(0x310200c, 0xfff, (para->dram_clk / 2) - 1);
++
++      // MRCTRL0 nibble 3 undocumented
++      clrsetbits_le32(0x3103108, 0xf00, 0x300);
++
++      if (para->dram_odt_en)
++              val = 0;
++      else
++              val = BIT(5);
++
++      // DX0GCR0
++      if (para->dram_clk > 672)
++              clrsetbits_le32(0x3103344, 0xf63e, val);
++      else
++              clrsetbits_le32(0x3103344, 0xf03e, val);
++
++      // DX1GCR0
++      if (para->dram_clk > 672) {
++                setbits_le32(0x3103344, 0x400);
++              clrsetbits_le32(0x31033c4, 0xf63e, val);
++      } else {
++              clrsetbits_le32(0x31033c4, 0xf03e, val);
++      }
++
++      // 0x3103208 undocumented
++      setbits_le32(0x3103208, BIT(1));
++
++      eye_delay_compensation(para);
++
++      // set PLL SSCG ?
++      val = readl(0x3103108);
++      if (dqs_gating_mode == 1) {
++              clrsetbits_le32(0x3103108, 0xc0, 0);
++              clrbits_le32(0x31030bc, 0x107);
++      } else if (dqs_gating_mode == 2) {
++              clrsetbits_le32(0x3103108, 0xc0, 0x80);
++
++              clrsetbits_le32(0x31030bc, 0x107,
++                              (((config->dram_tpr13 >> 16) & 0x1f) - 2) | 0x100);
++              clrsetbits_le32(0x310311c, BIT(31), BIT(27));
++      } else {
++              clrbits_le32(0x3103108, 0x40);
++              udelay(10);
++              setbits_le32(0x3103108, 0xc0);
++      }
++
++      if (para->dram_type == SUNXI_DRAM_TYPE_LPDDR2 ||
++          para->dram_type == SUNXI_DRAM_TYPE_LPDDR3) {
++              if (dqs_gating_mode == 1)
++                      clrsetbits_le32(0x310311c, 0x080000c0, 0x80000000);
++              else
++                      clrsetbits_le32(0x310311c, 0x77000000, 0x22000000);
++      }
++
++      clrsetbits_le32(0x31030c0, 0x0fffffff,
++                      (config->dram_para2 & BIT(12)) ? 0x03000001 : 0x01000007);
++
++      if (readl(0x70005d4) & BIT(16)) {
++              clrbits_le32(0x7010250, 0x2);
++              udelay(10);
++      }
++
++      // Set ZQ config
++      clrsetbits_le32(0x3103140, 0x3ffffff,
++                      (para->dram_zq & 0x00ffffff) | BIT(25));
++
++      // Initialise DRAM controller
++      if (dqs_gating_mode == 1) {
++              //writel(0x52, 0x3103000); // prep PHY reset + PLL init + z-cal
++              writel(0x53, 0x3103000); // Go
++
++              while ((readl(0x3103010) & 0x1) == 0) {
++              } // wait for IDONE
++              udelay(10);
++
++              // 0x520 = prep DQS gating + DRAM init + d-cal
++              if (para->dram_type == SUNXI_DRAM_TYPE_DDR3)
++                      writel(0x5a0, 0x3103000);               // + DRAM reset
++              else
++                      writel(0x520, 0x3103000);
++      } else {
++              if ((readl(0x70005d4) & (1 << 16)) == 0) {
++                      // prep DRAM init + PHY reset + d-cal + PLL init + z-cal
++                      if (para->dram_type == SUNXI_DRAM_TYPE_DDR3)
++                              writel(0x1f2, 0x3103000);       // + DRAM reset
++                      else
++                              writel(0x172, 0x3103000);
++              } else {
++                      // prep PHY reset + d-cal + z-cal
++                      writel(0x62, 0x3103000);
++              }
++      }
++
++      setbits_le32(0x3103000, 0x1);            // GO
++
++      udelay(10);
++      while ((readl(0x3103010) & 0x1) == 0) {
++      } // wait for IDONE
++
++      if (readl(0x70005d4) & BIT(16)) {
++              clrsetbits_le32(0x310310c, 0x06000000, 0x04000000);
++              udelay(10);
++
++              setbits_le32(0x3103004, 0x1);
++
++              while ((readl(0x3103018) & 0x7) != 0x3) {
++              }
++
++              clrbits_le32(0x7010250, 0x1);
++              udelay(10);
++
++              clrbits_le32(0x3103004, 0x1);
++
++              while ((readl(0x3103018) & 0x7) != 0x1) {
++              }
++
++              udelay(15);
++
++              if (dqs_gating_mode == 1) {
++                      clrbits_le32(0x3103108, 0xc0);
++                      clrsetbits_le32(0x310310c, 0x06000000, 0x02000000);
++                      udelay(1);
++                      writel(0x401, 0x3103000);
++
++                      while ((readl(0x3103010) & 0x1) == 0) {
++                      }
++              }
++      }
++
++      // Check for training error
++      if (readl(0x3103010) & BIT(20)) {
++              printf("ZQ calibration error, check external 240 ohm resistor\n");
++              return 0;
++      }
++
++      // STATR = Zynq STAT? Wait for status 'normal'?
++      while ((readl(0x3103018) & 0x1) == 0) {
++      }
++
++      setbits_le32(0x310308c, BIT(31));
++      udelay(10);
++      clrbits_le32(0x310308c, BIT(31));
++      udelay(10);
++      setbits_le32(0x3102014, BIT(31));
++      udelay(10);
++
++      clrbits_le32(0x310310c, 0x06000000);
++
++      if (dqs_gating_mode == 1)
++              clrsetbits_le32(0x310311c, 0xc0, 0x40);
++
++      return 1;
++}
++
++static unsigned int calculate_rank_size(uint32_t regval)
++{
++      unsigned int bits;
++
++      bits = (regval >> 8) & 0xf;     /* page size - 3 */
++      bits += (regval >> 4) & 0xf;    /* row width - 1 */
++      bits += (regval >> 2) & 0x3;    /* bank count - 2 */
++      bits -= 14;                     /* 1MB = 20 bits, minus above 6 = 14 */
++
++      return 1U << bits;
++}
++
++/*
++ * The below routine reads the dram config registers and extracts
++ * the number of address bits in each rank available. It then calculates
++ * total memory size in MB.
++ */
++static unsigned int DRAMC_get_dram_size(void)
++{
++      uint32_t val;
++      unsigned int size;
++
++      val = readl(0x3102000);         /* MC_WORK_MODE0 */
++      size = calculate_rank_size(val);
++      if ((val & 0x3) == 0)           /* single rank? */
++              return size;
++
++      val = readl(0x3102004);         /* MC_WORK_MODE1 */
++      if ((val & 0x3) == 0)           /* two identical ranks? */
++              return size * 2;
++
++      /* add sizes of both ranks */
++      return size + calculate_rank_size(val);
++}
++
++/*
++ * The below routine reads the command status register to extract
++ * DQ width and rank count. This follows the DQS training command in
++ * channel_init. If error bit 22 is reset, we have two ranks and full DQ.
++ * If there was an error, figure out whether it was half DQ, single rank,
++ * or both. Set bit 12 and 0 in dram_para2 with the results.
++ */
++static int dqs_gate_detect(dram_config_t *config)
++{
++      uint32_t dx0, dx1;
++
++      if ((readl(0x3103010) & BIT(22)) == 0) {
++              config->dram_para2 = (config->dram_para2 & ~0xf) | BIT(12);
++              debug("dual rank and full DQ\n");
++
++              return 1;
++      }
++
++      dx0 = (readl(0x3103348) & 0x3000000) >> 24;
++      if (dx0 == 0) {
++              config->dram_para2 = (config->dram_para2 & ~0xf) | 0x1001;
++              debug("dual rank and half DQ\n");
++
++              return 1;
++      }
++
++      if (dx0 == 2) {
++              dx1 = (readl(0x31033c8) & 0x3000000) >> 24;
++              if (dx1 == 2) {
++                      config->dram_para2 = config->dram_para2 & ~0xf00f;
++                      debug("single rank and full DQ\n");
++              } else {
++                      config->dram_para2 = (config->dram_para2 & ~0xf00f) | BIT(0);
++                      debug("single rank and half DQ\n");
++              }
++
++              return 1;
++      }
++
++      if ((config->dram_tpr13 & BIT(29)) == 0)
++              return 0;
++
++      debug("DX0 state: %d\n", dx0);
++      debug("DX1 state: %d\n", dx1);
++
++      return 0;
++}
++
++static int dramc_simple_wr_test(unsigned int mem_mb, int len)
++{
++      unsigned int  offs      = (mem_mb / 2) << 18; // half of memory size
++      unsigned int  patt1 = 0x01234567;
++      unsigned int  patt2 = 0xfedcba98;
++      unsigned int *addr, v1, v2, i;
++
++      addr = (unsigned int *)CFG_SYS_SDRAM_BASE;
++      for (i = 0; i != len; i++, addr++) {
++              writel(patt1 + i, (unsigned long)addr);
++              writel(patt2 + i, (unsigned long)(addr + offs));
++      }
++
++      addr = (unsigned int *)CFG_SYS_SDRAM_BASE;
++      for (i = 0; i != len; i++) {
++              v1 = readl((unsigned long)(addr + i));
++              v2 = patt1 + i;
++              if (v1 != v2) {
++                      printf("DRAM: simple test FAIL\n");
++                      printf("%x != %x at address %p\n", v1, v2, addr + i);
++                      return 1;
++              }
++              v1 = readl((unsigned long)(addr + offs + i));
++              v2 = patt2 + i;
++              if (v1 != v2) {
++                      printf("DRAM: simple test FAIL\n");
++                      printf("%x != %x at address %p\n", v1, v2, addr + offs + i);
++                      return 1;
++              }
++      }
++
++      debug("DRAM: simple test OK\n");
++      return 0;
++}
++
++// Set the Vref mode for the controller
++//
++static void mctl_vrefzq_init(const dram_para_t *para, const dram_config_t *config)
++{
++      if (config->dram_tpr13 & BIT(17))
++              return;
++
++      clrsetbits_le32(0x3103110, 0x7f7f7f7f, para->dram_tpr5);
++
++      // IOCVR1
++      if ((config->dram_tpr13 & BIT(16)) == 0)
++              clrsetbits_le32(0x3103114, 0x7f, para->dram_tpr6 & 0x7f);
++}
++
++// Perform an init of the controller. This is actually done 3 times. The first
++// time to establish the number of ranks and DQ width. The second time to
++// establish the actual ram size. The third time is final one, with the final
++// settings.
++//
++static int mctl_core_init(const dram_para_t *para, const dram_config_t *config)
++{
++      mctl_sys_init(para, config);
++
++      mctl_vrefzq_init(para, config);
++
++      mctl_com_init(para, config);
++
++      mctl_phy_ac_remapping(para, config);
++
++      mctl_set_timing_params(para, config);
++
++      return mctl_channel_init(0, para, config);
++}
++
++/*
++ * This routine sizes a DRAM device by cycling through address lines and
++ * figuring out if they are connected to a real address line, or if the
++ * address is a mirror.
++ * First the column and bank bit allocations are set to low values (2 and 9
++ * address lines). Then a maximum allocation (16 lines) is set for rows and
++ * this is tested.
++ * Next the BA2 line is checked. This seems to be placed above the column,
++ * BA0-1 and row addresses. Finally, the column address is allocated 13 lines
++ * and these are tested. The results are placed in dram_para1 and dram_para2.
++ */
++static int auto_scan_dram_size(const dram_para_t *para, dram_config_t *config)
++{
++      unsigned int rval, i, j, rank, maxrank, offs;
++      unsigned int shft;
++      unsigned long ptr, mc_work_mode, chk;
++
++      if (mctl_core_init(para, config) == 0) {
++              printf("DRAM initialisation error : 0\n");
++              return 0;
++      }
++
++      maxrank = (config->dram_para2 & 0xf000) ? 2 : 1;
++      mc_work_mode = 0x3102000;
++      offs = 0;
++
++      /* write test pattern */
++      for (i = 0, ptr = CFG_SYS_SDRAM_BASE; i < 64; i++, ptr += 4)
++              writel((i & 0x1) ? ptr : ~ptr, ptr);
++
++      for (rank = 0; rank < maxrank;) {
++              /* set row mode */
++              clrsetbits_le32(mc_work_mode, 0xf0c, 0x6f0);
++              udelay(1);
++
++              // Scan per address line, until address wraps (i.e. see shadow)
++              for (i = 11; i < 17; i++) {
++                      chk = CFG_SYS_SDRAM_BASE + (1U << (i + 11));
++                      ptr = CFG_SYS_SDRAM_BASE;
++                      for (j = 0; j < 64; j++) {
++                              if (readl(chk) != ((j & 1) ? ptr : ~ptr))
++                                      break;
++                              ptr += 4;
++                              chk += 4;
++                      }
++                      if (j == 64)
++                              break;
++              }
++              if (i > 16)
++                      i = 16;
++              debug("rank %d row = %d\n", rank, i);
++
++              /* Store rows in para 1 */
++              shft = offs + 4;
++              rval = config->dram_para1;
++              rval &= ~(0xff << shft);
++              rval |= i << shft;
++              config->dram_para1 = rval;
++
++              if (rank == 1)          /* Set bank mode for rank0 */
++                      clrsetbits_le32(0x3102000, 0xffc, 0x6a4);
++
++              /* Set bank mode for current rank */
++              clrsetbits_le32(mc_work_mode, 0xffc, 0x6a4);
++              udelay(1);
++
++              // Test if bit A23 is BA2 or mirror XXX A22?
++              chk = CFG_SYS_SDRAM_BASE + (1U << 22);
++              ptr = CFG_SYS_SDRAM_BASE;
++              for (i = 0, j = 0; i < 64; i++) {
++                      if (readl(chk) != ((i & 1) ? ptr : ~ptr)) {
++                              j = 1;
++                              break;
++                      }
++                      ptr += 4;
++                      chk += 4;
++              }
++
++              debug("rank %d bank = %d\n", rank, (j + 1) << 2); /* 4 or 8 */
++
++              /* Store banks in para 1 */
++              shft = 12 + offs;
++              rval = config->dram_para1;
++              rval &= ~(0xf << shft);
++              rval |= j << shft;
++              config->dram_para1 = rval;
++
++              if (rank == 1)          /* Set page mode for rank0 */
++                      clrsetbits_le32(0x3102000, 0xffc, 0xaa0);
++
++              /* Set page mode for current rank */
++              clrsetbits_le32(mc_work_mode, 0xffc, 0xaa0);
++              udelay(1);
++
++              // Scan per address line, until address wraps (i.e. see shadow)
++              for (i = 9; i < 14; i++) {
++                      chk = CFG_SYS_SDRAM_BASE + (1U << i);
++                      ptr = CFG_SYS_SDRAM_BASE;
++                      for (j = 0; j < 64; j++) {
++                              if (readl(chk) != ((j & 1) ? ptr : ~ptr))
++                                      break;
++                              ptr += 4;
++                              chk += 4;
++                      }
++                      if (j == 64)
++                              break;
++              }
++              if (i > 13)
++                      i = 13;
++
++              unsigned int pgsize = (i == 9) ? 0 : (1 << (i - 10));
++              debug("rank %d page size = %d KB\n", rank, pgsize);
++
++              /* Store page size */
++              shft = offs;
++              rval = config->dram_para1;
++              rval &= ~(0xf << shft);
++              rval |= pgsize << shft;
++              config->dram_para1 = rval;
++
++              // Move to next rank
++              rank++;
++              if (rank != maxrank) {
++                      if (rank == 1) {
++                              /* MC_WORK_MODE */
++                              clrsetbits_le32(0x3202000, 0xffc, 0x6f0);
++
++                              /* MC_WORK_MODE2 */
++                              clrsetbits_le32(0x3202004, 0xffc, 0x6f0);
++                      }
++                      /* store rank1 config in upper half of para1 */
++                      offs += 16;
++                      mc_work_mode += 4;      /* move to MC_WORK_MODE2 */
++              }
++      }
++      if (maxrank == 2) {
++              config->dram_para2 &= 0xfffff0ff;
++              /* note: rval is equal to para->dram_para1 here */
++              if ((rval & 0xffff) == (rval >> 16)) {
++                      debug("rank1 config same as rank0\n");
++              } else {
++                      config->dram_para2 |= BIT(8);
++                      debug("rank1 config different from rank0\n");
++              }
++      }
++
++      return 1;
++}
++
++/*
++ * This routine sets up parameters with dqs_gating_mode equal to 1 and two
++ * ranks enabled. It then configures the core and tests for 1 or 2 ranks and
++ * full or half DQ width. It then resets the parameters to the original values.
++ * dram_para2 is updated with the rank and width findings.
++ */
++static int auto_scan_dram_rank_width(const dram_para_t *para,
++                                   dram_config_t *config)
++{
++      unsigned int s1 = config->dram_tpr13;
++      unsigned int s2 = config->dram_para1;
++
++      config->dram_para1 = 0x00b000b0;
++      config->dram_para2 = (config->dram_para2 & ~0xf) | BIT(12);
++
++      /* set DQS probe mode */
++      config->dram_tpr13 = (config->dram_tpr13 & ~0x8) | BIT(2) | BIT(0);
++
++      mctl_core_init(para, config);
++
++      if (readl(0x3103010) & BIT(20))
++              return 0;
++
++      if (dqs_gate_detect(config) == 0)
++              return 0;
++
++      config->dram_tpr13 = s1;
++      config->dram_para1 = s2;
++
++      return 1;
++}
++
++/*
++ * This routine determines the SDRAM topology. It first establishes the number
++ * of ranks and the DQ width. Then it scans the SDRAM address lines to establish
++ * the size of each rank. It then updates dram_tpr13 to reflect that the sizes
++ * are now known: a re-init will not repeat the autoscan.
++ */
++static int auto_scan_dram_config(const dram_para_t *para,
++                               dram_config_t *config)
++{
++      if (((config->dram_tpr13 & BIT(14)) == 0) &&
++          (auto_scan_dram_rank_width(para, config) == 0)) {
++              printf("ERROR: auto scan dram rank & width failed\n");
++              return 0;
++      }
++
++      if (((config->dram_tpr13 & BIT(0)) == 0) &&
++          (auto_scan_dram_size(para, config) == 0)) {
++              printf("ERROR: auto scan dram size failed\n");
++              return 0;
++      }
++
++      if ((config->dram_tpr13 & BIT(15)) == 0)
++              config->dram_tpr13 |= BIT(14) | BIT(13) | BIT(1) | BIT(0);
++
++      return 1;
++}
++
++static int init_DRAM(int type, const dram_para_t *para)
++{
++      dram_config_t config = {
++              .dram_para1     = 0x000010d2,
++              .dram_para2     = 0,
++              .dram_tpr13     = CONFIG_DRAM_SUNXI_TPR13,
++      };
++      u32 rc, mem_size_mb;
++
++      debug("DRAM BOOT DRIVE INFO: %s\n", "V0.24");
++      debug("DRAM CLK = %d MHz\n", para->dram_clk);
++      debug("DRAM Type = %d (2:DDR2,3:DDR3)\n", para->dram_type);
++      if ((para->dram_odt_en & 0x1) == 0)
++              debug("DRAMC read ODT off\n");
++      else
++              debug("DRAMC ZQ value: 0x%x\n", para->dram_zq);
++
++      /* Test ZQ status */
++      if (config.dram_tpr13 & BIT(16)) {
++              debug("DRAM only have internal ZQ\n");
++              setbits_le32(0x3000160, BIT(8));
++              writel(0, 0x3000168);
++              udelay(10);
++      } else {
++              clrbits_le32(0x3000160, 0x3);
++              writel(config.dram_tpr13 & BIT(16), 0x7010254);
++              udelay(10);
++              clrsetbits_le32(0x3000160, 0x108, BIT(1));
++              udelay(10);
++              setbits_le32(0x3000160, BIT(0));
++              udelay(20);
++              debug("ZQ value = 0x%x\n", readl(0x300016c));
++      }
++
++      dram_voltage_set(para);
++
++      /* Set SDRAM controller auto config */
++      if ((config.dram_tpr13 & BIT(0)) == 0) {
++              if (auto_scan_dram_config(para, &config) == 0) {
++                      printf("auto_scan_dram_config() FAILED\n");
++                      return 0;
++              }
++      }
++
++      /* report ODT */
++      rc = para->dram_mr1;
++      if ((rc & 0x44) == 0)
++              debug("DRAM ODT off\n");
++      else
++              debug("DRAM ODT value: 0x%x\n", rc);
++
++      /* Init core, final run */
++      if (mctl_core_init(para, &config) == 0) {
++              printf("DRAM initialisation error: 1\n");
++              return 0;
++      }
++
++      /* Get SDRAM size */
++      /* TODO: who ever puts a negative number in the top half? */
++      rc = config.dram_para2;
++      if (rc & BIT(31)) {
++              rc = (rc >> 16) & ~BIT(15);
++      } else {
++              rc = DRAMC_get_dram_size();
++              debug("DRAM: size = %dMB\n", rc);
++              config.dram_para2 = (config.dram_para2 & 0xffffU) | rc << 16;
++      }
++      mem_size_mb = rc;
++
++      /* Purpose ?? */
++      if (config.dram_tpr13 & BIT(30)) {
++              rc = para->dram_tpr8;
++              if (rc == 0)
++                      rc = 0x10000200;
++              writel(rc, 0x31030a0);
++              writel(0x40a, 0x310309c);
++              setbits_le32(0x3103004, BIT(0));
++              debug("Enable Auto SR\n");
++      } else {
++              clrbits_le32(0x31030a0, 0xffff);
++              clrbits_le32(0x3103004, 0x1);
++      }
++
++      /* Purpose ?? */
++      if (config.dram_tpr13 & BIT(9)) {
++              clrsetbits_le32(0x3103100, 0xf000, 0x5000);
++      } else {
++              if (para->dram_type != SUNXI_DRAM_TYPE_LPDDR2)
++                      clrbits_le32(0x3103100, 0xf000);
++      }
++
++      setbits_le32(0x3103140, BIT(31));
++
++      /* CHECK: is that really writing to a different register? */
++      if (config.dram_tpr13 & BIT(8))
++              writel(readl(0x3103140) | 0x300, 0x31030b8);
++
++      if (config.dram_tpr13 & BIT(16))
++              clrbits_le32(0x3103108, BIT(13));
++      else
++              setbits_le32(0x3103108, BIT(13));
++
++      /* Purpose ?? */
++      if (para->dram_type == SUNXI_DRAM_TYPE_LPDDR3)
++              clrsetbits_le32(0x310307c, 0xf0000, 0x1000);
++
++      dram_enable_all_master();
++      if (config.dram_tpr13 & BIT(28)) {
++              if ((readl(0x70005d4) & BIT(16)) ||
++                  dramc_simple_wr_test(mem_size_mb, 4096))
++                      return 0;
++      }
++
++      return mem_size_mb;
++}
++
++      static const dram_para_t para = {
++              .dram_clk       = CONFIG_DRAM_CLK,
++              .dram_type      = CONFIG_SUNXI_DRAM_TYPE,
++              .dram_zq        = CONFIG_DRAM_ZQ,
++              .dram_odt_en    = CONFIG_DRAM_SUNXI_ODT_EN,
++              .dram_mr0       = 0x1c70,
++              .dram_mr1       = 0x42,
++              .dram_mr2       = 0x18,
++              .dram_mr3       = 0,
++              .dram_tpr0      = 0x004a2195,
++              .dram_tpr1      = 0x02423190,
++              .dram_tpr2      = 0x0008b061,
++              .dram_tpr3      = 0xb4787896, // unused
++              .dram_tpr4      = 0,
++              .dram_tpr5      = 0x48484848,
++              .dram_tpr6      = 0x00000048,
++              .dram_tpr7      = 0x1620121e, // unused
++              .dram_tpr8      = 0,
++              .dram_tpr9      = 0, // clock?
++              .dram_tpr10     = 0,
++              .dram_tpr11     = CONFIG_DRAM_SUNXI_TPR11,
++              .dram_tpr12     = CONFIG_DRAM_SUNXI_TPR12,
++      };
++
++unsigned long sunxi_dram_init(void)
++{
++      return init_DRAM(0, &para) * 1024UL * 1024;
++};
++
++#ifdef CONFIG_RAM             /* using the driver model */
++struct sunxi_ram_priv {
++      size_t size;
++};
++
++static int sunxi_ram_probe(struct udevice *dev)
++{
++      struct sunxi_ram_priv *priv = dev_get_priv(dev);
++      unsigned long dram_size;
++
++      debug("%s: %s: probing\n", __func__, dev->name);
++
++      dram_size = sunxi_dram_init();
++      if (!dram_size) {
++              printf("DRAM init failed: %d\n", ret);
++              return -ENODEV;
++      }
++
++      priv->size = dram_size;
++
++      return 0;
++}
++
++static int sunxi_ram_get_info(struct udevice *dev, struct ram_info *info)
++{
++      struct sunxi_ram_priv *priv = dev_get_priv(dev);
++
++      debug("%s: %s: getting info\n", __func__, dev->name);
++
++      info->base = CFG_SYS_SDRAM_BASE;
++      info->size = priv->size;
++
++      return 0;
++}
++
++static struct ram_ops sunxi_ram_ops = {
++      .get_info = sunxi_ram_get_info,
++};
++
++static const struct udevice_id sunxi_ram_ids[] = {
++      { .compatible = "allwinner,sun20i-d1-mbus" },
++      { }
++};
++
++U_BOOT_DRIVER(sunxi_ram) = {
++      .name = "sunxi_ram",
++      .id = UCLASS_RAM,
++      .of_match = sunxi_ram_ids,
++      .ops = &sunxi_ram_ops,
++      .probe = sunxi_ram_probe,
++      .priv_auto = sizeof(struct sunxi_ram_priv),
++};
++#endif                                /* CONFIG_RAM (using driver model) */
+diff --git a/drivers/ram/sunxi/dram_sun20i_d1.h b/drivers/ram/sunxi/dram_sun20i_d1.h
+new file mode 100644
+index 0000000000..91383f6cf1
+--- /dev/null
++++ b/drivers/ram/sunxi/dram_sun20i_d1.h
+@@ -0,0 +1,73 @@
++// SPDX-License-Identifier:   GPL-2.0+
++/*
++ * D1/R528/T113 DRAM controller register and constant defines
++ *
++ * (C) Copyright 2022 Arm Ltd.
++ * Based on H6 and H616 header, which are:
++ * (C) Copyright 2017  Icenowy Zheng <icenowy@aosc.io>
++ * (C) Copyright 2020  Jernej Skrabec <jernej.skrabec@siol.net>
++ *
++ */
++
++#ifndef _SUNXI_DRAM_SUN20I_D1_H
++#define _SUNXI_DRAM_SUN20I_D1_H
++
++enum sunxi_dram_type {
++      SUNXI_DRAM_TYPE_DDR2 = 2,
++      SUNXI_DRAM_TYPE_DDR3 = 3,
++      SUNXI_DRAM_TYPE_LPDDR2 = 6,
++      SUNXI_DRAM_TYPE_LPDDR3 = 7,
++};
++
++/*
++ * This structure contains a mixture of fixed configuration settings,
++ * variables that are used at runtime to communicate settings between
++ * different stages and functions, and unused values.
++ * This is copied from Allwinner's boot0 data structure, which can be
++ * found at offset 0x38 in any boot0 binary. To allow matching up some
++ * board specific settings, this struct is kept compatible, even though
++ * we don't need all members in our code.
++ */
++typedef struct dram_para {
++      /* normal configuration */
++      const u32       dram_clk;
++      const u32       dram_type;
++      const u32       dram_zq;
++      const u32       dram_odt_en;
++
++      /* timing configuration */
++      const u32       dram_mr0;
++      const u32       dram_mr1;
++      const u32       dram_mr2;
++      const u32       dram_mr3;
++      const u32       dram_tpr0;      //DRAMTMG0
++      const u32       dram_tpr1;      //DRAMTMG1
++      const u32       dram_tpr2;      //DRAMTMG2
++      const u32       dram_tpr3;      //DRAMTMG3
++      const u32       dram_tpr4;      //DRAMTMG4
++      const u32       dram_tpr5;      //DRAMTMG5
++      const u32       dram_tpr6;      //DRAMTMG8
++      const u32       dram_tpr7;
++      const u32       dram_tpr8;
++      const u32       dram_tpr9;
++      const u32       dram_tpr10;
++      const u32       dram_tpr11;
++      const u32       dram_tpr12;
++} dram_para_t;
++
++typedef struct dram_config {
++      /* control configuration */
++      u32     dram_para1;
++      u32     dram_para2;
++      /* contains a bitfield of DRAM setup settings */
++      u32     dram_tpr13;
++} dram_config_t;
++
++static inline int ns_to_t(int nanoseconds)
++{
++      const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
++
++      return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
++}
++
++#endif /* _SUNXI_DRAM_SUN20I_D1_H */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4021-sunxi-add-support-for-MangoPI-MQDual-T113-variant.patch b/package/boot/uboot-sunxi/patches/4021-sunxi-add-support-for-MangoPI-MQDual-T113-variant.patch
deleted file mode 100644 (file)
index 1e869dd..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-From 9c4f13ffba3c53b1d4beb8cdb71f658b80692b15 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Sat, 3 Jun 2023 00:52:40 +0200
-Subject: [PATCH 4021/4031] sunxi: add support for MangoPI MQDual T113 variant
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/arm/dts/Makefile                         |  3 +-
- .../dts/sun8i-t113s-mangopi-mqdual-t113.dts   | 50 +++++++++++++++++++
- configs/mangopi_mqdual_t113_defconfig         | 17 +++++++
- 3 files changed, 69 insertions(+), 1 deletion(-)
- create mode 100644 arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts
- create mode 100644 configs/mangopi_mqdual_t113_defconfig
-
-diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
-index 41ee9c4c65..4207f17601 100644
---- a/arch/arm/dts/Makefile
-+++ b/arch/arm/dts/Makefile
-@@ -711,7 +711,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
-       sun8i-v3-sl631-imx179.dtb \
-       sun8i-v3s-licheepi-zero.dtb
- dtb-$(CONFIG_MACH_SUN8I_R528) += \
--      sun8i-t113s-mangopi-mq-r-t113.dtb
-+      sun8i-t113s-mangopi-mq-r-t113.dtb \
-+      sun8i-t113s-mangopi-mqdual-t113.dtb
- dtb-$(CONFIG_MACH_SUN50I_H5) += \
-       sun50i-h5-bananapi-m2-plus.dtb \
-       sun50i-h5-emlid-neutis-n5-devboard.dtb \
-diff --git a/arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts b/arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts
-new file mode 100644
-index 0000000000..7de3ddb92f
---- /dev/null
-+++ b/arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts
-@@ -0,0 +1,50 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2022 Arm Ltd.
-+
-+#include <dt-bindings/interrupt-controller/irq.h>
-+
-+/dts-v1/;
-+
-+#include "sun8i-t113s.dtsi"
-+#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
-+
-+/ {
-+      model = "MangoPi MQDual T113";
-+      compatible = "widora,mangopi-mqdual-t113", "allwinner,sun8i-t113s";
-+
-+      aliases {
-+              serial0 = &uart0;
-+              ethernet0 = &rtl8189ftv;
-+      };
-+
-+      chosen {
-+              stdout-path = "serial0:115200n8";
-+      };
-+};
-+
-+&cpu0 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&cpu1 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&mmc1 {
-+      rtl8189ftv: wifi@1 {
-+              reg = <1>;
-+              interrupt-parent = <&pio>;
-+              interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 = WL_WAKE_AP */
-+              interrupt-names = "host-wake";
-+      };
-+};
-+
-+&uart0 {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&uart0_pins>;
-+      status = "okay";
-+};
-+
-+&uart3 {
-+      status = "disabled";
-+};
-diff --git a/configs/mangopi_mqdual_t113_defconfig b/configs/mangopi_mqdual_t113_defconfig
-new file mode 100644
-index 0000000000..98b90c55f4
---- /dev/null
-+++ b/configs/mangopi_mqdual_t113_defconfig
-@@ -0,0 +1,17 @@
-+CONFIG_ARM=y
-+CONFIG_ARCH_SUNXI=y
-+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-mangopi-mqdual-t113"
-+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
-+CONFIG_SPL=y
-+CONFIG_MACH_SUN8I_R528=y
-+CONFIG_CONS_INDEX=1
-+CONFIG_MMC0_CD_PIN="PF6"
-+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-+CONFIG_SYS_MONITOR_LEN=786432
-+CONFIG_DRAM_CLK=792
-+CONFIG_DRAM_ZQ=8092667
-+CONFIG_DRAM_SUNXI_ODT_EN=0
-+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
-+CONFIG_DRAM_SUNXI_TPR11=0x340000
-+CONFIG_DRAM_SUNXI_TPR12=0x46
-+CONFIG_DRAM_SUNXI_TPR13=0x34000100
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4022-sunxi-add-Allwinner-R528-T113-SoC-support.patch b/package/boot/uboot-sunxi/patches/4022-sunxi-add-Allwinner-R528-T113-SoC-support.patch
new file mode 100644 (file)
index 0000000..695926c
--- /dev/null
@@ -0,0 +1,202 @@
+From 2caf5cf5bb2d34f07d4920eb5e4eacd07f66a27b Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:46:02 +0100
+Subject: [PATCH 4022/4044] sunxi: add Allwinner R528/T113 SoC support
+
+This adds the remaining code bits to teach U-Boot about Allwinner's
+newest SoC generation. This was introduced with the RISC-V based
+Allwinner D1 SoC, which actually shares a die with the ARM cores versions
+called R528 (BGA, without DRAM) and T113s (QFP, with embedded DRAM).
+
+This adds the new Kconfig stanza, using the two newly introduced symbols
+for the new SoC generation and pincontroller. It also adds the new symbols
+to the relavent code places, to set all the hardcoded bits directly.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Tested-by: Maksim Kiselev <bigunclemax@gmail.com>
+---
+ arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h |  9 +++++++--
+ arch/arm/mach-sunxi/Kconfig                       | 11 +++++++++++
+ arch/arm/mach-sunxi/board.c                       |  8 ++++++++
+ arch/arm/mach-sunxi/clock_sun50i_h6.c             |  2 ++
+ arch/arm/mach-sunxi/cpu_info.c                    |  2 ++
+ common/spl/Kconfig                                |  1 +
+ drivers/clk/sunxi/Kconfig                         |  1 +
+ drivers/mmc/sunxi_mmc.c                           |  1 +
+ drivers/pinctrl/sunxi/Kconfig                     |  1 +
+ 9 files changed, 34 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+index 8471e11aa0..a84a57e5b4 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+@@ -266,7 +266,7 @@ struct sunxi_ccm_reg {
+ #define CCM_CPU_AXI_AXI_MASK          0x3
+ #define CCM_CPU_AXI_DEFAULT_FACTORS   0x301
+-#ifdef CONFIG_MACH_SUN50I_H6
++#ifdef CONFIG_MACH_SUN50I_H6                          /* H6 */
+ #define CCM_PLL6_DEFAULT              0xa0006300
+ /* psi_ahb1_ahb2 bit field */
+@@ -277,7 +277,7 @@ struct sunxi_ccm_reg {
+ /* apb1 bit field */
+ #define CCM_APB1_DEFAULT              0x03000102
+-#elif CONFIG_MACH_SUN50I_H616
++#elif CONFIG_MACH_SUN50I_H616                         /* H616 */
+ #define CCM_PLL6_DEFAULT              0xa8003100
+ /* psi_ahb1_ahb2 bit field */
+@@ -288,6 +288,11 @@ struct sunxi_ccm_reg {
+ /* apb1 bit field */
+ #define CCM_APB1_DEFAULT              0x03000102
++#elif CONFIG_MACH_SUN8I_R528                          /* R528 */
++#define CCM_PLL6_DEFAULT              0xe8216300
++#define CCM_PSI_AHB1_AHB2_DEFAULT     0x03000002
++//#define CCM_AHB3_DEFAULT            0x03000002
++#define CCM_APB1_DEFAULT              0x03000102
+ #endif
+ /* apb2 bit field */
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index 60ca1239dd..77b510cdfe 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -316,6 +316,15 @@ config MACH_SUN8I_R40
+       select PHY_SUN4I_USB
+       imply SPL_SYS_I2C_LEGACY
++config MACH_SUN8I_R528
++      bool "sun8i (Allwinner R528)"
++      select CPU_V7A
++      select SUNXI_GEN_NCAT2
++      select SUNXI_NEW_PINCTRL
++      select MMC_SUNXI_HAS_NEW_MODE
++      select SUPPORT_SPL
++      select DRAM_SUN8I_R528
++
+ config MACH_SUN8I_V3S
+       bool "sun8i (Allwinner V3/V3s/S3/S3L)"
+       select CPU_V7A
+@@ -612,6 +621,7 @@ config SYS_CLK_FREQ
+       default 1008000000 if MACH_SUN9I
+       default 888000000 if MACH_SUN50I_H6
+       default 1008000000 if MACH_SUN50I_H616
++      default 1008000000 if MACH_SUN8I_R528
+ config SYS_CONFIG_NAME
+       default "suniv" if MACH_SUNIV
+@@ -620,6 +630,7 @@ config SYS_CONFIG_NAME
+       default "sun6i" if MACH_SUN6I
+       default "sun7i" if MACH_SUN7I
+       default "sun8i" if MACH_SUN8I
++      default "sun8i" if MACH_SUN8I_R528
+       default "sun9i" if MACH_SUN9I
+       default "sun50i" if MACH_SUN50I
+       default "sun50i" if MACH_SUN50I_H6
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index 51b8e708b0..8980ffb509 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -147,6 +147,10 @@ static int gpio_init(void)
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0);
+       sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0);
+       sunxi_gpio_set_pull(SUNXI_GPH(13), SUNXI_GPIO_PULL_UP);
++#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_R528)
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(2), 6);
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(3), 6);
++      sunxi_gpio_set_pull(SUNXI_GPE(3), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUNIV)
+       sunxi_gpio_set_cfgpin(SUNXI_GPA(2), SUNIV_GPE_UART0);
+       sunxi_gpio_set_cfgpin(SUNXI_GPA(3), SUNIV_GPE_UART0);
+@@ -163,6 +167,10 @@ static int gpio_init(void)
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_GPB_UART2);
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
+       sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
++#elif CONFIG_CONS_INDEX == 4 && defined(CONFIG_MACH_SUN8I_R528)
++      sunxi_gpio_set_cfgpin(SUNXI_GPB(6), 7);
++      sunxi_gpio_set_cfgpin(SUNXI_GPB(7), 7);
++      sunxi_gpio_set_pull(SUNXI_GPB(7), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
+diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+index c3a4623d34..bf21a71542 100644
+--- a/arch/arm/mach-sunxi/clock_sun50i_h6.c
++++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c
+@@ -52,7 +52,9 @@ void clock_init_safe(void)
+                       CCM_CPU_AXI_DEFAULT_FACTORS);
+       writel(CCM_PSI_AHB1_AHB2_DEFAULT, &ccm->psi_ahb1_ahb2_cfg);
++#ifdef CCM_AHB3_DEFAULT
+       writel(CCM_AHB3_DEFAULT, &ccm->ahb3_cfg);
++#endif
+       writel(CCM_APB1_DEFAULT, &ccm->apb1_cfg);
+       /*
+diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
+index 7eef178859..7fecc3b88d 100644
+--- a/arch/arm/mach-sunxi/cpu_info.c
++++ b/arch/arm/mach-sunxi/cpu_info.c
+@@ -93,6 +93,8 @@ int print_cpuinfo(void)
+       printf("CPU:   Allwinner R40 (SUN8I %04x)\n", sunxi_get_sram_id());
+ #elif defined CONFIG_MACH_SUN8I_V3S
+       printf("CPU:   Allwinner V3s (SUN8I %04x)\n", sunxi_get_sram_id());
++#elif defined CONFIG_MACH_SUN8I_R528
++      puts("CPU:   Allwinner R528 (SUN8I)\n");
+ #elif defined CONFIG_MACH_SUN9I
+       puts("CPU:   Allwinner A80 (SUN9I)\n");
+ #elif defined CONFIG_MACH_SUN50I
+diff --git a/common/spl/Kconfig b/common/spl/Kconfig
+index 06bcedca7d..196a250ef9 100644
+--- a/common/spl/Kconfig
++++ b/common/spl/Kconfig
+@@ -357,6 +357,7 @@ config SPL_STACK
+       default 0x91ffb8 if ARCH_MX6 && !MX6_OCRAM_256KB
+       default 0x118000 if MACH_SUN50I_H6
+       default 0x58000 if MACH_SUN50I_H616
++      default 0x40000 if MACH_SUN8I_R528
+       default 0x54000 if MACH_SUN50I || MACH_SUN50I_H5
+       default 0x18000 if MACH_SUN9I
+       default 0x8000 if ARCH_SUNXI
+diff --git a/drivers/clk/sunxi/Kconfig b/drivers/clk/sunxi/Kconfig
+index f65e482ba4..8bdc094489 100644
+--- a/drivers/clk/sunxi/Kconfig
++++ b/drivers/clk/sunxi/Kconfig
+@@ -89,6 +89,7 @@ config CLK_SUN8I_H3
+ config CLK_SUN20I_D1
+       bool "Clock driver for Allwinner D1"
++      default MACH_SUN8I_R528
+       help
+         This enables common clock driver support for platforms based
+         on Allwinner D1 SoC.
+diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
+index a8e590561c..0837e8bb30 100644
+--- a/drivers/mmc/sunxi_mmc.c
++++ b/drivers/mmc/sunxi_mmc.c
+@@ -708,6 +708,7 @@ static const struct udevice_id sunxi_mmc_ids[] = {
+       { .compatible = "allwinner,sun50i-h6-emmc" },
+       { .compatible = "allwinner,sun50i-a100-mmc" },
+       { .compatible = "allwinner,sun50i-a100-emmc" },
++      { .compatible = "allwinner,sun20i-d1-mmc" },
+       { /* sentinel */ }
+ };
+diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
+index c8f937d91e..cbd6179598 100644
+--- a/drivers/pinctrl/sunxi/Kconfig
++++ b/drivers/pinctrl/sunxi/Kconfig
+@@ -126,6 +126,7 @@ config PINCTRL_SUN50I_H616_R
+ config PINCTRL_SUN20I_D1
+       bool "Support for the Allwinner D1/R528 PIO"
++      default MACH_SUN8I_R528
+       select PINCTRL_SUNXI
+ endif
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4022-sunxi-add-support-for-UART5-in-Port-E-group-on-T133.patch b/package/boot/uboot-sunxi/patches/4022-sunxi-add-support-for-UART5-in-Port-E-group-on-T133.patch
deleted file mode 100644 (file)
index 8be15ff..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From 34ee938e52f219912dd9c2333ce2174860201290 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Sat, 3 Jun 2023 23:41:31 +0200
-Subject: [PATCH 4022/4031] sunxi: add support for UART5 in Port E group on
- T133
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/arm/include/asm/arch-sunxi/serial.h | 1 +
- arch/arm/mach-sunxi/board.c              | 4 ++++
- drivers/pinctrl/sunxi/pinctrl-sunxi.c    | 1 +
- include/configs/sunxi-common.h           | 3 +++
- 4 files changed, 9 insertions(+)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/serial.h b/arch/arm/include/asm/arch-sunxi/serial.h
-index 9386287b65..48d0f42a3b 100644
---- a/arch/arm/include/asm/arch-sunxi/serial.h
-+++ b/arch/arm/include/asm/arch-sunxi/serial.h
-@@ -20,6 +20,7 @@
- #elif defined(CONFIG_SUNXI_GEN_NCAT2)
- #define SUNXI_UART0_BASE              0x02500000
- #define SUNXI_R_UART_BASE             0               // 0x07080000 (?>
-+#define SUNXI_UART5_BASE              (SUNXI_UART0_BASE + 0x1400)
- #else
- #define SUNXI_UART0_BASE              0x01c28000
- #define SUNXI_R_UART_BASE             0x01f02800
-diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
-index df4f32d10c..6a37b33767 100644
---- a/arch/arm/mach-sunxi/board.c
-+++ b/arch/arm/mach-sunxi/board.c
-@@ -175,6 +175,10 @@ static int gpio_init(void)
-       sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
-       sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
-       sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
-+#elif CONFIG_CONS_INDEX == 6 && defined(CONFIG_MACH_SUN8I_R528)
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(6), 9);
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(7), 9);
-+      sunxi_gpio_set_pull(SUNXI_GPE(7), SUNXI_GPIO_PULL_UP);
- #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN8I) && \
-                               !defined(CONFIG_MACH_SUN8I_R40)
-       sunxi_gpio_set_cfgpin(SUNXI_GPG(6), SUN8I_GPG_UART1);
-diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-index 614cfe6b73..2717d79bc3 100644
---- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-@@ -748,6 +748,7 @@ static const struct sunxi_pinctrl_function sun20i_d1_pinctrl_functions[] = {
-       { "uart0",      6 },    /* PB2-PB3 */
- #endif
-       { "uart3",      7 },    /* PB6-PB9 */
-+      { "uart5",      3 },    /* PE6-PE7 */
- };
- static const struct sunxi_pinctrl_desc __maybe_unused sun20i_d1_pinctrl_desc = {
-diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
-index b8ca77d031..bdb568af4b 100644
---- a/include/configs/sunxi-common.h
-+++ b/include/configs/sunxi-common.h
-@@ -29,6 +29,9 @@
- # define CFG_SYS_NS16550_COM3         SUNXI_UART2_BASE
- # define CFG_SYS_NS16550_COM4         SUNXI_UART3_BASE
- # define CFG_SYS_NS16550_COM5         SUNXI_R_UART_BASE
-+#if defined(CONFIG_SUNXI_GEN_NCAT2)
-+# define CFG_SYS_NS16550_COM6         SUNXI_UART5_BASE
-+#endif
- #endif
- /* CPU */
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4023-sunxi-add-MYIR-MYD-YT113X-board.patch b/package/boot/uboot-sunxi/patches/4023-sunxi-add-MYIR-MYD-YT113X-board.patch
deleted file mode 100644 (file)
index fe44e8c..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-From 8e178708d913eb1f4b40661519944db779d0476b Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Sun, 4 Jun 2023 00:13:45 +0200
-Subject: [PATCH 4023/4031] sunxi: add MYIR MYD-YT113X board
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/arm/dts/Makefile                        |  3 +-
- arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts | 48 ++++++++++++++++++++
- configs/myir_myd_t113x_defconfig             | 17 +++++++
- 3 files changed, 67 insertions(+), 1 deletion(-)
- create mode 100644 arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts
- create mode 100644 configs/myir_myd_t113x_defconfig
-
-diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
-index 4207f17601..6fb49de59a 100644
---- a/arch/arm/dts/Makefile
-+++ b/arch/arm/dts/Makefile
-@@ -712,7 +712,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
-       sun8i-v3s-licheepi-zero.dtb
- dtb-$(CONFIG_MACH_SUN8I_R528) += \
-       sun8i-t113s-mangopi-mq-r-t113.dtb \
--      sun8i-t113s-mangopi-mqdual-t113.dtb
-+      sun8i-t113s-mangopi-mqdual-t113.dtb \
-+      sun8i-t113s-myir-myd-yt113x.dtb
- dtb-$(CONFIG_MACH_SUN50I_H5) += \
-       sun50i-h5-bananapi-m2-plus.dtb \
-       sun50i-h5-emlid-neutis-n5-devboard.dtb \
-diff --git a/arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts
-new file mode 100644
-index 0000000000..1c568b4cee
---- /dev/null
-+++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts
-@@ -0,0 +1,48 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2022 Arm Ltd.
-+
-+#include <dt-bindings/interrupt-controller/irq.h>
-+
-+/dts-v1/;
-+
-+#include "sun8i-t113s.dtsi"
-+#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
-+
-+/ {
-+      model = "MYIR MYD-YT113X";
-+      compatible = "myir,myd-yt113x", "myir,myc-yt113x", "allwinner,sun8i-t113s";
-+
-+      aliases {
-+              serial5 = &uart5;
-+      };
-+
-+      chosen {
-+              stdout-path = "serial5:115200n8";
-+      };
-+};
-+
-+&cpu0 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&cpu1 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&pio {
-+      /omit-if-no-ref/
-+      uart5_pins: uart5-pins {
-+              pins = "PE6", "PE7";
-+              function = "uart5";
-+      };
-+};
-+
-+&uart5 {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&uart5_pins>;
-+      status = "okay";
-+};
-+
-+&uart3 {
-+      status = "disabled";
-+};
-diff --git a/configs/myir_myd_t113x_defconfig b/configs/myir_myd_t113x_defconfig
-new file mode 100644
-index 0000000000..dc652732e3
---- /dev/null
-+++ b/configs/myir_myd_t113x_defconfig
-@@ -0,0 +1,17 @@
-+CONFIG_ARM=y
-+CONFIG_ARCH_SUNXI=y
-+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-myir-myd-yt113x"
-+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
-+CONFIG_SPL=y
-+CONFIG_MACH_SUN8I_R528=y
-+CONFIG_CONS_INDEX=6
-+CONFIG_MMC0_CD_PIN="PF6"
-+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-+CONFIG_SYS_MONITOR_LEN=786432
-+CONFIG_DRAM_CLK=792
-+CONFIG_DRAM_ZQ=8092667
-+CONFIG_DRAM_SUNXI_ODT_EN=0
-+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
-+CONFIG_DRAM_SUNXI_TPR11=0x340000
-+CONFIG_DRAM_SUNXI_TPR12=0x46
-+CONFIG_DRAM_SUNXI_TPR13=0x34000100
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4023-sunxi-refactor-serial-base-addresses-to-avoid-asm-ar.patch b/package/boot/uboot-sunxi/patches/4023-sunxi-refactor-serial-base-addresses-to-avoid-asm-ar.patch
new file mode 100644 (file)
index 0000000..387d3e1
--- /dev/null
@@ -0,0 +1,265 @@
+From 3322934ace5532df9a783c138471abd479ed2737 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:46:03 +0100
+Subject: [PATCH 4023/4044] sunxi: refactor serial base addresses to avoid
+ asm/arch/cpu.h
+
+At the moment we have each SoC's memory map defined in its own cpu.h,
+which is included in include/configs/sunxi_common.h. This will be a
+problem with the introduction of Allwinner RISC-V support.
+
+Remove the inclusion of that header file from the common config header,
+instead move the required serial base addresses (for the SPL) into a
+separate header file. Then include the original cpu.h file only where
+we really need it, which is only under arch/arm now.
+
+This disentangles the architecture specific header files from the
+generic code.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/cpu/armv7/sunxi/sram.c               |  1 +
+ arch/arm/cpu/armv8/fel_utils.S                |  1 +
+ arch/arm/include/asm/arch-sunxi/boot0.h       |  2 ++
+ arch/arm/include/asm/arch-sunxi/clock.h       |  1 +
+ arch/arm/include/asm/arch-sunxi/cpu_sun4i.h   | 15 ---------
+ .../include/asm/arch-sunxi/cpu_sun50i_h6.h    |  5 ---
+ arch/arm/include/asm/arch-sunxi/cpu_sun9i.h   |  7 ----
+ .../include/asm/arch-sunxi/cpu_sunxi_ncat2.h  |  4 ---
+ arch/arm/include/asm/arch-sunxi/serial.h      | 32 +++++++++++++++++++
+ arch/arm/mach-sunxi/gtbus_sun9i.c             |  1 +
+ arch/arm/mach-sunxi/timer.c                   |  1 +
+ include/configs/sunxi-common.h                |  2 +-
+ 12 files changed, 40 insertions(+), 32 deletions(-)
+ create mode 100644 arch/arm/include/asm/arch-sunxi/serial.h
+
+diff --git a/arch/arm/cpu/armv7/sunxi/sram.c b/arch/arm/cpu/armv7/sunxi/sram.c
+index 28564c2846..28ff6a1b7c 100644
+--- a/arch/arm/cpu/armv7/sunxi/sram.c
++++ b/arch/arm/cpu/armv7/sunxi/sram.c
+@@ -12,6 +12,7 @@
+ #include <common.h>
+ #include <init.h>
+ #include <asm/io.h>
++#include <asm/arch/cpu.h>
+ void sunxi_sram_init(void)
+ {
+diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S
+index 2fe38a1a04..939869b9ff 100644
+--- a/arch/arm/cpu/armv8/fel_utils.S
++++ b/arch/arm/cpu/armv8/fel_utils.S
+@@ -10,6 +10,7 @@
+ #include <config.h>
+ #include <asm/system.h>
+ #include <linux/linkage.h>
++#include <asm/arch/cpu.h>
+ /*
+  * We don't overwrite save_boot_params() here, to save the FEL state upon
+diff --git a/arch/arm/include/asm/arch-sunxi/boot0.h b/arch/arm/include/asm/arch-sunxi/boot0.h
+index 46b7e073b5..8ff7ca9b20 100644
+--- a/arch/arm/include/asm/arch-sunxi/boot0.h
++++ b/arch/arm/include/asm/arch-sunxi/boot0.h
+@@ -3,6 +3,8 @@
+  * Configuration settings for the Allwinner A64 (sun50i) CPU
+  */
++#include <asm/arch/cpu.h>
++
+ #if defined(CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER) && !defined(CONFIG_SPL_BUILD)
+ /* reserve space for BOOT0 header information */
+       b       reset
+diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
+index 3d34261b0e..fcc8966cb0 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock.h
++++ b/arch/arm/include/asm/arch-sunxi/clock.h
+@@ -9,6 +9,7 @@
+ #define _SUNXI_CLOCK_H
+ #include <linux/types.h>
++#include <asm/arch/cpu.h>
+ #define CLK_GATE_OPEN                 0x1
+ #define CLK_GATE_CLOSE                        0x0
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+index d6fe51f24b..3daee2f574 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+@@ -128,20 +128,6 @@ defined(CONFIG_MACH_SUN50I)
+ #define SUNXI_CPUCFG_BASE             0x01c25c00
+ #endif
+-#ifdef CONFIG_MACH_SUNIV
+-#define SUNXI_UART0_BASE              0x01c25000
+-#define SUNXI_UART1_BASE              0x01c25400
+-#define SUNXI_UART2_BASE              0x01c25800
+-#else
+-#define SUNXI_UART0_BASE              0x01c28000
+-#define SUNXI_UART1_BASE              0x01c28400
+-#define SUNXI_UART2_BASE              0x01c28800
+-#endif
+-#define SUNXI_UART3_BASE              0x01c28c00
+-#define SUNXI_UART4_BASE              0x01c29000
+-#define SUNXI_UART5_BASE              0x01c29400
+-#define SUNXI_UART6_BASE              0x01c29800
+-#define SUNXI_UART7_BASE              0x01c29c00
+ #define SUNXI_PS2_0_BASE              0x01c2a000
+ #define SUNXI_PS2_1_BASE              0x01c2a400
+@@ -208,7 +194,6 @@ defined(CONFIG_MACH_SUN50I)
+ #endif
+ #define SUNXI_R_TWI_BASE              0x01f02400
+-#define SUNXI_R_UART_BASE             0x01f02800
+ #define SUN6I_P2WI_BASE                       0x01f03400
+ #define SUNXI_RSB_BASE                        0x01f03400
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
+index 9b6bf84360..15ee092d35 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h
+@@ -42,10 +42,6 @@
+ #define SUNXI_DRAM_PHY0_BASE          0x04800000
+ #endif
+-#define SUNXI_UART0_BASE              0x05000000
+-#define SUNXI_UART1_BASE              0x05000400
+-#define SUNXI_UART2_BASE              0x05000800
+-#define SUNXI_UART3_BASE              0x05000C00
+ #define SUNXI_TWI0_BASE                       0x05002000
+ #define SUNXI_TWI1_BASE                       0x05002400
+ #define SUNXI_TWI2_BASE                       0x05002800
+@@ -67,7 +63,6 @@
+ #define SUNXI_R_CPUCFG_BASE           0x07000400
+ #define SUNXI_PRCM_BASE                       0x07010000
+ #define SUNXI_R_WDOG_BASE             0x07020400
+-#define SUNXI_R_UART_BASE             0x07080000
+ #define SUNXI_R_TWI_BASE              0x07081400
+ #ifndef __ASSEMBLY__
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
+index 20025be231..2bf2675d5c 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h
+@@ -86,12 +86,6 @@
+ #define SUNXI_LRADC_BASE              (REGS_APB0_BASE + 0x1800)
+ /* APB1 Module */
+-#define SUNXI_UART0_BASE              (REGS_APB1_BASE + 0x0000)
+-#define SUNXI_UART1_BASE              (REGS_APB1_BASE + 0x0400)
+-#define SUNXI_UART2_BASE              (REGS_APB1_BASE + 0x0800)
+-#define SUNXI_UART3_BASE              (REGS_APB1_BASE + 0x0C00)
+-#define SUNXI_UART4_BASE              (REGS_APB1_BASE + 0x1000)
+-#define SUNXI_UART5_BASE              (REGS_APB1_BASE + 0x1400)
+ #define SUNXI_TWI0_BASE                       (REGS_APB1_BASE + 0x2800)
+ #define SUNXI_TWI1_BASE                       (REGS_APB1_BASE + 0x2C00)
+ #define SUNXI_TWI2_BASE                       (REGS_APB1_BASE + 0x3000)
+@@ -100,7 +94,6 @@
+ /* RCPUS Module */
+ #define SUNXI_PRCM_BASE                       (REGS_RCPUS_BASE + 0x1400)
+-#define SUNXI_R_UART_BASE             (REGS_RCPUS_BASE + 0x2800)
+ #define SUNXI_RSB_BASE                        (REGS_RCPUS_BASE + 0x3400)
+ /* Misc. */
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
+index b13be2c4e8..961a3b37c9 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
+@@ -10,10 +10,6 @@
+ #define SUNXI_CCM_BASE                        0x02001000
+ #define SUNXI_TIMER_BASE              0x02050000
+-#define SUNXI_UART0_BASE              0x02500000
+-#define SUNXI_UART1_BASE              0x02500400
+-#define SUNXI_UART2_BASE              0x02500800
+-#define SUNXI_UART3_BASE              0x02500C00
+ #define SUNXI_TWI0_BASE                       0x02502000
+ #define SUNXI_TWI1_BASE                       0x02502400
+ #define SUNXI_TWI2_BASE                       0x02502800
+diff --git a/arch/arm/include/asm/arch-sunxi/serial.h b/arch/arm/include/asm/arch-sunxi/serial.h
+new file mode 100644
+index 0000000000..9386287b65
+--- /dev/null
++++ b/arch/arm/include/asm/arch-sunxi/serial.h
+@@ -0,0 +1,32 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++/*
++ *  hardcoded UART base addresses for early SPL use
++ *
++ *  Copyright (c) 2022  Arm Ltd.
++ */
++
++#ifndef SUNXI_SERIAL_MEMMAP_H
++#define SUNXI_SERIAL_MEMMAP_H
++
++#if defined(CONFIG_MACH_SUN9I)
++#define SUNXI_UART0_BASE              0x07000000
++#define SUNXI_R_UART_BASE             0x08002800
++#elif defined(CONFIG_SUN50I_GEN_H6)
++#define SUNXI_UART0_BASE              0x05000000
++#define SUNXI_R_UART_BASE             0x07080000
++#elif defined(CONFIG_MACH_SUNIV)
++#define SUNXI_UART0_BASE              0x01c25000
++#define SUNXI_R_UART_BASE             0
++#elif defined(CONFIG_SUNXI_GEN_NCAT2)
++#define SUNXI_UART0_BASE              0x02500000
++#define SUNXI_R_UART_BASE             0               // 0x07080000 (?>
++#else
++#define SUNXI_UART0_BASE              0x01c28000
++#define SUNXI_R_UART_BASE             0x01f02800
++#endif
++
++#define SUNXI_UART1_BASE              (SUNXI_UART0_BASE + 0x400)
++#define SUNXI_UART2_BASE              (SUNXI_UART0_BASE + 0x800)
++#define SUNXI_UART3_BASE              (SUNXI_UART0_BASE + 0xc00)
++
++#endif /* SUNXI_SERIAL_MEMMAP_H */
+diff --git a/arch/arm/mach-sunxi/gtbus_sun9i.c b/arch/arm/mach-sunxi/gtbus_sun9i.c
+index cf011c4cfa..5624621b50 100644
+--- a/arch/arm/mach-sunxi/gtbus_sun9i.c
++++ b/arch/arm/mach-sunxi/gtbus_sun9i.c
+@@ -8,6 +8,7 @@
+ #include <common.h>
+ #include <asm/io.h>
++#include <asm/arch/cpu.h>
+ #include <asm/arch/gtbus_sun9i.h>
+ #include <asm/arch/sys_proto.h>
+diff --git a/arch/arm/mach-sunxi/timer.c b/arch/arm/mach-sunxi/timer.c
+index fc9d419a25..9a6f6c06d8 100644
+--- a/arch/arm/mach-sunxi/timer.c
++++ b/arch/arm/mach-sunxi/timer.c
+@@ -10,6 +10,7 @@
+ #include <time.h>
+ #include <asm/global_data.h>
+ #include <asm/io.h>
++#include <asm/arch/cpu.h>
+ #include <asm/arch/timer.h>
+ #include <linux/delay.h>
+diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
+index d2d70f0fc2..b8ca77d031 100644
+--- a/include/configs/sunxi-common.h
++++ b/include/configs/sunxi-common.h
+@@ -12,7 +12,6 @@
+ #ifndef _SUNXI_COMMON_CONFIG_H
+ #define _SUNXI_COMMON_CONFIG_H
+-#include <asm/arch/cpu.h>
+ #include <linux/stringify.h>
+ /* Serial & console */
+@@ -24,6 +23,7 @@
+ #define CFG_SYS_NS16550_CLK           24000000
+ #endif
+ #if !CONFIG_IS_ENABLED(DM_SERIAL)
++#include <asm/arch/serial.h>
+ # define CFG_SYS_NS16550_COM1         SUNXI_UART0_BASE
+ # define CFG_SYS_NS16550_COM2         SUNXI_UART1_BASE
+ # define CFG_SYS_NS16550_COM3         SUNXI_UART2_BASE
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4024-riscv-dts-allwinner-Add-the-D1-D1s-SoC-devicetree.patch b/package/boot/uboot-sunxi/patches/4024-riscv-dts-allwinner-Add-the-D1-D1s-SoC-devicetree.patch
new file mode 100644 (file)
index 0000000..3d71884
--- /dev/null
@@ -0,0 +1,1156 @@
+From ebd383f6a25566c6a0e72f702eb826182929cd2b Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Fri, 21 Jul 2023 14:46:04 +0100
+Subject: [PATCH 4024/4044] riscv: dts: allwinner: Add the D1/D1s SoC
+ devicetree
+
+D1 (aka D1-H), D1s (aka F133), R528, and T113 are a family of SoCs based
+on a single die, or at a pair of dies derived from the same design.
+
+D1 and D1s contain a single T-HEAD Xuantie C906 CPU, whereas R528 and
+T113 contain a pair of Cortex-A7's. D1 and R528 are the full version of
+the chip with a BGA package, whereas D1s and T113 are low-pin-count QFP
+variants.
+
+Because the original design supported both ARM and RISC-V CPUs, some
+peripherals are duplicated. In addition, all variants except D1s contain
+a HiFi 4 DSP with its own set of peripherals.
+
+The devicetrees are organized to minimize duplication:
+ - Common perhiperals are described in sunxi-d1s-t113.dtsi
+ - DSP-related peripherals are described in sunxi-d1-t113.dtsi
+ - RISC-V specific hardware is described in sun20i-d1s.dtsi
+ - Functionality unique to the D1 variant is described in sun20i-d1.dtsi
+
+The SOC_PERIPHERAL_IRQ macro handles the different #interrupt-cells
+values between the ARM (GIC) and RISC-V (PLIC) versions of the SoC.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+---
+ arch/riscv/dts/sun20i-common-regulators.dtsi |  28 +
+ arch/riscv/dts/sun20i-d1.dtsi                |  66 ++
+ arch/riscv/dts/sun20i-d1s.dtsi               |  76 ++
+ arch/riscv/dts/sunxi-d1-t113.dtsi            |  15 +
+ arch/riscv/dts/sunxi-d1s-t113.dtsi           | 846 +++++++++++++++++++
+ include/dt-bindings/clock/sun20i-d1-r-ccu.h  |  19 +
+ include/dt-bindings/reset/sun20i-d1-r-ccu.h  |  16 +
+ 7 files changed, 1066 insertions(+)
+ create mode 100644 arch/riscv/dts/sun20i-common-regulators.dtsi
+ create mode 100644 arch/riscv/dts/sun20i-d1.dtsi
+ create mode 100644 arch/riscv/dts/sun20i-d1s.dtsi
+ create mode 100644 arch/riscv/dts/sunxi-d1-t113.dtsi
+ create mode 100644 arch/riscv/dts/sunxi-d1s-t113.dtsi
+ create mode 100644 include/dt-bindings/clock/sun20i-d1-r-ccu.h
+ create mode 100644 include/dt-bindings/reset/sun20i-d1-r-ccu.h
+
+diff --git a/arch/riscv/dts/sun20i-common-regulators.dtsi b/arch/riscv/dts/sun20i-common-regulators.dtsi
+new file mode 100644
+index 0000000000..9b03fca244
+--- /dev/null
++++ b/arch/riscv/dts/sun20i-common-regulators.dtsi
+@@ -0,0 +1,28 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
++
++/ {
++      reg_vcc: vcc {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++      };
++
++      reg_vcc_3v3: vcc-3v3 {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              vin-supply = <&reg_vcc>;
++      };
++};
++
++&pio {
++      vcc-pb-supply = <&reg_vcc_3v3>;
++      vcc-pc-supply = <&reg_vcc_3v3>;
++      vcc-pd-supply = <&reg_vcc_3v3>;
++      vcc-pe-supply = <&reg_vcc_3v3>;
++      vcc-pf-supply = <&reg_vcc_3v3>;
++      vcc-pg-supply = <&reg_vcc_3v3>;
++};
+diff --git a/arch/riscv/dts/sun20i-d1.dtsi b/arch/riscv/dts/sun20i-d1.dtsi
+new file mode 100644
+index 0000000000..97e7cbb325
+--- /dev/null
++++ b/arch/riscv/dts/sun20i-d1.dtsi
+@@ -0,0 +1,66 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
++
++#include "sun20i-d1s.dtsi"
++#include "sunxi-d1-t113.dtsi"
++
++/ {
++      soc {
++              lradc: keys@2009800 {
++                      compatible = "allwinner,sun20i-d1-lradc",
++                                   "allwinner,sun50i-r329-lradc";
++                      reg = <0x2009800 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(61) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_LRADC>;
++                      resets = <&ccu RST_BUS_LRADC>;
++                      status = "disabled";
++              };
++
++              i2s0: i2s@2032000 {
++                      compatible = "allwinner,sun20i-d1-i2s",
++                                   "allwinner,sun50i-r329-i2s";
++                      reg = <0x2032000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(26) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_I2S0>,
++                               <&ccu CLK_I2S0>;
++                      clock-names = "apb", "mod";
++                      resets = <&ccu RST_BUS_I2S0>;
++                      dmas = <&dma 3>, <&dma 3>;
++                      dma-names = "rx", "tx";
++                      status = "disabled";
++                      #sound-dai-cells = <0>;
++              };
++      };
++};
++
++&pio {
++      /omit-if-no-ref/
++      dmic_pb11_d0_pin: dmic-pb11-d0-pin {
++              pins = "PB11";
++              function = "dmic";
++      };
++
++      /omit-if-no-ref/
++      dmic_pe17_clk_pin: dmic-pe17-clk-pin {
++              pins = "PE17";
++              function = "dmic";
++      };
++
++      /omit-if-no-ref/
++      i2c0_pb10_pins: i2c0-pb10-pins {
++              pins = "PB10", "PB11";
++              function = "i2c0";
++      };
++
++      /omit-if-no-ref/
++      i2c2_pb0_pins: i2c2-pb0-pins {
++              pins = "PB0", "PB1";
++              function = "i2c2";
++      };
++
++      /omit-if-no-ref/
++      uart0_pb8_pins: uart0-pb8-pins {
++              pins = "PB8", "PB9";
++              function = "uart0";
++      };
++};
+diff --git a/arch/riscv/dts/sun20i-d1s.dtsi b/arch/riscv/dts/sun20i-d1s.dtsi
+new file mode 100644
+index 0000000000..8275630af9
+--- /dev/null
++++ b/arch/riscv/dts/sun20i-d1s.dtsi
+@@ -0,0 +1,76 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
++
++#define SOC_PERIPHERAL_IRQ(nr)        (nr + 16)
++
++#include "sunxi-d1s-t113.dtsi"
++
++/ {
++      cpus {
++              timebase-frequency = <24000000>;
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              cpu0: cpu@0 {
++                      compatible = "thead,c906", "riscv";
++                      device_type = "cpu";
++                      reg = <0>;
++                      clocks = <&ccu CLK_RISCV>;
++                      d-cache-block-size = <64>;
++                      d-cache-sets = <256>;
++                      d-cache-size = <32768>;
++                      i-cache-block-size = <64>;
++                      i-cache-sets = <128>;
++                      i-cache-size = <32768>;
++                      mmu-type = "riscv,sv39";
++                      operating-points-v2 = <&opp_table_cpu>;
++                      riscv,isa = "rv64imafdc";
++                      #cooling-cells = <2>;
++
++                      cpu0_intc: interrupt-controller {
++                              compatible = "riscv,cpu-intc";
++                              interrupt-controller;
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                      };
++              };
++      };
++
++      opp_table_cpu: opp-table-cpu {
++              compatible = "operating-points-v2";
++
++              opp-408000000 {
++                      opp-hz = /bits/ 64 <408000000>;
++                      opp-microvolt = <900000 900000 1100000>;
++              };
++
++              opp-1080000000 {
++                      opp-hz = /bits/ 64 <1008000000>;
++                      opp-microvolt = <900000 900000 1100000>;
++              };
++      };
++
++      soc {
++              interrupt-parent = <&plic>;
++
++              riscv_wdt: watchdog@6011000 {
++                      compatible = "allwinner,sun20i-d1-wdt";
++                      reg = <0x6011000 0x20>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(131) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&dcxo>, <&rtc CLK_OSC32K>;
++                      clock-names = "hosc", "losc";
++              };
++
++              plic: interrupt-controller@10000000 {
++                      compatible = "allwinner,sun20i-d1-plic",
++                                   "thead,c900-plic";
++                      reg = <0x10000000 0x4000000>;
++                      interrupts-extended = <&cpu0_intc 11>,
++                                            <&cpu0_intc 9>;
++                      interrupt-controller;
++                      riscv,ndev = <175>;
++                      #address-cells = <0>;
++                      #interrupt-cells = <2>;
++              };
++      };
++};
+diff --git a/arch/riscv/dts/sunxi-d1-t113.dtsi b/arch/riscv/dts/sunxi-d1-t113.dtsi
+new file mode 100644
+index 0000000000..b7156123df
+--- /dev/null
++++ b/arch/riscv/dts/sunxi-d1-t113.dtsi
+@@ -0,0 +1,15 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
++
++/ {
++      soc {
++              dsp_wdt: watchdog@1700400 {
++                      compatible = "allwinner,sun20i-d1-wdt";
++                      reg = <0x1700400 0x20>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(122) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&dcxo>, <&rtc CLK_OSC32K>;
++                      clock-names = "hosc", "losc";
++                      status = "reserved";
++              };
++      };
++};
+diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+new file mode 100644
+index 0000000000..922e8e0e2c
+--- /dev/null
++++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+@@ -0,0 +1,846 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2021-2022 Samuel Holland <samuel@sholland.org>
++
++#include <dt-bindings/clock/sun6i-rtc.h>
++#include <dt-bindings/clock/sun8i-de2.h>
++#include <dt-bindings/clock/sun8i-tcon-top.h>
++#include <dt-bindings/clock/sun20i-d1-ccu.h>
++#include <dt-bindings/clock/sun20i-d1-r-ccu.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/reset/sun8i-de2.h>
++#include <dt-bindings/reset/sun20i-d1-ccu.h>
++#include <dt-bindings/reset/sun20i-d1-r-ccu.h>
++
++/ {
++      #address-cells = <1>;
++      #size-cells = <1>;
++
++      dcxo: dcxo-clk {
++              compatible = "fixed-clock";
++              clock-output-names = "dcxo";
++              #clock-cells = <0>;
++      };
++
++      de: display-engine {
++              compatible = "allwinner,sun20i-d1-display-engine";
++              allwinner,pipelines = <&mixer0>, <&mixer1>;
++              status = "disabled";
++      };
++
++      soc {
++              compatible = "simple-bus";
++              ranges;
++              dma-noncoherent;
++              #address-cells = <1>;
++              #size-cells = <1>;
++
++              pio: pinctrl@2000000 {
++                      compatible = "allwinner,sun20i-d1-pinctrl";
++                      reg = <0x2000000 0x800>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(69) IRQ_TYPE_LEVEL_HIGH>,
++                                   <SOC_PERIPHERAL_IRQ(71) IRQ_TYPE_LEVEL_HIGH>,
++                                   <SOC_PERIPHERAL_IRQ(73) IRQ_TYPE_LEVEL_HIGH>,
++                                   <SOC_PERIPHERAL_IRQ(75) IRQ_TYPE_LEVEL_HIGH>,
++                                   <SOC_PERIPHERAL_IRQ(77) IRQ_TYPE_LEVEL_HIGH>,
++                                   <SOC_PERIPHERAL_IRQ(79) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_APB0>,
++                               <&dcxo>,
++                               <&rtc CLK_OSC32K>;
++                      clock-names = "apb", "hosc", "losc";
++                      gpio-controller;
++                      interrupt-controller;
++                      #gpio-cells = <3>;
++                      #interrupt-cells = <3>;
++
++                      /omit-if-no-ref/
++                      clk_pg11_pin: clk-pg11-pin {
++                              pins = "PG11";
++                              function = "clk";
++                      };
++
++                      /omit-if-no-ref/
++                      dsi_4lane_pins: dsi-4lane-pins {
++                              pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5",
++                                     "PD6", "PD7", "PD8", "PD9";
++                              drive-strength = <30>;
++                              function = "dsi";
++                      };
++
++                      /omit-if-no-ref/
++                      lcd_rgb666_pins: lcd-rgb666-pins {
++                              pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5",
++                                     "PD6", "PD7", "PD8", "PD9", "PD10", "PD11",
++                                     "PD12", "PD13", "PD14", "PD15", "PD16", "PD17",
++                                     "PD18", "PD19", "PD20", "PD21";
++                              function = "lcd0";
++                      };
++
++                      /omit-if-no-ref/
++                      mmc0_pins: mmc0-pins {
++                              pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
++                              function = "mmc0";
++                      };
++
++                      /omit-if-no-ref/
++                      mmc1_pins: mmc1-pins {
++                              pins = "PG0", "PG1", "PG2", "PG3", "PG4", "PG5";
++                              function = "mmc1";
++                      };
++
++                      /omit-if-no-ref/
++                      mmc2_pins: mmc2-pins {
++                              pins = "PC2", "PC3", "PC4", "PC5", "PC6", "PC7";
++                              function = "mmc2";
++                      };
++
++                      /omit-if-no-ref/
++                      rgmii_pe_pins: rgmii-pe-pins {
++                              pins = "PE0", "PE1", "PE2", "PE3", "PE4",
++                                     "PE5", "PE6", "PE7", "PE8", "PE9",
++                                     "PE11", "PE12", "PE13", "PE14", "PE15";
++                              function = "emac";
++                      };
++
++                      /omit-if-no-ref/
++                      rmii_pe_pins: rmii-pe-pins {
++                              pins = "PE0", "PE1", "PE2", "PE3", "PE4",
++                                     "PE5", "PE6", "PE7", "PE8", "PE9";
++                              function = "emac";
++                      };
++
++                      /omit-if-no-ref/
++                      uart1_pg6_pins: uart1-pg6-pins {
++                              pins = "PG6", "PG7";
++                              function = "uart1";
++                      };
++
++                      /omit-if-no-ref/
++                      uart1_pg8_rts_cts_pins: uart1-pg8-rts-cts-pins {
++                              pins = "PG8", "PG9";
++                              function = "uart1";
++                      };
++
++                      /omit-if-no-ref/
++                      uart3_pb_pins: uart3-pb-pins {
++                              pins = "PB6", "PB7";
++                              function = "uart3";
++                      };
++              };
++
++              ccu: clock-controller@2001000 {
++                      compatible = "allwinner,sun20i-d1-ccu";
++                      reg = <0x2001000 0x1000>;
++                      clocks = <&dcxo>,
++                               <&rtc CLK_OSC32K>,
++                               <&rtc CLK_IOSC>;
++                      clock-names = "hosc", "losc", "iosc";
++                      #clock-cells = <1>;
++                      #reset-cells = <1>;
++              };
++
++              dmic: dmic@2031000 {
++                      compatible = "allwinner,sun20i-d1-dmic",
++                                   "allwinner,sun50i-h6-dmic";
++                      reg = <0x2031000 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(24) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_DMIC>,
++                               <&ccu CLK_DMIC>;
++                      clock-names = "bus", "mod";
++                      resets = <&ccu RST_BUS_DMIC>;
++                      dmas = <&dma 8>;
++                      dma-names = "rx";
++                      status = "disabled";
++                      #sound-dai-cells = <0>;
++              };
++
++              i2s1: i2s@2033000 {
++                      compatible = "allwinner,sun20i-d1-i2s",
++                                   "allwinner,sun50i-r329-i2s";
++                      reg = <0x2033000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(27) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_I2S1>,
++                               <&ccu CLK_I2S1>;
++                      clock-names = "apb", "mod";
++                      resets = <&ccu RST_BUS_I2S1>;
++                      dmas = <&dma 4>, <&dma 4>;
++                      dma-names = "rx", "tx";
++                      status = "disabled";
++                      #sound-dai-cells = <0>;
++              };
++
++              i2s2: i2s@2034000 {
++                      compatible = "allwinner,sun20i-d1-i2s",
++                                   "allwinner,sun50i-r329-i2s";
++                      reg = <0x2034000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(28) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_I2S2>,
++                               <&ccu CLK_I2S2>;
++                      clock-names = "apb", "mod";
++                      resets = <&ccu RST_BUS_I2S2>;
++                      dmas = <&dma 5>, <&dma 5>;
++                      dma-names = "rx", "tx";
++                      status = "disabled";
++                      #sound-dai-cells = <0>;
++              };
++
++              timer: timer@2050000 {
++                      compatible = "allwinner,sun20i-d1-timer",
++                                   "allwinner,sun8i-a23-timer";
++                      reg = <0x2050000 0xa0>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(59) IRQ_TYPE_LEVEL_HIGH>,
++                                   <SOC_PERIPHERAL_IRQ(60) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&dcxo>;
++              };
++
++              wdt: watchdog@20500a0 {
++                      compatible = "allwinner,sun20i-d1-wdt-reset",
++                                   "allwinner,sun20i-d1-wdt";
++                      reg = <0x20500a0 0x20>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(63) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&dcxo>, <&rtc CLK_OSC32K>;
++                      clock-names = "hosc", "losc";
++                      status = "reserved";
++              };
++
++              uart0: serial@2500000 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x2500000 0x400>;
++                      reg-io-width = <4>;
++                      reg-shift = <2>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(2) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_UART0>;
++                      resets = <&ccu RST_BUS_UART0>;
++                      dmas = <&dma 14>, <&dma 14>;
++                      dma-names = "tx", "rx";
++                      status = "disabled";
++              };
++
++              uart1: serial@2500400 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x2500400 0x400>;
++                      reg-io-width = <4>;
++                      reg-shift = <2>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(3) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_UART1>;
++                      resets = <&ccu RST_BUS_UART1>;
++                      dmas = <&dma 15>, <&dma 15>;
++                      dma-names = "tx", "rx";
++                      status = "disabled";
++              };
++
++              uart2: serial@2500800 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x2500800 0x400>;
++                      reg-io-width = <4>;
++                      reg-shift = <2>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(4) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_UART2>;
++                      resets = <&ccu RST_BUS_UART2>;
++                      dmas = <&dma 16>, <&dma 16>;
++                      dma-names = "tx", "rx";
++                      status = "disabled";
++              };
++
++              uart3: serial@2500c00 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x2500c00 0x400>;
++                      reg-io-width = <4>;
++                      reg-shift = <2>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(5) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_UART3>;
++                      resets = <&ccu RST_BUS_UART3>;
++                      dmas = <&dma 17>, <&dma 17>;
++                      dma-names = "tx", "rx";
++                      status = "disabled";
++              };
++
++              uart4: serial@2501000 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x2501000 0x400>;
++                      reg-io-width = <4>;
++                      reg-shift = <2>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(6) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_UART4>;
++                      resets = <&ccu RST_BUS_UART4>;
++                      dmas = <&dma 18>, <&dma 18>;
++                      dma-names = "tx", "rx";
++                      status = "disabled";
++              };
++
++              uart5: serial@2501400 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x2501400 0x400>;
++                      reg-io-width = <4>;
++                      reg-shift = <2>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(7) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_UART5>;
++                      resets = <&ccu RST_BUS_UART5>;
++                      dmas = <&dma 19>, <&dma 19>;
++                      dma-names = "tx", "rx";
++                      status = "disabled";
++              };
++
++              i2c0: i2c@2502000 {
++                      compatible = "allwinner,sun20i-d1-i2c",
++                                   "allwinner,sun8i-v536-i2c",
++                                   "allwinner,sun6i-a31-i2c";
++                      reg = <0x2502000 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(9) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_I2C0>;
++                      resets = <&ccu RST_BUS_I2C0>;
++                      dmas = <&dma 43>, <&dma 43>;
++                      dma-names = "rx", "tx";
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              i2c1: i2c@2502400 {
++                      compatible = "allwinner,sun20i-d1-i2c",
++                                   "allwinner,sun8i-v536-i2c",
++                                   "allwinner,sun6i-a31-i2c";
++                      reg = <0x2502400 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(10) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_I2C1>;
++                      resets = <&ccu RST_BUS_I2C1>;
++                      dmas = <&dma 44>, <&dma 44>;
++                      dma-names = "rx", "tx";
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              i2c2: i2c@2502800 {
++                      compatible = "allwinner,sun20i-d1-i2c",
++                                   "allwinner,sun8i-v536-i2c",
++                                   "allwinner,sun6i-a31-i2c";
++                      reg = <0x2502800 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(11) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_I2C2>;
++                      resets = <&ccu RST_BUS_I2C2>;
++                      dmas = <&dma 45>, <&dma 45>;
++                      dma-names = "rx", "tx";
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              i2c3: i2c@2502c00 {
++                      compatible = "allwinner,sun20i-d1-i2c",
++                                   "allwinner,sun8i-v536-i2c",
++                                   "allwinner,sun6i-a31-i2c";
++                      reg = <0x2502c00 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(12) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_I2C3>;
++                      resets = <&ccu RST_BUS_I2C3>;
++                      dmas = <&dma 46>, <&dma 46>;
++                      dma-names = "rx", "tx";
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              syscon: syscon@3000000 {
++                      compatible = "allwinner,sun20i-d1-system-control";
++                      reg = <0x3000000 0x1000>;
++                      ranges;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++              };
++
++              dma: dma-controller@3002000 {
++                      compatible = "allwinner,sun20i-d1-dma";
++                      reg = <0x3002000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(50) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>;
++                      clock-names = "bus", "mbus";
++                      resets = <&ccu RST_BUS_DMA>;
++                      dma-channels = <16>;
++                      dma-requests = <48>;
++                      #dma-cells = <1>;
++              };
++
++              sid: efuse@3006000 {
++                      compatible = "allwinner,sun20i-d1-sid";
++                      reg = <0x3006000 0x1000>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++              };
++
++              crypto: crypto@3040000 {
++                      compatible = "allwinner,sun20i-d1-crypto";
++                      reg = <0x3040000 0x800>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(52) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_CE>,
++                               <&ccu CLK_CE>,
++                               <&ccu CLK_MBUS_CE>,
++                               <&rtc CLK_IOSC>;
++                      clock-names = "bus", "mod", "ram", "trng";
++                      resets = <&ccu RST_BUS_CE>;
++              };
++
++              mbus: dram-controller@3102000 {
++                      compatible = "allwinner,sun20i-d1-mbus";
++                      reg = <0x3102000 0x1000>,
++                            <0x3103000 0x1000>;
++                      reg-names = "mbus", "dram";
++                      interrupts = <SOC_PERIPHERAL_IRQ(43) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_MBUS>,
++                               <&ccu CLK_DRAM>,
++                               <&ccu CLK_BUS_DRAM>;
++                      clock-names = "mbus", "dram", "bus";
++                      dma-ranges = <0 0x40000000 0x80000000>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++                      #interconnect-cells = <1>;
++              };
++
++              mmc0: mmc@4020000 {
++                      compatible = "allwinner,sun20i-d1-mmc";
++                      reg = <0x4020000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(40) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
++                      clock-names = "ahb", "mmc";
++                      resets = <&ccu RST_BUS_MMC0>;
++                      reset-names = "ahb";
++                      cap-sd-highspeed;
++                      max-frequency = <150000000>;
++                      no-mmc;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              mmc1: mmc@4021000 {
++                      compatible = "allwinner,sun20i-d1-mmc";
++                      reg = <0x4021000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(41) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
++                      clock-names = "ahb", "mmc";
++                      resets = <&ccu RST_BUS_MMC1>;
++                      reset-names = "ahb";
++                      cap-sd-highspeed;
++                      max-frequency = <150000000>;
++                      no-mmc;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              mmc2: mmc@4022000 {
++                      compatible = "allwinner,sun20i-d1-emmc",
++                                   "allwinner,sun50i-a100-emmc";
++                      reg = <0x4022000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(42) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
++                      clock-names = "ahb", "mmc";
++                      resets = <&ccu RST_BUS_MMC2>;
++                      reset-names = "ahb";
++                      cap-mmc-highspeed;
++                      max-frequency = <150000000>;
++                      mmc-ddr-1_8v;
++                      mmc-ddr-3_3v;
++                      no-sd;
++                      no-sdio;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              usb_otg: usb@4100000 {
++                      compatible = "allwinner,sun20i-d1-musb",
++                                   "allwinner,sun8i-a33-musb";
++                      reg = <0x4100000 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(29) IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "mc";
++                      clocks = <&ccu CLK_BUS_OTG>;
++                      resets = <&ccu RST_BUS_OTG>;
++                      extcon = <&usbphy 0>;
++                      phys = <&usbphy 0>;
++                      phy-names = "usb";
++                      status = "disabled";
++              };
++
++              usbphy: phy@4100400 {
++                      compatible = "allwinner,sun20i-d1-usb-phy";
++                      reg = <0x4100400 0x100>,
++                            <0x4101800 0x100>,
++                            <0x4200800 0x100>;
++                      reg-names = "phy_ctrl",
++                                  "pmu0",
++                                  "pmu1";
++                      clocks = <&dcxo>,
++                               <&dcxo>;
++                      clock-names = "usb0_phy",
++                                    "usb1_phy";
++                      resets = <&ccu RST_USB_PHY0>,
++                               <&ccu RST_USB_PHY1>;
++                      reset-names = "usb0_reset",
++                                    "usb1_reset";
++                      status = "disabled";
++                      #phy-cells = <1>;
++              };
++
++              ehci0: usb@4101000 {
++                      compatible = "allwinner,sun20i-d1-ehci",
++                                   "generic-ehci";
++                      reg = <0x4101000 0x100>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(30) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_OHCI0>,
++                               <&ccu CLK_BUS_EHCI0>,
++                               <&ccu CLK_USB_OHCI0>;
++                      resets = <&ccu RST_BUS_OHCI0>,
++                               <&ccu RST_BUS_EHCI0>;
++                      phys = <&usbphy 0>;
++                      phy-names = "usb";
++                      status = "disabled";
++              };
++
++              ohci0: usb@4101400 {
++                      compatible = "allwinner,sun20i-d1-ohci",
++                                   "generic-ohci";
++                      reg = <0x4101400 0x100>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(31) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_OHCI0>,
++                               <&ccu CLK_USB_OHCI0>;
++                      resets = <&ccu RST_BUS_OHCI0>;
++                      phys = <&usbphy 0>;
++                      phy-names = "usb";
++                      status = "disabled";
++              };
++
++              ehci1: usb@4200000 {
++                      compatible = "allwinner,sun20i-d1-ehci",
++                                   "generic-ehci";
++                      reg = <0x4200000 0x100>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(33) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_OHCI1>,
++                               <&ccu CLK_BUS_EHCI1>,
++                               <&ccu CLK_USB_OHCI1>;
++                      resets = <&ccu RST_BUS_OHCI1>,
++                               <&ccu RST_BUS_EHCI1>;
++                      phys = <&usbphy 1>;
++                      phy-names = "usb";
++                      status = "disabled";
++              };
++
++              ohci1: usb@4200400 {
++                      compatible = "allwinner,sun20i-d1-ohci",
++                                   "generic-ohci";
++                      reg = <0x4200400 0x100>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(34) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_OHCI1>,
++                               <&ccu CLK_USB_OHCI1>;
++                      resets = <&ccu RST_BUS_OHCI1>;
++                      phys = <&usbphy 1>;
++                      phy-names = "usb";
++                      status = "disabled";
++              };
++
++              emac: ethernet@4500000 {
++                      compatible = "allwinner,sun20i-d1-emac",
++                                   "allwinner,sun50i-a64-emac";
++                      reg = <0x4500000 0x10000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(46) IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "macirq";
++                      clocks = <&ccu CLK_BUS_EMAC>;
++                      clock-names = "stmmaceth";
++                      resets = <&ccu RST_BUS_EMAC>;
++                      reset-names = "stmmaceth";
++                      syscon = <&syscon>;
++                      status = "disabled";
++
++                      mdio: mdio {
++                              compatible = "snps,dwmac-mdio";
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++                      };
++              };
++
++              display_clocks: clock-controller@5000000 {
++                      compatible = "allwinner,sun20i-d1-de2-clk",
++                                   "allwinner,sun50i-h5-de2-clk";
++                      reg = <0x5000000 0x10000>;
++                      clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>;
++                      clock-names = "bus", "mod";
++                      resets = <&ccu RST_BUS_DE>;
++                      #clock-cells = <1>;
++                      #reset-cells = <1>;
++              };
++
++              mixer0: mixer@5100000 {
++                      compatible = "allwinner,sun20i-d1-de2-mixer-0";
++                      reg = <0x5100000 0x100000>;
++                      clocks = <&display_clocks CLK_BUS_MIXER0>,
++                               <&display_clocks CLK_MIXER0>;
++                      clock-names = "bus", "mod";
++                      resets = <&display_clocks RST_MIXER0>;
++
++                      ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              mixer0_out: port@1 {
++                                      reg = <1>;
++
++                                      mixer0_out_tcon_top_mixer0: endpoint {
++                                              remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
++                                      };
++                              };
++                      };
++              };
++
++              mixer1: mixer@5200000 {
++                      compatible = "allwinner,sun20i-d1-de2-mixer-1";
++                      reg = <0x5200000 0x100000>;
++                      clocks = <&display_clocks CLK_BUS_MIXER1>,
++                               <&display_clocks CLK_MIXER1>;
++                      clock-names = "bus", "mod";
++                      resets = <&display_clocks RST_MIXER1>;
++
++                      ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              mixer1_out: port@1 {
++                                      reg = <1>;
++
++                                      mixer1_out_tcon_top_mixer1: endpoint {
++                                              remote-endpoint = <&tcon_top_mixer1_in_mixer1>;
++                                      };
++                              };
++                      };
++              };
++
++              dsi: dsi@5450000 {
++                      compatible = "allwinner,sun20i-d1-mipi-dsi",
++                                   "allwinner,sun50i-a100-mipi-dsi";
++                      reg = <0x5450000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(92) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_MIPI_DSI>,
++                               <&tcon_top CLK_TCON_TOP_DSI>;
++                      clock-names = "bus", "mod";
++                      resets = <&ccu RST_BUS_MIPI_DSI>;
++                      phys = <&dphy>;
++                      phy-names = "dphy";
++                      status = "disabled";
++
++                      port {
++                              dsi_in_tcon_lcd0: endpoint {
++                                      remote-endpoint = <&tcon_lcd0_out_dsi>;
++                              };
++                      };
++              };
++
++              dphy: phy@5451000 {
++                      compatible = "allwinner,sun20i-d1-mipi-dphy",
++                                   "allwinner,sun50i-a100-mipi-dphy";
++                      reg = <0x5451000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(92) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_MIPI_DSI>,
++                               <&ccu CLK_MIPI_DSI>;
++                      clock-names = "bus", "mod";
++                      resets = <&ccu RST_BUS_MIPI_DSI>;
++                      #phy-cells = <0>;
++              };
++
++              tcon_top: tcon-top@5460000 {
++                      compatible = "allwinner,sun20i-d1-tcon-top";
++                      reg = <0x5460000 0x1000>;
++                      clocks = <&ccu CLK_BUS_DPSS_TOP>,
++                               <&ccu CLK_TCON_TV>,
++                               <&ccu CLK_TVE>,
++                               <&ccu CLK_TCON_LCD0>;
++                      clock-names = "bus", "tcon-tv0", "tve0", "dsi";
++                      clock-output-names = "tcon-top-tv0", "tcon-top-dsi";
++                      resets = <&ccu RST_BUS_DPSS_TOP>;
++                      #clock-cells = <1>;
++
++                      ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              tcon_top_mixer0_in: port@0 {
++                                      reg = <0>;
++
++                                      tcon_top_mixer0_in_mixer0: endpoint {
++                                              remote-endpoint = <&mixer0_out_tcon_top_mixer0>;
++                                      };
++                              };
++
++                              tcon_top_mixer0_out: port@1 {
++                                      reg = <1>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      tcon_top_mixer0_out_tcon_lcd0: endpoint@0 {
++                                              reg = <0>;
++                                              remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer0>;
++                                      };
++
++                                      tcon_top_mixer0_out_tcon_tv0: endpoint@2 {
++                                              reg = <2>;
++                                              remote-endpoint = <&tcon_tv0_in_tcon_top_mixer0>;
++                                      };
++                              };
++
++                              tcon_top_mixer1_in: port@2 {
++                                      reg = <2>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      tcon_top_mixer1_in_mixer1: endpoint@1 {
++                                              reg = <1>;
++                                              remote-endpoint = <&mixer1_out_tcon_top_mixer1>;
++                                      };
++                              };
++
++                              tcon_top_mixer1_out: port@3 {
++                                      reg = <3>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      tcon_top_mixer1_out_tcon_lcd0: endpoint@0 {
++                                              reg = <0>;
++                                              remote-endpoint = <&tcon_lcd0_in_tcon_top_mixer1>;
++                                      };
++
++                                      tcon_top_mixer1_out_tcon_tv0: endpoint@2 {
++                                              reg = <2>;
++                                              remote-endpoint = <&tcon_tv0_in_tcon_top_mixer1>;
++                                      };
++                              };
++
++                              tcon_top_hdmi_in: port@4 {
++                                      reg = <4>;
++
++                                      tcon_top_hdmi_in_tcon_tv0: endpoint {
++                                              remote-endpoint = <&tcon_tv0_out_tcon_top_hdmi>;
++                                      };
++                              };
++
++                              tcon_top_hdmi_out: port@5 {
++                                      reg = <5>;
++                              };
++                      };
++              };
++
++              tcon_lcd0: lcd-controller@5461000 {
++                      compatible = "allwinner,sun20i-d1-tcon-lcd";
++                      reg = <0x5461000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(90) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_TCON_LCD0>,
++                               <&ccu CLK_TCON_LCD0>;
++                      clock-names = "ahb", "tcon-ch0";
++                      clock-output-names = "tcon-pixel-clock";
++                      resets = <&ccu RST_BUS_TCON_LCD0>,
++                               <&ccu RST_BUS_LVDS0>;
++                      reset-names = "lcd", "lvds";
++                      #clock-cells = <0>;
++
++                      ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              tcon_lcd0_in: port@0 {
++                                      reg = <0>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      tcon_lcd0_in_tcon_top_mixer0: endpoint@0 {
++                                              reg = <0>;
++                                              remote-endpoint = <&tcon_top_mixer0_out_tcon_lcd0>;
++                                      };
++
++                                      tcon_lcd0_in_tcon_top_mixer1: endpoint@1 {
++                                              reg = <1>;
++                                              remote-endpoint = <&tcon_top_mixer1_out_tcon_lcd0>;
++                                      };
++                              };
++
++                              tcon_lcd0_out: port@1 {
++                                      reg = <1>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      tcon_lcd0_out_dsi: endpoint@1 {
++                                              reg = <1>;
++                                              remote-endpoint = <&dsi_in_tcon_lcd0>;
++                                      };
++                              };
++                      };
++              };
++
++              tcon_tv0: lcd-controller@5470000 {
++                      compatible = "allwinner,sun20i-d1-tcon-tv";
++                      reg = <0x5470000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(91) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_TCON_TV>,
++                               <&tcon_top CLK_TCON_TOP_TV0>;
++                      clock-names = "ahb", "tcon-ch1";
++                      resets = <&ccu RST_BUS_TCON_TV>;
++                      reset-names = "lcd";
++
++                      ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              tcon_tv0_in: port@0 {
++                                      reg = <0>;
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++
++                                      tcon_tv0_in_tcon_top_mixer0: endpoint@0 {
++                                              reg = <0>;
++                                              remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>;
++                                      };
++
++                                      tcon_tv0_in_tcon_top_mixer1: endpoint@1 {
++                                              reg = <1>;
++                                              remote-endpoint = <&tcon_top_mixer1_out_tcon_tv0>;
++                                      };
++                              };
++
++                              tcon_tv0_out: port@1 {
++                                      reg = <1>;
++
++                                      tcon_tv0_out_tcon_top_hdmi: endpoint {
++                                              remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>;
++                                      };
++                              };
++                      };
++              };
++
++              ppu: power-controller@7001000 {
++                      compatible = "allwinner,sun20i-d1-ppu";
++                      reg = <0x7001000 0x1000>;
++                      clocks = <&r_ccu CLK_BUS_R_PPU>;
++                      resets = <&r_ccu RST_BUS_R_PPU>;
++                      #power-domain-cells = <1>;
++              };
++
++              r_ccu: clock-controller@7010000 {
++                      compatible = "allwinner,sun20i-d1-r-ccu";
++                      reg = <0x7010000 0x400>;
++                      clocks = <&dcxo>,
++                               <&rtc CLK_OSC32K>,
++                               <&rtc CLK_IOSC>,
++                               <&ccu CLK_PLL_PERIPH0_DIV3>;
++                      clock-names = "hosc", "losc", "iosc", "pll-periph";
++                      #clock-cells = <1>;
++                      #reset-cells = <1>;
++              };
++
++              rtc: rtc@7090000 {
++                      compatible = "allwinner,sun20i-d1-rtc",
++                                   "allwinner,sun50i-r329-rtc";
++                      reg = <0x7090000 0x400>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(144) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&r_ccu CLK_BUS_R_RTC>,
++                               <&dcxo>,
++                               <&r_ccu CLK_R_AHB>;
++                      clock-names = "bus", "hosc", "ahb";
++                      #clock-cells = <1>;
++              };
++      };
++};
+diff --git a/include/dt-bindings/clock/sun20i-d1-r-ccu.h b/include/dt-bindings/clock/sun20i-d1-r-ccu.h
+new file mode 100644
+index 0000000000..4c2697fd32
+--- /dev/null
++++ b/include/dt-bindings/clock/sun20i-d1-r-ccu.h
+@@ -0,0 +1,19 @@
++/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
++/*
++ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
++ */
++
++#ifndef _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
++#define _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
++
++#define CLK_R_AHB             0
++
++#define CLK_BUS_R_TIMER               2
++#define CLK_BUS_R_TWD         3
++#define CLK_BUS_R_PPU         4
++#define CLK_R_IR_RX           5
++#define CLK_BUS_R_IR_RX               6
++#define CLK_BUS_R_RTC         7
++#define CLK_BUS_R_CPUCFG      8
++
++#endif /* _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_ */
+diff --git a/include/dt-bindings/reset/sun20i-d1-r-ccu.h b/include/dt-bindings/reset/sun20i-d1-r-ccu.h
+new file mode 100644
+index 0000000000..d93d6423d2
+--- /dev/null
++++ b/include/dt-bindings/reset/sun20i-d1-r-ccu.h
+@@ -0,0 +1,16 @@
++/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
++/*
++ * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
++ */
++
++#ifndef _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
++#define _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
++
++#define RST_BUS_R_TIMER               0
++#define RST_BUS_R_TWD         1
++#define RST_BUS_R_PPU         2
++#define RST_BUS_R_IR_RX               3
++#define RST_BUS_R_RTC         4
++#define RST_BUS_R_CPUCFG      5
++
++#endif /* _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_ */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4024-sunxi-add-support-for-UART3-on-PE-pins.patch b/package/boot/uboot-sunxi/patches/4024-sunxi-add-support-for-UART3-on-PE-pins.patch
deleted file mode 100644 (file)
index 9b57b68..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-From 9dd404ee6108f09894d5ff60feedb713284ca617 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Sat, 3 Jun 2023 23:57:46 +0200
-Subject: [PATCH 4024/4031] sunxi: add support for UART3 on PE pins
-
-Some boards use Port E pins for muxing the UART3 as console. Add a new
-Kconfig option allowing to select this (mimicking MMC_PINS_PH).
-
-Pinmux taken from https://bbs.aw-ol.com/assets/uploads/files/1648883311844-t113-s3_datasheet_v1.2.pdf
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/arm/mach-sunxi/Kconfig           |  6 ++++++
- arch/arm/mach-sunxi/board.c           | 10 ++++++++--
- arch/riscv/dts/sunxi-d1s-t113.dtsi    |  6 ++++++
- drivers/pinctrl/sunxi/pinctrl-sunxi.c |  4 ++++
- 4 files changed, 24 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index 142d86afc6..59fa62c8d5 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -665,6 +665,12 @@ config UART0_PORT_F
-       at the same time, the system can be only booted in the FEL mode.
-       Only enable this if you really know what you are doing.
-+config UART3_PINS_PE
-+      bool "Pins for uart3 are on Port E"
-+      ---help---
-+      Select this option for boards where uart3 uses the Port E pinmux.
-+      (Some T113-S3 boards use uart3 as console.)
-+
- config OLD_SUNXI_KERNEL_COMPAT
-       bool "Enable workarounds for booting old kernels"
-       ---help---
-diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
-index 6a37b33767..5de490feda 100644
---- a/arch/arm/mach-sunxi/board.c
-+++ b/arch/arm/mach-sunxi/board.c
-@@ -168,16 +168,22 @@ static int gpio_init(void)
-       sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
-       sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
- #elif CONFIG_CONS_INDEX == 4 && defined(CONFIG_MACH_SUN8I_R528)
-+#if defined(CONFIG_UART3_PINS_PE)
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(8), 5);
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(9), 5);
-+      sunxi_gpio_set_pull(SUNXI_GPE(9), SUNXI_GPIO_PULL_UP);
-+#else
-       sunxi_gpio_set_cfgpin(SUNXI_GPB(6), 7);
-       sunxi_gpio_set_cfgpin(SUNXI_GPB(7), 7);
-       sunxi_gpio_set_pull(SUNXI_GPB(7), SUNXI_GPIO_PULL_UP);
-+#endif
- #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
-       sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
-       sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
-       sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
- #elif CONFIG_CONS_INDEX == 6 && defined(CONFIG_MACH_SUN8I_R528)
--      sunxi_gpio_set_cfgpin(SUNXI_GPE(6), 9);
--      sunxi_gpio_set_cfgpin(SUNXI_GPE(7), 9);
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(6), 3);
-+      sunxi_gpio_set_cfgpin(SUNXI_GPE(7), 3);
-       sunxi_gpio_set_pull(SUNXI_GPE(7), SUNXI_GPIO_PULL_UP);
- #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN8I) && \
-                               !defined(CONFIG_MACH_SUN8I_R40)
-diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-index 2b7d54aab4..d858f21fd2 100644
---- a/arch/riscv/dts/sunxi-d1s-t113.dtsi
-+++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-@@ -126,6 +126,12 @@
-                               function = "uart3";
-                       };
-+                      /omit-if-no-ref/
-+                      uart3_pe_pins: uart3-pe-pins {
-+                              pins = "PE8", "PE9";
-+                              function = "uart3";
-+                      };
-+
-                       /omit-if-no-ref/
-                       uart0_pins: uart0-pins {
-                               pins = "PE2", "PE3";
-diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-index 2717d79bc3..e466808e4e 100644
---- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
-@@ -747,7 +747,11 @@ static const struct sunxi_pinctrl_function sun20i_d1_pinctrl_functions[] = {
- #else
-       { "uart0",      6 },    /* PB2-PB3 */
- #endif
-+#if IS_ENABLED(CONFIG_UART3_PINS_E)
-+      { "uart3",      5 },    /* PE8-PE9 */
-+else
-       { "uart3",      7 },    /* PB6-PB9 */
-+#endif
-       { "uart5",      3 },    /* PE6-PE7 */
- };
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4025-ARM-dts-sunxi-add-Allwinner-T113-s-SoC-.dtsi.patch b/package/boot/uboot-sunxi/patches/4025-ARM-dts-sunxi-add-Allwinner-T113-s-SoC-.dtsi.patch
new file mode 100644 (file)
index 0000000..da52b7d
--- /dev/null
@@ -0,0 +1,113 @@
+From 32020fad9d2fc6ce8f6e67af2ac7c9c6e7c47dec Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:46:05 +0100
+Subject: [PATCH 4025/4044] ARM: dts: sunxi: add Allwinner T113-s SoC .dtsi
+
+The Allwinner T113-s SoC is apparently using the same (or at least a very
+similar) die as the D1/D1s, but replaces the single RISC-V core with
+two Arm Cortex-A7 cores.
+Since the D1 core .dtsi already describes all common peripherals, we
+just need a DT describing the ARM specific peripherals: the CPU cores,
+the Generic Timer, the GIC and the PMU.
+We include the core .dtsi directly from the riscv DT directory.
+
+The ARM core version of the DT specifies the CPUX watchdog as
+"reserved", which means it won't be recognised by U-Boot. Override this
+in our generic sunxi-u-boot.dtsi, to let U-Boot pick up this watchdog,
+so that the generic reset driver will work.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Sam Edwards <CFSworks@gmail.com>
+Tested-by: Sam Edwards <CFSworks@gmail.com>
+---
+ arch/arm/dts/sun8i-t113s.dtsi  | 59 ++++++++++++++++++++++++++++++++++
+ arch/arm/dts/sunxi-u-boot.dtsi |  7 ++++
+ 2 files changed, 66 insertions(+)
+ create mode 100644 arch/arm/dts/sun8i-t113s.dtsi
+
+diff --git a/arch/arm/dts/sun8i-t113s.dtsi b/arch/arm/dts/sun8i-t113s.dtsi
+new file mode 100644
+index 0000000000..ce00883130
+--- /dev/null
++++ b/arch/arm/dts/sun8i-t113s.dtsi
+@@ -0,0 +1,59 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2022 Arm Ltd.
++
++#define SOC_PERIPHERAL_IRQ(nr) GIC_SPI nr
++
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <../../riscv/dts/sunxi-d1s-t113.dtsi>
++#include <../../riscv/dts/sunxi-d1-t113.dtsi>
++
++/ {
++      interrupt-parent = <&gic>;
++
++      cpus {
++              #address-cells = <1>;
++              #size-cells = <0>;
++
++              cpu0: cpu@0 {
++                      compatible = "arm,cortex-a7";
++                      device_type = "cpu";
++                      reg = <0>;
++                      clocks = <&ccu CLK_CPUX>;
++                      clock-names = "cpu";
++              };
++
++              cpu1: cpu@1 {
++                      compatible = "arm,cortex-a7";
++                      device_type = "cpu";
++                      reg = <1>;
++                      clocks = <&ccu CLK_CPUX>;
++                      clock-names = "cpu";
++              };
++      };
++
++      gic: interrupt-controller@1c81000 {
++              compatible = "arm,gic-400";
++              reg = <0x03021000 0x1000>,
++                    <0x03022000 0x2000>,
++                    <0x03024000 0x2000>,
++                    <0x03026000 0x2000>;
++              interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
++              interrupt-controller;
++              #interrupt-cells = <3>;
++      };
++
++      timer {
++              compatible = "arm,armv7-timer";
++              interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
++                           <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
++                           <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
++                           <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
++      };
++
++      pmu {
++              compatible = "arm,cortex-a7-pmu";
++              interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
++                           <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
++              interrupt-affinity = <&cpu0>, <&cpu1>;
++      };
++};
+diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
+index e959eb2a40..27de5b8eac 100644
+--- a/arch/arm/dts/sunxi-u-boot.dtsi
++++ b/arch/arm/dts/sunxi-u-boot.dtsi
+@@ -23,6 +23,13 @@
+       };
+ };
++/* Let U-Boot be the firmware layer that controls the watchdog. */
++#ifdef CONFIG_MACH_SUN8I_R528
++&wdt {
++      status = "okay";
++};
++#endif
++
+ &binman {
+       u-boot-sunxi-with-spl {
+               filename = "u-boot-sunxi-with-spl.bin";
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4025-sunxi-add-support-for-Rongpin-RP-T113-board.patch b/package/boot/uboot-sunxi/patches/4025-sunxi-add-support-for-Rongpin-RP-T113-board.patch
deleted file mode 100644 (file)
index 45cd530..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-From d3a69c14de1b3b2e61bfeb421f0f0f4ecec1207e Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Sat, 3 Jun 2023 23:42:33 +0200
-Subject: [PATCH 4025/4031] sunxi: add support for Rongpin RP-T113 board
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/arm/dts/Makefile                        |  3 +-
- arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts | 98 ++++++++++++++++++++
- configs/rongpin_rp_t113_defconfig            | 18 ++++
- 3 files changed, 118 insertions(+), 1 deletion(-)
- create mode 100644 arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
- create mode 100644 configs/rongpin_rp_t113_defconfig
-
-diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
-index 6fb49de59a..be89021657 100644
---- a/arch/arm/dts/Makefile
-+++ b/arch/arm/dts/Makefile
-@@ -713,7 +713,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
- dtb-$(CONFIG_MACH_SUN8I_R528) += \
-       sun8i-t113s-mangopi-mq-r-t113.dtb \
-       sun8i-t113s-mangopi-mqdual-t113.dtb \
--      sun8i-t113s-myir-myd-yt113x.dtb
-+      sun8i-t113s-myir-myd-yt113x.dtb \
-+      sun8i-t113s-rongpin-rp-t113.dtb
- dtb-$(CONFIG_MACH_SUN50I_H5) += \
-       sun50i-h5-bananapi-m2-plus.dtb \
-       sun50i-h5-emlid-neutis-n5-devboard.dtb \
-diff --git a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-new file mode 100644
-index 0000000000..6ac2c065c4
---- /dev/null
-+++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-@@ -0,0 +1,98 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2022 Arm Ltd.
-+
-+#include <dt-bindings/interrupt-controller/irq.h>
-+
-+/dts-v1/;
-+
-+#include "sun8i-t113s.dtsi"
-+
-+/ {
-+      model = "Rongpin RP-T113";
-+      compatible = "rongpin,rp-t113", "allwinner,sun8i-t113s";
-+
-+      aliases {
-+              serial3 = &uart3;
-+      };
-+
-+      chosen {
-+              stdout-path = "serial3:115200n8";
-+      };
-+
-+      /* board wide 5V supply directly from the USB-C socket */
-+      reg_vcc5v: regulator-5v {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc-5v";
-+              regulator-min-microvolt = <5000000>;
-+              regulator-max-microvolt = <5000000>;
-+              regulator-always-on;
-+      };
-+
-+      /* SY8008 DC/DC regulator on the board */
-+      reg_3v3: regulator-3v3 {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc-3v3";
-+              regulator-min-microvolt = <3300000>;
-+              regulator-max-microvolt = <3300000>;
-+              vin-supply = <&reg_vcc5v>;
-+      };
-+
-+      /* SY8008 DC/DC regulator on the board, also supplying VDD-SYS */
-+      reg_vcc_core: regulator-core {
-+              compatible = "regulator-fixed";
-+              regulator-name = "vcc-core";
-+              regulator-min-microvolt = <880000>;
-+              regulator-max-microvolt = <880000>;
-+              vin-supply = <&reg_vcc5v>;
-+      };
-+
-+      /* XC6206 LDO on the board */
-+      reg_avdd2v8: regulator-avdd {
-+              compatible = "regulator-fixed";
-+              regulator-name = "avdd2v8";
-+              regulator-min-microvolt = <2800000>;
-+              regulator-max-microvolt = <2800000>;
-+              vin-supply = <&reg_3v3>;
-+      };
-+};
-+
-+&cpu0 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&cpu1 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&pio {
-+      vcc-pb-supply = <&reg_3v3>;
-+      vcc-pd-supply = <&reg_3v3>;
-+      vcc-pe-supply = <&reg_avdd2v8>;
-+      vcc-pf-supply = <&reg_3v3>;
-+      vcc-pg-supply = <&reg_3v3>;
-+};
-+
-+&uart3 {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&uart3_pe_pins>;
-+      status = "okay";
-+};
-+
-+&mmc0 {
-+      pinctrl-0 = <&mmc0_pins>;
-+      pinctrl-names = "default";
-+      vmmc-supply = <&reg_3v3>;
-+      cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
-+      disable-wp;
-+      bus-width = <4>;
-+      status = "okay";
-+};
-+
-+&mmc2 {
-+      pinctrl-0 = <&mmc2_pins>;
-+      pinctrl-names = "default";
-+      vmmc-supply = <&reg_3v3>;
-+      non-removable;
-+      bus-width = <4>;
-+      status = "okay";
-+};
-diff --git a/configs/rongpin_rp_t113_defconfig b/configs/rongpin_rp_t113_defconfig
-new file mode 100644
-index 0000000000..9b5a5bcd65
---- /dev/null
-+++ b/configs/rongpin_rp_t113_defconfig
-@@ -0,0 +1,18 @@
-+CONFIG_ARM=y
-+CONFIG_ARCH_SUNXI=y
-+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-rongpin-rp-t113"
-+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
-+CONFIG_SPL=y
-+CONFIG_MACH_SUN8I_R528=y
-+CONFIG_CONS_INDEX=4
-+CONFIG_MMC0_CD_PIN="PF6"
-+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-+CONFIG_SYS_MONITOR_LEN=786432
-+CONFIG_DRAM_CLK=792
-+CONFIG_DRAM_ZQ=8092667
-+CONFIG_DRAM_SUNXI_ODT_EN=0
-+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
-+CONFIG_DRAM_SUNXI_TPR11=0x340000
-+CONFIG_DRAM_SUNXI_TPR12=0x46
-+CONFIG_DRAM_SUNXI_TPR13=0x34000100
-+CONFIG_UART3_PINS_PE=y
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4026-net-add-ICPlus-PHY-driver.patch b/package/boot/uboot-sunxi/patches/4026-net-add-ICPlus-PHY-driver.patch
deleted file mode 100644 (file)
index 7530e94..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-From 7dbc707b5911c28724c2f5a220315513bf9ce3f3 Mon Sep 17 00:00:00 2001
-From: Yegor Yefremov <yegorslists@googlemail.com>
-Date: Wed, 28 Nov 2012 11:15:18 +0100
-Subject: [PATCH 4026/4031] net: add ICPlus PHY driver
-
-The driver code was taken from Linux kernel source:
-drivers/net/phy/icplus.c
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
-Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
----
- drivers/net/phy/Kconfig  |  3 ++
- drivers/net/phy/Makefile |  1 +
- drivers/net/phy/icplus.c | 94 ++++++++++++++++++++++++++++++++++++++++
- drivers/net/phy/phy.c    |  3 ++
- include/phy.h            |  1 +
- 5 files changed, 102 insertions(+)
- create mode 100644 drivers/net/phy/icplus.c
-
-diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
-index 5eaff053a0..93980398f1 100644
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -165,6 +165,9 @@ config PHY_DAVICOM
- config PHY_ET1011C
-       bool "LSI TruePHY ET1011C support"
-+config PHY_ICPLUS
-+      bool "IC+ IP101 Ethernet PHY support"
-+
- config PHY_LXT
-       bool "LXT971 Ethernet PHY support"
-diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
-index d38e99e717..5b6b78631d 100644
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -18,6 +18,7 @@ obj-$(CONFIG_PHY_CORTINA) += cortina.o
- obj-$(CONFIG_PHY_CORTINA_ACCESS) += ca_phy.o
- obj-$(CONFIG_PHY_DAVICOM) += davicom.o
- obj-$(CONFIG_PHY_ET1011C) += et1011c.o
-+obj-$(CONFIG_PHY_ICPLUS) += icplus.o
- obj-$(CONFIG_PHY_LXT) += lxt.o
- obj-$(CONFIG_PHY_MARVELL) += marvell.o
- obj-$(CONFIG_PHY_MICREL_KSZ8XXX) += micrel_ksz8xxx.o
-diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
-new file mode 100644
-index 0000000000..dd5c59259d
---- /dev/null
-+++ b/drivers/net/phy/icplus.c
-@@ -0,0 +1,94 @@
-+/*
-+ * ICPlus PHY drivers
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-+ * MA 02111-1307 USA
-+ *
-+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
-+ *
-+ */
-+#include <phy.h>
-+
-+/* IP101A/G - IP1001 */
-+#define IP10XX_SPEC_CTRL_STATUS         16      /* Spec. Control Register */
-+#define IP1001_SPEC_CTRL_STATUS_2       20      /* IP1001 Spec. Control Reg 2 */
-+#define IP1001_PHASE_SEL_MASK           3       /* IP1001 RX/TXPHASE_SEL */
-+#define IP1001_APS_ON                   11      /* IP1001 APS Mode  bit */
-+#define IP101A_G_APS_ON                 2       /* IP101A/G APS Mode bit */
-+#define IP101A_G_IRQ_CONF_STATUS        0x11    /* Conf Info IRQ & Status Reg */
-+#define IP101A_G_IRQ_PIN_USED           (1<<15) /* INTR pin used */
-+#define IP101A_G_IRQ_DEFAULT            IP101A_G_IRQ_PIN_USED
-+
-+static int ip1001_config(struct phy_device *phydev)
-+{
-+      int c;
-+
-+      /* Enable Auto Power Saving mode */
-+      c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2);
-+      if (c < 0)
-+              return c;
-+      c |= IP1001_APS_ON;
-+      c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c);
-+      if (c < 0)
-+              return c;
-+
-+      /* INTR pin used: speed/link/duplex will cause an interrupt */
-+      c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS,
-+                    IP101A_G_IRQ_DEFAULT);
-+      if (c < 0)
-+              return c;
-+
-+      if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
-+              /*
-+               * Additional delay (2ns) used to adjust RX clock phase
-+               * at RGMII interface
-+               */
-+              c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS);
-+              if (c < 0)
-+                      return c;
-+
-+              c |= IP1001_PHASE_SEL_MASK;
-+              c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS,
-+                            c);
-+              if (c < 0)
-+                      return c;
-+      }
-+
-+      return 0;
-+}
-+
-+static int ip1001_startup(struct phy_device *phydev)
-+{
-+      genphy_update_link(phydev);
-+      genphy_parse_link(phydev);
-+
-+      return 0;
-+}
-+static struct phy_driver IP1001_driver = {
-+      .name = "ICPlus IP1001",
-+      .uid = 0x02430d90,
-+      .mask = 0x0ffffff0,
-+      .features = PHY_GBIT_FEATURES,
-+      .config = &ip1001_config,
-+      .startup = &ip1001_startup,
-+      .shutdown = &genphy_shutdown,
-+};
-+
-+int phy_icplus_init(void)
-+{
-+      phy_register(&IP1001_driver);
-+
-+      return 0;
-+}
-diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
-index 80230b907c..9e22db3fc8 100644
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -514,6 +514,9 @@ int phy_init(void)
- #ifdef CONFIG_PHY_ET1011C
-       phy_et1011c_init();
- #endif
-+#ifdef CONFIG_PHY_ICPLUS
-+      phy_icplus_init();
-+#endif
- #ifdef CONFIG_PHY_LXT
-       phy_lxt_init();
- #endif
-diff --git a/include/phy.h b/include/phy.h
-index 87aa86c2e7..749285f15e 100644
---- a/include/phy.h
-+++ b/include/phy.h
-@@ -325,6 +325,7 @@ int phy_cortina_init(void);
- int phy_cortina_access_init(void);
- int phy_davicom_init(void);
- int phy_et1011c_init(void);
-+int phy_icplus_init(void);
- int phy_lxt_init(void);
- int phy_marvell_init(void);
- int phy_micrel_ksz8xxx_init(void);
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4026-sunxi-add-MangoPi-MQ-R-board-support.patch b/package/boot/uboot-sunxi/patches/4026-sunxi-add-MangoPi-MQ-R-board-support.patch
new file mode 100644 (file)
index 0000000..a403d0c
--- /dev/null
@@ -0,0 +1,229 @@
+From 3cab8f3bd34a0d16fca67ad10ec2ad413fdc99da Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Fri, 21 Jul 2023 14:46:06 +0100
+Subject: [PATCH 4026/4044] sunxi: add MangoPi MQ-R board support
+
+This copies the T113s specific DTs from the Linux kernel tree
+(v6.4-rc1), and adds a defconfig to get the board booted.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+---
+ arch/arm/dts/Makefile                         |   2 +
+ .../arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts |  35 +++++
+ arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi | 126 ++++++++++++++++++
+ configs/mangopi_mq_r_defconfig                |  15 +++
+ 4 files changed, 178 insertions(+)
+ create mode 100644 arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts
+ create mode 100644 arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi
+ create mode 100644 configs/mangopi_mq_r_defconfig
+
+diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
+index c160e884bf..41ee9c4c65 100644
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -710,6 +710,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
+       sun8i-s3-pinecube.dtb \
+       sun8i-v3-sl631-imx179.dtb \
+       sun8i-v3s-licheepi-zero.dtb
++dtb-$(CONFIG_MACH_SUN8I_R528) += \
++      sun8i-t113s-mangopi-mq-r-t113.dtb
+ dtb-$(CONFIG_MACH_SUN50I_H5) += \
+       sun50i-h5-bananapi-m2-plus.dtb \
+       sun50i-h5-emlid-neutis-n5-devboard.dtb \
+diff --git a/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts b/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts
+new file mode 100644
+index 0000000000..94e24b5926
+--- /dev/null
++++ b/arch/arm/dts/sun8i-t113s-mangopi-mq-r-t113.dts
+@@ -0,0 +1,35 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2022 Arm Ltd.
++
++#include <dt-bindings/interrupt-controller/irq.h>
++
++/dts-v1/;
++
++#include "sun8i-t113s.dtsi"
++#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
++
++/ {
++      model = "MangoPi MQ-R-T113";
++      compatible = "widora,mangopi-mq-r-t113", "allwinner,sun8i-t113s";
++
++      aliases {
++              ethernet0 = &rtl8189ftv;
++      };
++};
++
++&cpu0 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&cpu1 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&mmc1 {
++      rtl8189ftv: wifi@1 {
++              reg = <1>;
++              interrupt-parent = <&pio>;
++              interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 = WL_WAKE_AP */
++              interrupt-names = "host-wake";
++      };
++};
+diff --git a/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi b/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi
+new file mode 100644
+index 0000000000..e9bc749488
+--- /dev/null
++++ b/arch/arm/dts/sunxi-d1s-t113-mangopi-mq-r.dtsi
+@@ -0,0 +1,126 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2022 Arm Ltd.
++/*
++ * Common peripherals and configurations for MangoPi MQ-R boards.
++ */
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++
++/ {
++      aliases {
++              serial3 = &uart3;
++      };
++
++      chosen {
++              stdout-path = "serial3:115200n8";
++      };
++
++      leds {
++              compatible = "gpio-leds";
++
++              led-0 {
++                      color = <LED_COLOR_ID_BLUE>;
++                      function = LED_FUNCTION_STATUS;
++                      gpios = <&pio 3 22 GPIO_ACTIVE_LOW>; /* PD22 */
++              };
++      };
++
++      /* board wide 5V supply directly from the USB-C socket */
++      reg_vcc5v: regulator-5v {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-5v";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              regulator-always-on;
++      };
++
++      /* SY8008 DC/DC regulator on the board */
++      reg_3v3: regulator-3v3 {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              vin-supply = <&reg_vcc5v>;
++      };
++
++      /* SY8008 DC/DC regulator on the board, also supplying VDD-SYS */
++      reg_vcc_core: regulator-core {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-core";
++              regulator-min-microvolt = <880000>;
++              regulator-max-microvolt = <880000>;
++              vin-supply = <&reg_vcc5v>;
++      };
++
++      /* XC6206 LDO on the board */
++      reg_avdd2v8: regulator-avdd {
++              compatible = "regulator-fixed";
++              regulator-name = "avdd2v8";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              vin-supply = <&reg_3v3>;
++      };
++
++      wifi_pwrseq: wifi-pwrseq {
++              compatible = "mmc-pwrseq-simple";
++              reset-gpios = <&pio 6 12 GPIO_ACTIVE_LOW>; /* PG12 */
++      };
++};
++
++&dcxo {
++      clock-frequency = <24000000>;
++};
++
++&ehci1 {
++      status = "okay";
++};
++
++&mmc0 {
++      pinctrl-0 = <&mmc0_pins>;
++      pinctrl-names = "default";
++      vmmc-supply = <&reg_3v3>;
++      cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
++      disable-wp;
++      bus-width = <4>;
++      status = "okay";
++};
++
++&mmc1 {
++      pinctrl-0 = <&mmc1_pins>;
++      pinctrl-names = "default";
++      vmmc-supply = <&reg_3v3>;
++      non-removable;
++      bus-width = <4>;
++      mmc-pwrseq = <&wifi_pwrseq>;
++      status = "okay";
++};
++
++&ohci1 {
++      status = "okay";
++};
++
++&pio {
++      vcc-pb-supply = <&reg_3v3>;
++      vcc-pd-supply = <&reg_3v3>;
++      vcc-pe-supply = <&reg_avdd2v8>;
++      vcc-pf-supply = <&reg_3v3>;
++      vcc-pg-supply = <&reg_3v3>;
++};
++
++&uart3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart3_pb_pins>;
++      status = "okay";
++};
++
++/* The USB-C socket has its CC pins pulled to GND, so is hardwired as a UFP. */
++&usb_otg {
++      dr_mode = "peripheral";
++      status = "okay";
++};
++
++&usbphy {
++      usb1_vbus-supply = <&reg_vcc5v>;
++      status = "okay";
++};
+diff --git a/configs/mangopi_mq_r_defconfig b/configs/mangopi_mq_r_defconfig
+new file mode 100644
+index 0000000000..66ae639326
+--- /dev/null
++++ b/configs/mangopi_mq_r_defconfig
+@@ -0,0 +1,15 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-mangopi-mq-r-t113"
++CONFIG_SPL=y
++CONFIG_MACH_SUN8I_R528=y
++CONFIG_DRAM_CLK=792
++CONFIG_DRAM_ZQ=8092667
++CONFIG_SUNXI_MINIMUM_DRAM_MB=128
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_DRAM_SUNXI_ODT_EN=0
++CONFIG_DRAM_SUNXI_TPR0=0x004a2195
++CONFIG_DRAM_SUNXI_TPR11=0x340000
++CONFIG_DRAM_SUNXI_TPR12=0x46
++CONFIG_DRAM_SUNXI_TPR13=0x34000100
++CONFIG_CONS_INDEX=4
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4027-sunxi-add-uart0_pins-on-Port-E-PE2-PE3-on-D1s-T133.patch b/package/boot/uboot-sunxi/patches/4027-sunxi-add-uart0_pins-on-Port-E-PE2-PE3-on-D1s-T133.patch
new file mode 100644 (file)
index 0000000..cd4a7da
--- /dev/null
@@ -0,0 +1,30 @@
+From f9950a4c4cbabde0c07f4b2e3fdeee52b0c1f788 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 3 Jun 2023 00:52:04 +0200
+Subject: [PATCH 4027/4044] sunxi: add uart0_pins on Port E PE2/PE3 on D1s/T133
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/dts/sunxi-d1s-t113.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+index 922e8e0e2c..b1f97bd0bc 100644
+--- a/arch/riscv/dts/sunxi-d1s-t113.dtsi
++++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+@@ -125,6 +125,12 @@
+                               pins = "PB6", "PB7";
+                               function = "uart3";
+                       };
++
++                      /omit-if-no-ref/
++                      uart0_pins: uart0-pins {
++                              pins = "PE2", "PE3";
++                              function = "uart0";
++                      };
+               };
+               ccu: clock-controller@2001000 {
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4027-sunxi-enable-emac-on-Rongpin-RP-T113.patch b/package/boot/uboot-sunxi/patches/4027-sunxi-enable-emac-on-Rongpin-RP-T113.patch
deleted file mode 100644 (file)
index a93f0bf..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-From 789c1062934120dcbf4f88a867638f23dcfc1c39 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Sun, 4 Jun 2023 15:40:42 +0200
-Subject: [PATCH 4027/4031] sunxi: enable emac on Rongpin RP-T113
-
-The emac is connected to an IC+ IP101 PHY, for which the driver
-has been re-added (it was removed in 2014).
-
-Currently the driver init fails with the below, so further tweaking
-will be required.
-
-CPU:   Allwinner R528 (SUN8I)
-Model: Rongpin RP-T113
-DRAM:  128 MiB
-Core:  36 devices, 15 uclasses, devicetree: separate
-MMC:   mmc@4020000: 0, mmc@4022000: 1
-Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1...
-In:    serial@2500c00
-Out:   serial@2500c00
-Err:   serial@2500c00
-Net:   eth_sun8i_emac ethernet@4500000: failed to get TX clock
-No ethernet found.
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts | 28 ++++++++++++++++++++
- configs/rongpin_rp_t113_defconfig            |  3 +++
- 2 files changed, 31 insertions(+)
-
-diff --git a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-index 6ac2c065c4..f2521438fb 100644
---- a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-+++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-@@ -54,6 +54,16 @@
-               regulator-max-microvolt = <2800000>;
-               vin-supply = <&reg_3v3>;
-       };
-+
-+        reg_gmac_3v3: gmac-3v3 {
-+                compatible = "regulator-fixed";
-+                regulator-name = "gmac-3v3";
-+                regulator-min-microvolt = <3300000>;
-+                regulator-max-microvolt = <3300000>;
-+                startup-delay-us = <100000>;
-+                enable-active-high;
-+                gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
-+      };
- };
- &cpu0 {
-@@ -78,6 +88,17 @@
-       status = "okay";
- };
-+&emac {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&rmii_pe_pins>;
-+
-+      phy-supply = <&reg_3v3>;
-+      phy-handle = <&ext_rgmii_phy>;
-+      phy-mode = "rmii";
-+
-+      status = "okay";
-+};
-+
- &mmc0 {
-       pinctrl-0 = <&mmc0_pins>;
-       pinctrl-names = "default";
-@@ -96,3 +117,10 @@
-       bus-width = <4>;
-       status = "okay";
- };
-+
-+&mdio {
-+      ext_rgmii_phy: ethernet-phy@1 {
-+              compatible = "ethernet-phy-ieee802.3-c22";
-+              reg = <1>;
-+      };
-+};
-diff --git a/configs/rongpin_rp_t113_defconfig b/configs/rongpin_rp_t113_defconfig
-index 9b5a5bcd65..e234934f50 100644
---- a/configs/rongpin_rp_t113_defconfig
-+++ b/configs/rongpin_rp_t113_defconfig
-@@ -16,3 +16,6 @@ CONFIG_DRAM_SUNXI_TPR11=0x340000
- CONFIG_DRAM_SUNXI_TPR12=0x46
- CONFIG_DRAM_SUNXI_TPR13=0x34000100
- CONFIG_UART3_PINS_PE=y
-+CONFIG_SUN8I_EMAC=y
-+CONFIG_PHY_ICPLUS=y
-+CONFIG_RMII=y
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4028-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethe.patch b/package/boot/uboot-sunxi/patches/4028-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethe.patch
deleted file mode 100644 (file)
index dc3a82a..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-From 9dd54fb43abdb66b42679eb668612b9e055a962e Mon Sep 17 00:00:00 2001
-From: Yanhong Wang <yanhong.wang@starfivetech.com>
-Date: Thu, 25 May 2023 17:36:27 +0800
-Subject: [PATCH 4028/4031] net: phy: Add driver for Motorcomm yt8531 gigabit
- ethernet phy
-
-Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have
-verified the driver on StarFive VisionFive2 board.
-
-Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
-Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
----
- drivers/net/phy/Kconfig     |   6 +
- drivers/net/phy/Makefile    |   1 +
- drivers/net/phy/motorcomm.c | 437 ++++++++++++++++++++++++++++++++++++
- 3 files changed, 444 insertions(+)
- create mode 100644 drivers/net/phy/motorcomm.c
-
-diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
-index 93980398f1..0a99682c27 100644
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -215,6 +215,12 @@ config PHY_MICREL_KSZ8XXX
- endif # PHY_MICREL
-+config PHY_MOTORCOMM
-+      tristate "Motorcomm PHYs"
-+      help
-+        Enables support for Motorcomm network PHYs.
-+        Currently supports the YT8531 Gigabit Ethernet PHYs.
-+
- config PHY_MSCC
-       bool "Microsemi Corp Ethernet PHYs support"
-diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
-index 5b6b78631d..9637a138f8 100644
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -24,6 +24,7 @@ obj-$(CONFIG_PHY_MARVELL) += marvell.o
- obj-$(CONFIG_PHY_MICREL_KSZ8XXX) += micrel_ksz8xxx.o
- obj-$(CONFIG_PHY_MICREL_KSZ90X1) += micrel_ksz90x1.o
- obj-$(CONFIG_PHY_MESON_GXL) += meson-gxl.o
-+obj-$(CONFIG_PHY_MOTORCOMM) += motorcomm.o
- obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
- obj-$(CONFIG_PHY_NXP_C45_TJA11XX) += nxp-c45-tja11xx.o
- obj-$(CONFIG_PHY_NXP_TJA11XX) += nxp-tja11xx.o
-diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
-new file mode 100644
-index 0000000000..e822fd76f2
---- /dev/null
-+++ b/drivers/net/phy/motorcomm.c
-@@ -0,0 +1,437 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Motorcomm 8531 PHY driver.
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <config.h>
-+#include <common.h>
-+#include <malloc.h>
-+#include <phy.h>
-+#include <linux/bitfield.h>
-+
-+#define PHY_ID_YT8531                         0x4f51e91b
-+#define PHY_ID_MASK                           GENMASK(31, 0)
-+
-+/* Extended Register's Address Offset Register */
-+#define YTPHY_PAGE_SELECT                     0x1E
-+
-+/* Extended Register's Data Register */
-+#define YTPHY_PAGE_DATA                       0x1F
-+
-+#define YTPHY_SYNCE_CFG_REG                   0xA012
-+
-+#define YTPHY_DTS_OUTPUT_CLK_DIS              0
-+#define YTPHY_DTS_OUTPUT_CLK_25M              25000000
-+#define YTPHY_DTS_OUTPUT_CLK_125M             125000000
-+
-+#define YT8531_SCR_SYNCE_ENABLE               BIT(6)
-+/* 1b0 output 25m clock   *default*
-+ * 1b1 output 125m clock
-+ */
-+#define YT8531_SCR_CLK_FRE_SEL_125M           BIT(4)
-+#define YT8531_SCR_CLK_SRC_MASK               GENMASK(3, 1)
-+#define YT8531_SCR_CLK_SRC_PLL_125M           0
-+#define YT8531_SCR_CLK_SRC_UTP_RX             1
-+#define YT8531_SCR_CLK_SRC_SDS_RX             2
-+#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
-+#define YT8531_SCR_CLK_SRC_REF_25M            4
-+#define YT8531_SCR_CLK_SRC_SSC_25M            5
-+
-+/* 1b0 use original tx_clk_rgmii  *default*
-+ * 1b1 use inverted tx_clk_rgmii.
-+ */
-+#define YT8531_RC1R_TX_CLK_SEL_INVERTED       BIT(14)
-+#define YT8531_RC1R_RX_DELAY_MASK             GENMASK(13, 10)
-+#define YT8531_RC1R_FE_TX_DELAY_MASK          GENMASK(7, 4)
-+#define YT8531_RC1R_GE_TX_DELAY_MASK          GENMASK(3, 0)
-+#define YT8531_RC1R_RGMII_0_000_NS            0
-+#define YT8531_RC1R_RGMII_0_150_NS            1
-+#define YT8531_RC1R_RGMII_0_300_NS            2
-+#define YT8531_RC1R_RGMII_0_450_NS            3
-+#define YT8531_RC1R_RGMII_0_600_NS            4
-+#define YT8531_RC1R_RGMII_0_750_NS            5
-+#define YT8531_RC1R_RGMII_0_900_NS            6
-+#define YT8531_RC1R_RGMII_1_050_NS            7
-+#define YT8531_RC1R_RGMII_1_200_NS            8
-+#define YT8531_RC1R_RGMII_1_350_NS            9
-+#define YT8531_RC1R_RGMII_1_500_NS            10
-+#define YT8531_RC1R_RGMII_1_650_NS            11
-+#define YT8531_RC1R_RGMII_1_800_NS            12
-+#define YT8531_RC1R_RGMII_1_950_NS            13
-+#define YT8531_RC1R_RGMII_2_100_NS            14
-+#define YT8531_RC1R_RGMII_2_250_NS            15
-+
-+/* Phy gmii clock gating Register */
-+#define YT8531_CLOCK_GATING_REG               0xC
-+#define YT8531_CGR_RX_CLK_EN                  BIT(12)
-+
-+/* Specific Status Register */
-+#define YTPHY_SPECIFIC_STATUS_REG             0x11
-+#define YTPHY_DUPLEX_MASK                     BIT(13)
-+#define YTPHY_DUPLEX_SHIFT                    13
-+#define YTPHY_SPEED_MODE_MASK                 GENMASK(15, 14)
-+#define YTPHY_SPEED_MODE_SHIFT                        14
-+
-+#define YT8531_EXTREG_SLEEP_CONTROL1_REG      0x27
-+#define YT8531_ESC1R_SLEEP_SW                 BIT(15)
-+#define YT8531_ESC1R_PLLON_SLP                        BIT(14)
-+
-+#define YT8531_RGMII_CONFIG1_REG              0xA003
-+
-+#define YT8531_CHIP_CONFIG_REG                        0xA001
-+#define YT8531_CCR_SW_RST                     BIT(15)
-+/* 1b0 disable 1.9ns rxc clock delay  *default*
-+ * 1b1 enable 1.9ns rxc clock delay
-+ */
-+#define YT8531_CCR_RXC_DLY_EN                 BIT(8)
-+#define YT8531_CCR_RXC_DLY_1_900_NS           1900
-+
-+/* bits in struct ytphy_plat_priv->flag */
-+#define TX_CLK_ADJ_ENABLED                    BIT(0)
-+#define AUTO_SLEEP_DISABLED                   BIT(1)
-+#define KEEP_PLL_ENABLED                      BIT(2)
-+#define TX_CLK_10_INVERTED                    BIT(3)
-+#define TX_CLK_100_INVERTED                   BIT(4)
-+#define TX_CLK_1000_INVERTED                  BIT(5)
-+
-+struct ytphy_plat_priv {
-+      u32 rx_delay_ps;
-+      u32 tx_delay_ps;
-+      u32 clk_out_frequency;
-+      u32 flag;
-+};
-+
-+/**
-+ * struct ytphy_cfg_reg_map - map a config value to a register value
-+ * @cfg: value in device configuration
-+ * @reg: value in the register
-+ */
-+struct ytphy_cfg_reg_map {
-+      u32 cfg;
-+      u32 reg;
-+};
-+
-+static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
-+      /* for tx delay / rx delay with YT8531_CCR_RXC_DLY_EN is not set. */
-+      { 0,    YT8531_RC1R_RGMII_0_000_NS },
-+      { 150,  YT8531_RC1R_RGMII_0_150_NS },
-+      { 300,  YT8531_RC1R_RGMII_0_300_NS },
-+      { 450,  YT8531_RC1R_RGMII_0_450_NS },
-+      { 600,  YT8531_RC1R_RGMII_0_600_NS },
-+      { 750,  YT8531_RC1R_RGMII_0_750_NS },
-+      { 900,  YT8531_RC1R_RGMII_0_900_NS },
-+      { 1050, YT8531_RC1R_RGMII_1_050_NS },
-+      { 1200, YT8531_RC1R_RGMII_1_200_NS },
-+      { 1350, YT8531_RC1R_RGMII_1_350_NS },
-+      { 1500, YT8531_RC1R_RGMII_1_500_NS },
-+      { 1650, YT8531_RC1R_RGMII_1_650_NS },
-+      { 1800, YT8531_RC1R_RGMII_1_800_NS },
-+      { 1950, YT8531_RC1R_RGMII_1_950_NS },   /* default tx/rx delay */
-+      { 2100, YT8531_RC1R_RGMII_2_100_NS },
-+      { 2250, YT8531_RC1R_RGMII_2_250_NS },
-+
-+      /* only for rx delay with YT8531_CCR_RXC_DLY_EN is set. */
-+      { 0    + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_000_NS },
-+      { 150  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_150_NS },
-+      { 300  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_300_NS },
-+      { 450  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_450_NS },
-+      { 600  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_600_NS },
-+      { 750  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_750_NS },
-+      { 900  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_900_NS },
-+      { 1050 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_050_NS },
-+      { 1200 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_200_NS },
-+      { 1350 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_350_NS },
-+      { 1500 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_500_NS },
-+      { 1650 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_650_NS },
-+      { 1800 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_800_NS },
-+      { 1950 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_950_NS },
-+      { 2100 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_2_100_NS },
-+      { 2250 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_2_250_NS }
-+};
-+
-+static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
-+                                   u32 val,
-+                                   u16 *rxc_dly_en)
-+{
-+      int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
-+      int tb_size_half = tb_size / 2;
-+      int i;
-+
-+      /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
-+       * tb_size is valid.
-+       */
-+      if (!rxc_dly_en)
-+              tb_size = tb_size_half;
-+
-+      for (i = 0; i < tb_size; i++) {
-+              if (ytphy_rgmii_delays[i].cfg == val) {
-+                      if (rxc_dly_en && i < tb_size_half)
-+                              *rxc_dly_en = 0;
-+                      return ytphy_rgmii_delays[i].reg;
-+              }
-+      }
-+
-+      pr_warn("Unsupported value %d, using default (%u)\n",
-+              val, YT8531_RC1R_RGMII_1_950_NS);
-+
-+      /* when rxc_dly_en is not NULL, it is get the delay for rx.
-+       * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
-+       * so YT8531_CCR_RXC_DLY_EN should not be set.
-+       */
-+      if (rxc_dly_en)
-+              *rxc_dly_en = 0;
-+
-+      return YT8531_RC1R_RGMII_1_950_NS;
-+}
-+
-+static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
-+                          u16 set)
-+{
-+      int ret;
-+
-+      ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
-+      if (ret < 0)
-+              return ret;
-+
-+      return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
-+}
-+
-+static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
-+{
-+      struct ytphy_plat_priv  *priv = phydev->priv;
-+      u16 rxc_dly_en = YT8531_CCR_RXC_DLY_EN;
-+      u32 rx_reg, tx_reg;
-+      u16 mask, val = 0;
-+      int ret;
-+
-+      rx_reg = ytphy_get_delay_reg_value(phydev, priv->rx_delay_ps,
-+                                         &rxc_dly_en);
-+      tx_reg = ytphy_get_delay_reg_value(phydev, priv->tx_delay_ps,
-+                                         NULL);
-+
-+      switch (phydev->interface) {
-+      case PHY_INTERFACE_MODE_RGMII:
-+              rxc_dly_en = 0;
-+              break;
-+      case PHY_INTERFACE_MODE_RGMII_RXID:
-+              val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg);
-+              break;
-+      case PHY_INTERFACE_MODE_RGMII_TXID:
-+              rxc_dly_en = 0;
-+              val |= FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
-+              break;
-+      case PHY_INTERFACE_MODE_RGMII_ID:
-+              val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg) |
-+                     FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
-+              break;
-+      default: /* do not support other modes */
-+              return -EOPNOTSUPP;
-+      }
-+
-+      ret = ytphy_modify_ext(phydev, YT8531_CHIP_CONFIG_REG,
-+                             YT8531_CCR_RXC_DLY_EN, rxc_dly_en);
-+      if (ret < 0)
-+              return ret;
-+
-+      /* Generally, it is not necessary to adjust YT8531_RC1R_FE_TX_DELAY */
-+      mask = YT8531_RC1R_RX_DELAY_MASK | YT8531_RC1R_GE_TX_DELAY_MASK;
-+      return ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG, mask, val);
-+}
-+
-+static int yt8531_parse_status(struct phy_device *phydev)
-+{
-+      int val;
-+      int speed, speed_mode;
-+
-+      val = phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_SPECIFIC_STATUS_REG);
-+      if (val < 0)
-+              return val;
-+
-+      speed_mode = (val & YTPHY_SPEED_MODE_MASK) >> YTPHY_SPEED_MODE_SHIFT;
-+      switch (speed_mode) {
-+      case 2:
-+              speed = SPEED_1000;
-+              break;
-+      case 1:
-+              speed = SPEED_100;
-+              break;
-+      default:
-+              speed = SPEED_10;
-+              break;
-+      }
-+
-+      phydev->speed = speed;
-+      phydev->duplex = (val & YTPHY_DUPLEX_MASK) >> YTPHY_DUPLEX_SHIFT;
-+
-+      return 0;
-+}
-+
-+static int yt8531_startup(struct phy_device *phydev)
-+{
-+      struct ytphy_plat_priv  *priv = phydev->priv;
-+      u16 val = 0;
-+      int ret;
-+
-+      ret = genphy_update_link(phydev);
-+      if (ret)
-+              return ret;
-+
-+      ret = yt8531_parse_status(phydev);
-+      if (ret)
-+              return ret;
-+
-+      if (phydev->speed < 0)
-+              return -EINVAL;
-+
-+      if (!(priv->flag & TX_CLK_ADJ_ENABLED))
-+              return 0;
-+
-+      switch (phydev->speed) {
-+      case SPEED_1000:
-+              if (priv->flag & TX_CLK_1000_INVERTED)
-+                      val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
-+              break;
-+      case SPEED_100:
-+              if (priv->flag & TX_CLK_100_INVERTED)
-+                      val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
-+              break;
-+      case SPEED_10:
-+              if (priv->flag & TX_CLK_10_INVERTED)
-+                      val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
-+              break;
-+      default:
-+              printf("UNKNOWN SPEED\n");
-+              return -EINVAL;
-+      }
-+
-+      ret = ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG,
-+                             YT8531_RC1R_TX_CLK_SEL_INVERTED, val);
-+      if (ret < 0)
-+              pr_warn("Modify TX_CLK_SEL err:%d\n", ret);
-+
-+      return 0;
-+}
-+
-+static void ytphy_dt_parse(struct phy_device *phydev)
-+{
-+      struct ytphy_plat_priv  *priv = phydev->priv;
-+
-+      priv->clk_out_frequency = ofnode_read_u32_default(phydev->node,
-+                                                        "motorcomm,clk-out-frequency-hz",
-+                                                        YTPHY_DTS_OUTPUT_CLK_DIS);
-+      priv->rx_delay_ps = ofnode_read_u32_default(phydev->node,
-+                                                  "rx-internal-delay-ps",
-+                                                  YT8531_RC1R_RGMII_1_950_NS);
-+      priv->tx_delay_ps = ofnode_read_u32_default(phydev->node,
-+                                                  "tx-internal-delay-ps",
-+                                                  YT8531_RC1R_RGMII_1_950_NS);
-+
-+      if (ofnode_read_bool(phydev->node, "motorcomm,auto-sleep-disabled"))
-+              priv->flag |= AUTO_SLEEP_DISABLED;
-+
-+      if (ofnode_read_bool(phydev->node, "motorcomm,keep-pll-enabled"))
-+              priv->flag |= KEEP_PLL_ENABLED;
-+
-+      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-adj-enabled"))
-+              priv->flag |= TX_CLK_ADJ_ENABLED;
-+
-+      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-10-inverted"))
-+              priv->flag |= TX_CLK_10_INVERTED;
-+
-+      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-100-inverted"))
-+              priv->flag |= TX_CLK_100_INVERTED;
-+
-+      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-1000-inverted"))
-+              priv->flag |= TX_CLK_1000_INVERTED;
-+}
-+
-+static int yt8531_config(struct phy_device *phydev)
-+{
-+      struct ytphy_plat_priv  *priv = phydev->priv;
-+      u16 mask, val;
-+      int ret;
-+
-+      ret = genphy_config_aneg(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      ytphy_dt_parse(phydev);
-+      switch (priv->clk_out_frequency) {
-+      case YTPHY_DTS_OUTPUT_CLK_DIS:
-+              mask = YT8531_SCR_SYNCE_ENABLE;
-+              val = 0;
-+              break;
-+      case YTPHY_DTS_OUTPUT_CLK_25M:
-+              mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
-+                         YT8531_SCR_CLK_FRE_SEL_125M;
-+              val = YT8531_SCR_SYNCE_ENABLE |
-+                        FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+                                   YT8531_SCR_CLK_SRC_REF_25M);
-+              break;
-+      case YTPHY_DTS_OUTPUT_CLK_125M:
-+              mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
-+                         YT8531_SCR_CLK_FRE_SEL_125M;
-+              val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
-+                        FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
-+                                   YT8531_SCR_CLK_SRC_PLL_125M);
-+              break;
-+      default:
-+              pr_warn("Freq err:%u\n", priv->clk_out_frequency);
-+              return -EINVAL;
-+      }
-+
-+      ret = ytphy_modify_ext(phydev, YTPHY_SYNCE_CFG_REG, mask,
-+                             val);
-+      if (ret < 0)
-+              return ret;
-+
-+      ret = ytphy_rgmii_clk_delay_config(phydev);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (priv->flag & AUTO_SLEEP_DISABLED) {
-+              /* disable auto sleep */
-+              ret = ytphy_modify_ext(phydev,
-+                                     YT8531_EXTREG_SLEEP_CONTROL1_REG,
-+                                     YT8531_ESC1R_SLEEP_SW, 0);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-+      if (priv->flag & KEEP_PLL_ENABLED) {
-+              /* enable RXC clock when no wire plug */
-+              ret = ytphy_modify_ext(phydev,
-+                                     YT8531_CLOCK_GATING_REG,
-+                                     YT8531_CGR_RX_CLK_EN, 0);
-+              if (ret < 0)
-+                      return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int yt8531_probe(struct phy_device *phydev)
-+{
-+      struct ytphy_plat_priv  *priv;
-+
-+      priv = calloc(1, sizeof(struct ytphy_plat_priv));
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      phydev->priv = priv;
-+
-+      return 0;
-+}
-+
-+U_BOOT_PHY_DRIVER(motorcomm8531) = {
-+      .name          = "YT8531 Gigabit Ethernet",
-+      .uid           = PHY_ID_YT8531,
-+      .mask          = PHY_ID_MASK,
-+      .features      = PHY_GBIT_FEATURES,
-+      .probe         = &yt8531_probe,
-+      .config        = &yt8531_config,
-+      .startup       = &yt8531_startup,
-+      .shutdown      = &genphy_shutdown,
-+};
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4028-sunxi-add-support-for-MangoPI-MQDual-T113-variant.patch b/package/boot/uboot-sunxi/patches/4028-sunxi-add-support-for-MangoPI-MQDual-T113-variant.patch
new file mode 100644 (file)
index 0000000..5882c4f
--- /dev/null
@@ -0,0 +1,110 @@
+From b4f63d64a10847dc64c456ddcf262ac5c5eea616 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 3 Jun 2023 00:52:40 +0200
+Subject: [PATCH 4028/4044] sunxi: add support for MangoPI MQDual T113 variant
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/dts/Makefile                         |  3 +-
+ .../dts/sun8i-t113s-mangopi-mqdual-t113.dts   | 50 +++++++++++++++++++
+ configs/mangopi_mqdual_t113_defconfig         | 17 +++++++
+ 3 files changed, 69 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts
+ create mode 100644 configs/mangopi_mqdual_t113_defconfig
+
+diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
+index 41ee9c4c65..4207f17601 100644
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -711,7 +711,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
+       sun8i-v3-sl631-imx179.dtb \
+       sun8i-v3s-licheepi-zero.dtb
+ dtb-$(CONFIG_MACH_SUN8I_R528) += \
+-      sun8i-t113s-mangopi-mq-r-t113.dtb
++      sun8i-t113s-mangopi-mq-r-t113.dtb \
++      sun8i-t113s-mangopi-mqdual-t113.dtb
+ dtb-$(CONFIG_MACH_SUN50I_H5) += \
+       sun50i-h5-bananapi-m2-plus.dtb \
+       sun50i-h5-emlid-neutis-n5-devboard.dtb \
+diff --git a/arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts b/arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts
+new file mode 100644
+index 0000000000..7de3ddb92f
+--- /dev/null
++++ b/arch/arm/dts/sun8i-t113s-mangopi-mqdual-t113.dts
+@@ -0,0 +1,50 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2022 Arm Ltd.
++
++#include <dt-bindings/interrupt-controller/irq.h>
++
++/dts-v1/;
++
++#include "sun8i-t113s.dtsi"
++#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
++
++/ {
++      model = "MangoPi MQDual T113";
++      compatible = "widora,mangopi-mqdual-t113", "allwinner,sun8i-t113s";
++
++      aliases {
++              serial0 = &uart0;
++              ethernet0 = &rtl8189ftv;
++      };
++
++      chosen {
++              stdout-path = "serial0:115200n8";
++      };
++};
++
++&cpu0 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&cpu1 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&mmc1 {
++      rtl8189ftv: wifi@1 {
++              reg = <1>;
++              interrupt-parent = <&pio>;
++              interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 = WL_WAKE_AP */
++              interrupt-names = "host-wake";
++      };
++};
++
++&uart0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart0_pins>;
++      status = "okay";
++};
++
++&uart3 {
++      status = "disabled";
++};
+diff --git a/configs/mangopi_mqdual_t113_defconfig b/configs/mangopi_mqdual_t113_defconfig
+new file mode 100644
+index 0000000000..98b90c55f4
+--- /dev/null
++++ b/configs/mangopi_mqdual_t113_defconfig
+@@ -0,0 +1,17 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-mangopi-mqdual-t113"
++CONFIG_SUNXI_MINIMUM_DRAM_MB=128
++CONFIG_SPL=y
++CONFIG_MACH_SUN8I_R528=y
++CONFIG_CONS_INDEX=1
++CONFIG_MMC0_CD_PIN="PF6"
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_SYS_MONITOR_LEN=786432
++CONFIG_DRAM_CLK=792
++CONFIG_DRAM_ZQ=8092667
++CONFIG_DRAM_SUNXI_ODT_EN=0
++CONFIG_DRAM_SUNXI_TPR0=0x004a2195
++CONFIG_DRAM_SUNXI_TPR11=0x340000
++CONFIG_DRAM_SUNXI_TPR12=0x46
++CONFIG_DRAM_SUNXI_TPR13=0x34000100
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4029-sunxi-add-support-for-UART5-in-Port-E-group-on-T133.patch b/package/boot/uboot-sunxi/patches/4029-sunxi-add-support-for-UART5-in-Port-E-group-on-T133.patch
new file mode 100644 (file)
index 0000000..040feb3
--- /dev/null
@@ -0,0 +1,70 @@
+From c58e825d57bff0f9124f3afbcbad4a5c06d3670f Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 3 Jun 2023 23:41:31 +0200
+Subject: [PATCH 4029/4044] sunxi: add support for UART5 in Port E group on
+ T133
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/include/asm/arch-sunxi/serial.h | 1 +
+ arch/arm/mach-sunxi/board.c              | 4 ++++
+ drivers/pinctrl/sunxi/pinctrl-sunxi.c    | 1 +
+ include/configs/sunxi-common.h           | 3 +++
+ 4 files changed, 9 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/serial.h b/arch/arm/include/asm/arch-sunxi/serial.h
+index 9386287b65..48d0f42a3b 100644
+--- a/arch/arm/include/asm/arch-sunxi/serial.h
++++ b/arch/arm/include/asm/arch-sunxi/serial.h
+@@ -20,6 +20,7 @@
+ #elif defined(CONFIG_SUNXI_GEN_NCAT2)
+ #define SUNXI_UART0_BASE              0x02500000
+ #define SUNXI_R_UART_BASE             0               // 0x07080000 (?>
++#define SUNXI_UART5_BASE              (SUNXI_UART0_BASE + 0x1400)
+ #else
+ #define SUNXI_UART0_BASE              0x01c28000
+ #define SUNXI_R_UART_BASE             0x01f02800
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index 8980ffb509..50693d216b 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -175,6 +175,10 @@ static int gpio_init(void)
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
+       sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
++#elif CONFIG_CONS_INDEX == 6 && defined(CONFIG_MACH_SUN8I_R528)
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(6), 9);
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(7), 9);
++      sunxi_gpio_set_pull(SUNXI_GPE(7), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN8I) && \
+                               !defined(CONFIG_MACH_SUN8I_R40)
+       sunxi_gpio_set_cfgpin(SUNXI_GPG(6), SUN8I_GPG_UART1);
+diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+index 614cfe6b73..2717d79bc3 100644
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -748,6 +748,7 @@ static const struct sunxi_pinctrl_function sun20i_d1_pinctrl_functions[] = {
+       { "uart0",      6 },    /* PB2-PB3 */
+ #endif
+       { "uart3",      7 },    /* PB6-PB9 */
++      { "uart5",      3 },    /* PE6-PE7 */
+ };
+ static const struct sunxi_pinctrl_desc __maybe_unused sun20i_d1_pinctrl_desc = {
+diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
+index b8ca77d031..bdb568af4b 100644
+--- a/include/configs/sunxi-common.h
++++ b/include/configs/sunxi-common.h
+@@ -29,6 +29,9 @@
+ # define CFG_SYS_NS16550_COM3         SUNXI_UART2_BASE
+ # define CFG_SYS_NS16550_COM4         SUNXI_UART3_BASE
+ # define CFG_SYS_NS16550_COM5         SUNXI_R_UART_BASE
++#if defined(CONFIG_SUNXI_GEN_NCAT2)
++# define CFG_SYS_NS16550_COM6         SUNXI_UART5_BASE
++#endif
+ #endif
+ /* CPU */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4029-sunxi-enable-gmac-on-MYIR-MYD-YT113X-with-the-YT8531.patch b/package/boot/uboot-sunxi/patches/4029-sunxi-enable-gmac-on-MYIR-MYD-YT113X-with-the-YT8531.patch
deleted file mode 100644 (file)
index 2e4654e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 98a8ab5c4b9695d806f5e0d0d8db9935fe7ed6f8 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Mon, 5 Jun 2023 17:57:15 +0200
-Subject: [PATCH 4029/4031] sunxi: enable gmac on MYIR MYD-YT113X with the
- YT8531 PHY
-
-The gmac is connected to a Motorcomm YT8531, for which the driver
-has been picked from Starfive and ported over.
-
-Support is not yet added in DTS, only for compile testing.
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- configs/myir_myd_t113x_defconfig | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/configs/myir_myd_t113x_defconfig b/configs/myir_myd_t113x_defconfig
-index dc652732e3..ad2b59ed70 100644
---- a/configs/myir_myd_t113x_defconfig
-+++ b/configs/myir_myd_t113x_defconfig
-@@ -15,3 +15,7 @@ CONFIG_DRAM_SUNXI_TPR0=0x004a2195
- CONFIG_DRAM_SUNXI_TPR11=0x340000
- CONFIG_DRAM_SUNXI_TPR12=0x46
- CONFIG_DRAM_SUNXI_TPR13=0x34000100
-+CONFIG_PHY_MOTORCOMM=y
-+CONFIG_SUN8I_EMAC=y
-+CONFIG_RGMII=y
-+CONFIG_RMII=y
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4030-net-phy-backport-and-update-driver-for-Motorcomm-yt8.patch b/package/boot/uboot-sunxi/patches/4030-net-phy-backport-and-update-driver-for-Motorcomm-yt8.patch
deleted file mode 100644 (file)
index 4f4ca8d..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From 099cca9ab11daf77d1b8e5864ebb3b08a41b94fb Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Mon, 5 Jun 2023 18:15:15 +0200
-Subject: [PATCH 4030/4031] net: phy: backport and update driver for Motorcomm
- yt8531 phy
-
-Don't use U_BOOT_PHY_DRIVER yet.
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- drivers/net/phy/motorcomm.c | 9 ++++++++-
- drivers/net/phy/phy.c       | 3 +++
- include/phy.h               | 1 +
- 3 files changed, 12 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
-index e822fd76f2..eb2dd65c4a 100644
---- a/drivers/net/phy/motorcomm.c
-+++ b/drivers/net/phy/motorcomm.c
-@@ -425,7 +425,7 @@ static int yt8531_probe(struct phy_device *phydev)
-       return 0;
- }
--U_BOOT_PHY_DRIVER(motorcomm8531) = {
-+static struct phy_driver YT8531_driver =  {
-       .name          = "YT8531 Gigabit Ethernet",
-       .uid           = PHY_ID_YT8531,
-       .mask          = PHY_ID_MASK,
-@@ -435,3 +435,10 @@ U_BOOT_PHY_DRIVER(motorcomm8531) = {
-       .startup       = &yt8531_startup,
-       .shutdown      = &genphy_shutdown,
- };
-+
-+int phy_motorcomm_init(void)
-+{
-+        phy_register(&YT8531_driver);
-+
-+        return 0;
-+}
-diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
-index 9e22db3fc8..3613c3dd17 100644
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -532,6 +532,9 @@ int phy_init(void)
- #ifdef CONFIG_PHY_MESON_GXL
-       phy_meson_gxl_init();
- #endif
-+#ifdef CONFIG_PHY_MOTORCOMM
-+      phy_motorcomm_init();
-+#endif
- #ifdef CONFIG_PHY_NATSEMI
-       phy_natsemi_init();
- #endif
-diff --git a/include/phy.h b/include/phy.h
-index 749285f15e..05208d7f3d 100644
---- a/include/phy.h
-+++ b/include/phy.h
-@@ -331,6 +331,7 @@ int phy_marvell_init(void);
- int phy_micrel_ksz8xxx_init(void);
- int phy_micrel_ksz90x1_init(void);
- int phy_meson_gxl_init(void);
-+int phy_motorcomm_init(void);
- int phy_natsemi_init(void);
- int phy_nxp_c45_tja11xx_init(void);
- int phy_nxp_tja11xx_init(void);
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4030-sunxi-add-MYIR-MYD-YT113X-board.patch b/package/boot/uboot-sunxi/patches/4030-sunxi-add-MYIR-MYD-YT113X-board.patch
new file mode 100644 (file)
index 0000000..331ddd8
--- /dev/null
@@ -0,0 +1,131 @@
+From 542c6069f64d4e97c68007bb7e22c030ab7f9526 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 4 Jun 2023 00:13:45 +0200
+Subject: [PATCH 4030/4044] sunxi: add MYIR MYD-YT113X board
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/dts/Makefile                        |  3 +-
+ arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts | 68 ++++++++++++++++++++
+ configs/myir_myd_t113x_defconfig             | 19 ++++++
+ 3 files changed, 89 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts
+ create mode 100644 configs/myir_myd_t113x_defconfig
+
+diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
+index 4207f17601..6fb49de59a 100644
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -712,7 +712,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
+       sun8i-v3s-licheepi-zero.dtb
+ dtb-$(CONFIG_MACH_SUN8I_R528) += \
+       sun8i-t113s-mangopi-mq-r-t113.dtb \
+-      sun8i-t113s-mangopi-mqdual-t113.dtb
++      sun8i-t113s-mangopi-mqdual-t113.dtb \
++      sun8i-t113s-myir-myd-yt113x.dtb
+ dtb-$(CONFIG_MACH_SUN50I_H5) += \
+       sun50i-h5-bananapi-m2-plus.dtb \
+       sun50i-h5-emlid-neutis-n5-devboard.dtb \
+diff --git a/arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts
+new file mode 100644
+index 0000000000..afd0d8f532
+--- /dev/null
++++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x.dts
+@@ -0,0 +1,68 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2022 Arm Ltd.
++
++#include <dt-bindings/interrupt-controller/irq.h>
++
++/dts-v1/;
++
++#include "sun8i-t113s.dtsi"
++#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
++
++/ {
++      model = "MYIR MYD-YT113X";
++      compatible = "myir,myd-yt113x", "myir,myc-yt113x", "allwinner,sun8i-t113s";
++
++      aliases {
++              serial5 = &uart5;
++      };
++
++      chosen {
++              stdout-path = "serial5:115200n8";
++      };
++};
++
++&cpu0 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&cpu1 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&mmc2_pins {
++      bias-pull-up;
++      drive-strength = <40>;
++};
++
++&mmc2 {
++      pinctrl-0 = <&mmc2_pins>;
++      pinctrl-names = "default";
++      vmmc-supply = <&reg_3v3>;
++      non-removable;
++      bus-width = <4>;
++      status = "okay";
++
++      emmc: emmc@0 {
++              reg = <0>;
++              compatible = "mmc-card";
++              broken-hpi;
++      };
++};
++
++&pio {
++      /omit-if-no-ref/
++      uart5_pins: uart5-pins {
++              pins = "PE6", "PE7";
++              function = "uart5";
++      };
++};
++
++&uart5 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart5_pins>;
++      status = "okay";
++};
++
++&uart3 {
++      status = "disabled";
++};
+diff --git a/configs/myir_myd_t113x_defconfig b/configs/myir_myd_t113x_defconfig
+new file mode 100644
+index 0000000000..21f939272a
+--- /dev/null
++++ b/configs/myir_myd_t113x_defconfig
+@@ -0,0 +1,20 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-myir-myd-yt113x"
++CONFIG_SUNXI_MINIMUM_DRAM_MB=128
++CONFIG_SPL=y
++CONFIG_MACH_SUN8I_R528=y
++CONFIG_CONS_INDEX=6
++CONFIG_MMC0_CD_PIN="PF6"
++CONFIG_MMC_SUNXI_SLOT_EXTRA=2
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_SYS_MONITOR_LEN=786432
++CONFIG_DRAM_CLK=792
++CONFIG_DRAM_ZQ=8092667
++CONFIG_DRAM_SUNXI_ODT_EN=0
++CONFIG_DRAM_SUNXI_TPR0=0x004a2195
++CONFIG_DRAM_SUNXI_TPR11=0x340000
++CONFIG_DRAM_SUNXI_TPR12=0x46
++CONFIG_DRAM_SUNXI_TPR13=0x34000100
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_OHCI_HCD=y
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4031-sunxi-add-support-for-UART3-on-PE-pins.patch b/package/boot/uboot-sunxi/patches/4031-sunxi-add-support-for-UART3-on-PE-pins.patch
new file mode 100644 (file)
index 0000000..4fa00b9
--- /dev/null
@@ -0,0 +1,100 @@
+From 0c47a295e3d6f4611a152485fac63bb2b64369e8 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 3 Jun 2023 23:57:46 +0200
+Subject: [PATCH 4031/4044] sunxi: add support for UART3 on PE pins
+
+Some boards use Port E pins for muxing the UART3 as console. Add a new
+Kconfig option allowing to select this (mimicking MMC_PINS_PH).
+
+Pinmux taken from https://bbs.aw-ol.com/assets/uploads/files/1648883311844-t113-s3_datasheet_v1.2.pdf
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/mach-sunxi/Kconfig           |  6 ++++++
+ arch/arm/mach-sunxi/board.c           | 10 ++++++++--
+ arch/riscv/dts/sunxi-d1s-t113.dtsi    |  6 ++++++
+ drivers/pinctrl/sunxi/pinctrl-sunxi.c |  4 ++++
+ 4 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index 77b510cdfe..1ddf496a55 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -664,6 +664,12 @@ config UART0_PORT_F
+       at the same time, the system can be only booted in the FEL mode.
+       Only enable this if you really know what you are doing.
++config UART3_PINS_PE
++      bool "Pins for uart3 are on Port E"
++      ---help---
++      Select this option for boards where uart3 uses the Port E pinmux.
++      (Some T113-S3 boards use uart3 as console.)
++
+ config OLD_SUNXI_KERNEL_COMPAT
+       bool "Enable workarounds for booting old kernels"
+       ---help---
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index 50693d216b..85dbad0552 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -168,16 +168,22 @@ static int gpio_init(void)
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
+       sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 4 && defined(CONFIG_MACH_SUN8I_R528)
++#if defined(CONFIG_UART3_PINS_PE)
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(8), 5);
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(9), 5);
++      sunxi_gpio_set_pull(SUNXI_GPE(9), SUNXI_GPIO_PULL_UP);
++#else
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(6), 7);
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(7), 7);
+       sunxi_gpio_set_pull(SUNXI_GPB(7), SUNXI_GPIO_PULL_UP);
++#endif
+ #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
+       sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
+       sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 6 && defined(CONFIG_MACH_SUN8I_R528)
+-      sunxi_gpio_set_cfgpin(SUNXI_GPE(6), 9);
+-      sunxi_gpio_set_cfgpin(SUNXI_GPE(7), 9);
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(6), 3);
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(7), 3);
+       sunxi_gpio_set_pull(SUNXI_GPE(7), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN8I) && \
+                               !defined(CONFIG_MACH_SUN8I_R40)
+diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+index b1f97bd0bc..b72bbc5e43 100644
+--- a/arch/riscv/dts/sunxi-d1s-t113.dtsi
++++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+@@ -126,6 +126,12 @@
+                               function = "uart3";
+                       };
++                      /omit-if-no-ref/
++                      uart3_pe_pins: uart3-pe-pins {
++                              pins = "PE8", "PE9";
++                              function = "uart3";
++                      };
++
+                       /omit-if-no-ref/
+                       uart0_pins: uart0-pins {
+                               pins = "PE2", "PE3";
+diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+index 2717d79bc3..e466808e4e 100644
+--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
++++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+@@ -747,7 +747,11 @@ static const struct sunxi_pinctrl_function sun20i_d1_pinctrl_functions[] = {
+ #else
+       { "uart0",      6 },    /* PB2-PB3 */
+ #endif
++#if IS_ENABLED(CONFIG_UART3_PINS_E)
++      { "uart3",      5 },    /* PE8-PE9 */
++else
+       { "uart3",      7 },    /* PB6-PB9 */
++#endif
+       { "uart5",      3 },    /* PE6-PE7 */
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4031-sunxi-rongpin-rp-t113-add-missing-gpio.h-include.patch b/package/boot/uboot-sunxi/patches/4031-sunxi-rongpin-rp-t113-add-missing-gpio.h-include.patch
deleted file mode 100644 (file)
index 805d6f5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From 4481a2790ed667a206203ecf3fd8f8bbcf35d062 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Mon, 5 Jun 2023 18:29:41 +0200
-Subject: [PATCH 4031/4031] sunxi: rongpin-rp-t113: add missing gpio.h include
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-index f2521438fb..348ae5eec6 100644
---- a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-+++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
-@@ -2,6 +2,7 @@
- // Copyright (C) 2022 Arm Ltd.
- #include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/gpio/gpio.h>
- /dts-v1/;
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4032-sunxi-add-support-for-Rongpin-RP-T113-board.patch b/package/boot/uboot-sunxi/patches/4032-sunxi-add-support-for-Rongpin-RP-T113-board.patch
new file mode 100644 (file)
index 0000000..1e81498
--- /dev/null
@@ -0,0 +1,159 @@
+From 11fe7200d693e88d1f648fd000c327dcc529fa28 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 3 Jun 2023 23:42:33 +0200
+Subject: [PATCH 4032/4044] sunxi: add support for Rongpin RP-T113 board
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/dts/Makefile                        |  3 +-
+ arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts | 98 ++++++++++++++++++++
+ configs/rongpin_rp_t113_defconfig            | 18 ++++
+ 3 files changed, 118 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
+ create mode 100644 configs/rongpin_rp_t113_defconfig
+
+diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
+index 6fb49de59a..be89021657 100644
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -713,7 +713,8 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
+ dtb-$(CONFIG_MACH_SUN8I_R528) += \
+       sun8i-t113s-mangopi-mq-r-t113.dtb \
+       sun8i-t113s-mangopi-mqdual-t113.dtb \
+-      sun8i-t113s-myir-myd-yt113x.dtb
++      sun8i-t113s-myir-myd-yt113x.dtb \
++      sun8i-t113s-rongpin-rp-t113.dtb
+ dtb-$(CONFIG_MACH_SUN50I_H5) += \
+       sun50i-h5-bananapi-m2-plus.dtb \
+       sun50i-h5-emlid-neutis-n5-devboard.dtb \
+diff --git a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
+new file mode 100644
+index 0000000000..6ac2c065c4
+--- /dev/null
++++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
+@@ -0,0 +1,98 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2022 Arm Ltd.
++
++#include <dt-bindings/interrupt-controller/irq.h>
++
++/dts-v1/;
++
++#include "sun8i-t113s.dtsi"
++
++/ {
++      model = "Rongpin RP-T113";
++      compatible = "rongpin,rp-t113", "allwinner,sun8i-t113s";
++
++      aliases {
++              serial3 = &uart3;
++      };
++
++      chosen {
++              stdout-path = "serial3:115200n8";
++      };
++
++      /* board wide 5V supply directly from the USB-C socket */
++      reg_vcc5v: regulator-5v {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-5v";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              regulator-always-on;
++      };
++
++      /* SY8008 DC/DC regulator on the board */
++      reg_3v3: regulator-3v3 {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              vin-supply = <&reg_vcc5v>;
++      };
++
++      /* SY8008 DC/DC regulator on the board, also supplying VDD-SYS */
++      reg_vcc_core: regulator-core {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-core";
++              regulator-min-microvolt = <880000>;
++              regulator-max-microvolt = <880000>;
++              vin-supply = <&reg_vcc5v>;
++      };
++
++      /* XC6206 LDO on the board */
++      reg_avdd2v8: regulator-avdd {
++              compatible = "regulator-fixed";
++              regulator-name = "avdd2v8";
++              regulator-min-microvolt = <2800000>;
++              regulator-max-microvolt = <2800000>;
++              vin-supply = <&reg_3v3>;
++      };
++};
++
++&cpu0 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&cpu1 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&pio {
++      vcc-pb-supply = <&reg_3v3>;
++      vcc-pd-supply = <&reg_3v3>;
++      vcc-pe-supply = <&reg_avdd2v8>;
++      vcc-pf-supply = <&reg_3v3>;
++      vcc-pg-supply = <&reg_3v3>;
++};
++
++&uart3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart3_pe_pins>;
++      status = "okay";
++};
++
++&mmc0 {
++      pinctrl-0 = <&mmc0_pins>;
++      pinctrl-names = "default";
++      vmmc-supply = <&reg_3v3>;
++      cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
++      disable-wp;
++      bus-width = <4>;
++      status = "okay";
++};
++
++&mmc2 {
++      pinctrl-0 = <&mmc2_pins>;
++      pinctrl-names = "default";
++      vmmc-supply = <&reg_3v3>;
++      non-removable;
++      bus-width = <4>;
++      status = "okay";
++};
+diff --git a/configs/rongpin_rp_t113_defconfig b/configs/rongpin_rp_t113_defconfig
+new file mode 100644
+index 0000000000..9b5a5bcd65
+--- /dev/null
++++ b/configs/rongpin_rp_t113_defconfig
+@@ -0,0 +1,18 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-rongpin-rp-t113"
++CONFIG_SUNXI_MINIMUM_DRAM_MB=128
++CONFIG_SPL=y
++CONFIG_MACH_SUN8I_R528=y
++CONFIG_CONS_INDEX=4
++CONFIG_MMC0_CD_PIN="PF6"
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_SYS_MONITOR_LEN=786432
++CONFIG_DRAM_CLK=792
++CONFIG_DRAM_ZQ=8092667
++CONFIG_DRAM_SUNXI_ODT_EN=0
++CONFIG_DRAM_SUNXI_TPR0=0x004a2195
++CONFIG_DRAM_SUNXI_TPR11=0x340000
++CONFIG_DRAM_SUNXI_TPR12=0x46
++CONFIG_DRAM_SUNXI_TPR13=0x34000100
++CONFIG_UART3_PINS_PE=y
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4033-net-add-ICPlus-PHY-driver.patch b/package/boot/uboot-sunxi/patches/4033-net-add-ICPlus-PHY-driver.patch
new file mode 100644 (file)
index 0000000..210ff9e
--- /dev/null
@@ -0,0 +1,174 @@
+From daa5621013e06419c90bf27b5c88b8036af2b3da Mon Sep 17 00:00:00 2001
+From: Yegor Yefremov <yegorslists@googlemail.com>
+Date: Wed, 28 Nov 2012 11:15:18 +0100
+Subject: [PATCH 4033/4044] net: add ICPlus PHY driver
+
+The driver code was taken from Linux kernel source:
+drivers/net/phy/icplus.c
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
+---
+ drivers/net/phy/Kconfig  |  3 ++
+ drivers/net/phy/Makefile |  1 +
+ drivers/net/phy/icplus.c | 94 ++++++++++++++++++++++++++++++++++++++++
+ drivers/net/phy/phy.c    |  3 ++
+ include/phy.h            |  1 +
+ 5 files changed, 102 insertions(+)
+ create mode 100644 drivers/net/phy/icplus.c
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 5eaff053a0..93980398f1 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -165,6 +165,9 @@ config PHY_DAVICOM
+ config PHY_ET1011C
+       bool "LSI TruePHY ET1011C support"
++config PHY_ICPLUS
++      bool "IC+ IP101 Ethernet PHY support"
++
+ config PHY_LXT
+       bool "LXT971 Ethernet PHY support"
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index d38e99e717..5b6b78631d 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -18,6 +18,7 @@ obj-$(CONFIG_PHY_CORTINA) += cortina.o
+ obj-$(CONFIG_PHY_CORTINA_ACCESS) += ca_phy.o
+ obj-$(CONFIG_PHY_DAVICOM) += davicom.o
+ obj-$(CONFIG_PHY_ET1011C) += et1011c.o
++obj-$(CONFIG_PHY_ICPLUS) += icplus.o
+ obj-$(CONFIG_PHY_LXT) += lxt.o
+ obj-$(CONFIG_PHY_MARVELL) += marvell.o
+ obj-$(CONFIG_PHY_MICREL_KSZ8XXX) += micrel_ksz8xxx.o
+diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
+new file mode 100644
+index 0000000000..dd5c59259d
+--- /dev/null
++++ b/drivers/net/phy/icplus.c
+@@ -0,0 +1,94 @@
++/*
++ * ICPlus PHY drivers
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ * Copyright (c) 2007 Freescale Semiconductor, Inc.
++ *
++ */
++#include <phy.h>
++
++/* IP101A/G - IP1001 */
++#define IP10XX_SPEC_CTRL_STATUS         16      /* Spec. Control Register */
++#define IP1001_SPEC_CTRL_STATUS_2       20      /* IP1001 Spec. Control Reg 2 */
++#define IP1001_PHASE_SEL_MASK           3       /* IP1001 RX/TXPHASE_SEL */
++#define IP1001_APS_ON                   11      /* IP1001 APS Mode  bit */
++#define IP101A_G_APS_ON                 2       /* IP101A/G APS Mode bit */
++#define IP101A_G_IRQ_CONF_STATUS        0x11    /* Conf Info IRQ & Status Reg */
++#define IP101A_G_IRQ_PIN_USED           (1<<15) /* INTR pin used */
++#define IP101A_G_IRQ_DEFAULT            IP101A_G_IRQ_PIN_USED
++
++static int ip1001_config(struct phy_device *phydev)
++{
++      int c;
++
++      /* Enable Auto Power Saving mode */
++      c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2);
++      if (c < 0)
++              return c;
++      c |= IP1001_APS_ON;
++      c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c);
++      if (c < 0)
++              return c;
++
++      /* INTR pin used: speed/link/duplex will cause an interrupt */
++      c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS,
++                    IP101A_G_IRQ_DEFAULT);
++      if (c < 0)
++              return c;
++
++      if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
++              /*
++               * Additional delay (2ns) used to adjust RX clock phase
++               * at RGMII interface
++               */
++              c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS);
++              if (c < 0)
++                      return c;
++
++              c |= IP1001_PHASE_SEL_MASK;
++              c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS,
++                            c);
++              if (c < 0)
++                      return c;
++      }
++
++      return 0;
++}
++
++static int ip1001_startup(struct phy_device *phydev)
++{
++      genphy_update_link(phydev);
++      genphy_parse_link(phydev);
++
++      return 0;
++}
++static struct phy_driver IP1001_driver = {
++      .name = "ICPlus IP1001",
++      .uid = 0x02430d90,
++      .mask = 0x0ffffff0,
++      .features = PHY_GBIT_FEATURES,
++      .config = &ip1001_config,
++      .startup = &ip1001_startup,
++      .shutdown = &genphy_shutdown,
++};
++
++int phy_icplus_init(void)
++{
++      phy_register(&IP1001_driver);
++
++      return 0;
++}
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index 80230b907c..9e22db3fc8 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -514,6 +514,9 @@ int phy_init(void)
+ #ifdef CONFIG_PHY_ET1011C
+       phy_et1011c_init();
+ #endif
++#ifdef CONFIG_PHY_ICPLUS
++      phy_icplus_init();
++#endif
+ #ifdef CONFIG_PHY_LXT
+       phy_lxt_init();
+ #endif
+diff --git a/include/phy.h b/include/phy.h
+index 87aa86c2e7..749285f15e 100644
+--- a/include/phy.h
++++ b/include/phy.h
+@@ -325,6 +325,7 @@ int phy_cortina_init(void);
+ int phy_cortina_access_init(void);
+ int phy_davicom_init(void);
+ int phy_et1011c_init(void);
++int phy_icplus_init(void);
+ int phy_lxt_init(void);
+ int phy_marvell_init(void);
+ int phy_micrel_ksz8xxx_init(void);
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4034-sunxi-enable-emac-on-Rongpin-RP-T113.patch b/package/boot/uboot-sunxi/patches/4034-sunxi-enable-emac-on-Rongpin-RP-T113.patch
new file mode 100644 (file)
index 0000000..31ec113
--- /dev/null
@@ -0,0 +1,93 @@
+From 7d987c1284c883d31090e940dbec78fb2a66ea60 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sun, 4 Jun 2023 15:40:42 +0200
+Subject: [PATCH 4034/4044] sunxi: enable emac on Rongpin RP-T113
+
+The emac is connected to an IC+ IP101 PHY, for which the driver
+has been re-added (it was removed in 2014).
+
+Currently the driver init fails with the below, so further tweaking
+will be required.
+
+CPU:   Allwinner R528 (SUN8I)
+Model: Rongpin RP-T113
+DRAM:  128 MiB
+Core:  36 devices, 15 uclasses, devicetree: separate
+MMC:   mmc@4020000: 0, mmc@4022000: 1
+Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1...
+In:    serial@2500c00
+Out:   serial@2500c00
+Err:   serial@2500c00
+Net:   eth_sun8i_emac ethernet@4500000: failed to get TX clock
+No ethernet found.
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts | 28 ++++++++++++++++++++
+ configs/rongpin_rp_t113_defconfig            |  3 +++
+ 2 files changed, 31 insertions(+)
+
+diff --git a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
+index 6ac2c065c4..f2521438fb 100644
+--- a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
++++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
+@@ -54,6 +54,16 @@
+               regulator-max-microvolt = <2800000>;
+               vin-supply = <&reg_3v3>;
+       };
++
++        reg_gmac_3v3: gmac-3v3 {
++                compatible = "regulator-fixed";
++                regulator-name = "gmac-3v3";
++                regulator-min-microvolt = <3300000>;
++                regulator-max-microvolt = <3300000>;
++                startup-delay-us = <100000>;
++                enable-active-high;
++                gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
++      };
+ };
+ &cpu0 {
+@@ -78,6 +88,17 @@
+       status = "okay";
+ };
++&emac {
++      pinctrl-names = "default";
++      pinctrl-0 = <&rmii_pe_pins>;
++
++      phy-supply = <&reg_3v3>;
++      phy-handle = <&ext_rgmii_phy>;
++      phy-mode = "rmii";
++
++      status = "okay";
++};
++
+ &mmc0 {
+       pinctrl-0 = <&mmc0_pins>;
+       pinctrl-names = "default";
+@@ -96,3 +117,10 @@
+       bus-width = <4>;
+       status = "okay";
+ };
++
++&mdio {
++      ext_rgmii_phy: ethernet-phy@1 {
++              compatible = "ethernet-phy-ieee802.3-c22";
++              reg = <1>;
++      };
++};
+diff --git a/configs/rongpin_rp_t113_defconfig b/configs/rongpin_rp_t113_defconfig
+index 9b5a5bcd65..e234934f50 100644
+--- a/configs/rongpin_rp_t113_defconfig
++++ b/configs/rongpin_rp_t113_defconfig
+@@ -16,3 +16,6 @@ CONFIG_DRAM_SUNXI_TPR11=0x340000
+ CONFIG_DRAM_SUNXI_TPR12=0x46
+ CONFIG_DRAM_SUNXI_TPR13=0x34000100
+ CONFIG_UART3_PINS_PE=y
++CONFIG_SUN8I_EMAC=y
++CONFIG_PHY_ICPLUS=y
++CONFIG_RMII=y
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4035-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethe.patch b/package/boot/uboot-sunxi/patches/4035-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethe.patch
new file mode 100644 (file)
index 0000000..4bc5653
--- /dev/null
@@ -0,0 +1,493 @@
+From 1b83ab458f7e8971576c9f1ac884eb9e6de4d0cd Mon Sep 17 00:00:00 2001
+From: Yanhong Wang <yanhong.wang@starfivetech.com>
+Date: Thu, 25 May 2023 17:36:27 +0800
+Subject: [PATCH 4035/4044] net: phy: Add driver for Motorcomm yt8531 gigabit
+ ethernet phy
+
+Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have
+verified the driver on StarFive VisionFive2 board.
+
+Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
+Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
+---
+ drivers/net/phy/Kconfig     |   6 +
+ drivers/net/phy/Makefile    |   1 +
+ drivers/net/phy/motorcomm.c | 437 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 444 insertions(+)
+ create mode 100644 drivers/net/phy/motorcomm.c
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 93980398f1..0a99682c27 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -215,6 +215,12 @@ config PHY_MICREL_KSZ8XXX
+ endif # PHY_MICREL
++config PHY_MOTORCOMM
++      tristate "Motorcomm PHYs"
++      help
++        Enables support for Motorcomm network PHYs.
++        Currently supports the YT8531 Gigabit Ethernet PHYs.
++
+ config PHY_MSCC
+       bool "Microsemi Corp Ethernet PHYs support"
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index 5b6b78631d..9637a138f8 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -24,6 +24,7 @@ obj-$(CONFIG_PHY_MARVELL) += marvell.o
+ obj-$(CONFIG_PHY_MICREL_KSZ8XXX) += micrel_ksz8xxx.o
+ obj-$(CONFIG_PHY_MICREL_KSZ90X1) += micrel_ksz90x1.o
+ obj-$(CONFIG_PHY_MESON_GXL) += meson-gxl.o
++obj-$(CONFIG_PHY_MOTORCOMM) += motorcomm.o
+ obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
+ obj-$(CONFIG_PHY_NXP_C45_TJA11XX) += nxp-c45-tja11xx.o
+ obj-$(CONFIG_PHY_NXP_TJA11XX) += nxp-tja11xx.o
+diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
+new file mode 100644
+index 0000000000..e822fd76f2
+--- /dev/null
++++ b/drivers/net/phy/motorcomm.c
+@@ -0,0 +1,437 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Motorcomm 8531 PHY driver.
++ *
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++#include <config.h>
++#include <common.h>
++#include <malloc.h>
++#include <phy.h>
++#include <linux/bitfield.h>
++
++#define PHY_ID_YT8531                         0x4f51e91b
++#define PHY_ID_MASK                           GENMASK(31, 0)
++
++/* Extended Register's Address Offset Register */
++#define YTPHY_PAGE_SELECT                     0x1E
++
++/* Extended Register's Data Register */
++#define YTPHY_PAGE_DATA                       0x1F
++
++#define YTPHY_SYNCE_CFG_REG                   0xA012
++
++#define YTPHY_DTS_OUTPUT_CLK_DIS              0
++#define YTPHY_DTS_OUTPUT_CLK_25M              25000000
++#define YTPHY_DTS_OUTPUT_CLK_125M             125000000
++
++#define YT8531_SCR_SYNCE_ENABLE               BIT(6)
++/* 1b0 output 25m clock   *default*
++ * 1b1 output 125m clock
++ */
++#define YT8531_SCR_CLK_FRE_SEL_125M           BIT(4)
++#define YT8531_SCR_CLK_SRC_MASK               GENMASK(3, 1)
++#define YT8531_SCR_CLK_SRC_PLL_125M           0
++#define YT8531_SCR_CLK_SRC_UTP_RX             1
++#define YT8531_SCR_CLK_SRC_SDS_RX             2
++#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3
++#define YT8531_SCR_CLK_SRC_REF_25M            4
++#define YT8531_SCR_CLK_SRC_SSC_25M            5
++
++/* 1b0 use original tx_clk_rgmii  *default*
++ * 1b1 use inverted tx_clk_rgmii.
++ */
++#define YT8531_RC1R_TX_CLK_SEL_INVERTED       BIT(14)
++#define YT8531_RC1R_RX_DELAY_MASK             GENMASK(13, 10)
++#define YT8531_RC1R_FE_TX_DELAY_MASK          GENMASK(7, 4)
++#define YT8531_RC1R_GE_TX_DELAY_MASK          GENMASK(3, 0)
++#define YT8531_RC1R_RGMII_0_000_NS            0
++#define YT8531_RC1R_RGMII_0_150_NS            1
++#define YT8531_RC1R_RGMII_0_300_NS            2
++#define YT8531_RC1R_RGMII_0_450_NS            3
++#define YT8531_RC1R_RGMII_0_600_NS            4
++#define YT8531_RC1R_RGMII_0_750_NS            5
++#define YT8531_RC1R_RGMII_0_900_NS            6
++#define YT8531_RC1R_RGMII_1_050_NS            7
++#define YT8531_RC1R_RGMII_1_200_NS            8
++#define YT8531_RC1R_RGMII_1_350_NS            9
++#define YT8531_RC1R_RGMII_1_500_NS            10
++#define YT8531_RC1R_RGMII_1_650_NS            11
++#define YT8531_RC1R_RGMII_1_800_NS            12
++#define YT8531_RC1R_RGMII_1_950_NS            13
++#define YT8531_RC1R_RGMII_2_100_NS            14
++#define YT8531_RC1R_RGMII_2_250_NS            15
++
++/* Phy gmii clock gating Register */
++#define YT8531_CLOCK_GATING_REG               0xC
++#define YT8531_CGR_RX_CLK_EN                  BIT(12)
++
++/* Specific Status Register */
++#define YTPHY_SPECIFIC_STATUS_REG             0x11
++#define YTPHY_DUPLEX_MASK                     BIT(13)
++#define YTPHY_DUPLEX_SHIFT                    13
++#define YTPHY_SPEED_MODE_MASK                 GENMASK(15, 14)
++#define YTPHY_SPEED_MODE_SHIFT                        14
++
++#define YT8531_EXTREG_SLEEP_CONTROL1_REG      0x27
++#define YT8531_ESC1R_SLEEP_SW                 BIT(15)
++#define YT8531_ESC1R_PLLON_SLP                        BIT(14)
++
++#define YT8531_RGMII_CONFIG1_REG              0xA003
++
++#define YT8531_CHIP_CONFIG_REG                        0xA001
++#define YT8531_CCR_SW_RST                     BIT(15)
++/* 1b0 disable 1.9ns rxc clock delay  *default*
++ * 1b1 enable 1.9ns rxc clock delay
++ */
++#define YT8531_CCR_RXC_DLY_EN                 BIT(8)
++#define YT8531_CCR_RXC_DLY_1_900_NS           1900
++
++/* bits in struct ytphy_plat_priv->flag */
++#define TX_CLK_ADJ_ENABLED                    BIT(0)
++#define AUTO_SLEEP_DISABLED                   BIT(1)
++#define KEEP_PLL_ENABLED                      BIT(2)
++#define TX_CLK_10_INVERTED                    BIT(3)
++#define TX_CLK_100_INVERTED                   BIT(4)
++#define TX_CLK_1000_INVERTED                  BIT(5)
++
++struct ytphy_plat_priv {
++      u32 rx_delay_ps;
++      u32 tx_delay_ps;
++      u32 clk_out_frequency;
++      u32 flag;
++};
++
++/**
++ * struct ytphy_cfg_reg_map - map a config value to a register value
++ * @cfg: value in device configuration
++ * @reg: value in the register
++ */
++struct ytphy_cfg_reg_map {
++      u32 cfg;
++      u32 reg;
++};
++
++static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = {
++      /* for tx delay / rx delay with YT8531_CCR_RXC_DLY_EN is not set. */
++      { 0,    YT8531_RC1R_RGMII_0_000_NS },
++      { 150,  YT8531_RC1R_RGMII_0_150_NS },
++      { 300,  YT8531_RC1R_RGMII_0_300_NS },
++      { 450,  YT8531_RC1R_RGMII_0_450_NS },
++      { 600,  YT8531_RC1R_RGMII_0_600_NS },
++      { 750,  YT8531_RC1R_RGMII_0_750_NS },
++      { 900,  YT8531_RC1R_RGMII_0_900_NS },
++      { 1050, YT8531_RC1R_RGMII_1_050_NS },
++      { 1200, YT8531_RC1R_RGMII_1_200_NS },
++      { 1350, YT8531_RC1R_RGMII_1_350_NS },
++      { 1500, YT8531_RC1R_RGMII_1_500_NS },
++      { 1650, YT8531_RC1R_RGMII_1_650_NS },
++      { 1800, YT8531_RC1R_RGMII_1_800_NS },
++      { 1950, YT8531_RC1R_RGMII_1_950_NS },   /* default tx/rx delay */
++      { 2100, YT8531_RC1R_RGMII_2_100_NS },
++      { 2250, YT8531_RC1R_RGMII_2_250_NS },
++
++      /* only for rx delay with YT8531_CCR_RXC_DLY_EN is set. */
++      { 0    + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_000_NS },
++      { 150  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_150_NS },
++      { 300  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_300_NS },
++      { 450  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_450_NS },
++      { 600  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_600_NS },
++      { 750  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_750_NS },
++      { 900  + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_0_900_NS },
++      { 1050 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_050_NS },
++      { 1200 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_200_NS },
++      { 1350 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_350_NS },
++      { 1500 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_500_NS },
++      { 1650 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_650_NS },
++      { 1800 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_800_NS },
++      { 1950 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_1_950_NS },
++      { 2100 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_2_100_NS },
++      { 2250 + YT8531_CCR_RXC_DLY_1_900_NS,   YT8531_RC1R_RGMII_2_250_NS }
++};
++
++static u32 ytphy_get_delay_reg_value(struct phy_device *phydev,
++                                   u32 val,
++                                   u16 *rxc_dly_en)
++{
++      int tb_size = ARRAY_SIZE(ytphy_rgmii_delays);
++      int tb_size_half = tb_size / 2;
++      int i;
++
++      /* when rxc_dly_en is NULL, it is get the delay for tx, only half of
++       * tb_size is valid.
++       */
++      if (!rxc_dly_en)
++              tb_size = tb_size_half;
++
++      for (i = 0; i < tb_size; i++) {
++              if (ytphy_rgmii_delays[i].cfg == val) {
++                      if (rxc_dly_en && i < tb_size_half)
++                              *rxc_dly_en = 0;
++                      return ytphy_rgmii_delays[i].reg;
++              }
++      }
++
++      pr_warn("Unsupported value %d, using default (%u)\n",
++              val, YT8531_RC1R_RGMII_1_950_NS);
++
++      /* when rxc_dly_en is not NULL, it is get the delay for rx.
++       * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps,
++       * so YT8531_CCR_RXC_DLY_EN should not be set.
++       */
++      if (rxc_dly_en)
++              *rxc_dly_en = 0;
++
++      return YT8531_RC1R_RGMII_1_950_NS;
++}
++
++static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
++                          u16 set)
++{
++      int ret;
++
++      ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
++      if (ret < 0)
++              return ret;
++
++      return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
++}
++
++static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
++{
++      struct ytphy_plat_priv  *priv = phydev->priv;
++      u16 rxc_dly_en = YT8531_CCR_RXC_DLY_EN;
++      u32 rx_reg, tx_reg;
++      u16 mask, val = 0;
++      int ret;
++
++      rx_reg = ytphy_get_delay_reg_value(phydev, priv->rx_delay_ps,
++                                         &rxc_dly_en);
++      tx_reg = ytphy_get_delay_reg_value(phydev, priv->tx_delay_ps,
++                                         NULL);
++
++      switch (phydev->interface) {
++      case PHY_INTERFACE_MODE_RGMII:
++              rxc_dly_en = 0;
++              break;
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++              val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg);
++              break;
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++              rxc_dly_en = 0;
++              val |= FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
++              break;
++      case PHY_INTERFACE_MODE_RGMII_ID:
++              val |= FIELD_PREP(YT8531_RC1R_RX_DELAY_MASK, rx_reg) |
++                     FIELD_PREP(YT8531_RC1R_GE_TX_DELAY_MASK, tx_reg);
++              break;
++      default: /* do not support other modes */
++              return -EOPNOTSUPP;
++      }
++
++      ret = ytphy_modify_ext(phydev, YT8531_CHIP_CONFIG_REG,
++                             YT8531_CCR_RXC_DLY_EN, rxc_dly_en);
++      if (ret < 0)
++              return ret;
++
++      /* Generally, it is not necessary to adjust YT8531_RC1R_FE_TX_DELAY */
++      mask = YT8531_RC1R_RX_DELAY_MASK | YT8531_RC1R_GE_TX_DELAY_MASK;
++      return ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG, mask, val);
++}
++
++static int yt8531_parse_status(struct phy_device *phydev)
++{
++      int val;
++      int speed, speed_mode;
++
++      val = phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_SPECIFIC_STATUS_REG);
++      if (val < 0)
++              return val;
++
++      speed_mode = (val & YTPHY_SPEED_MODE_MASK) >> YTPHY_SPEED_MODE_SHIFT;
++      switch (speed_mode) {
++      case 2:
++              speed = SPEED_1000;
++              break;
++      case 1:
++              speed = SPEED_100;
++              break;
++      default:
++              speed = SPEED_10;
++              break;
++      }
++
++      phydev->speed = speed;
++      phydev->duplex = (val & YTPHY_DUPLEX_MASK) >> YTPHY_DUPLEX_SHIFT;
++
++      return 0;
++}
++
++static int yt8531_startup(struct phy_device *phydev)
++{
++      struct ytphy_plat_priv  *priv = phydev->priv;
++      u16 val = 0;
++      int ret;
++
++      ret = genphy_update_link(phydev);
++      if (ret)
++              return ret;
++
++      ret = yt8531_parse_status(phydev);
++      if (ret)
++              return ret;
++
++      if (phydev->speed < 0)
++              return -EINVAL;
++
++      if (!(priv->flag & TX_CLK_ADJ_ENABLED))
++              return 0;
++
++      switch (phydev->speed) {
++      case SPEED_1000:
++              if (priv->flag & TX_CLK_1000_INVERTED)
++                      val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
++              break;
++      case SPEED_100:
++              if (priv->flag & TX_CLK_100_INVERTED)
++                      val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
++              break;
++      case SPEED_10:
++              if (priv->flag & TX_CLK_10_INVERTED)
++                      val = YT8531_RC1R_TX_CLK_SEL_INVERTED;
++              break;
++      default:
++              printf("UNKNOWN SPEED\n");
++              return -EINVAL;
++      }
++
++      ret = ytphy_modify_ext(phydev, YT8531_RGMII_CONFIG1_REG,
++                             YT8531_RC1R_TX_CLK_SEL_INVERTED, val);
++      if (ret < 0)
++              pr_warn("Modify TX_CLK_SEL err:%d\n", ret);
++
++      return 0;
++}
++
++static void ytphy_dt_parse(struct phy_device *phydev)
++{
++      struct ytphy_plat_priv  *priv = phydev->priv;
++
++      priv->clk_out_frequency = ofnode_read_u32_default(phydev->node,
++                                                        "motorcomm,clk-out-frequency-hz",
++                                                        YTPHY_DTS_OUTPUT_CLK_DIS);
++      priv->rx_delay_ps = ofnode_read_u32_default(phydev->node,
++                                                  "rx-internal-delay-ps",
++                                                  YT8531_RC1R_RGMII_1_950_NS);
++      priv->tx_delay_ps = ofnode_read_u32_default(phydev->node,
++                                                  "tx-internal-delay-ps",
++                                                  YT8531_RC1R_RGMII_1_950_NS);
++
++      if (ofnode_read_bool(phydev->node, "motorcomm,auto-sleep-disabled"))
++              priv->flag |= AUTO_SLEEP_DISABLED;
++
++      if (ofnode_read_bool(phydev->node, "motorcomm,keep-pll-enabled"))
++              priv->flag |= KEEP_PLL_ENABLED;
++
++      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-adj-enabled"))
++              priv->flag |= TX_CLK_ADJ_ENABLED;
++
++      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-10-inverted"))
++              priv->flag |= TX_CLK_10_INVERTED;
++
++      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-100-inverted"))
++              priv->flag |= TX_CLK_100_INVERTED;
++
++      if (ofnode_read_bool(phydev->node, "motorcomm,tx-clk-1000-inverted"))
++              priv->flag |= TX_CLK_1000_INVERTED;
++}
++
++static int yt8531_config(struct phy_device *phydev)
++{
++      struct ytphy_plat_priv  *priv = phydev->priv;
++      u16 mask, val;
++      int ret;
++
++      ret = genphy_config_aneg(phydev);
++      if (ret < 0)
++              return ret;
++
++      ytphy_dt_parse(phydev);
++      switch (priv->clk_out_frequency) {
++      case YTPHY_DTS_OUTPUT_CLK_DIS:
++              mask = YT8531_SCR_SYNCE_ENABLE;
++              val = 0;
++              break;
++      case YTPHY_DTS_OUTPUT_CLK_25M:
++              mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
++                         YT8531_SCR_CLK_FRE_SEL_125M;
++              val = YT8531_SCR_SYNCE_ENABLE |
++                        FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
++                                   YT8531_SCR_CLK_SRC_REF_25M);
++              break;
++      case YTPHY_DTS_OUTPUT_CLK_125M:
++              mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK |
++                         YT8531_SCR_CLK_FRE_SEL_125M;
++              val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M |
++                        FIELD_PREP(YT8531_SCR_CLK_SRC_MASK,
++                                   YT8531_SCR_CLK_SRC_PLL_125M);
++              break;
++      default:
++              pr_warn("Freq err:%u\n", priv->clk_out_frequency);
++              return -EINVAL;
++      }
++
++      ret = ytphy_modify_ext(phydev, YTPHY_SYNCE_CFG_REG, mask,
++                             val);
++      if (ret < 0)
++              return ret;
++
++      ret = ytphy_rgmii_clk_delay_config(phydev);
++      if (ret < 0)
++              return ret;
++
++      if (priv->flag & AUTO_SLEEP_DISABLED) {
++              /* disable auto sleep */
++              ret = ytphy_modify_ext(phydev,
++                                     YT8531_EXTREG_SLEEP_CONTROL1_REG,
++                                     YT8531_ESC1R_SLEEP_SW, 0);
++              if (ret < 0)
++                      return ret;
++      }
++
++      if (priv->flag & KEEP_PLL_ENABLED) {
++              /* enable RXC clock when no wire plug */
++              ret = ytphy_modify_ext(phydev,
++                                     YT8531_CLOCK_GATING_REG,
++                                     YT8531_CGR_RX_CLK_EN, 0);
++              if (ret < 0)
++                      return ret;
++      }
++
++      return 0;
++}
++
++static int yt8531_probe(struct phy_device *phydev)
++{
++      struct ytphy_plat_priv  *priv;
++
++      priv = calloc(1, sizeof(struct ytphy_plat_priv));
++      if (!priv)
++              return -ENOMEM;
++
++      phydev->priv = priv;
++
++      return 0;
++}
++
++U_BOOT_PHY_DRIVER(motorcomm8531) = {
++      .name          = "YT8531 Gigabit Ethernet",
++      .uid           = PHY_ID_YT8531,
++      .mask          = PHY_ID_MASK,
++      .features      = PHY_GBIT_FEATURES,
++      .probe         = &yt8531_probe,
++      .config        = &yt8531_config,
++      .startup       = &yt8531_startup,
++      .shutdown      = &genphy_shutdown,
++};
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4036-sunxi-enable-gmac-on-MYIR-MYD-YT113X-with-the-YT8531.patch b/package/boot/uboot-sunxi/patches/4036-sunxi-enable-gmac-on-MYIR-MYD-YT113X-with-the-YT8531.patch
new file mode 100644 (file)
index 0000000..daf4281
--- /dev/null
@@ -0,0 +1,36 @@
+From 7530416165eb2a6c7378f7bb4a90fdf67439277d Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 5 Jun 2023 17:57:15 +0200
+Subject: [PATCH 4036/4044] sunxi: enable gmac on MYIR MYD-YT113X with the
+ YT8531 PHY
+
+The gmac is connected to a Motorcomm YT8531, for which the driver
+has been picked from Starfive and ported over.
+
+Support is not yet added in DTS, only for compile testing.
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ configs/myir_myd_t113x_defconfig | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/configs/myir_myd_t113x_defconfig b/configs/myir_myd_t113x_defconfig
+index 21f939272a..088196389a 100644
+--- a/configs/myir_myd_t113x_defconfig
++++ b/configs/myir_myd_t113x_defconfig
+@@ -17,3 +17,12 @@ CONFIG_DRAM_SUNXI_TPR12=0x46
+ CONFIG_DRAM_SUNXI_TPR13=0x34000100
+ CONFIG_USB_EHCI_HCD=y
+ CONFIG_USB_OHCI_HCD=y
++CONFIG_PHY_MOTORCOMM=y
++CONFIG_SUN8I_EMAC=y
++CONFIG_RGMII=y
++CONFIG_RMII=y
++CONFIG_SUPPORT_EMMC_BOOT=y
++CONFIG_MMC_IO_VOLTAGE=y
++CONFIG_SPL_MMC_IO_VOLTAGE=y
++CONFIG_MMC_HS200_SUPPORT=y
++CONFIG_SPL_MMC_HS200_SUPPORT=y
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4037-net-phy-backport-and-update-driver-for-Motorcomm-yt8.patch b/package/boot/uboot-sunxi/patches/4037-net-phy-backport-and-update-driver-for-Motorcomm-yt8.patch
new file mode 100644 (file)
index 0000000..f93b764
--- /dev/null
@@ -0,0 +1,68 @@
+From 05b11cc62c2c6e523636143b6db255fa98b77de3 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 5 Jun 2023 18:15:15 +0200
+Subject: [PATCH 4037/4044] net: phy: backport and update driver for Motorcomm
+ yt8531 phy
+
+Don't use U_BOOT_PHY_DRIVER yet.
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ drivers/net/phy/motorcomm.c | 9 ++++++++-
+ drivers/net/phy/phy.c       | 3 +++
+ include/phy.h               | 1 +
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
+index e822fd76f2..eb2dd65c4a 100644
+--- a/drivers/net/phy/motorcomm.c
++++ b/drivers/net/phy/motorcomm.c
+@@ -425,7 +425,7 @@ static int yt8531_probe(struct phy_device *phydev)
+       return 0;
+ }
+-U_BOOT_PHY_DRIVER(motorcomm8531) = {
++static struct phy_driver YT8531_driver =  {
+       .name          = "YT8531 Gigabit Ethernet",
+       .uid           = PHY_ID_YT8531,
+       .mask          = PHY_ID_MASK,
+@@ -435,3 +435,10 @@ U_BOOT_PHY_DRIVER(motorcomm8531) = {
+       .startup       = &yt8531_startup,
+       .shutdown      = &genphy_shutdown,
+ };
++
++int phy_motorcomm_init(void)
++{
++        phy_register(&YT8531_driver);
++
++        return 0;
++}
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index 9e22db3fc8..3613c3dd17 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -532,6 +532,9 @@ int phy_init(void)
+ #ifdef CONFIG_PHY_MESON_GXL
+       phy_meson_gxl_init();
+ #endif
++#ifdef CONFIG_PHY_MOTORCOMM
++      phy_motorcomm_init();
++#endif
+ #ifdef CONFIG_PHY_NATSEMI
+       phy_natsemi_init();
+ #endif
+diff --git a/include/phy.h b/include/phy.h
+index 749285f15e..05208d7f3d 100644
+--- a/include/phy.h
++++ b/include/phy.h
+@@ -331,6 +331,7 @@ int phy_marvell_init(void);
+ int phy_micrel_ksz8xxx_init(void);
+ int phy_micrel_ksz90x1_init(void);
+ int phy_meson_gxl_init(void);
++int phy_motorcomm_init(void);
+ int phy_natsemi_init(void);
+ int phy_nxp_c45_tja11xx_init(void);
+ int phy_nxp_tja11xx_init(void);
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4038-sunxi-rongpin-rp-t113-add-missing-gpio.h-include.patch b/package/boot/uboot-sunxi/patches/4038-sunxi-rongpin-rp-t113-add-missing-gpio.h-include.patch
new file mode 100644 (file)
index 0000000..7040d88
--- /dev/null
@@ -0,0 +1,25 @@
+From 808463e5b8f77b2daaa9a2a7d8aefbdbbad16141 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Mon, 5 Jun 2023 18:29:41 +0200
+Subject: [PATCH 4038/4044] sunxi: rongpin-rp-t113: add missing gpio.h include
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
+index f2521438fb..348ae5eec6 100644
+--- a/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
++++ b/arch/arm/dts/sun8i-t113s-rongpin-rp-t113.dts
+@@ -2,6 +2,7 @@
+ // Copyright (C) 2022 Arm Ltd.
+ #include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/gpio/gpio.h>
+ /dts-v1/;
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4039-sunxi-SPL-SPI-Add-SPI-boot-support-for-the-Allwinner.patch b/package/boot/uboot-sunxi/patches/4039-sunxi-SPL-SPI-Add-SPI-boot-support-for-the-Allwinner.patch
new file mode 100644 (file)
index 0000000..64bcc72
--- /dev/null
@@ -0,0 +1,206 @@
+From 2392217ef179219a41246e883a52dc64fcfede2a Mon Sep 17 00:00:00 2001
+From: Maxim Kiselev <bigunclemax@gmail.com>
+Date: Fri, 19 May 2023 16:40:07 +0300
+Subject: [PATCH 4039/4044] sunxi: SPL SPI: Add SPI boot support for the
+ Allwinner R528/T113 SoCs
+
+R528/T113 SoCs uses the same SPI IP as the H6, also have the same clocks
+and reset bits layout, but the CCU base is different. Another difference
+is that the new SoCs do not have a clock divider inside. Instead of this
+we should configure sample mode depending on input clock rate.
+
+The pin assignment is also different: the H6 uses PC0, the R528/T113 PC4
+instead. This makes for a change in spi0_pinmux_setup() routine.
+
+This patch extends the H6/H616 #ifdef guards to also cover the R528/T113,
+using the shared CONFIG_SUNXI_GEN_NCAT2 and CONFIG_MACH_SUN8I_R528
+symbols. Also use CONFIG_SUNXI_GEN_NCAT2 symbol for the Kconfig
+dependency.
+
+Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
+Tested-by: Sam Edwards <CFSworks@gmail.com>
+---
+ arch/arm/mach-sunxi/Kconfig         |  2 +-
+ arch/arm/mach-sunxi/spl_spi_sunxi.c | 78 +++++++++++++++++++++--------
+ 2 files changed, 58 insertions(+), 22 deletions(-)
+
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index 1ddf496a55..d914066298 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -1003,7 +1003,7 @@ config SPL_STACK_R_ADDR
+ config SPL_SPI_SUNXI
+       bool "Support for SPI Flash on Allwinner SoCs in SPL"
+-      depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV
++      depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV || SUNXI_GEN_NCAT2
+       help
+         Enable support for SPI Flash. This option allows SPL to read from
+         sunxi SPI Flash. It uses the same method as the boot ROM, so does
+diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
+index c2410dd7bb..3cfbf56d59 100644
+--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
++++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
+@@ -73,18 +73,27 @@
+ #define SUN6I_CTL_ENABLE            BIT(0)
+ #define SUN6I_CTL_MASTER            BIT(1)
+ #define SUN6I_CTL_SRST              BIT(31)
++#define SUN6I_TCR_SDM               BIT(13)
+ #define SUN6I_TCR_XCH               BIT(31)
+ /*****************************************************************************/
+-#define CCM_AHB_GATING0             (0x01C20000 + 0x60)
+-#define CCM_H6_SPI_BGR_REG          (0x03001000 + 0x96c)
+-#ifdef CONFIG_SUN50I_GEN_H6
+-#define CCM_SPI0_CLK                (0x03001000 + 0x940)
++#if defined(CONFIG_SUN50I_GEN_H6)
++#define CCM_BASE                    0x03001000
++#elif defined(CONFIG_SUNXI_GEN_NCAT2)
++#define CCM_BASE                    0x02001000
+ #else
+-#define CCM_SPI0_CLK                (0x01C20000 + 0xA0)
++#define CCM_BASE                    0x01C20000
+ #endif
+-#define SUN6I_BUS_SOFT_RST_REG0     (0x01C20000 + 0x2C0)
++
++#define CCM_AHB_GATING0             (CCM_BASE + 0x60)
++#define CCM_H6_SPI_BGR_REG          (CCM_BASE + 0x96c)
++#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
++#define CCM_SPI0_CLK                (CCM_BASE + 0x940)
++#else
++#define CCM_SPI0_CLK                (CCM_BASE + 0xA0)
++#endif
++#define SUN6I_BUS_SOFT_RST_REG0     (CCM_BASE + 0x2C0)
+ #define AHB_RESET_SPI0_SHIFT        20
+ #define AHB_GATE_OFFSET_SPI0        20
+@@ -102,17 +111,22 @@
+  */
+ static void spi0_pinmux_setup(unsigned int pin_function)
+ {
+-      /* All chips use PC0 and PC2. */
+-      sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function);
++      /* All chips use PC2. And all chips use PC0, except R528/T113 */
++      if (!IS_ENABLED(CONFIG_MACH_SUN8I_R528))
++              sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function);
++
+       sunxi_gpio_set_cfgpin(SUNXI_GPC(2), pin_function);
+-      /* All chips except H6 and H616 use PC1. */
+-      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
++      /* All chips except H6/H616/R528/T113 use PC1. */
++      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) &&
++          !IS_ENABLED(CONFIG_MACH_SUN8I_R528))
+               sunxi_gpio_set_cfgpin(SUNXI_GPC(1), pin_function);
+-      if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
++      if (IS_ENABLED(CONFIG_MACH_SUN50I_H6) ||
++          IS_ENABLED(CONFIG_MACH_SUN8I_R528))
+               sunxi_gpio_set_cfgpin(SUNXI_GPC(5), pin_function);
+-      if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
++      if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
++          IS_ENABLED(CONFIG_MACH_SUN8I_R528))
+               sunxi_gpio_set_cfgpin(SUNXI_GPC(4), pin_function);
+       /* Older generations use PC23 for CS, newer ones use PC3. */
+@@ -126,7 +140,8 @@ static void spi0_pinmux_setup(unsigned int pin_function)
+ static bool is_sun6i_gen_spi(void)
+ {
+       return IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ||
+-             IS_ENABLED(CONFIG_SUN50I_GEN_H6);
++             IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
++             IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2);
+ }
+ static uintptr_t spi0_base_address(void)
+@@ -137,6 +152,9 @@ static uintptr_t spi0_base_address(void)
+       if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
+               return 0x05010000;
++      if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
++              return 0x04025000;
++
+       if (!is_sun6i_gen_spi() ||
+           IS_ENABLED(CONFIG_MACH_SUNIV))
+               return 0x01C05000;
+@@ -152,23 +170,30 @@ static void spi0_enable_clock(void)
+       uintptr_t base = spi0_base_address();
+       /* Deassert SPI0 reset on SUN6I */
+-      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
++      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
++          IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
+               setbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1);
+       else if (is_sun6i_gen_spi())
+               setbits_le32(SUN6I_BUS_SOFT_RST_REG0,
+                            (1 << AHB_RESET_SPI0_SHIFT));
+       /* Open the SPI0 gate */
+-      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
++      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) &&
++          !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
+               setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
+       if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
+               /* Divide by 32, clock source is AHB clock 200MHz */
+               writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL);
+       } else {
+-              /* Divide by 4 */
+-              writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
+-                                        SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
++              /* New SoCs do not have a clock divider inside */
++              if (!IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) {
++                      /* Divide by 4 */
++                      writel(SPI0_CLK_DIV_BY_4,
++                             base + (is_sun6i_gen_spi() ? SUN6I_SPI0_CCTL :
++                             SUN4I_SPI0_CCTL));
++              }
++
+               /* 24MHz from OSC24M */
+               writel((1 << 31), CCM_SPI0_CLK);
+       }
+@@ -180,6 +205,14 @@ static void spi0_enable_clock(void)
+               /* Wait for completion */
+               while (readl(base + SUN6I_SPI0_GCR) & SUN6I_CTL_SRST)
+                       ;
++
++              /*
++               * For new SoCs we should configure sample mode depending on
++               * input clock. As 24MHz from OSC24M is used, we could use
++               * normal sample mode by setting SDM bit in the TCR register
++               */
++              if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
++                      setbits_le32(base + SUN6I_SPI0_TCR, SUN6I_TCR_SDM);
+       } else {
+               /* Enable SPI in the master mode and reset FIFO */
+               setbits_le32(base + SUN4I_SPI0_CTL, SUN4I_CTL_MASTER |
+@@ -206,11 +239,13 @@ static void spi0_disable_clock(void)
+               writel(0, CCM_SPI0_CLK);
+       /* Close the SPI0 gate */
+-      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
++      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) &&
++          !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
+               clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
+       /* Assert SPI0 reset on SUN6I */
+-      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
++      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
++          IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
+               clrbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1);
+       else if (is_sun6i_gen_spi())
+               clrbits_le32(SUN6I_BUS_SOFT_RST_REG0,
+@@ -224,7 +259,8 @@ static void spi0_init(void)
+       if (IS_ENABLED(CONFIG_MACH_SUN50I) ||
+           IS_ENABLED(CONFIG_SUN50I_GEN_H6))
+               pin_function = SUN50I_GPC_SPI0;
+-      else if (IS_ENABLED(CONFIG_MACH_SUNIV))
++      else if (IS_ENABLED(CONFIG_MACH_SUNIV) ||
++               IS_ENABLED(CONFIG_MACH_SUN8I_R528))
+               pin_function = SUNIV_GPC_SPI0;
+       spi0_pinmux_setup(pin_function);
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4040-spi-sunxi-Add-support-for-R329-D1-R528-T113-SPI-cont.patch b/package/boot/uboot-sunxi/patches/4040-spi-sunxi-Add-support-for-R329-D1-R528-T113-SPI-cont.patch
new file mode 100644 (file)
index 0000000..373e784
--- /dev/null
@@ -0,0 +1,122 @@
+From 805c9053f77e86e442f7a76832ea259695918a8c Mon Sep 17 00:00:00 2001
+From: Maxim Kiselev <bigunclemax@gmail.com>
+Date: Fri, 19 May 2023 16:40:08 +0300
+Subject: [PATCH 4040/4044] spi: sunxi: Add support for R329/D1/R528/T113 SPI
+ controller
+
+These SoCs have two SPI controllers that are quite similar to the SPI
+on previous Allwinner SoCs. The main difference is that new SoCs
+don't have a clock divider (SPI_CCR register) inside SPI IP.
+
+Instead SPI sample mode should be configured depending on the input clock.
+
+For now SPI input clock source selection is not supported by this driver,
+and only HOSC@24MHz can be used as input clock. Therefore, according to
+the, manual we could change the SPI sample mode from delay half
+cycle(default) to normal.
+
+This patch adds a quirk for this kind of SPI controllers
+
+Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
+Tested-by: Sam Edwards <CFSworks@gmail.com>
+---
+ drivers/spi/spi-sunxi.c | 34 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 33 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c
+index c56d82d998..9ec6b359e2 100644
+--- a/drivers/spi/spi-sunxi.c
++++ b/drivers/spi/spi-sunxi.c
+@@ -117,6 +117,8 @@ enum sun4i_spi_bits {
+       SPI_TCR_XCH,
+       SPI_TCR_CS_MANUAL,
+       SPI_TCR_CS_LEVEL,
++      SPI_TCR_SDC,
++      SPI_TCR_SDM,
+       SPI_FCR_TF_RST,
+       SPI_FCR_RF_RST,
+       SPI_FSR_RF_CNT_MASK,
+@@ -128,6 +130,7 @@ struct sun4i_spi_variant {
+       u32 fifo_depth;
+       bool has_soft_reset;
+       bool has_burst_ctl;
++      bool has_clk_ctl;
+ };
+ struct sun4i_spi_plat {
+@@ -302,7 +305,19 @@ static int sun4i_spi_claim_bus(struct udevice *dev)
+       setbits_le32(SPI_REG(priv, SPI_TCR), SPI_BIT(priv, SPI_TCR_CS_MANUAL) |
+                    SPI_BIT(priv, SPI_TCR_CS_ACTIVE_LOW));
+-      sun4i_spi_set_speed_mode(dev->parent);
++      if (priv->variant->has_clk_ctl) {
++              sun4i_spi_set_speed_mode(dev->parent);
++      } else {
++              /*
++               * At this moment there is no ability to change input clock.
++               * Therefore, we can only use default HOSC@24MHz clock and
++               * set SPI sampling mode to normal
++               */
++              clrsetbits_le32(SPI_REG(priv, SPI_TCR),
++                              SPI_BIT(priv, SPI_TCR_SDC) |
++                              SPI_BIT(priv, SPI_TCR_SDM),
++                              SPI_BIT(priv, SPI_TCR_SDM));
++      }
+       return 0;
+ }
+@@ -516,6 +531,8 @@ static const u32 sun6i_spi_bits[] = {
+       [SPI_TCR_CS_MASK]       = 0x30,
+       [SPI_TCR_CS_MANUAL]     = BIT(6),
+       [SPI_TCR_CS_LEVEL]      = BIT(7),
++      [SPI_TCR_SDC]           = BIT(11),
++      [SPI_TCR_SDM]           = BIT(13),
+       [SPI_TCR_XCH]           = BIT(31),
+       [SPI_FCR_RF_RST]        = BIT(15),
+       [SPI_FCR_TF_RST]        = BIT(31),
+@@ -526,6 +543,7 @@ static const struct sun4i_spi_variant sun4i_a10_spi_variant = {
+       .regs                   = sun4i_spi_regs,
+       .bits                   = sun4i_spi_bits,
+       .fifo_depth             = 64,
++      .has_clk_ctl            = true,
+ };
+ static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
+@@ -534,6 +552,7 @@ static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
+       .fifo_depth             = 128,
+       .has_soft_reset         = true,
+       .has_burst_ctl          = true,
++      .has_clk_ctl            = true,
+ };
+ static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
+@@ -542,6 +561,15 @@ static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
+       .fifo_depth             = 64,
+       .has_soft_reset         = true,
+       .has_burst_ctl          = true,
++      .has_clk_ctl            = true,
++};
++
++static const struct sun4i_spi_variant sun50i_r329_spi_variant = {
++      .regs                   = sun6i_spi_regs,
++      .bits                   = sun6i_spi_bits,
++      .fifo_depth             = 64,
++      .has_soft_reset         = true,
++      .has_burst_ctl          = true,
+ };
+ static const struct udevice_id sun4i_spi_ids[] = {
+@@ -557,6 +585,10 @@ static const struct udevice_id sun4i_spi_ids[] = {
+         .compatible = "allwinner,sun8i-h3-spi",
+         .data = (ulong)&sun8i_h3_spi_variant,
+       },
++      {
++        .compatible = "allwinner,sun50i-r329-spi",
++        .data = (ulong)&sun50i_r329_spi_variant,
++      },
+       { /* sentinel */ }
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4041-riscv-dts-allwinner-d1-Add-SPI-controllers-node.patch b/package/boot/uboot-sunxi/patches/4041-riscv-dts-allwinner-d1-Add-SPI-controllers-node.patch
new file mode 100644 (file)
index 0000000..90c015a
--- /dev/null
@@ -0,0 +1,77 @@
+From ae59ce94c3dd062bd6f371cef729664fea5c8c71 Mon Sep 17 00:00:00 2001
+From: Maxim Kiselev <bigunclemax@gmail.com>
+Date: Fri, 19 May 2023 16:40:09 +0300
+Subject: [PATCH 4041/4044] riscv: dts: allwinner: d1: Add SPI controllers node
+
+Some boards form the MangoPi family (MQ\MQ-Dual\MQ-R) may have
+an optional SPI flash that connects to the SPI0 controller.
+
+This controller is the same for R329/D1/R528/T113s SoCs and
+should be supported by the sun50i-r329-spi driver.
+
+So let's add its DT nodes.
+
+Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
+Reviewed-by: Sam Edwards <CFSworks@gmail.com>
+---
+ arch/riscv/dts/sunxi-d1s-t113.dtsi | 37 ++++++++++++++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+index b72bbc5e43..324353905f 100644
+--- a/arch/riscv/dts/sunxi-d1s-t113.dtsi
++++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+@@ -108,6 +108,12 @@
+                               function = "emac";
+                       };
++                      /omit-if-no-ref/
++                      spi0_pins: spi0-pins {
++                              pins = "PC2", "PC3", "PC4", "PC5";
++                              function = "spi0";
++                      };
++
+                       /omit-if-no-ref/
+                       uart1_pg6_pins: uart1-pg6-pins {
+                               pins = "PG6", "PG7";
+@@ -459,6 +465,37 @@
+                       #size-cells = <0>;
+               };
++              spi0: spi@4025000 {
++                      compatible = "allwinner,sun20i-d1-spi",
++                                   "allwinner,sun50i-r329-spi";
++                      reg = <0x04025000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(15) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
++                      clock-names = "ahb", "mod";
++                      dmas = <&dma 22>, <&dma 22>;
++                      dma-names = "rx", "tx";
++                      resets = <&ccu RST_BUS_SPI0>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              spi1: spi@4026000 {
++                      compatible = "allwinner,sun20i-d1-spi-dbi",
++                                   "allwinner,sun50i-r329-spi-dbi",
++                                   "allwinner,sun50i-r329-spi";
++                      reg = <0x04026000 0x1000>;
++                      interrupts = <SOC_PERIPHERAL_IRQ(16) IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
++                      clock-names = "ahb", "mod";
++                      dmas = <&dma 23>, <&dma 23>;
++                      dma-names = "rx", "tx";
++                      resets = <&ccu RST_BUS_SPI1>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
+               usb_otg: usb@4100000 {
+                       compatible = "allwinner,sun20i-d1-musb",
+                                    "allwinner,sun8i-a33-musb";
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4042-sunxi-add-MYIR-MYD-YT113X-SPI-board.patch b/package/boot/uboot-sunxi/patches/4042-sunxi-add-MYIR-MYD-YT113X-SPI-board.patch
new file mode 100644 (file)
index 0000000..b4e50e8
--- /dev/null
@@ -0,0 +1,140 @@
+From 433545eafc6867a9b468bb9cd805bce36e172cda Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 29 Jul 2023 11:23:47 +0200
+Subject: [PATCH 4042/4044] sunxi: add MYIR MYD-YT113X-SPI board
+
+Instead of eMMC, this board sports a 256Mb SPI NAND flash.
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/arm/dts/Makefile                         |  1 +
+ .../dts/sun8i-t113s-myir-myd-yt113x-spi.dts   | 59 +++++++++++++++++++
+ configs/myir_myd_t113x-spi_defconfig          | 38 ++++++++++++
+ 3 files changed, 98 insertions(+)
+ create mode 100644 arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
+ create mode 100644 configs/myir_myd_t113x-spi_defconfig
+
+diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
+index be89021657..267f7bc07e 100644
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -714,6 +714,7 @@ dtb-$(CONFIG_MACH_SUN8I_R528) += \
+       sun8i-t113s-mangopi-mq-r-t113.dtb \
+       sun8i-t113s-mangopi-mqdual-t113.dtb \
+       sun8i-t113s-myir-myd-yt113x.dtb \
++      sun8i-t113s-myir-myd-yt113x-spi.dtb \
+       sun8i-t113s-rongpin-rp-t113.dtb
+ dtb-$(CONFIG_MACH_SUN50I_H5) += \
+       sun50i-h5-bananapi-m2-plus.dtb \
+diff --git a/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
+new file mode 100644
+index 0000000000..f72bab29a6
+--- /dev/null
++++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
+@@ -0,0 +1,59 @@
++// SPDX-License-Identifier: (GPL-2.0+ or MIT)
++// Copyright (C) 2022 Arm Ltd.
++
++#include <dt-bindings/interrupt-controller/irq.h>
++
++/dts-v1/;
++
++#include "sun8i-t113s.dtsi"
++#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
++
++/ {
++      model = "MYIR MYD-YT113X (SPI)";
++      compatible = "myir,myd-yt113x", "myir,myc-yt113x", "allwinner,sun8i-t113s";
++
++      aliases {
++              serial5 = &uart5;
++      };
++
++      chosen {
++              stdout-path = "serial5:115200n8";
++      };
++};
++
++&cpu0 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&cpu1 {
++      cpu-supply = <&reg_vcc_core>;
++};
++
++&pio {
++      /omit-if-no-ref/
++      uart5_pins: uart5-pins {
++              pins = "PE6", "PE7";
++              function = "uart5";
++      };
++};
++
++&uart5 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart5_pins>;
++      status = "okay";
++};
++
++&uart3 {
++      status = "disabled";
++};
++
++&spi0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spi0_pins>;
++      status = "okay";
++      spi_nand@0 {
++              compatible = "spi-nand";
++              reg = <0>;
++              spi-max-frequency = <52000000>;
++      };
++};
+diff --git a/configs/myir_myd_t113x-spi_defconfig b/configs/myir_myd_t113x-spi_defconfig
+new file mode 100644
+index 0000000000..a433fe0449
+--- /dev/null
++++ b/configs/myir_myd_t113x-spi_defconfig
+@@ -0,0 +1,38 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-myir-myd-yt113x-spi"
++CONFIG_SUNXI_MINIMUM_DRAM_MB=128
++CONFIG_SPL=y
++CONFIG_SPL_SPI_SUNXI=y
++CONFIG_MTD_SPI_NAND=y
++CONFIG_MACH_SUN8I_R528=y
++CONFIG_CONS_INDEX=6
++CONFIG_MMC0_CD_PIN="PF6"
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_SYS_MONITOR_LEN=786432
++CONFIG_DRAM_CLK=792
++CONFIG_DRAM_ZQ=8092667
++CONFIG_DRAM_SUNXI_ODT_EN=0
++CONFIG_DRAM_SUNXI_TPR0=0x004a2195
++CONFIG_DRAM_SUNXI_TPR11=0x340000
++CONFIG_DRAM_SUNXI_TPR12=0x46
++CONFIG_DRAM_SUNXI_TPR13=0x34000100
++CONFIG_CLK_SUN20I_D1=y
++CONFIG_PHY_MOTORCOMM=y
++CONFIG_SUN8I_EMAC=y
++CONFIG_RGMII=y
++CONFIG_RMII=y
++CONFIG_MTD=y
++CONFIG_DM_MTD=y
++CONFIG_SYS_MTDPARTS_RUNTIME=y
++CONFIG_NAND_STM32_FMC2=y
++CONFIG_SYS_NAND_ONFI_DETECTION=y
++CONFIG_MTD_SPI_NAND=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SPI_FLASH_MACRONIX=y
++CONFIG_SPI_FLASH_SPANSION=y
++CONFIG_SPI_FLASH_STMICRO=y
++CONFIG_SPI_FLASH_WINBOND=y
++# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
++CONFIG_SPI_FLASH_MTD=y
++CONFIG_SPI=y
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4043-sunxi-add-support-for-emac-on-PG-pins.patch b/package/boot/uboot-sunxi/patches/4043-sunxi-add-support-for-emac-on-PG-pins.patch
new file mode 100644 (file)
index 0000000..6735973
--- /dev/null
@@ -0,0 +1,34 @@
+From 7e690876a4d143df61950c4c60c56dc27d8fb0e2 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 29 Jul 2023 11:29:26 +0200
+Subject: [PATCH 4043/4044] sunxi: add support for emac on PG pins
+
+Some boards use Port G pins for muxing EMAC.
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ arch/riscv/dts/sunxi-d1s-t113.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+index 324353905f..2426c71f25 100644
+--- a/arch/riscv/dts/sunxi-d1s-t113.dtsi
++++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
+@@ -101,6 +101,14 @@
+                               function = "emac";
+                       };
++                      /omit-if-no-ref/
++                      rgmii_pg_pins: rgmii-pg-pins {
++                              pins = "PG0", "PG1", "PG2", "PG3", "PG4",
++                                     "PG5", "PG6", "PG7", "PG8", "PG9",
++                                     "PG11", "PG12", "PG13", "PG14", "PG15";
++                              function = "emac";
++                      };
++
+                       /omit-if-no-ref/
+                       rmii_pe_pins: rmii-pe-pins {
+                               pins = "PE0", "PE1", "PE2", "PE3", "PE4",
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4044-sunxi-add-ethernet-support-on-MYIR-MYD-YT113X-SPI.patch b/package/boot/uboot-sunxi/patches/4044-sunxi-add-ethernet-support-on-MYIR-MYD-YT113X-SPI.patch
new file mode 100644 (file)
index 0000000..58dc35b
--- /dev/null
@@ -0,0 +1,62 @@
+From d664819e1142f0f44945ed31d62e666146639403 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 29 Jul 2023 11:34:19 +0200
+Subject: [PATCH 4044/4044] sunxi: add ethernet support on MYIR MYD-YT113X-SPI
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ .../dts/sun8i-t113s-myir-myd-yt113x-spi.dts   | 34 +++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
+index f72bab29a6..431d5593d6 100644
+--- a/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
++++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
+@@ -19,6 +19,23 @@
+       chosen {
+               stdout-path = "serial5:115200n8";
+       };
++
++      reg_vcc5v: regulator-5v {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-5v";
++              regulator-min-microvolt = <5000000>;
++              regulator-max-microvolt = <5000000>;
++              regulator-always-on;
++      };
++
++      /* SY8008 DC/DC regulator on the board */
++      reg_3v3: regulator-3v3 {
++              compatible = "regulator-fixed";
++              regulator-name = "vcc-3v3";
++              regulator-min-microvolt = <3300000>;
++              regulator-max-microvolt = <3300000>;
++              vin-supply = <&reg_vcc5v>;
++      };
+ };
+ &cpu0 {
+@@ -57,3 +74,20 @@
+               spi-max-frequency = <52000000>;
+       };
+ };
++
++&emac {
++      pinctrl-names = "default";
++      pinctrl-0 = <&rgmii_pg_pins>;
++      phy-supply = <&reg_3v3>;
++      phy-handle = <&ext_rgmii_phy>;
++      phy-mode = "rgmii-id";
++
++      status = "okay";
++};
++
++&mdio {
++      ext_rgmii_phy: ethernet-phy@4 {
++              compatible = "ethernet-phy-ieee802.3-c22";
++              reg = <4>;
++      };
++};
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4045-mtd-spi-nand-backport-from-upstream-kernel.patch b/package/boot/uboot-sunxi/patches/4045-mtd-spi-nand-backport-from-upstream-kernel.patch
new file mode 100644 (file)
index 0000000..36eef6d
--- /dev/null
@@ -0,0 +1,1569 @@
+From d44bacf6dab96824f23f06d264271d370f2f4431 Mon Sep 17 00:00:00 2001
+From: Weijie Gao <weijie.gao@mediatek.com>
+Date: Wed, 27 Jul 2022 16:36:13 +0800
+Subject: [PATCH 46/46] mtd: spi-nand: backport from upstream kernel
+
+Backport new features from upstream kernel
+
+Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+---
+ drivers/mtd/nand/spi/Kconfig      |   8 +
+ drivers/mtd/nand/spi/core.c       | 101 ++++++----
+ drivers/mtd/nand/spi/gigadevice.c | 322 ++++++++++++++++++++++++++----
+ drivers/mtd/nand/spi/macronix.c   | 173 +++++++++++++---
+ drivers/mtd/nand/spi/micron.c     |  50 ++---
+ drivers/mtd/nand/spi/toshiba.c    |  66 +++---
+ drivers/mtd/nand/spi/winbond.c    | 171 +++++++++++++---
+ include/linux/mtd/spinand.h       |  86 +++++---
+ 8 files changed, 753 insertions(+), 224 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/Kconfig b/drivers/mtd/nand/spi/Kconfig
+index 0777dfdf0a..bbd0981968 100644
+--- a/drivers/mtd/nand/spi/Kconfig
++++ b/drivers/mtd/nand/spi/Kconfig
+@@ -5,3 +5,11 @@ menuconfig MTD_SPI_NAND
+       select SPI_MEM
+       help
+         This is the framework for the SPI NAND device drivers.
++
++config MTD_SPI_NAND_W25N01KV
++      tristate "Winbond W25N01KV Support"
++      select MTD_SPI_NAND
++      default n
++      help
++        Winbond W25N01KV share the same ID with W25N01GV. However, they have
++        different attributes.
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index 134bf22c80..46ce48e0ea 100644
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -17,6 +17,7 @@
+ #include <linux/mtd/spinand.h>
+ #include <linux/of.h>
+ #include <linux/slab.h>
++#include <linux/string.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/spi-mem.h>
+ #else
+@@ -451,10 +452,11 @@ out:
+       return status & STATUS_BUSY ? -ETIMEDOUT : 0;
+ }
+-static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf)
++static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr,
++                            u8 ndummy, u8 *buf)
+ {
+-      struct spi_mem_op op = SPINAND_READID_OP(0, spinand->scratchbuf,
+-                                               SPINAND_MAX_ID_LEN);
++      struct spi_mem_op op = SPINAND_READID_OP(
++              naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN);
+       int ret;
+       ret = spi_mem_exec_op(spinand->slave, &op);
+@@ -464,18 +466,6 @@ static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf)
+       return ret;
+ }
+-static int spinand_reset_op(struct spinand_device *spinand)
+-{
+-      struct spi_mem_op op = SPINAND_RESET_OP;
+-      int ret;
+-
+-      ret = spi_mem_exec_op(spinand->slave, &op);
+-      if (ret)
+-              return ret;
+-
+-      return spinand_wait(spinand, NULL);
+-}
+-
+ static int spinand_lock_block(struct spinand_device *spinand, u8 lock)
+ {
+       return spinand_write_reg_op(spinand, REG_BLOCK_LOCK, lock);
+@@ -836,24 +826,63 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = {
+       &winbond_spinand_manufacturer,
+ };
+-static int spinand_manufacturer_detect(struct spinand_device *spinand)
++static int spinand_manufacturer_match(struct spinand_device *spinand,
++                                    enum spinand_readid_method rdid_method)
+ {
++      u8 *id = spinand->id.data;
+       unsigned int i;
+       int ret;
+       for (i = 0; i < ARRAY_SIZE(spinand_manufacturers); i++) {
+-              ret = spinand_manufacturers[i]->ops->detect(spinand);
+-              if (ret > 0) {
+-                      spinand->manufacturer = spinand_manufacturers[i];
+-                      return 0;
+-              } else if (ret < 0) {
+-                      return ret;
+-              }
++              const struct spinand_manufacturer *manufacturer =
++                      spinand_manufacturers[i];
++
++              if (id[0] != manufacturer->id)
++                      continue;
++
++              ret = spinand_match_and_init(spinand,
++                                           manufacturer->chips,
++                                           manufacturer->nchips,
++                                           rdid_method);
++              if (ret < 0)
++                      continue;
++
++              spinand->manufacturer = manufacturer;
++              return 0;
+       }
+       return -ENOTSUPP;
+ }
++static int spinand_id_detect(struct spinand_device *spinand)
++{
++      u8 *id = spinand->id.data;
++      int ret;
++
++      ret = spinand_read_id_op(spinand, 0, 0, id);
++      if (ret)
++              return ret;
++      ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE);
++      if (!ret)
++              return 0;
++
++      ret = spinand_read_id_op(spinand, 1, 0, id);
++      if (ret)
++              return ret;
++      ret = spinand_manufacturer_match(spinand,
++                                       SPINAND_READID_METHOD_OPCODE_ADDR);
++      if (!ret)
++              return 0;
++
++      ret = spinand_read_id_op(spinand, 0, 1, id);
++      if (ret)
++              return ret;
++      ret = spinand_manufacturer_match(spinand,
++                                       SPINAND_READID_METHOD_OPCODE_DUMMY);
++
++      return ret;
++}
++
+ static int spinand_manufacturer_init(struct spinand_device *spinand)
+ {
+       if (spinand->manufacturer->ops->init)
+@@ -909,9 +938,9 @@ spinand_select_op_variant(struct spinand_device *spinand,
+  * @spinand: SPI NAND object
+  * @table: SPI NAND device description table
+  * @table_size: size of the device description table
++ * @rdid_method: read id method to match
+  *
+- * Should be used by SPI NAND manufacturer drivers when they want to find a
+- * match between a device ID retrieved through the READ_ID command and an
++ * Match between a device ID retrieved through the READ_ID command and an
+  * entry in the SPI NAND description table. If a match is found, the spinand
+  * object will be initialized with information provided by the matching
+  * spinand_info entry.
+@@ -920,8 +949,10 @@ spinand_select_op_variant(struct spinand_device *spinand,
+  */
+ int spinand_match_and_init(struct spinand_device *spinand,
+                          const struct spinand_info *table,
+-                         unsigned int table_size, u8 devid)
++                         unsigned int table_size,
++                         enum spinand_readid_method rdid_method)
+ {
++      u8 *id = spinand->id.data;
+       struct nand_device *nand = spinand_to_nand(spinand);
+       unsigned int i;
+@@ -929,13 +960,17 @@ int spinand_match_and_init(struct spinand_device *spinand,
+               const struct spinand_info *info = &table[i];
+               const struct spi_mem_op *op;
+-              if (devid != info->devid)
++              if (rdid_method != info->devid.method)
++                      continue;
++
++              if (memcmp(id + 1, info->devid.id, info->devid.len))
+                       continue;
+               nand->memorg = table[i].memorg;
+               nand->eccreq = table[i].eccreq;
+               spinand->eccinfo = table[i].eccinfo;
+               spinand->flags = table[i].flags;
++              spinand->id.len = 1 + table[i].devid.len;
+               spinand->select_target = table[i].select_target;
+               op = spinand_select_op_variant(spinand,
+@@ -967,17 +1002,7 @@ static int spinand_detect(struct spinand_device *spinand)
+       struct nand_device *nand = spinand_to_nand(spinand);
+       int ret;
+-      ret = spinand_reset_op(spinand);
+-      if (ret)
+-              return ret;
+-
+-      ret = spinand_read_id_op(spinand, spinand->id.data);
+-      if (ret)
+-              return ret;
+-
+-      spinand->id.len = SPINAND_MAX_ID_LEN;
+-
+-      ret = spinand_manufacturer_detect(spinand);
++      ret = spinand_id_detect(spinand);
+       if (ret) {
+               dev_err(spinand->slave->dev, "unknown raw ID %*phN\n",
+                       SPINAND_MAX_ID_LEN, spinand->id.data);
+diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
+index a2c93486f4..5357f02ddc 100644
+--- a/drivers/mtd/nand/spi/gigadevice.c
++++ b/drivers/mtd/nand/spi/gigadevice.c
+@@ -22,8 +22,13 @@
+ #define GD5FXGQXXEXXG_REG_STATUS2             0xf0
++#define GD5FXGQ4UXFXXG_STATUS_ECC_MASK                (7 << 4)
++#define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
++#define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS        (1 << 4)
++#define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4)
++
+ /* Q4 devices, QUADIO: Dummy bytes valid for 1 and 2 GBit variants */
+-static SPINAND_OP_VARIANTS(gd5fxgq4_read_cache_variants,
++static SPINAND_OP_VARIANTS(read_cache_variants,
+               SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
+               SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+               SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+@@ -31,8 +36,17 @@ static SPINAND_OP_VARIANTS(gd5fxgq4_read_cache_variants,
+               SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+               SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+-/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */
+-static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
++static SPINAND_OP_VARIANTS(read_cache_variants_f,
++              SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
++
++/* For Q5 devices, QUADIO use different dummy byte settings */
++/* Q5 1Gb */
++static SPINAND_OP_VARIANTS(dummy2_read_cache_variants,
+               SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+               SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+               SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+@@ -40,6 +54,15 @@ static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
+               SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+               SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
++/* Q5 2Gb & 4Gb */
++static SPINAND_OP_VARIANTS(dummy4_read_cache_variants,
++              SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
++              SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
++
+ static SPINAND_OP_VARIANTS(write_cache_variants,
+               SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+               SPINAND_PROG_LOAD(true, 0, NULL, 0));
+@@ -48,7 +71,65 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
+               SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+               SPINAND_PROG_LOAD(false, 0, NULL, 0));
+-static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
++static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
++                                struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      region->offset = (16 * section) + 8;
++      region->length = 8;
++
++      return 0;
++}
++
++static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
++                                 struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      if (section) {
++              region->offset = 16 * section;
++              region->length = 8;
++      } else {
++              /* section 0 has one byte reserved for bad block mark */
++              region->offset = 1;
++              region->length = 7;
++      }
++      return 0;
++}
++
++static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
++      .ecc = gd5fxgq4xa_ooblayout_ecc,
++      .rfree = gd5fxgq4xa_ooblayout_free,
++};
++
++static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
++                                       u8 status)
++{
++      switch (status & STATUS_ECC_MASK) {
++      case STATUS_ECC_NO_BITFLIPS:
++              return 0;
++
++      case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
++              /* 1-7 bits are flipped. return the maximum. */
++              return 7;
++
++      case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
++              return 8;
++
++      case STATUS_ECC_UNCOR_ERROR:
++              return -EBADMSG;
++
++      default:
++              break;
++      }
++
++      return -EINVAL;
++}
++
++static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
+                                      struct mtd_oob_region *region)
+ {
+       if (section)
+@@ -60,7 +141,7 @@ static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
+       return 0;
+ }
+-static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section,
++static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
+                                       struct mtd_oob_region *region)
+ {
+       if (section)
+@@ -73,7 +154,13 @@ static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section,
+       return 0;
+ }
+-static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
++/* Valid for Q4/Q5 and Q6 (untested) devices */
++static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
++      .ecc = gd5fxgqx_variant2_ooblayout_ecc,
++      .rfree = gd5fxgqx_variant2_ooblayout_free,
++};
++
++static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
+                                       u8 status)
+ {
+       u8 status2;
+@@ -152,59 +239,214 @@ static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
+       return -EINVAL;
+ }
+-static const struct mtd_ooblayout_ops gd5fxgqxxexxg_ooblayout = {
+-      .ecc = gd5fxgqxxexxg_ooblayout_ecc,
+-      .rfree = gd5fxgqxxexxg_ooblayout_free,
++static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
++                                      u8 status)
++{
++      switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
++      case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
++              return 0;
++
++      case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
++              return 3;
++
++      case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
++              return -EBADMSG;
++
++      default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
++              return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
++      }
++
++      return -EINVAL;
++}
++
++static int esmt_1_ooblayout_ecc(struct mtd_info *mtd, int section,
++                                struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      region->offset = (16 * section) + 8;
++      region->length = 8;
++
++      return 0;
++}
++
++static int esmt_1_ooblayout_free(struct mtd_info *mtd, int section,
++                                 struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      region->offset = (16 * section) + 2;
++      region->length = 6;
++
++      return 0;
++}
++
++static const struct mtd_ooblayout_ops esmt_1_ooblayout = {
++      .ecc = esmt_1_ooblayout_ecc,
++      .rfree = esmt_1_ooblayout_free,
+ };
+ static const struct spinand_info gigadevice_spinand_table[] = {
+-      SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
+-                   NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
++      SPINAND_INFO("F50L1G41LB",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
++                   NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+-                   SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants,
++                   SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
+                                             &write_cache_variants,
+                                             &update_cache_variants),
+                    0,
+-                   SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
+-                                   gd5fxgq4xexxg_ecc_get_status)),
+-      SPINAND_INFO("GD5F1GQ5UExxG", 0x51,
++                   SPINAND_ECCINFO(&esmt_1_ooblayout, NULL)),
++      SPINAND_INFO("GD5F1GQ4xA",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
++                   NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
++                                   gd5fxgq4xa_ecc_get_status)),
++      SPINAND_INFO("GD5F2GQ4xA",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
++                   NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
++                                   gd5fxgq4xa_ecc_get_status)),
++      SPINAND_INFO("GD5F4GQ4xA",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
++                   NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
++                                   gd5fxgq4xa_ecc_get_status)),
++      SPINAND_INFO("GD5F1GQ4UExxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
++                   NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq4uexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F1GQ4UFxxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
++                   NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq4ufxxg_ecc_get_status)),
++      SPINAND_INFO("GD5F1GQ5UExxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(4, 512),
+-                   SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
++                   SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
+                                             &write_cache_variants,
+                                             &update_cache_variants),
+-                   0,
+-                   SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq5xexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F2GQ5UExxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x52),
++                   NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq5xexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F4GQ6UExxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x55),
++                   NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq5xexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F1GM7UExxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x91),
++                   NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq4uexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F2GM7UExxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x92),
++                       NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
++                       NAND_ECCREQ(8, 512),
++                       SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                       SPINAND_HAS_QE_BIT,
++                       SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq4uexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F4GM8UExxG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x95),
++                       NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
++                       NAND_ECCREQ(8, 512),
++                       SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                       SPINAND_HAS_QE_BIT,
++                       SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq4uexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F1GQ5UExxH",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x31),
++                       NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
++                       NAND_ECCREQ(4, 512),
++                       SPINAND_INFO_OP_VARIANTS(&dummy2_read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                       SPINAND_HAS_QE_BIT,
++                       SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq5xexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F2GQ5UExxH",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
++                       NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
++                       NAND_ECCREQ(4, 512),
++                       SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                       SPINAND_HAS_QE_BIT,
++                       SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
++                                   gd5fxgq5xexxg_ecc_get_status)),
++      SPINAND_INFO("GD5F4GQ6UExxH",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
++                       NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
++                       NAND_ECCREQ(4, 512),
++                       SPINAND_INFO_OP_VARIANTS(&dummy4_read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                       SPINAND_HAS_QE_BIT,
++                       SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
+                                    gd5fxgq5xexxg_ecc_get_status)),
+ };
+-static int gigadevice_spinand_detect(struct spinand_device *spinand)
+-{
+-      u8 *id = spinand->id.data;
+-      int ret;
+-
+-      /*
+-       * For GD NANDs, There is an address byte needed to shift in before IDs
+-       * are read out, so the first byte in raw_id is dummy.
+-       */
+-      if (id[1] != SPINAND_MFR_GIGADEVICE)
+-              return 0;
+-
+-      ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
+-                                   ARRAY_SIZE(gigadevice_spinand_table),
+-                                   id[2]);
+-      if (ret)
+-              return ret;
+-
+-      return 1;
+-}
+-
+ static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
+-      .detect = gigadevice_spinand_detect,
+ };
+ const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
+       .id = SPINAND_MFR_GIGADEVICE,
+       .name = "GigaDevice",
++      .chips = gigadevice_spinand_table,
++      .nchips = ARRAY_SIZE(gigadevice_spinand_table),
+       .ops = &gigadevice_spinand_manuf_ops,
+ };
+diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
+index 6d643a8000..34e622d6e9 100644
+--- a/drivers/mtd/nand/spi/macronix.c
++++ b/drivers/mtd/nand/spi/macronix.c
+@@ -105,7 +105,8 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
+ }
+ static const struct spinand_info macronix_spinand_table[] = {
+-      SPINAND_INFO("MX35LF1GE4AB", 0x12,
++      SPINAND_INFO("MX35LF1GE4AB",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(4, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -114,7 +115,8 @@ static const struct spinand_info macronix_spinand_table[] = {
+                    SPINAND_HAS_QE_BIT,
+                    SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
+                                    mx35lf1ge4ab_ecc_get_status)),
+-      SPINAND_INFO("MX35LF2GE4AB", 0x22,
++      SPINAND_INFO("MX35LF2GE4AB",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
+                    NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
+                    NAND_ECCREQ(4, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -122,7 +124,96 @@ static const struct spinand_info macronix_spinand_table[] = {
+                                             &update_cache_variants),
+                    SPINAND_HAS_QE_BIT,
+                    SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
+-      SPINAND_INFO("MX35UF4GE4AD", 0xb7,
++      SPINAND_INFO("MX35LF2GE4AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26),
++                   NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35LF4GE4AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
++                   NAND_MEMORG(1, 4096, 128, 64, 2048, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35LF1G24AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
++                   NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
++      SPINAND_INFO("MX35LF2G24AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
++                   NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
++      SPINAND_INFO("MX35LF4G24AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
++                   NAND_MEMORG(1, 4096, 256, 64, 2048, 2, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
++      SPINAND_INFO("MX31LF1GE4BC",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
++                   NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX31UF1GE4BC",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
++                   NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++
++      SPINAND_INFO("MX35LF2G14AC",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20),
++                   NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35UF4G24AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5),
++                   NAND_MEMORG(1, 4096, 256, 64, 2048, 2, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35UF4GE4AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -131,7 +222,28 @@ static const struct spinand_info macronix_spinand_table[] = {
+                    SPINAND_HAS_QE_BIT,
+                    SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
+                                    mx35lf1ge4ab_ecc_get_status)),
+-      SPINAND_INFO("MX35UF2GE4AD", 0xa6,
++      SPINAND_INFO("MX35UF2G14AC",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
++                   NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35UF2G24AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4),
++                   NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
++                   NAND_ECCREQ(8, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35UF2GE4AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -140,16 +252,38 @@ static const struct spinand_info macronix_spinand_table[] = {
+                    SPINAND_HAS_QE_BIT,
+                    SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
+                                    mx35lf1ge4ab_ecc_get_status)),
+-      SPINAND_INFO("MX35UF2GE4AC", 0xa2,
++      SPINAND_INFO("MX35UF2GE4AC",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2),
+                    NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(4, 512),
++                       SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35UF1G14AC",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90),
++                   NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   SPINAND_HAS_QE_BIT,
++                   SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++                                   mx35lf1ge4ab_ecc_get_status)),
++      SPINAND_INFO("MX35UF1G24AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94),
++                   NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+                                             &write_cache_variants,
+                                             &update_cache_variants),
+                    SPINAND_HAS_QE_BIT,
+                    SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
+                                    mx35lf1ge4ab_ecc_get_status)),
+-      SPINAND_INFO("MX35UF1GE4AD", 0x96,
++      SPINAND_INFO("MX35UF1GE4AD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -158,7 +292,8 @@ static const struct spinand_info macronix_spinand_table[] = {
+                    SPINAND_HAS_QE_BIT,
+                    SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
+                                    mx35lf1ge4ab_ecc_get_status)),
+-      SPINAND_INFO("MX35UF1GE4AC", 0x92,
++      SPINAND_INFO("MX35UF1GE4AC",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(4, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -170,33 +305,13 @@ static const struct spinand_info macronix_spinand_table[] = {
+ };
+-static int macronix_spinand_detect(struct spinand_device *spinand)
+-{
+-      u8 *id = spinand->id.data;
+-      int ret;
+-
+-      /*
+-       * Macronix SPI NAND read ID needs a dummy byte, so the first byte in
+-       * raw_id is garbage.
+-       */
+-      if (id[1] != SPINAND_MFR_MACRONIX)
+-              return 0;
+-
+-      ret = spinand_match_and_init(spinand, macronix_spinand_table,
+-                                   ARRAY_SIZE(macronix_spinand_table),
+-                                   id[2]);
+-      if (ret)
+-              return ret;
+-
+-      return 1;
+-}
+-
+ static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
+-      .detect = macronix_spinand_detect,
+ };
+ const struct spinand_manufacturer macronix_spinand_manufacturer = {
+       .id = SPINAND_MFR_MACRONIX,
+       .name = "Macronix",
++      .chips = macronix_spinand_table,
++      .nchips = ARRAY_SIZE(macronix_spinand_table),
+       .ops = &macronix_spinand_manuf_ops,
+ };
+diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
+index 6bacf14aaf..cecd3db958 100644
+--- a/drivers/mtd/nand/spi/micron.c
++++ b/drivers/mtd/nand/spi/micron.c
+@@ -120,7 +120,8 @@ static int micron_8_ecc_get_status(struct spinand_device *spinand,
+ static const struct spinand_info micron_spinand_table[] = {
+       /* M79A 2Gb 3.3V */
+-      SPINAND_INFO("MT29F2G01ABAGD", 0x24,
++      SPINAND_INFO("MT29F2G01ABAGD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -130,7 +131,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                    SPINAND_ECCINFO(&micron_8_ooblayout,
+                                    micron_8_ecc_get_status)),
+       /* M79A 2Gb 1.8V */
+-      SPINAND_INFO("MT29F2G01ABBGD", 0x25,
++      SPINAND_INFO("MT29F2G01ABBGD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -140,7 +142,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                    SPINAND_ECCINFO(&micron_8_ooblayout,
+                                    micron_8_ecc_get_status)),
+       /* M78A 1Gb 3.3V */
+-      SPINAND_INFO("MT29F1G01ABAFD", 0x14,
++      SPINAND_INFO("MT29F1G01ABAFD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -150,7 +153,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                    SPINAND_ECCINFO(&micron_8_ooblayout,
+                                    micron_8_ecc_get_status)),
+       /* M78A 1Gb 1.8V */
+-      SPINAND_INFO("MT29F1G01ABAFD", 0x15,
++      SPINAND_INFO("MT29F1G01ABAFD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -160,7 +164,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                    SPINAND_ECCINFO(&micron_8_ooblayout,
+                                    micron_8_ecc_get_status)),
+       /* M79A 4Gb 3.3V */
+-      SPINAND_INFO("MT29F4G01ADAGD", 0x36,
++      SPINAND_INFO("MT29F4G01ADAGD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 2),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -171,7 +176,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                                    micron_8_ecc_get_status),
+                    SPINAND_SELECT_TARGET(micron_select_target)),
+       /* M70A 4Gb 3.3V */
+-      SPINAND_INFO("MT29F4G01ABAFD", 0x34,
++      SPINAND_INFO("MT29F4G01ABAFD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -181,7 +187,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                    SPINAND_ECCINFO(&micron_8_ooblayout,
+                                    micron_8_ecc_get_status)),
+       /* M70A 4Gb 1.8V */
+-      SPINAND_INFO("MT29F4G01ABBFD", 0x35,
++      SPINAND_INFO("MT29F4G01ABBFD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -191,7 +198,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                    SPINAND_ECCINFO(&micron_8_ooblayout,
+                                    micron_8_ecc_get_status)),
+       /* M70A 8Gb 3.3V */
+-      SPINAND_INFO("MT29F8G01ADAFD", 0x46,
++      SPINAND_INFO("MT29F8G01ADAFD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -202,7 +210,8 @@ static const struct spinand_info micron_spinand_table[] = {
+                                    micron_8_ecc_get_status),
+                    SPINAND_SELECT_TARGET(micron_select_target)),
+       /* M70A 8Gb 1.8V */
+-      SPINAND_INFO("MT29F8G01ADBFD", 0x47,
++      SPINAND_INFO("MT29F8G01ADBFD",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -214,26 +223,6 @@ static const struct spinand_info micron_spinand_table[] = {
+                    SPINAND_SELECT_TARGET(micron_select_target)),
+ };
+-static int micron_spinand_detect(struct spinand_device *spinand)
+-{
+-      u8 *id = spinand->id.data;
+-      int ret;
+-
+-      /*
+-       * Micron SPI NAND read ID need a dummy byte,
+-       * so the first byte in raw_id is dummy.
+-       */
+-      if (id[1] != SPINAND_MFR_MICRON)
+-              return 0;
+-
+-      ret = spinand_match_and_init(spinand, micron_spinand_table,
+-                                   ARRAY_SIZE(micron_spinand_table), id[2]);
+-      if (ret)
+-              return ret;
+-
+-      return 1;
+-}
+-
+ static int micron_spinand_init(struct spinand_device *spinand)
+ {
+       /*
+@@ -248,12 +237,13 @@ static int micron_spinand_init(struct spinand_device *spinand)
+ }
+ static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
+-      .detect = micron_spinand_detect,
+       .init = micron_spinand_init,
+ };
+ const struct spinand_manufacturer micron_spinand_manufacturer = {
+       .id = SPINAND_MFR_MICRON,
+       .name = "Micron",
++      .chips = micron_spinand_table,
++      .nchips = ARRAY_SIZE(micron_spinand_table),
+       .ops = &micron_spinand_manuf_ops,
+ };
+diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
+index c2cd3b426b..e057b08c70 100644
+--- a/drivers/mtd/nand/spi/toshiba.c
++++ b/drivers/mtd/nand/spi/toshiba.c
+@@ -111,7 +111,8 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
+ static const struct spinand_info toshiba_spinand_table[] = {
+       /* 3.3V 1Gb (1st generation) */
+-      SPINAND_INFO("TC58CVG0S3HRAIG", 0xC2,
++      SPINAND_INFO("TC58CVG0S3HRAIG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -121,7 +122,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 3.3V 2Gb (1st generation) */
+-      SPINAND_INFO("TC58CVG1S3HRAIG", 0xCB,
++      SPINAND_INFO("TC58CVG1S3HRAIG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -131,7 +133,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 3.3V 4Gb (1st generation) */
+-      SPINAND_INFO("TC58CVG2S0HRAIG", 0xCD,
++      SPINAND_INFO("TC58CVG2S0HRAIG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -141,7 +144,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 1.8V 1Gb (1st generation) */
+-      SPINAND_INFO("TC58CYG0S3HRAIG", 0xB2,
++      SPINAND_INFO("TC58CYG0S3HRAIG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -151,7 +155,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 1.8V 2Gb (1st generation) */
+-      SPINAND_INFO("TC58CYG1S3HRAIG", 0xBB,
++      SPINAND_INFO("TC58CYG1S3HRAIG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -161,7 +166,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 1.8V 4Gb (1st generation) */
+-      SPINAND_INFO("TC58CYG2S0HRAIG", 0xBD,
++      SPINAND_INFO("TC58CYG2S0HRAIG",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -176,7 +182,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+        * QE_BIT.
+        */
+       /* 3.3V 1Gb (2nd generation) */
+-      SPINAND_INFO("TC58CVG0S3HRAIJ", 0xE2,
++      SPINAND_INFO("TC58CVG0S3HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -186,7 +193,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 3.3V 2Gb (2nd generation) */
+-      SPINAND_INFO("TC58CVG1S3HRAIJ", 0xEB,
++      SPINAND_INFO("TC58CVG1S3HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -196,7 +204,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 3.3V 4Gb (2nd generation) */
+-      SPINAND_INFO("TC58CVG2S0HRAIJ", 0xED,
++      SPINAND_INFO("TC58CVG2S0HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -206,7 +215,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 3.3V 8Gb (2nd generation) */
+-      SPINAND_INFO("TH58CVG3S0HRAIJ", 0xE4,
++      SPINAND_INFO("TH58CVG3S0HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
+                    NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -216,7 +226,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 1.8V 1Gb (2nd generation) */
+-      SPINAND_INFO("TC58CYG0S3HRAIJ", 0xD2,
++      SPINAND_INFO("TC58CYG0S3HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -226,7 +237,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 1.8V 2Gb (2nd generation) */
+-      SPINAND_INFO("TC58CYG1S3HRAIJ", 0xDB,
++      SPINAND_INFO("TC58CYG1S3HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -236,7 +248,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 1.8V 4Gb (2nd generation) */
+-      SPINAND_INFO("TC58CYG2S0HRAIJ", 0xDD,
++      SPINAND_INFO("TC58CYG2S0HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -246,7 +259,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                    SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
+                                    tx58cxgxsxraix_ecc_get_status)),
+       /* 1.8V 8Gb (2nd generation) */
+-      SPINAND_INFO("TH58CYG3S0HRAIJ", 0xD4,
++      SPINAND_INFO("TH58CYG3S0HRAIJ",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
+                    NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
+                    NAND_ECCREQ(8, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -257,33 +271,13 @@ static const struct spinand_info toshiba_spinand_table[] = {
+                                    tx58cxgxsxraix_ecc_get_status)),
+ };
+-static int toshiba_spinand_detect(struct spinand_device *spinand)
+-{
+-      u8 *id = spinand->id.data;
+-      int ret;
+-
+-      /*
+-       * Toshiba SPI NAND read ID needs a dummy byte,
+-       * so the first byte in id is garbage.
+-       */
+-      if (id[1] != SPINAND_MFR_TOSHIBA)
+-              return 0;
+-
+-      ret = spinand_match_and_init(spinand, toshiba_spinand_table,
+-                                   ARRAY_SIZE(toshiba_spinand_table),
+-                                   id[2]);
+-      if (ret)
+-              return ret;
+-
+-      return 1;
+-}
+-
+ static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
+-      .detect = toshiba_spinand_detect,
+ };
+ const struct spinand_manufacturer toshiba_spinand_manufacturer = {
+       .id = SPINAND_MFR_TOSHIBA,
+       .name = "Toshiba",
++      .chips = toshiba_spinand_table,
++      .nchips = ARRAY_SIZE(toshiba_spinand_table),
+       .ops = &toshiba_spinand_manuf_ops,
+ };
+diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
+index c119486efb..7a108cb3e6 100644
+--- a/drivers/mtd/nand/spi/winbond.c
++++ b/drivers/mtd/nand/spi/winbond.c
+@@ -19,6 +19,25 @@
+ #define WINBOND_CFG_BUF_READ          BIT(3)
++#define W25N02_N04KV_STATUS_ECC_MASK          (3 << 4)
++#define W25N02_N04KV_STATUS_ECC_NO_BITFLIPS   (0 << 4)
++#define W25N02_N04KV_STATUS_ECC_1_4_BITFLIPS  (1 << 4)
++#define W25N02_N04KV_STATUS_ECC_5_8_BITFLIPS  (3 << 4)
++#define W25N02_N04KV_STATUS_ECC_UNCOR_ERROR   (2 << 4)
++
++#define W25N01_M02GV_STATUS_ECC_MASK          (3 << 4)
++#define W25N01_M02GV_STATUS_ECC_NO_BITFLIPS   (0 << 4)
++#define W25N01_M02GV_STATUS_ECC_1_BITFLIPS    (1 << 4)
++#define W25N01_M02GV_STATUS_ECC_UNCOR_ERROR   (2 << 4)
++
++#if IS_ENABLED(CONFIG_MTD_SPI_NAND_W25N01KV)
++#define W25N01KV_STATUS_ECC_MASK              (3 << 4)
++#define W25N01KV_STATUS_ECC_NO_BITFLIPS               (0 << 4)
++#define W25N01KV_STATUS_ECC_1_3_BITFLIPS      (1 << 4)
++#define W25N01KV_STATUS_ECC_4_BITFLIPS                (3 << 4)
++#define W25N01KV_STATUS_ECC_UNCOR_ERROR               (2 << 4)
++#endif
++
+ static SPINAND_OP_VARIANTS(read_cache_variants,
+               SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+               SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+@@ -35,6 +54,35 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
+               SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+               SPINAND_PROG_LOAD(false, 0, NULL, 0));
++static int w25n02kv_n04kv_ooblayout_ecc(struct mtd_info *mtd, int section,
++                                struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      region->offset = (16 * section) + 64;
++      region->length = 16;
++
++      return 0;
++}
++
++static int w25n02kv_n04kv_ooblayout_free(struct mtd_info *mtd, int section,
++                                 struct mtd_oob_region *region)
++{
++      if (section > 3)
++              return -ERANGE;
++
++      region->offset = (16 * section) + 2;
++      region->length = 14;
++
++      return 0;
++}
++
++static const struct mtd_ooblayout_ops w25n02kv_n04kv_ooblayout = {
++      .ecc = w25n02kv_n04kv_ooblayout_ecc,
++      .rfree = w25n02kv_n04kv_ooblayout_free,
++};
++
+ static int w25m02gv_ooblayout_ecc(struct mtd_info *mtd, int section,
+                                 struct mtd_oob_region *region)
+ {
+@@ -78,8 +126,63 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
+       return spi_mem_exec_op(spinand->slave, &op);
+ }
++#if IS_ENABLED(CONFIG_MTD_SPI_NAND_W25N01KV)
++static int w25n01kv_ecc_get_status(struct spinand_device *spinand,
++                                      u8 status)
++{
++      switch (status & W25N01KV_STATUS_ECC_MASK) {
++      case W25N01KV_STATUS_ECC_NO_BITFLIPS:
++              return 0;
++
++      case W25N01KV_STATUS_ECC_1_3_BITFLIPS:
++              return 3;
++
++      case W25N01KV_STATUS_ECC_4_BITFLIPS:
++              return 4;
++
++      case W25N01KV_STATUS_ECC_UNCOR_ERROR:
++              return -EBADMSG;
++
++      default:
++              break;
++      }
++
++      return -EINVAL;
++}
++#endif
++
++static int w25n02kv_n04kv_ecc_get_status(struct spinand_device *spinand,
++                                      u8 status)
++{
++      switch (status & W25N02_N04KV_STATUS_ECC_MASK) {
++      case W25N02_N04KV_STATUS_ECC_NO_BITFLIPS:
++              return 0;
++
++      case W25N02_N04KV_STATUS_ECC_1_4_BITFLIPS:
++              return 3;
++
++      case W25N02_N04KV_STATUS_ECC_5_8_BITFLIPS:
++              return 4;
++
++      /* W25N02_N04KV_use internal 8bit ECC algorithm.
++       * But the ECC strength is 4 bit requried.
++       * Return 3 if the bit bit flip count less than 5.
++       * Return 4 if the bit bit flip count more than 5 to 8.
++      */
++
++      case W25N02_N04KV_STATUS_ECC_UNCOR_ERROR:
++              return -EBADMSG;
++
++      default:
++              break;
++      }
++
++      return -EINVAL;
++}
++
+ static const struct spinand_info winbond_spinand_table[] = {
+-      SPINAND_INFO("W25M02GV", 0xAB,
++      SPINAND_INFO("W25M02GV",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 2),
+                    NAND_ECCREQ(1, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -88,7 +191,19 @@ static const struct spinand_info winbond_spinand_table[] = {
+                    0,
+                    SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
+                    SPINAND_SELECT_TARGET(w25m02gv_select_target)),
+-      SPINAND_INFO("W25N01GV", 0xAA,
++#if IS_ENABLED(CONFIG_MTD_SPI_NAND_W25N01KV)
++      SPINAND_INFO("W25N01KV",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
++                   NAND_MEMORG(1, 2048, 96, 64, 1024, 1, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   0,
++                   SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout, w25n01kv_ecc_get_status)),
++#else
++      SPINAND_INFO("W25N01GV",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+                    NAND_ECCREQ(1, 512),
+                    SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+@@ -96,32 +211,31 @@ static const struct spinand_info winbond_spinand_table[] = {
+                                             &update_cache_variants),
+                    0,
+                    SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
+-};
+-
+-/**
+- * winbond_spinand_detect - initialize device related part in spinand_device
+- * struct if it is a Winbond device.
+- * @spinand: SPI NAND device structure
+- */
+-static int winbond_spinand_detect(struct spinand_device *spinand)
+-{
+-      u8 *id = spinand->id.data;
+-      int ret;
+-
+-      /*
+-       * Winbond SPI NAND read ID need a dummy byte,
+-       * so the first byte in raw_id is dummy.
++#endif
++      SPINAND_INFO("W25N02KV",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
++                   NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   0,
++                   SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout,
++                                   w25n02kv_n04kv_ecc_get_status)),
++      /* W25N04KV has 2-die(lun), however, it can select die automatically.
++       * Treat it as single die here and double block size.
+        */
+-      if (id[1] != SPINAND_MFR_WINBOND)
+-              return 0;
+-
+-      ret = spinand_match_and_init(spinand, winbond_spinand_table,
+-                                   ARRAY_SIZE(winbond_spinand_table), id[2]);
+-      if (ret)
+-              return ret;
+-
+-      return 1;
+-}
++      SPINAND_INFO("W25N04KV",
++                   SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23),
++                   NAND_MEMORG(1, 2048, 128, 64, 4096, 2, 1, 1),
++                   NAND_ECCREQ(4, 512),
++                   SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++                                            &write_cache_variants,
++                                            &update_cache_variants),
++                   0,
++                   SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout,
++                                   w25n02kv_n04kv_ecc_get_status)),
++};
+ static int winbond_spinand_init(struct spinand_device *spinand)
+ {
+@@ -142,12 +256,13 @@ static int winbond_spinand_init(struct spinand_device *spinand)
+ }
+ static const struct spinand_manufacturer_ops winbond_spinand_manuf_ops = {
+-      .detect = winbond_spinand_detect,
+       .init = winbond_spinand_init,
+ };
+ const struct spinand_manufacturer winbond_spinand_manufacturer = {
+       .id = SPINAND_MFR_WINBOND,
+       .name = "Winbond",
++      .chips = winbond_spinand_table,
++      .nchips = ARRAY_SIZE(winbond_spinand_table),
+       .ops = &winbond_spinand_manuf_ops,
+ };
+diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
+index 15bcd59f34..3a138f977e 100644
+--- a/include/linux/mtd/spinand.h
++++ b/include/linux/mtd/spinand.h
+@@ -39,15 +39,15 @@
+                  SPI_MEM_OP_NO_DUMMY,                                 \
+                  SPI_MEM_OP_NO_DATA)
+-#define SPINAND_READID_OP(ndummy, buf, len)                           \
++#define SPINAND_READID_OP(naddr, ndummy, buf, len)                    \
+       SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1),                             \
+-                 SPI_MEM_OP_NO_ADDR,                                  \
++                 SPI_MEM_OP_ADDR(naddr, 0, 1),                        \
+                  SPI_MEM_OP_DUMMY(ndummy, 1),                         \
+                  SPI_MEM_OP_DATA_IN(len, buf, 1))
+ #define SPINAND_SET_FEATURE_OP(reg, valptr)                           \
+       SPI_MEM_OP(SPI_MEM_OP_CMD(0x1f, 1),                             \
+-                 SPI_MEM_OP_ADDR(1, reg, 1),                          \
++                 SPI_MEM_OP_ADDR(1, reg, 1),                                  \
+                  SPI_MEM_OP_NO_DUMMY,                                 \
+                  SPI_MEM_OP_DATA_OUT(1, valptr, 1))
+@@ -75,18 +75,36 @@
+                  SPI_MEM_OP_DUMMY(ndummy, 1),                         \
+                  SPI_MEM_OP_DATA_IN(len, buf, 1))
++#define SPINAND_PAGE_READ_FROM_CACHE_OP_3A(fast, addr, ndummy, buf, len)\
++      SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1),               \
++                 SPI_MEM_OP_ADDR(3, addr, 1),                         \
++                 SPI_MEM_OP_DUMMY(ndummy, 1),                         \
++                 SPI_MEM_OP_DATA_IN(len, buf, 1))
++
+ #define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len)    \
+       SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1),                             \
+                  SPI_MEM_OP_ADDR(2, addr, 1),                         \
+                  SPI_MEM_OP_DUMMY(ndummy, 1),                         \
+                  SPI_MEM_OP_DATA_IN(len, buf, 2))
++#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(addr, ndummy, buf, len) \
++      SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1),                             \
++                 SPI_MEM_OP_ADDR(3, addr, 1),                         \
++                 SPI_MEM_OP_DUMMY(ndummy, 1),                         \
++                 SPI_MEM_OP_DATA_IN(len, buf, 2))
++
+ #define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len)    \
+       SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1),                             \
+                  SPI_MEM_OP_ADDR(2, addr, 1),                         \
+                  SPI_MEM_OP_DUMMY(ndummy, 1),                         \
+                  SPI_MEM_OP_DATA_IN(len, buf, 4))
++#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(addr, ndummy, buf, len) \
++      SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1),                             \
++                 SPI_MEM_OP_ADDR(3, addr, 1),                         \
++                 SPI_MEM_OP_DUMMY(ndummy, 1),                         \
++                 SPI_MEM_OP_DATA_IN(len, buf, 4))
++
+ #define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len)        \
+       SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1),                             \
+                  SPI_MEM_OP_ADDR(2, addr, 2),                         \
+@@ -153,37 +171,46 @@ struct spinand_device;
+  * @data: buffer containing the id bytes. Currently 4 bytes large, but can
+  *      be extended if required
+  * @len: ID length
+- *
+- * struct_spinand_id->data contains all bytes returned after a READ_ID command,
+- * including dummy bytes if the chip does not emit ID bytes right after the
+- * READ_ID command. The responsibility to extract real ID bytes is left to
+- * struct_manufacurer_ops->detect().
+  */
+ struct spinand_id {
+       u8 data[SPINAND_MAX_ID_LEN];
+       int len;
+ };
++enum spinand_readid_method {
++      SPINAND_READID_METHOD_OPCODE,
++      SPINAND_READID_METHOD_OPCODE_ADDR,
++      SPINAND_READID_METHOD_OPCODE_DUMMY,
++};
++
++/**
++ * struct spinand_devid - SPI NAND device id structure
++ * @id: device id of current chip
++ * @len: number of bytes in device id
++ * @method: method to read chip id
++ *        There are 3 possible variants:
++ *        SPINAND_READID_METHOD_OPCODE: chip id is returned immediately
++ *        after read_id opcode.
++ *        SPINAND_READID_METHOD_OPCODE_ADDR: chip id is returned after
++ *        read_id opcode + 1-byte address.
++ *        SPINAND_READID_METHOD_OPCODE_DUMMY: chip id is returned after
++ *        read_id opcode + 1 dummy byte.
++ */
++struct spinand_devid {
++      const u8 *id;
++      const u8 len;
++      const enum spinand_readid_method method;
++};
++
+ /**
+  * struct manufacurer_ops - SPI NAND manufacturer specific operations
+- * @detect: detect a SPI NAND device. Every time a SPI NAND device is probed
+- *        the core calls the struct_manufacurer_ops->detect() hook of each
+- *        registered manufacturer until one of them return 1. Note that
+- *        the first thing to check in this hook is that the manufacturer ID
+- *        in struct_spinand_device->id matches the manufacturer whose
+- *        ->detect() hook has been called. Should return 1 if there's a
+- *        match, 0 if the manufacturer ID does not match and a negative
+- *        error code otherwise. When true is returned, the core assumes
+- *        that properties of the NAND chip (spinand->base.memorg and
+- *        spinand->base.eccreq) have been filled
+  * @init: initialize a SPI NAND device
+  * @cleanup: cleanup a SPI NAND device
+  *
+  * Each SPI NAND manufacturer driver should implement this interface so that
+- * NAND chips coming from this vendor can be detected and initialized properly.
++ * NAND chips coming from this vendor can be initialized properly.
+  */
+ struct spinand_manufacturer_ops {
+-      int (*detect)(struct spinand_device *spinand);
+       int (*init)(struct spinand_device *spinand);
+       void (*cleanup)(struct spinand_device *spinand);
+ };
+@@ -192,11 +219,16 @@ struct spinand_manufacturer_ops {
+  * struct spinand_manufacturer - SPI NAND manufacturer instance
+  * @id: manufacturer ID
+  * @name: manufacturer name
++ * @devid_len: number of bytes in device ID
++ * @chips: supported SPI NANDs under current manufacturer
++ * @nchips: number of SPI NANDs available in chips array
+  * @ops: manufacturer operations
+  */
+ struct spinand_manufacturer {
+       u8 id;
+       char *name;
++      const struct spinand_info *chips;
++      const size_t nchips;
+       const struct spinand_manufacturer_ops *ops;
+ };
+@@ -268,7 +300,7 @@ struct spinand_ecc_info {
+  */
+ struct spinand_info {
+       const char *model;
+-      u8 devid;
++      struct spinand_devid devid;
+       u32 flags;
+       struct nand_memory_organization memorg;
+       struct nand_ecc_req eccreq;
+@@ -282,6 +314,13 @@ struct spinand_info {
+                            unsigned int target);
+ };
++#define SPINAND_ID(__method, ...)                                     \
++      {                                                               \
++              .id = (const u8[]){ __VA_ARGS__ },                      \
++              .len = sizeof((u8[]){ __VA_ARGS__ }),                   \
++              .method = __method,                                     \
++      }
++
+ #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update)           \
+       {                                                               \
+               .read_cache = __read,                                   \
+@@ -440,9 +479,10 @@ static inline void spinand_set_ofnode(struct spinand_device *spinand,
+ }
+ #endif /* __UBOOT__ */
+-int spinand_match_and_init(struct spinand_device *dev,
++int spinand_match_and_init(struct spinand_device *spinand,
+                          const struct spinand_info *table,
+-                         unsigned int table_size, u8 devid);
++                         unsigned int table_size,
++                         enum spinand_readid_method rdid_method);
+ int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
+ int spinand_select_target(struct spinand_device *spinand, unsigned int target);
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4046-arm-dts-add-partition-table-for-MYIR-MYD-YT113X-SPI.patch b/package/boot/uboot-sunxi/patches/4046-arm-dts-add-partition-table-for-MYIR-MYD-YT113X-SPI.patch
new file mode 100644 (file)
index 0000000..132505f
--- /dev/null
@@ -0,0 +1,60 @@
+From b943ca1bd3580393f1525cb021c9a2051c9f1958 Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 26 Aug 2023 17:45:03 +0200
+Subject: [PATCH 4046/4047] arm: dts: add partition table for MYIR
+ MYD-YT113X-SPI
+
+The original bootloader reports the following as the partition table:
+
+device nand0 <nand>, # parts = 4
+ #: name                size            offset          mask_flags
+ 0: boot0               0x00100000      0x00000000      1
+ 1: uboot               0x00300000      0x00100000      1
+ 2: secure_storage      0x00100000      0x00400000      1
+ 3: sys                 0x0fb00000      0x00500000      0
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ .../dts/sun8i-t113s-myir-myd-yt113x-spi.dts   | 26 +++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
+index 431d5593d6..a5fd8c6bea 100644
+--- a/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
++++ b/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
+@@ -72,6 +72,32 @@
+               compatible = "spi-nand";
+               reg = <0>;
+               spi-max-frequency = <52000000>;
++
++              partitions {
++                      compatible = "fixed-partitions";
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++
++                      partition@0 {
++                              label = "boot0";
++                              reg = <0x0 0x100000>;
++                      };
++
++                      partition@100000 {
++                              label = "uboot";
++                              reg = <0x0 0x300000>;
++                      };
++
++                      partition@400000 {
++                              label = "secure_storage";
++                              reg = <0x0 0x400000>;
++                      };
++
++                      partition@500000 {
++                              label = "sys";
++                              reg = <0x0 0xfb00000>;
++                      };
++              };
+       };
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4047-configs-enable-UBI-support-for-MYIR-MYD-YT113X-SPI.patch b/package/boot/uboot-sunxi/patches/4047-configs-enable-UBI-support-for-MYIR-MYD-YT113X-SPI.patch
new file mode 100644 (file)
index 0000000..0fab750
--- /dev/null
@@ -0,0 +1,22 @@
+From a6fbb8f2e7555c2fdd3e42d9e46523eb2d03d83a Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 26 Aug 2023 17:46:22 +0200
+Subject: [PATCH 4047/4047] configs: enable UBI support for MYIR MYD-YT113X-SPI
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ configs/myir_myd_t113x-spi_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/configs/myir_myd_t113x-spi_defconfig b/configs/myir_myd_t113x-spi_defconfig
+index a433fe0449..d7b9a9bbcf 100644
+--- a/configs/myir_myd_t113x-spi_defconfig
++++ b/configs/myir_myd_t113x-spi_defconfig
+@@ -36,3 +36,4 @@ CONFIG_SPI_FLASH_WINBOND=y
+ # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+ CONFIG_SPI_FLASH_MTD=y
+ CONFIG_SPI=y
++CONFIG_MTD_UBI_FASTMAP=y
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4048-sunxi-r528-d1-t113-add-SDC2-pinmux-on-PC2-7-pins.patch b/package/boot/uboot-sunxi/patches/4048-sunxi-r528-d1-t113-add-SDC2-pinmux-on-PC2-7-pins.patch
new file mode 100644 (file)
index 0000000..a07fb47
--- /dev/null
@@ -0,0 +1,31 @@
+From bbc0d9a9ee7da3b64d70010e79098c1ca24c351c Mon Sep 17 00:00:00 2001
+From: Zoltan HERPAI <wigyori@uid0.hu>
+Date: Sat, 26 Aug 2023 21:09:17 +0200
+Subject: [PATCH 4048/4048] sunxi: r528/d1/t113: add SDC2 pinmux on PC2-7 pins
+
+Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
+---
+ board/sunxi/board.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/board/sunxi/board.c b/board/sunxi/board.c
+index 661137f43c..c00629f9b5 100644
+--- a/board/sunxi/board.c
++++ b/board/sunxi/board.c
+@@ -424,6 +424,13 @@ static void mmc_pinmux_setup(int sdc)
+               sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
+               sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
+               sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
++#elif defined(CONFIG_MACH_SUN8I_R528)
++              /* SDC2: PC2-PC7 */
++              for (pin = SUNXI_GPC(2); pin <= SUNXI_GPC(7); pin++) {
++                      sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
++                      sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
++                      sunxi_gpio_set_drv(pin, 2);
++              }
+ #elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I)
+               /* SDC2: PC5-PC6, PC8-PC16 */
+               for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-sunxi/patches/4100-SQUASH-ME.patch b/package/boot/uboot-sunxi/patches/4100-SQUASH-ME.patch
deleted file mode 100644 (file)
index 22bb1dd..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-From 6ab5a9624210408ea57e957c3ebbafd35ece224d Mon Sep 17 00:00:00 2001
-From: Sam Edwards <cfsworks@gmail.com>
-Date: Thu, 1 Jun 2023 15:48:11 -0600
-Subject: [PATCH 4100/4103] SQUASH ME
-
-This patch contains only register defs for cpu_sunxi_ncat2.h, and should
-be combined (as appropriate) into:
-
-sunxi: introduce NCAT2 generation model
----
- arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-index d01508517c..25f71bbccd 100644
---- a/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-+++ b/arch/arm/include/asm/arch-sunxi/cpu_sunxi_ncat2.h
-@@ -17,6 +17,9 @@
- #define SUNXI_SIDC_BASE                       0x03006000
- #define SUNXI_SID_BASE                        0x03006200
- #define SUNXI_TIMER_BASE              0x02050000
-+#define SUNXI_GIC400_BASE             0x03020000
-+#define SUNXI_CPUX_BASE                       0x09010000
-+#define SUNXI_CPUCFG_BASE             0
- #ifdef CONFIG_MACH_SUN50I_H6
- #define SUNXI_DRAM_COM_BASE           0x04002000
-@@ -34,11 +37,11 @@
- #define SUNXI_SPI0_BASE                       0x04025000
- #define SUNXI_SPI1_BASE                       0x04026000
--#define SUNXI_RTC_BASE                        0x07000000
- #define SUNXI_R_CPUCFG_BASE           0x07000400
- #define SUNXI_PRCM_BASE                       0x07010000
- #define SUNXI_R_WDOG_BASE             0x07020400
--#define SUNXI_R_TWI_BASE              0x07081400
-+#define SUNXI_R_TWI_BASE              0x07020800
-+#define SUNXI_RTC_BASE                        0x07090000
- #ifndef __ASSEMBLY__
- void sunxi_board_init(void);
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4101-sunxi-psci-clean-away-preprocessor-macros.patch b/package/boot/uboot-sunxi/patches/4101-sunxi-psci-clean-away-preprocessor-macros.patch
deleted file mode 100644 (file)
index 842e47c..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-From a183878133f04cb53810e2e70cb39169efde27c4 Mon Sep 17 00:00:00 2001
-From: Sam Edwards <cfsworks@gmail.com>
-Date: Thu, 1 Jun 2023 15:48:12 -0600
-Subject: [PATCH 4101/4103] sunxi: psci: clean away preprocessor macros
-
-This patch restructures psci.c to get away from the "many different
-function definitions switched by #ifdef" paradigm to the preferred style
-of having a single function definition with `if (IS_ENABLED(...))` to
-make the optimizer include only the appropriate function bodies instead.
-
-There are no functional changes here.
-
-Signed-off-by: Sam Edwards <CFSworks@gmail.com>
----
- arch/arm/cpu/armv7/sunxi/psci.c | 94 ++++++++++++++-------------------
- 1 file changed, 41 insertions(+), 53 deletions(-)
-
-diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
-index e1d3638b5c..7809b074f8 100644
---- a/arch/arm/cpu/armv7/sunxi/psci.c
-+++ b/arch/arm/cpu/armv7/sunxi/psci.c
-@@ -76,28 +76,24 @@ static void __secure __mdelay(u32 ms)
-       isb();
- }
--static void __secure clamp_release(u32 __maybe_unused *clamp)
-+static void __secure clamp_release(u32 *clamp)
- {
--#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
--      defined(CONFIG_MACH_SUN8I_H3) || \
--      defined(CONFIG_MACH_SUN8I_R40)
--      u32 tmp = 0x1ff;
--      do {
--              tmp >>= 1;
--              writel(tmp, clamp);
--      } while (tmp);
--
--      __mdelay(10);
--#endif
-+      if (clamp) {
-+              u32 tmp = 0x1ff;
-+              do {
-+                      tmp >>= 1;
-+                      writel(tmp, clamp);
-+              } while (tmp);
-+
-+              __mdelay(10);
-+      }
- }
--static void __secure clamp_set(u32 __maybe_unused *clamp)
-+static void __secure clamp_set(u32 *clamp)
- {
--#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || \
--      defined(CONFIG_MACH_SUN8I_H3) || \
--      defined(CONFIG_MACH_SUN8I_R40)
--      writel(0xff, clamp);
--#endif
-+      if (clamp) {
-+              writel(0xff, clamp);
-+      }
- }
- static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on,
-@@ -118,53 +114,45 @@ static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on,
-       }
- }
--#ifdef CONFIG_MACH_SUN8I_R40
--/* secondary core entry address is programmed differently on R40 */
- static void __secure sunxi_set_entry_address(void *entry)
- {
--      writel((u32)entry,
--             SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
--}
--#else
--static void __secure sunxi_set_entry_address(void *entry)
--{
--      struct sunxi_cpucfg_reg *cpucfg =
--              (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+      /* secondary core entry address is programmed differently on R40 */
-+      if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
-+              writel((u32)entry,
-+                     SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
-+      } else {
-+              struct sunxi_cpucfg_reg *cpucfg =
-+                      (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
--      writel((u32)entry, &cpucfg->priv0);
-+              writel((u32)entry, &cpucfg->priv0);
-+      }
- }
--#endif
--#ifdef CONFIG_MACH_SUN7I
--/* sun7i (A20) is different from other single cluster SoCs */
--static void __secure sunxi_cpu_set_power(int __always_unused cpu, bool on)
--{
--      struct sunxi_cpucfg_reg *cpucfg =
--              (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
--
--      sunxi_power_switch(&cpucfg->cpu1_pwr_clamp, &cpucfg->cpu1_pwroff,
--                         on, 0);
--}
--#elif defined CONFIG_MACH_SUN8I_R40
- static void __secure sunxi_cpu_set_power(int cpu, bool on)
- {
-       struct sunxi_cpucfg_reg *cpucfg =
-               (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
--      sunxi_power_switch((void *)cpucfg + SUN8I_R40_PWR_CLAMP(cpu),
--                         (void *)cpucfg + SUN8I_R40_PWROFF,
--                         on, cpu);
--}
--#else /* ! CONFIG_MACH_SUN7I && ! CONFIG_MACH_SUN8I_R40 */
--static void __secure sunxi_cpu_set_power(int cpu, bool on)
--{
--      struct sunxi_prcm_reg *prcm =
--              (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
-+      /* sun7i (A20) is different from other single cluster SoCs */
-+      if (IS_ENABLED(CONFIG_MACH_SUN7I)) {
-+              sunxi_power_switch(NULL, &cpucfg->cpu1_pwroff, on, 0);
-+      } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
-+              sunxi_power_switch(NULL, (void *)cpucfg + SUN8I_R40_PWROFF,
-+                                 on, cpu);
-+      } else {
-+#if !defined(CONFIG_SUN50I_GEN_H6) && !defined(CONFIG_SUNXI_GEN_NCAT2)
-+              struct sunxi_prcm_reg *prcm =
-+                      (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
--      sunxi_power_switch(&prcm->cpu_pwr_clamp[cpu], &prcm->cpu_pwroff,
--                         on, cpu);
-+              u32 *clamp = &prcm->cpu_pwr_clamp[cpu];
-+              if (IS_ENABLED(CONFIG_MACH_SUN6I) ||
-+                  IS_ENABLED(CONFIG_MACH_SUN8I_H3))
-+                      clamp = NULL;
-+
-+              sunxi_power_switch(clamp, &prcm->cpu_pwroff, on, cpu);
-+#endif
-+      }
- }
--#endif /* CONFIG_MACH_SUN7I */
- void __secure sunxi_cpu_power_off(u32 cpuid)
- {
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4102-sunxi-psci-refactor-register-access-to-separate-func.patch b/package/boot/uboot-sunxi/patches/4102-sunxi-psci-refactor-register-access-to-separate-func.patch
deleted file mode 100644 (file)
index 926bb7f..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-From 1422f560d647d466f2b99fbc917ac4f6a1d3af38 Mon Sep 17 00:00:00 2001
-From: Sam Edwards <cfsworks@gmail.com>
-Date: Thu, 1 Jun 2023 15:48:13 -0600
-Subject: [PATCH 4102/4103] sunxi: psci: refactor register access to separate
- functions
-
-This is to prepare for R528, which does not have the typical
-"CPUCFG" block; it has a "CPUX" block which provides these
-same functions but is organized differently.
-
-Moving the hardware-access bits to their own functions separates the
-logic from the hardware so we can reuse the same logic.
-
-Signed-off-by: Sam Edwards <CFSworks@gmail.com>
----
- arch/arm/cpu/armv7/sunxi/psci.c | 66 +++++++++++++++++++++++----------
- 1 file changed, 47 insertions(+), 19 deletions(-)
-
-diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
-index 7809b074f8..94120e7526 100644
---- a/arch/arm/cpu/armv7/sunxi/psci.c
-+++ b/arch/arm/cpu/armv7/sunxi/psci.c
-@@ -114,7 +114,7 @@ static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on,
-       }
- }
--static void __secure sunxi_set_entry_address(void *entry)
-+static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
- {
-       /* secondary core entry address is programmed differently on R40 */
-       if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
-@@ -154,30 +154,60 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
-       }
- }
--void __secure sunxi_cpu_power_off(u32 cpuid)
-+static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
-+{
-+      struct sunxi_cpucfg_reg *cpucfg =
-+              (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+
-+      writel(reset ? 0b00 : 0b11, &cpucfg->cpu[cpu].rst);
-+}
-+
-+static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
- {
-       struct sunxi_cpucfg_reg *cpucfg =
-               (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+
-+      if (lock)
-+              clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
-+      else
-+              setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
-+}
-+
-+static bool __secure sunxi_cpu_poll_wfi(int cpu)
-+{
-+      struct sunxi_cpucfg_reg *cpucfg =
-+              (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+
-+      return !!(readl(&cpucfg->cpu[cpu].status) & BIT(2));
-+}
-+
-+static void __secure sunxi_cpu_invalidate_cache(int cpu)
-+{
-+      struct sunxi_cpucfg_reg *cpucfg =
-+              (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+
-+      clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
-+}
-+
-+void __secure sunxi_cpu_power_off(u32 cpuid)
-+{
-       u32 cpu = cpuid & 0x3;
-       /* Wait for the core to enter WFI */
--      while (1) {
--              if (readl(&cpucfg->cpu[cpu].status) & BIT(2))
--                      break;
-+      while (!sunxi_cpu_poll_wfi(cpu))
-               __mdelay(1);
--      }
-       /* Assert reset on target CPU */
--      writel(0, &cpucfg->cpu[cpu].rst);
-+      sunxi_cpu_set_reset(cpu, true);
-       /* Lock CPU (Disable external debug access) */
--      clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
-+      sunxi_cpu_set_locking(cpu, true);
-       /* Power down CPU */
-       sunxi_cpu_set_power(cpuid, false);
--      /* Unlock CPU (Disable external debug access) */
--      setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
-+      /* Unlock CPU (Reenable external debug access) */
-+      sunxi_cpu_set_locking(cpu, false);
- }
- static u32 __secure cp15_read_scr(void)
-@@ -234,33 +264,31 @@ out:
- int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc,
-                        u32 context_id)
- {
--      struct sunxi_cpucfg_reg *cpucfg =
--              (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-       u32 cpu = (mpidr & 0x3);
-       /* store target PC and context id */
-       psci_save(cpu, pc, context_id);
-       /* Set secondary core power on PC */
--      sunxi_set_entry_address(&psci_cpu_entry);
-+      sunxi_cpu_set_entry(cpu, &psci_cpu_entry);
-       /* Assert reset on target CPU */
--      writel(0, &cpucfg->cpu[cpu].rst);
-+      sunxi_cpu_set_reset(cpu, true);
-       /* Invalidate L1 cache */
--      clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
-+      sunxi_cpu_invalidate_cache(cpu);
-       /* Lock CPU (Disable external debug access) */
--      clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
-+      sunxi_cpu_set_locking(cpu, true);
-       /* Power up target CPU */
-       sunxi_cpu_set_power(cpu, true);
-       /* De-assert reset on target CPU */
--      writel(BIT(1) | BIT(0), &cpucfg->cpu[cpu].rst);
-+      sunxi_cpu_set_reset(cpu, false);
--      /* Unlock CPU (Disable external debug access) */
--      setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
-+      /* Unlock CPU (Reenable external debug access) */
-+      sunxi_cpu_set_locking(cpu, false);
-       return ARM_PSCI_RET_SUCCESS;
- }
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4103-sunxi-psci-implement-PSCI-on-R528.patch b/package/boot/uboot-sunxi/patches/4103-sunxi-psci-implement-PSCI-on-R528.patch
deleted file mode 100644 (file)
index e57d6b8..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-From bc42c4edff3af5b31702989527c4adb691838084 Mon Sep 17 00:00:00 2001
-From: Sam Edwards <cfsworks@gmail.com>
-Date: Thu, 1 Jun 2023 15:48:14 -0600
-Subject: [PATCH 4103/4103] sunxi: psci: implement PSCI on R528
-
-This patch adds the necessary code to make nonsec booting and PSCI
-secondary core management functional on the R528/T113.
-
-Signed-off-by: Sam Edwards <CFSworks@gmail.com>
-Tested-by: Maksim Kiselev <bigunclemax@gmail.com>
----
- arch/arm/cpu/armv7/sunxi/psci.c | 47 ++++++++++++++++++++++++++++++++-
- arch/arm/mach-sunxi/Kconfig     |  2 ++
- include/configs/sunxi-common.h  |  8 ++++++
- 3 files changed, 56 insertions(+), 1 deletion(-)
-
-diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
-index 94120e7526..f3c1c459c2 100644
---- a/arch/arm/cpu/armv7/sunxi/psci.c
-+++ b/arch/arm/cpu/armv7/sunxi/psci.c
-@@ -38,6 +38,19 @@
- #define SUN8I_R40_PWR_CLAMP(cpu)              (0x120 + (cpu) * 0x4)
- #define SUN8I_R40_SRAMC_SOFT_ENTRY_REG0               (0xbc)
-+/*
-+ * R528 is also different, as it has both cores powered up (but held in reset
-+ * state) after the SoC is reset. Like the R40, it uses a "soft" entry point
-+ * address register, but unlike the R40, it uses a newer "CPUX" block to manage
-+ * CPU state, rather than the older CPUCFG system.
-+ */
-+#define SUN8I_R528_SOFT_ENTRY                 (0x1c8)
-+#define SUN8I_R528_C0_RST_CTRL                        (0x0000)
-+#define SUN8I_R528_C0_CTRL_REG0                       (0x0010)
-+#define SUN8I_R528_C0_CPU_STATUS              (0x0080)
-+
-+#define SUN8I_R528_C0_STATUS_STANDBYWFI               (16)
-+
- static void __secure cp15_write_cntp_tval(u32 tval)
- {
-       asm volatile ("mcr p15, 0, %0, c14, c2, 0" : : "r" (tval));
-@@ -116,10 +129,13 @@ static void __secure sunxi_power_switch(u32 *clamp, u32 *pwroff, bool on,
- static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
- {
--      /* secondary core entry address is programmed differently on R40 */
-+      /* secondary core entry address is programmed differently on R40/528 */
-       if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
-               writel((u32)entry,
-                      SUNXI_SRAMC_BASE + SUN8I_R40_SRAMC_SOFT_ENTRY_REG0);
-+      } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
-+              writel((u32)entry,
-+                     SUNXI_R_CPUCFG_BASE + SUN8I_R528_SOFT_ENTRY);
-       } else {
-               struct sunxi_cpucfg_reg *cpucfg =
-                       (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-@@ -139,6 +155,8 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on)
-       } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) {
-               sunxi_power_switch(NULL, (void *)cpucfg + SUN8I_R40_PWROFF,
-                                  on, cpu);
-+      } else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
-+              /* R528 leaves both cores powered up, manages them via reset */
-       } else {
- #if !defined(CONFIG_SUN50I_GEN_H6) && !defined(CONFIG_SUNXI_GEN_NCAT2)
-               struct sunxi_prcm_reg *prcm =
-@@ -159,6 +177,17 @@ static void __secure sunxi_cpu_set_reset(int cpu, bool reset)
-       struct sunxi_cpucfg_reg *cpucfg =
-               (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+      if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
-+              if (reset) {
-+                      clrbits_le32(SUNXI_CPUX_BASE + SUN8I_R528_C0_RST_CTRL,
-+                                   BIT(cpu));
-+              } else {
-+                      setbits_le32(SUNXI_CPUX_BASE + SUN8I_R528_C0_RST_CTRL,
-+                                   BIT(cpu));
-+              }
-+              return;
-+      }
-+
-       writel(reset ? 0b00 : 0b11, &cpucfg->cpu[cpu].rst);
- }
-@@ -167,6 +196,11 @@ static void __secure sunxi_cpu_set_locking(int cpu, bool lock)
-       struct sunxi_cpucfg_reg *cpucfg =
-               (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+      if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
-+              /* Not required on R528 */
-+              return;
-+      }
-+
-       if (lock)
-               clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
-       else
-@@ -178,6 +212,11 @@ static bool __secure sunxi_cpu_poll_wfi(int cpu)
-       struct sunxi_cpucfg_reg *cpucfg =
-               (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+      if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
-+              return !!(readl(SUNXI_CPUX_BASE + SUN8I_R528_C0_CPU_STATUS) &
-+                        BIT(SUN8I_R528_C0_STATUS_STANDBYWFI + cpu));
-+      }
-+
-       return !!(readl(&cpucfg->cpu[cpu].status) & BIT(2));
- }
-@@ -186,6 +225,12 @@ static void __secure sunxi_cpu_invalidate_cache(int cpu)
-       struct sunxi_cpucfg_reg *cpucfg =
-               (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
-+      if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
-+              clrbits_le32(SUNXI_CPUX_BASE + SUN8I_R528_C0_CTRL_REG0,
-+                           BIT(cpu));
-+              return;
-+      }
-+
-       clrbits_le32(&cpucfg->gen_ctrl, BIT(cpu));
- }
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index 59fa62c8d5..1d126a00ec 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -321,6 +321,8 @@ config MACH_SUN8I_R40
- config MACH_SUN8I_R528
-       bool "sun8i (Allwinner R528)"
-       select CPU_V7A
-+      select CPU_V7_HAS_NONSEC
-+      select ARCH_SUPPORT_PSCI
-       select SUNXI_GEN_NCAT2
-       select SUNXI_NEW_PINCTRL
-       select MMC_SUNXI_HAS_NEW_MODE
-diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
-index 2a8c54a7a8..0f6086e54f 100644
---- a/include/configs/sunxi-common.h
-+++ b/include/configs/sunxi-common.h
-@@ -34,6 +34,14 @@
- /* CPU */
-+/*
-+ * Newer ARM SoCs have moved the GIC, but have not updated their ARM cores to
-+ * reflect the correct address in CBAR/PERIPHBASE.
-+ */
-+#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
-+#define CFG_ARM_GIC_BASE_ADDRESS      0x03020000
-+#endif
-+
- /*
-  * The DRAM Base differs between some models. We cannot use macros for the
-  * CONFIG_FOO defines which contain the DRAM base address since they end
--- 
-2.20.1
-
diff --git a/package/boot/uboot-sunxi/patches/4200-spi.patch b/package/boot/uboot-sunxi/patches/4200-spi.patch
deleted file mode 100644 (file)
index c4d20f5..0000000
+++ /dev/null
@@ -1,751 +0,0 @@
-From patchwork Fri May 19 13:40:07 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Maksim Kiselev <bigunclemax@gmail.com>
-X-Patchwork-Id: 1783781
-X-Patchwork-Delegate: andre.przywara@arm.com
-Return-Path: <u-boot-bounces@lists.denx.de>
-X-Original-To: incoming@patchwork.ozlabs.org
-Delivered-To: patchwork-incoming@legolas.ozlabs.org
-Authentication-Results: legolas.ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
- (client-ip=85.214.62.61; helo=phobos.denx.de;
- envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)
-Authentication-Results: legolas.ozlabs.org;
-       dkim=pass (2048-bit key;
- unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256
- header.s=20221208 header.b=cTD9tSbd;
-       dkim-atps=neutral
-Received: from phobos.denx.de (phobos.denx.de [85.214.62.61])
-       (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
-        key-exchange X25519 server-signature ECDSA (P-384))
-       (No client certificate requested)
-       by legolas.ozlabs.org (Postfix) with ESMTPS id 4QN7Jx1TH1z20dv
-       for <incoming@patchwork.ozlabs.org>; Fri, 19 May 2023 23:40:49 +1000 (AEST)
-Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
-       by phobos.denx.de (Postfix) with ESMTP id BC5EE86312;
-       Fri, 19 May 2023 15:40:37 +0200 (CEST)
-Authentication-Results: phobos.denx.de;
- dmarc=pass (p=none dis=none) header.from=gmail.com
-Authentication-Results: phobos.denx.de;
- spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
-Authentication-Results: phobos.denx.de;
-       dkim=pass (2048-bit key;
- unprotected) header.d=gmail.com header.i=@gmail.com header.b="cTD9tSbd";
-       dkim-atps=neutral
-Received: by phobos.denx.de (Postfix, from userid 109)
- id 76B3D86312; Fri, 19 May 2023 15:40:35 +0200 (CEST)
-X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
-X-Spam-Level: 
-X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,
- DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE,
- SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no
- version=3.4.2
-Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com
- [IPv6:2a00:1450:4864:20::42c])
- (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))
- (No client certificate requested)
- by phobos.denx.de (Postfix) with ESMTPS id 5F8AE862F7
- for <u-boot@lists.denx.de>; Fri, 19 May 2023 15:40:32 +0200 (CEST)
-Authentication-Results: phobos.denx.de;
- dmarc=pass (p=none dis=none) header.from=gmail.com
-Authentication-Results: phobos.denx.de;
- spf=pass smtp.mailfrom=bigunclemax@gmail.com
-Received: by mail-wr1-x42c.google.com with SMTP id
- ffacd0b85a97d-30957dd7640so370247f8f.3
- for <u-boot@lists.denx.de>; Fri, 19 May 2023 06:40:32 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20221208; t=1684503631; x=1687095631;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=YUP1z0w4h2cZv/wQXQCw1Cy1zgJe6JHGfqSmy2vVnL8=;
- b=cTD9tSbdyQlxF0Y7erPxsd79LYuLiPINAeD1DMRr/7GOIs4kwUj3c+aIdBEPDd2sNx
- QUUWCtJO8xyhoqLLZPq6VRe4vgHDv6xGVMZGEKJ+WtKyZ3ki9MTyErk/jL0xZMTlMYdk
- os6PhwH/RpouCAMKTMyq++YZtUBMRnLMF/9nc7vwWLPEmx/2U4za8Qe90XS02sB/hwsT
- HU4v0YoXBkX2drI2tERNRIKzsIXJRoeu3mwV4QW8dDkGkIP45XtW2BqQjgCwd19q4LOf
- cnlkGxCIlk5fuS5QghrV+W1tN7S1hGLCHgD4U3ddN4sZHhCxZTOnBYxUEHMCLnV3XZsy
- 4xFg==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20221208; t=1684503631; x=1687095631;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=YUP1z0w4h2cZv/wQXQCw1Cy1zgJe6JHGfqSmy2vVnL8=;
- b=KjEg432zx44xNg4Z1IwQygnJdbxJPj9HjQq03tgXlZF6K3tBgBrjSuzzq1Gbvlz6PZ
- LhlH3p0PzZpJpNwxIVul5ETVJAKUBYPmVgziizxy54jhi7INZF5OYiv9504QKW5slpBv
- R4lq+U/kRVbgfydEXRBdE6vbDPfUvg6kHtHT1S14Cd+KZXI1mplmaQulTBmSXpTH0UH9
- KF9DNiZXlS2zU64vkurAlefEj78IIHt4b1O6qEgpBi+rt6ah4RW5Uapn296g/Dgy6b/T
- QCjmIh5KVlFOTi9vFwTPKDo9qQ0Nzq709I5rxhNNZEbuO0Gd/nSk+RzvYHAEjBFpAnJe
- Fe1g==
-X-Gm-Message-State: AC+VfDyvlP1JR37qkV9MYt5TDplSIUbUgxJODKI0TwJTMNVb/VhJVqrd
- 9zNxItUGraxvDCAiwxhXu/mYGBxAhKs=
-X-Google-Smtp-Source: 
- ACHHUZ5G99dPHkK4AviYJ4YM/vZ1llN4335rcmycK/cfHMEFhg609FaTXuZb6u10r9U2wYvZcRHwKQ==
-X-Received: by 2002:adf:e60b:0:b0:309:a4e:52d3 with SMTP id
- p11-20020adfe60b000000b003090a4e52d3mr2047534wrm.5.1684503631220;
- Fri, 19 May 2023 06:40:31 -0700 (PDT)
-Received: from localhost.localdomain ([176.221.215.212])
- by smtp.gmail.com with ESMTPSA id
- l5-20020adfe585000000b002f7780eee10sm5315421wrm.59.2023.05.19.06.40.30
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Fri, 19 May 2023 06:40:30 -0700 (PDT)
-From: Maxim Kiselev <bigunclemax@gmail.com>
-To: u-boot@lists.denx.de
-Cc: Maxim Kiselev <bigunclemax@gmail.com>,
- Jagan Teki <jagan@amarulasolutions.com>,
- Andre Przywara <andre.przywara@arm.com>, Rick Chen <rick@andestech.com>,
- Leo <ycliang@andestech.com>
-Subject: [RFC PATCH v1 1/3] sunxi: SPL SPI: Add SPI boot support for the
- Allwinner R528/T113 SoCs
-Date: Fri, 19 May 2023 16:40:07 +0300
-Message-Id: <20230519134010.3102343-2-bigunclemax@gmail.com>
-X-Mailer: git-send-email 2.39.2
-In-Reply-To: <20230519134010.3102343-1-bigunclemax@gmail.com>
-References: <20230519134010.3102343-1-bigunclemax@gmail.com>
-MIME-Version: 1.0
-X-BeenThere: u-boot@lists.denx.de
-X-Mailman-Version: 2.1.39
-Precedence: list
-List-Id: U-Boot discussion <u-boot.lists.denx.de>
-List-Unsubscribe: <https://lists.denx.de/options/u-boot>,
- <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>
-List-Archive: <https://lists.denx.de/pipermail/u-boot/>
-List-Post: <mailto:u-boot@lists.denx.de>
-List-Help: <mailto:u-boot-request@lists.denx.de?subject=help>
-List-Subscribe: <https://lists.denx.de/listinfo/u-boot>,
- <mailto:u-boot-request@lists.denx.de?subject=subscribe>
-Errors-To: u-boot-bounces@lists.denx.de
-Sender: "U-Boot" <u-boot-bounces@lists.denx.de>
-X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de
-X-Virus-Status: Clean
-
-R528/T113 SoCs uses the same SPI IP as the H6, also have the same clocks
-and reset bits layout, but the CCU base is different. Another difference
-is that the new SoCs do not have a clock divider inside. Instead of this
-we should configure sample mode depending on input clock rate.
-
-The pin assignment is also different: the H6 uses PC0, the R528/T113 PC4
-instead. This makes for a change in spi0_pinmux_setup() routine.
-
-This patch extends the H6/H616 #ifdef guards to also cover the R528/T113,
-using the shared CONFIG_SUNXI_GEN_NCAT2 and CONFIG_MACH_SUN8I_R528
-symbols. Also use CONFIG_SUNXI_GEN_NCAT2 symbol for the Kconfig
-dependency.
-
-Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
-Tested-by: Sam Edwards <CFSworks@gmail.com>
----
- arch/arm/mach-sunxi/Kconfig         |  2 +-
- arch/arm/mach-sunxi/spl_spi_sunxi.c | 78 +++++++++++++++++++++--------
- 2 files changed, 58 insertions(+), 22 deletions(-)
-
-diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
-index 142d86afc6..210dd41176 100644
---- a/arch/arm/mach-sunxi/Kconfig
-+++ b/arch/arm/mach-sunxi/Kconfig
-@@ -998,7 +998,7 @@ config SPL_STACK_R_ADDR
- config SPL_SPI_SUNXI
-       bool "Support for SPI Flash on Allwinner SoCs in SPL"
--      depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV
-+      depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV || SUNXI_GEN_NCAT2
-       help
-         Enable support for SPI Flash. This option allows SPL to read from
-         sunxi SPI Flash. It uses the same method as the boot ROM, so does
-diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
-index c2410dd7bb..3cfbf56d59 100644
---- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
-+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
-@@ -73,18 +73,27 @@
- #define SUN6I_CTL_ENABLE            BIT(0)
- #define SUN6I_CTL_MASTER            BIT(1)
- #define SUN6I_CTL_SRST              BIT(31)
-+#define SUN6I_TCR_SDM               BIT(13)
- #define SUN6I_TCR_XCH               BIT(31)
- /*****************************************************************************/
--#define CCM_AHB_GATING0             (0x01C20000 + 0x60)
--#define CCM_H6_SPI_BGR_REG          (0x03001000 + 0x96c)
--#ifdef CONFIG_SUN50I_GEN_H6
--#define CCM_SPI0_CLK                (0x03001000 + 0x940)
-+#if defined(CONFIG_SUN50I_GEN_H6)
-+#define CCM_BASE                    0x03001000
-+#elif defined(CONFIG_SUNXI_GEN_NCAT2)
-+#define CCM_BASE                    0x02001000
- #else
--#define CCM_SPI0_CLK                (0x01C20000 + 0xA0)
-+#define CCM_BASE                    0x01C20000
- #endif
--#define SUN6I_BUS_SOFT_RST_REG0     (0x01C20000 + 0x2C0)
-+
-+#define CCM_AHB_GATING0             (CCM_BASE + 0x60)
-+#define CCM_H6_SPI_BGR_REG          (CCM_BASE + 0x96c)
-+#if defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
-+#define CCM_SPI0_CLK                (CCM_BASE + 0x940)
-+#else
-+#define CCM_SPI0_CLK                (CCM_BASE + 0xA0)
-+#endif
-+#define SUN6I_BUS_SOFT_RST_REG0     (CCM_BASE + 0x2C0)
- #define AHB_RESET_SPI0_SHIFT        20
- #define AHB_GATE_OFFSET_SPI0        20
-@@ -102,17 +111,22 @@
-  */
- static void spi0_pinmux_setup(unsigned int pin_function)
- {
--      /* All chips use PC0 and PC2. */
--      sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function);
-+      /* All chips use PC2. And all chips use PC0, except R528/T113 */
-+      if (!IS_ENABLED(CONFIG_MACH_SUN8I_R528))
-+              sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function);
-+
-       sunxi_gpio_set_cfgpin(SUNXI_GPC(2), pin_function);
--      /* All chips except H6 and H616 use PC1. */
--      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-+      /* All chips except H6/H616/R528/T113 use PC1. */
-+      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) &&
-+          !IS_ENABLED(CONFIG_MACH_SUN8I_R528))
-               sunxi_gpio_set_cfgpin(SUNXI_GPC(1), pin_function);
--      if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
-+      if (IS_ENABLED(CONFIG_MACH_SUN50I_H6) ||
-+          IS_ENABLED(CONFIG_MACH_SUN8I_R528))
-               sunxi_gpio_set_cfgpin(SUNXI_GPC(5), pin_function);
--      if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
-+      if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) ||
-+          IS_ENABLED(CONFIG_MACH_SUN8I_R528))
-               sunxi_gpio_set_cfgpin(SUNXI_GPC(4), pin_function);
-       /* Older generations use PC23 for CS, newer ones use PC3. */
-@@ -126,7 +140,8 @@ static void spi0_pinmux_setup(unsigned int pin_function)
- static bool is_sun6i_gen_spi(void)
- {
-       return IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ||
--             IS_ENABLED(CONFIG_SUN50I_GEN_H6);
-+             IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
-+             IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2);
- }
- static uintptr_t spi0_base_address(void)
-@@ -137,6 +152,9 @@ static uintptr_t spi0_base_address(void)
-       if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-               return 0x05010000;
-+      if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-+              return 0x04025000;
-+
-       if (!is_sun6i_gen_spi() ||
-           IS_ENABLED(CONFIG_MACH_SUNIV))
-               return 0x01C05000;
-@@ -152,23 +170,30 @@ static void spi0_enable_clock(void)
-       uintptr_t base = spi0_base_address();
-       /* Deassert SPI0 reset on SUN6I */
--      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-+      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
-+          IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-               setbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1);
-       else if (is_sun6i_gen_spi())
-               setbits_le32(SUN6I_BUS_SOFT_RST_REG0,
-                            (1 << AHB_RESET_SPI0_SHIFT));
-       /* Open the SPI0 gate */
--      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-+      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) &&
-+          !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-               setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
-       if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
-               /* Divide by 32, clock source is AHB clock 200MHz */
-               writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL);
-       } else {
--              /* Divide by 4 */
--              writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
--                                        SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
-+              /* New SoCs do not have a clock divider inside */
-+              if (!IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) {
-+                      /* Divide by 4 */
-+                      writel(SPI0_CLK_DIV_BY_4,
-+                             base + (is_sun6i_gen_spi() ? SUN6I_SPI0_CCTL :
-+                             SUN4I_SPI0_CCTL));
-+              }
-+
-               /* 24MHz from OSC24M */
-               writel((1 << 31), CCM_SPI0_CLK);
-       }
-@@ -180,6 +205,14 @@ static void spi0_enable_clock(void)
-               /* Wait for completion */
-               while (readl(base + SUN6I_SPI0_GCR) & SUN6I_CTL_SRST)
-                       ;
-+
-+              /*
-+               * For new SoCs we should configure sample mode depending on
-+               * input clock. As 24MHz from OSC24M is used, we could use
-+               * normal sample mode by setting SDM bit in the TCR register
-+               */
-+              if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-+                      setbits_le32(base + SUN6I_SPI0_TCR, SUN6I_TCR_SDM);
-       } else {
-               /* Enable SPI in the master mode and reset FIFO */
-               setbits_le32(base + SUN4I_SPI0_CTL, SUN4I_CTL_MASTER |
-@@ -206,11 +239,13 @@ static void spi0_disable_clock(void)
-               writel(0, CCM_SPI0_CLK);
-       /* Close the SPI0 gate */
--      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-+      if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) &&
-+          !IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-               clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
-       /* Assert SPI0 reset on SUN6I */
--      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-+      if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
-+          IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2))
-               clrbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1);
-       else if (is_sun6i_gen_spi())
-               clrbits_le32(SUN6I_BUS_SOFT_RST_REG0,
-@@ -224,7 +259,8 @@ static void spi0_init(void)
-       if (IS_ENABLED(CONFIG_MACH_SUN50I) ||
-           IS_ENABLED(CONFIG_SUN50I_GEN_H6))
-               pin_function = SUN50I_GPC_SPI0;
--      else if (IS_ENABLED(CONFIG_MACH_SUNIV))
-+      else if (IS_ENABLED(CONFIG_MACH_SUNIV) ||
-+               IS_ENABLED(CONFIG_MACH_SUN8I_R528))
-               pin_function = SUNIV_GPC_SPI0;
-       spi0_pinmux_setup(pin_function);
-
-From patchwork Fri May 19 13:40:08 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Maksim Kiselev <bigunclemax@gmail.com>
-X-Patchwork-Id: 1783782
-X-Patchwork-Delegate: andre.przywara@arm.com
-Return-Path: <u-boot-bounces@lists.denx.de>
-X-Original-To: incoming@patchwork.ozlabs.org
-Delivered-To: patchwork-incoming@legolas.ozlabs.org
-Authentication-Results: legolas.ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
- (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;
- envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)
-Authentication-Results: legolas.ozlabs.org;
-       dkim=pass (2048-bit key;
- unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256
- header.s=20221208 header.b=XVN86gy6;
-       dkim-atps=neutral
-Received: from phobos.denx.de (phobos.denx.de
- [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])
-       (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
-        key-exchange X25519 server-signature ECDSA (P-384))
-       (No client certificate requested)
-       by legolas.ozlabs.org (Postfix) with ESMTPS id 4QN7KH4Bzbz20dv
-       for <incoming@patchwork.ozlabs.org>; Fri, 19 May 2023 23:41:07 +1000 (AEST)
-Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
-       by phobos.denx.de (Postfix) with ESMTP id 0451386328;
-       Fri, 19 May 2023 15:40:42 +0200 (CEST)
-Authentication-Results: phobos.denx.de;
- dmarc=pass (p=none dis=none) header.from=gmail.com
-Authentication-Results: phobos.denx.de;
- spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
-Authentication-Results: phobos.denx.de;
-       dkim=pass (2048-bit key;
- unprotected) header.d=gmail.com header.i=@gmail.com header.b="XVN86gy6";
-       dkim-atps=neutral
-Received: by phobos.denx.de (Postfix, from userid 109)
- id 8B5B986327; Fri, 19 May 2023 15:40:40 +0200 (CEST)
-X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
-X-Spam-Level: 
-X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,
- DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE,
- SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no
- version=3.4.2
-Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com
- [IPv6:2a00:1450:4864:20::42a])
- (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))
- (No client certificate requested)
- by phobos.denx.de (Postfix) with ESMTPS id 4A39286131
- for <u-boot@lists.denx.de>; Fri, 19 May 2023 15:40:37 +0200 (CEST)
-Authentication-Results: phobos.denx.de;
- dmarc=pass (p=none dis=none) header.from=gmail.com
-Authentication-Results: phobos.denx.de;
- spf=pass smtp.mailfrom=bigunclemax@gmail.com
-Received: by mail-wr1-x42a.google.com with SMTP id
- ffacd0b85a97d-307d20548adso2178236f8f.0
- for <u-boot@lists.denx.de>; Fri, 19 May 2023 06:40:37 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20221208; t=1684503636; x=1687095636;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=y8+rF/p5Jdncjufm65vWHEGLS+C/ytaDC9RSOXQj3YY=;
- b=XVN86gy67HoVcRBvpuLqZWNZjA0qoeGsc1plc19OUmaDbDkfIz97H+xr4reZEBCj12
- PokzHuazEC6QCiGZI46+hcptobvX09pQGcfer9yoxdFD7W7w9uDhwAgceQZ9NILRaH/I
- gvaxtYIQ9jjvb60TnHm3E9ORj5KlcY3aS1B2iDBw3tstlcrKeLTT2gWaSvZf4m4WBaF3
- R0fz+CDnjhfAAZkyj9vr9/wvPSl4aVe/MxctoNRRZOTW3nC5Vr7G9OMH5V9wtlp5X9f/
- FFOfUSx62PitgyezRFVsdororOdlHsSqq9tGh9qaVbBPBtGWI0J69haBU/Vi5OVBUox/
- C+Wg==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20221208; t=1684503636; x=1687095636;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=y8+rF/p5Jdncjufm65vWHEGLS+C/ytaDC9RSOXQj3YY=;
- b=BIVofAJc2HA5kiEUXl6+vfzeq5peOA4vRnGVTtbcSRRoATcx72Yv+fTJEjA7usMwB7
- 3DMiHkH14gVXqDLM020VfVyJI9s3Wa2eQAracOP2LaBMOhDuG/XoLdGTomPPbA/hDNdk
- w+RWBpG0oY3dpjEgsGTOo7op70GZ2ugI5SYe8ZIFTTO8DN71MYq/z0wo6On4k9l5X3sP
- nv15nZkgqzwBVi8n+zSuz+ocXR08O9c+pgqWNoX7XwohjHjU9EOhNosihH1HKv/WpV6G
- /VNimAooGEcGiulbeMgirYC2qOb9/nq6TzFa7xnYNff3MR5MDE4G7s+wlfaB0/WwD+sU
- +C7g==
-X-Gm-Message-State: AC+VfDzbvvkLM5kEmV1WxzB5hTeKHweME4U+BnwLiEXS8cX2Tj5flr98
- DRNdhkguOOYWqDZIPsvxebO06NiixPk=
-X-Google-Smtp-Source: 
- ACHHUZ5ZYgm4pzeYsvUicktbj4rwgRUtHboj9r3ofAcxlNjpTAnaHo/yhaOSHex344NVs25oWALOmg==
-X-Received: by 2002:adf:df84:0:b0:306:2dc3:8b67 with SMTP id
- z4-20020adfdf84000000b003062dc38b67mr1991533wrl.53.1684503636216;
- Fri, 19 May 2023 06:40:36 -0700 (PDT)
-Received: from localhost.localdomain ([176.221.215.212])
- by smtp.gmail.com with ESMTPSA id
- l5-20020adfe585000000b002f7780eee10sm5315421wrm.59.2023.05.19.06.40.35
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Fri, 19 May 2023 06:40:35 -0700 (PDT)
-From: Maxim Kiselev <bigunclemax@gmail.com>
-To: u-boot@lists.denx.de
-Cc: Maxim Kiselev <bigunclemax@gmail.com>,
- Jagan Teki <jagan@amarulasolutions.com>,
- Andre Przywara <andre.przywara@arm.com>, Rick Chen <rick@andestech.com>,
- Leo <ycliang@andestech.com>
-Subject: [RFC PATCH v1 2/3] spi: sunxi: Add support for R329/D1/R528/T113 SPI
- controller
-Date: Fri, 19 May 2023 16:40:08 +0300
-Message-Id: <20230519134010.3102343-3-bigunclemax@gmail.com>
-X-Mailer: git-send-email 2.39.2
-In-Reply-To: <20230519134010.3102343-1-bigunclemax@gmail.com>
-References: <20230519134010.3102343-1-bigunclemax@gmail.com>
-MIME-Version: 1.0
-X-BeenThere: u-boot@lists.denx.de
-X-Mailman-Version: 2.1.39
-Precedence: list
-List-Id: U-Boot discussion <u-boot.lists.denx.de>
-List-Unsubscribe: <https://lists.denx.de/options/u-boot>,
- <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>
-List-Archive: <https://lists.denx.de/pipermail/u-boot/>
-List-Post: <mailto:u-boot@lists.denx.de>
-List-Help: <mailto:u-boot-request@lists.denx.de?subject=help>
-List-Subscribe: <https://lists.denx.de/listinfo/u-boot>,
- <mailto:u-boot-request@lists.denx.de?subject=subscribe>
-Errors-To: u-boot-bounces@lists.denx.de
-Sender: "U-Boot" <u-boot-bounces@lists.denx.de>
-X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de
-X-Virus-Status: Clean
-
-These SoCs have two SPI controllers that are quite similar to the SPI
-on previous Allwinner SoCs. The main difference is that new SoCs
-don't have a clock divider (SPI_CCR register) inside SPI IP.
-
-Instead SPI sample mode should be configured depending on the input clock.
-
-For now SPI input clock source selection is not supported by this driver,
-and only HOSC@24MHz can be used as input clock. Therefore, according to
-the, manual we could change the SPI sample mode from delay half
-cycle(default) to normal.
-
-This patch adds a quirk for this kind of SPI controllers
-
-Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
-Tested-by: Sam Edwards <CFSworks@gmail.com>
----
- drivers/spi/spi-sunxi.c | 34 +++++++++++++++++++++++++++++++++-
- 1 file changed, 33 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c
-index c56d82d998..9ec6b359e2 100644
---- a/drivers/spi/spi-sunxi.c
-+++ b/drivers/spi/spi-sunxi.c
-@@ -117,6 +117,8 @@ enum sun4i_spi_bits {
-       SPI_TCR_XCH,
-       SPI_TCR_CS_MANUAL,
-       SPI_TCR_CS_LEVEL,
-+      SPI_TCR_SDC,
-+      SPI_TCR_SDM,
-       SPI_FCR_TF_RST,
-       SPI_FCR_RF_RST,
-       SPI_FSR_RF_CNT_MASK,
-@@ -128,6 +130,7 @@ struct sun4i_spi_variant {
-       u32 fifo_depth;
-       bool has_soft_reset;
-       bool has_burst_ctl;
-+      bool has_clk_ctl;
- };
- struct sun4i_spi_plat {
-@@ -302,7 +305,19 @@ static int sun4i_spi_claim_bus(struct udevice *dev)
-       setbits_le32(SPI_REG(priv, SPI_TCR), SPI_BIT(priv, SPI_TCR_CS_MANUAL) |
-                    SPI_BIT(priv, SPI_TCR_CS_ACTIVE_LOW));
--      sun4i_spi_set_speed_mode(dev->parent);
-+      if (priv->variant->has_clk_ctl) {
-+              sun4i_spi_set_speed_mode(dev->parent);
-+      } else {
-+              /*
-+               * At this moment there is no ability to change input clock.
-+               * Therefore, we can only use default HOSC@24MHz clock and
-+               * set SPI sampling mode to normal
-+               */
-+              clrsetbits_le32(SPI_REG(priv, SPI_TCR),
-+                              SPI_BIT(priv, SPI_TCR_SDC) |
-+                              SPI_BIT(priv, SPI_TCR_SDM),
-+                              SPI_BIT(priv, SPI_TCR_SDM));
-+      }
-       return 0;
- }
-@@ -516,6 +531,8 @@ static const u32 sun6i_spi_bits[] = {
-       [SPI_TCR_CS_MASK]       = 0x30,
-       [SPI_TCR_CS_MANUAL]     = BIT(6),
-       [SPI_TCR_CS_LEVEL]      = BIT(7),
-+      [SPI_TCR_SDC]           = BIT(11),
-+      [SPI_TCR_SDM]           = BIT(13),
-       [SPI_TCR_XCH]           = BIT(31),
-       [SPI_FCR_RF_RST]        = BIT(15),
-       [SPI_FCR_TF_RST]        = BIT(31),
-@@ -526,6 +543,7 @@ static const struct sun4i_spi_variant sun4i_a10_spi_variant = {
-       .regs                   = sun4i_spi_regs,
-       .bits                   = sun4i_spi_bits,
-       .fifo_depth             = 64,
-+      .has_clk_ctl            = true,
- };
- static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
-@@ -534,6 +552,7 @@ static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
-       .fifo_depth             = 128,
-       .has_soft_reset         = true,
-       .has_burst_ctl          = true,
-+      .has_clk_ctl            = true,
- };
- static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
-@@ -542,6 +561,15 @@ static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
-       .fifo_depth             = 64,
-       .has_soft_reset         = true,
-       .has_burst_ctl          = true,
-+      .has_clk_ctl            = true,
-+};
-+
-+static const struct sun4i_spi_variant sun50i_r329_spi_variant = {
-+      .regs                   = sun6i_spi_regs,
-+      .bits                   = sun6i_spi_bits,
-+      .fifo_depth             = 64,
-+      .has_soft_reset         = true,
-+      .has_burst_ctl          = true,
- };
- static const struct udevice_id sun4i_spi_ids[] = {
-@@ -557,6 +585,10 @@ static const struct udevice_id sun4i_spi_ids[] = {
-         .compatible = "allwinner,sun8i-h3-spi",
-         .data = (ulong)&sun8i_h3_spi_variant,
-       },
-+      {
-+        .compatible = "allwinner,sun50i-r329-spi",
-+        .data = (ulong)&sun50i_r329_spi_variant,
-+      },
-       { /* sentinel */ }
- };
-
-From patchwork Fri May 19 13:40:09 2023
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Maksim Kiselev <bigunclemax@gmail.com>
-X-Patchwork-Id: 1783783
-X-Patchwork-Delegate: andre.przywara@arm.com
-Return-Path: <u-boot-bounces@lists.denx.de>
-X-Original-To: incoming@patchwork.ozlabs.org
-Delivered-To: patchwork-incoming@legolas.ozlabs.org
-Authentication-Results: legolas.ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
- (client-ip=85.214.62.61; helo=phobos.denx.de;
- envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)
-Authentication-Results: legolas.ozlabs.org;
-       dkim=pass (2048-bit key;
- unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256
- header.s=20221208 header.b=WKEkOHKi;
-       dkim-atps=neutral
-Received: from phobos.denx.de (phobos.denx.de [85.214.62.61])
-       (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
-        key-exchange X25519 server-signature ECDSA (P-384))
-       (No client certificate requested)
-       by legolas.ozlabs.org (Postfix) with ESMTPS id 4QN7KT2Ntcz20dv
-       for <incoming@patchwork.ozlabs.org>; Fri, 19 May 2023 23:41:17 +1000 (AEST)
-Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
-       by phobos.denx.de (Postfix) with ESMTP id 4EBFA8634E;
-       Fri, 19 May 2023 15:40:47 +0200 (CEST)
-Authentication-Results: phobos.denx.de;
- dmarc=pass (p=none dis=none) header.from=gmail.com
-Authentication-Results: phobos.denx.de;
- spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
-Authentication-Results: phobos.denx.de;
-       dkim=pass (2048-bit key;
- unprotected) header.d=gmail.com header.i=@gmail.com header.b="WKEkOHKi";
-       dkim-atps=neutral
-Received: by phobos.denx.de (Postfix, from userid 109)
- id 7157D86334; Fri, 19 May 2023 15:40:43 +0200 (CEST)
-X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
-X-Spam-Level: 
-X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,
- DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE,
- SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no
- version=3.4.2
-Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com
- [IPv6:2a00:1450:4864:20::432])
- (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))
- (No client certificate requested)
- by phobos.denx.de (Postfix) with ESMTPS id C224E86131
- for <u-boot@lists.denx.de>; Fri, 19 May 2023 15:40:40 +0200 (CEST)
-Authentication-Results: phobos.denx.de;
- dmarc=pass (p=none dis=none) header.from=gmail.com
-Authentication-Results: phobos.denx.de;
- spf=pass smtp.mailfrom=bigunclemax@gmail.com
-Received: by mail-wr1-x432.google.com with SMTP id
- ffacd0b85a97d-309550d4f73so501090f8f.1
- for <u-boot@lists.denx.de>; Fri, 19 May 2023 06:40:40 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20221208; t=1684503640; x=1687095640;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:from:to:cc:subject:date
- :message-id:reply-to;
- bh=NrlUXRmVOv93TD0HdBbwH04KM6T5eHPc/wRD/kVHw50=;
- b=WKEkOHKiGzpdoQNn0FShQ9ESX297aAOR2qdZ43W5RSGiXWij7hEgbg3BzrPR3w9okx
- X21Je0wJ4l+VUyv48EHiHlhMezq1Vgk44Ne/aOOYikouUf8k6fkjzjoT9wkw0x+Sqgr6
- MgodDFL5CQ1qpMCU3lQxKqSE1eVQd1O2KNT5JMucQrnux/0gLwAf3sLczeydvCvK0nv8
- m3vmYqBy/w8MzGD4ogeM1slUX24ilT7wZHx1fDoz2K6ygRgeN7UzRJP9iqNMuxjVWj2o
- YLngIulrlZarjLLeH8Yas8HPrycICIb+QgA84WIY65U+F0s5Bliv/EW1CIqFPBFxrxET
- OhUQ==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20221208; t=1684503640; x=1687095640;
- h=content-transfer-encoding:mime-version:references:in-reply-to
- :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
- :subject:date:message-id:reply-to;
- bh=NrlUXRmVOv93TD0HdBbwH04KM6T5eHPc/wRD/kVHw50=;
- b=L3leC190RMssJ8neJlB3kWCGFUE71ArJn2vb/I6cuJ1N/CJ3XZRIdjsDUFNw7ED//R
- 2JpNx3x7mnB/fhojtzCkk+UuzkRuZNISO/Bgu/7pxVoRVth4aEx7frZ+boGZlMy9oUQ0
- KYPzme2rcMGpi+Gl2P9Rv65K3jrnZs7N+r2VvcEDd+Y3TmL+xogAuuC+2l46qJHQ2qXT
- OOHfKXTsAxyc5vOKrL7WpF+EynCAWhuj03Ps4FxQfllOA4CGGiEUv5jKm0yM8D/HpBz8
- ys1nHELarilGdHatUQO5gAB87Ir9vKsfTKt9hleIFJdWN1B0wvXYi0o2Lkj8TCI5D3l2
- SE9w==
-X-Gm-Message-State: AC+VfDyMqvODjmLMCPv0QeUpXa78p1k0ZcyJHKZLfTTaiVbDjq+aL7JT
- c4Qx93jxKzpnkxV7RPOXLurVp/bZ8qA=
-X-Google-Smtp-Source: 
- ACHHUZ6RxZNvSxCvoRohqWdRTv2thSi33TWc4CN0RsmFexdSvPZtKWRMQQ7Nqt/2bACBm66BUi/Qcw==
-X-Received: by 2002:a5d:5305:0:b0:306:3ec9:99c5 with SMTP id
- e5-20020a5d5305000000b003063ec999c5mr1949351wrv.9.1684503639737;
- Fri, 19 May 2023 06:40:39 -0700 (PDT)
-Received: from localhost.localdomain ([176.221.215.212])
- by smtp.gmail.com with ESMTPSA id
- l5-20020adfe585000000b002f7780eee10sm5315421wrm.59.2023.05.19.06.40.38
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Fri, 19 May 2023 06:40:39 -0700 (PDT)
-From: Maxim Kiselev <bigunclemax@gmail.com>
-To: u-boot@lists.denx.de
-Cc: Maxim Kiselev <bigunclemax@gmail.com>,
- Jagan Teki <jagan@amarulasolutions.com>,
- Andre Przywara <andre.przywara@arm.com>, Rick Chen <rick@andestech.com>,
- Leo <ycliang@andestech.com>
-Subject: [RFC PATCH v1 3/3] riscv: dts: allwinner: d1: Add SPI controllers
- node
-Date: Fri, 19 May 2023 16:40:09 +0300
-Message-Id: <20230519134010.3102343-4-bigunclemax@gmail.com>
-X-Mailer: git-send-email 2.39.2
-In-Reply-To: <20230519134010.3102343-1-bigunclemax@gmail.com>
-References: <20230519134010.3102343-1-bigunclemax@gmail.com>
-MIME-Version: 1.0
-X-BeenThere: u-boot@lists.denx.de
-X-Mailman-Version: 2.1.39
-Precedence: list
-List-Id: U-Boot discussion <u-boot.lists.denx.de>
-List-Unsubscribe: <https://lists.denx.de/options/u-boot>,
- <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>
-List-Archive: <https://lists.denx.de/pipermail/u-boot/>
-List-Post: <mailto:u-boot@lists.denx.de>
-List-Help: <mailto:u-boot-request@lists.denx.de?subject=help>
-List-Subscribe: <https://lists.denx.de/listinfo/u-boot>,
- <mailto:u-boot-request@lists.denx.de?subject=subscribe>
-Errors-To: u-boot-bounces@lists.denx.de
-Sender: "U-Boot" <u-boot-bounces@lists.denx.de>
-X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de
-X-Virus-Status: Clean
-
-Some boards form the MangoPi family (MQ\MQ-Dual\MQ-R) may have
-an optional SPI flash that connects to the SPI0 controller.
-
-This controller is the same for R329/D1/R528/T113s SoCs and
-should be supported by the sun50i-r329-spi driver.
-
-So let's add its DT nodes.
-
-Signed-off-by: Maxim Kiselev <bigunclemax@gmail.com>
-Reviewed-by: Sam Edwards <CFSworks@gmail.com>
----
- arch/riscv/dts/sunxi-d1s-t113.dtsi | 37 ++++++++++++++++++++++++++++++
- 1 file changed, 37 insertions(+)
-
-diff --git a/arch/riscv/dts/sunxi-d1s-t113.dtsi b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-index a7c95f59a0..094ad0e460 100644
---- a/arch/riscv/dts/sunxi-d1s-t113.dtsi
-+++ b/arch/riscv/dts/sunxi-d1s-t113.dtsi
-@@ -123,6 +123,12 @@
-                               function = "emac";
-                       };
-+                      /omit-if-no-ref/
-+                      spi0_pins: spi0-pins {
-+                              pins = "PC2", "PC3", "PC4", "PC5";
-+                              function = "spi0";
-+                      };
-+
-                       /omit-if-no-ref/
-                       uart1_pg6_pins: uart1-pg6-pins {
-                               pins = "PG6", "PG7";
-@@ -456,6 +462,37 @@
-                       #size-cells = <0>;
-               };
-+              spi0: spi@4025000 {
-+                      compatible = "allwinner,sun20i-d1-spi",
-+                                   "allwinner,sun50i-r329-spi";
-+                      reg = <0x04025000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(15) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
-+                      clock-names = "ahb", "mod";
-+                      dmas = <&dma 22>, <&dma 22>;
-+                      dma-names = "rx", "tx";
-+                      resets = <&ccu RST_BUS_SPI0>;
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-+              spi1: spi@4026000 {
-+                      compatible = "allwinner,sun20i-d1-spi-dbi",
-+                                   "allwinner,sun50i-r329-spi-dbi",
-+                                   "allwinner,sun50i-r329-spi";
-+                      reg = <0x04026000 0x1000>;
-+                      interrupts = <SOC_PERIPHERAL_IRQ(16) IRQ_TYPE_LEVEL_HIGH>;
-+                      clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
-+                      clock-names = "ahb", "mod";
-+                      dmas = <&dma 23>, <&dma 23>;
-+                      dma-names = "rx", "tx";
-+                      resets = <&ccu RST_BUS_SPI1>;
-+                      status = "disabled";
-+                      #address-cells = <1>;
-+                      #size-cells = <0>;
-+              };
-+
-               usb_otg: usb@4100000 {
-                       compatible = "allwinner,sun20i-d1-musb",
-                                    "allwinner,sun8i-a33-musb";
diff --git a/package/boot/uboot-sunxi/patches/4201-myir-spi.patch b/package/boot/uboot-sunxi/patches/4201-myir-spi.patch
deleted file mode 100644 (file)
index 0d1dde5..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-diff -ruN u-boot-2023.04/arch/arm/dts/Makefile spi/arch/arm/dts/Makefile
---- u-boot-2023.04/arch/arm/dts/Makefile       2023-07-20 13:58:39.714010154 +0200
-+++ spi/arch/arm/dts/Makefile  2023-07-20 14:46:44.403569974 +0200
-@@ -715,6 +715,7 @@
-       sun8i-t113s-mangopi-mq-r-t113.dtb \
-       sun8i-t113s-mangopi-mqdual-t113.dtb \
-       sun8i-t113s-myir-myd-yt113x.dtb \
-+      sun8i-t113s-myir-myd-yt113x-spi.dtb \
-       sun8i-t113s-rongpin-rp-t113.dtb
- dtb-$(CONFIG_MACH_SUN50I_H5) += \
-       sun50i-h5-bananapi-m2-plus.dtb \
-diff -ruN u-boot-2023.04/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts spi/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts
---- u-boot-2023.04/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts    1970-01-01 01:00:00.000000000 +0100
-+++ spi/arch/arm/dts/sun8i-t113s-myir-myd-yt113x-spi.dts       2023-07-20 14:52:36.468334540 +0200
-@@ -0,0 +1,59 @@
-+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-+// Copyright (C) 2022 Arm Ltd.
-+
-+#include <dt-bindings/interrupt-controller/irq.h>
-+
-+/dts-v1/;
-+
-+#include "sun8i-t113s.dtsi"
-+#include "sunxi-d1s-t113-mangopi-mq-r.dtsi"
-+
-+/ {
-+      model = "MYIR MYD-YT113X (SPI)";
-+      compatible = "myir,myd-yt113x", "myir,myc-yt113x", "allwinner,sun8i-t113s";
-+
-+      aliases {
-+              serial5 = &uart5;
-+      };
-+
-+      chosen {
-+              stdout-path = "serial5:115200n8";
-+      };
-+};
-+
-+&cpu0 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&cpu1 {
-+      cpu-supply = <&reg_vcc_core>;
-+};
-+
-+&pio {
-+      /omit-if-no-ref/
-+      uart5_pins: uart5-pins {
-+              pins = "PE6", "PE7";
-+              function = "uart5";
-+      };
-+};
-+
-+&uart5 {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&uart5_pins>;
-+      status = "okay";
-+};
-+
-+&uart3 {
-+      status = "disabled";
-+};
-+
-+&spi0 {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&spi0_pins>;
-+      status = "okay";
-+      spi_nand@0 {
-+              compatible = "spi-nand";
-+              reg = <0>;
-+               spi-max-frequency = <52000000>;
-+      };
-+};
-diff -ruN u-boot-2023.04/configs/myir_myd_t113x-spi_defconfig spi/configs/myir_myd_t113x-spi_defconfig
---- u-boot-2023.04/configs/myir_myd_t113x-spi_defconfig        1970-01-01 01:00:00.000000000 +0100
-+++ spi/configs/myir_myd_t113x-spi_defconfig   2023-07-20 14:33:59.790587258 +0200
-@@ -0,0 +1,37 @@
-+CONFIG_ARM=y
-+CONFIG_ARCH_SUNXI=y
-+CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113s-myir-myd-yt113x-spi"
-+CONFIG_SUNXI_MINIMUM_DRAM_MB=128
-+CONFIG_SPL=y
-+CONFIG_SPL_SPI_SUNXI=y
-+CONFIG_MTD_SPI_NAND=y
-+CONFIG_MACH_SUN8I_R528=y
-+CONFIG_CONS_INDEX=6
-+CONFIG_MMC0_CD_PIN="PF6"
-+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-+CONFIG_SYS_MONITOR_LEN=786432
-+CONFIG_DRAM_CLK=792
-+CONFIG_DRAM_ZQ=8092667
-+CONFIG_DRAM_SUNXI_ODT_EN=0
-+CONFIG_DRAM_SUNXI_TPR0=0x004a2195
-+CONFIG_DRAM_SUNXI_TPR11=0x340000
-+CONFIG_DRAM_SUNXI_TPR12=0x46
-+CONFIG_DRAM_SUNXI_TPR13=0x34000100
-+CONFIG_PHY_MOTORCOMM=y
-+CONFIG_SUN8I_EMAC=y
-+CONFIG_RGMII=y
-+CONFIG_RMII=y
-+CONFIG_MTD=y
-+CONFIG_DM_MTD=y
-+CONFIG_SYS_MTDPARTS_RUNTIME=y
-+CONFIG_NAND_STM32_FMC2=y
-+CONFIG_SYS_NAND_ONFI_DETECTION=y
-+CONFIG_MTD_SPI_NAND=y
-+CONFIG_DM_SPI_FLASH=y
-+CONFIG_SPI_FLASH_MACRONIX=y
-+CONFIG_SPI_FLASH_SPANSION=y
-+CONFIG_SPI_FLASH_STMICRO=y
-+CONFIG_SPI_FLASH_WINBOND=y
-+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
-+CONFIG_SPI_FLASH_MTD=y
-+CONFIG_SPI=y