suniv: add new target
authorZoltan HERPAI <wigyori@uid0.hu>
Wed, 13 Mar 2019 23:24:50 +0000 (00:24 +0100)
committerZoltan HERPAI <wigyori@uid0.hu>
Thu, 21 Apr 2022 07:18:35 +0000 (09:18 +0200)
This is Allwinner's ARM926EJ-S core, which is one of its early
products, reappearing in recent compact designs. The SoC includes
32/64Mb memory integrated, and has display and USB interfaces,
allowing for small footprint boards.

The target consists of basic 5.10 support, with u-boot.

Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
56 files changed:
package/boot/uboot-suniv/Makefile [new file with mode: 0644]
package/boot/uboot-suniv/patches/0001-arm-arm926ejs-start.S-port-save_boot_params-support-.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0002-arm-arm926ej-s-add-sunxi-code.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0003-sunxi-add-support-for-suniv-architecture.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0004-sunxi-suniv-add-support-for-Lichee-Pi-Nano.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0005-sunxi-suniv-add-boot-sequence-for-SPL-to-try.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0006-sunxi-spi-spl-add-support-for-SUNIV.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0007-sunxi-add-missing-AHB_GATE_OFFSET_SPIx-defines-for-s.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0008-sunxi-add-SPI-register-definitions-for-sun4i-sun7i.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0009-sunxi-add-SPI-register-definitions-for-sun6i-sun8i-s.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0010-introduce-and-use-sunxi_gpio_setup_dt_pins.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0011-sunxi-add-SPI-Flash-block-size-for-env-storage.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0012-spi-sunxi_spi-Add-DM-SPI-driver-for-A31-A80-A64.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0013-sunxi-add-SPI0-node-for-suniv.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0014-sunxi-enable-SPI-NOR-on-Lichee-Pi-Nano.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0015-sunxi-add-defconfig-for-Lichee-Pi-Nano-with-SPI-Flas.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0016-sunxi-add-support-for-UART-at-PF-for-suniv.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0017-sunxi-do-not-set-PF-MMC0-pinmux-when-PF-uart-is-used.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0018-sunxi-allow-to-enable-MMC-driver-when-using-PF-UART0.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0019-sunxi-timer-forward-declare-function.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/002-add-olimex-a13-som.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0020-disable-sunxi-enable_caches-function-for-arm926ejs.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0022-remove-suniv-config-ubs-phys-define.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0023-fix-sun6i-spi-driver-wait_for_bit.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0024-ensure-correct-spi-driver-is-loaded.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0025-add-suniv-pinctrl-compatibility-to-sunxi-gpio-driver.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0028-sunxi-suniv-add-device-tree-nodes-for-f1c100s-MMC-co.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/0029-licheepi-nano-dts-enable-mmc0.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/003-add-theobroma-a31-pangolin.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/062-A20-improve-gmac-upload.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/063-fix-lime2-revK-add-micrel-PHY.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/091-sun6i-sync-PLL1-multdiv-with-Boot1.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/093-sun6i-fix-PLL-LDO-voltselect.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/100-sun6i-alternate-on-UART2.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/101-sun6i-support-console-on-UART2.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/102-sunxi-make_CONS_INDEX-configurable.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/200-mkimage-check-environment-for-dtc-binary-location.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/210-sunxi-deactivate-binman.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/230-disable-axp209-on-a13-olinuxino.diff [new file with mode: 0644]
package/boot/uboot-suniv/patches/240-add-rgl-c64mini.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/250-add-mmc-to-chip.diff [new file with mode: 0644]
package/boot/uboot-suniv/patches/250-sun8i-h3-zeropi-add-device-tree.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/251-sun8i-h3-zeropi-add-defconfig.patch [new file with mode: 0644]
package/boot/uboot-suniv/patches/252-sunxi-h3-add-support-for-nanopi-r1.patch [new file with mode: 0644]
package/boot/uboot-suniv/uEnv-default.txt [new file with mode: 0644]
target/linux/suniv/Makefile [new file with mode: 0644]
target/linux/suniv/arm926ej-s/config-5.4 [new file with mode: 0644]
target/linux/suniv/arm926ej-s/target.mk [new file with mode: 0644]
target/linux/suniv/base-files/etc/board.d/02_network [new file with mode: 0755]
target/linux/suniv/base-files/lib/upgrade/platform.sh [new file with mode: 0644]
target/linux/suniv/config-5.10 [new file with mode: 0644]
target/linux/suniv/image/Config.in [new file with mode: 0644]
target/linux/suniv/image/Makefile [new file with mode: 0644]
target/linux/suniv/image/arm926ej-s.mk [new file with mode: 0644]
target/linux/suniv/image/gen_sunxi_sdcard_img.sh [new file with mode: 0755]
target/linux/suniv/patches-5.10/0001-series.patch [new file with mode: 0644]

diff --git a/package/boot/uboot-suniv/Makefile b/package/boot/uboot-suniv/Makefile
new file mode 100644 (file)
index 0000000..51de94c
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2013-2021 OpenWrt.org
+# Copyright (C) 2017 Yousong Zhou
+# Copyright (C) 2021 Zoltan Herpai
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_VERSION:=2020.04
+
+PKG_HASH:=fe732aaf037d9cc3c0909bad8362af366ae964bbdac6913a34081ff4ad565372
+
+PKG_MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
+
+include $(INCLUDE_DIR)/u-boot.mk
+include $(INCLUDE_DIR)/package.mk
+
+define U-Boot/Default
+  BUILD_TARGET:=suniv
+  UBOOT_IMAGE:=u-boot-sunxi-with-spl.bin
+  UENV:=default
+  HIDDEN:=1
+endef
+
+define U-Boot/licheepi_nano
+  NAME:=LicheePi Nano
+  BUILD_DEVICES:=licheepi-nano
+endef
+
+UBOOT_TARGETS := \
+       licheepi_nano
+
+UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(STAGING_DIR_IMAGE)
+       $(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-u-boot-with-spl.bin
+       mkimage -C none -A arm -T script -d uEnv-$(UENV).txt \
+               $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-boot.scr
+endef
+
+define Package/u-boot/install/default
+endef
+
+$(eval $(call BuildPackage/U-Boot))
diff --git a/package/boot/uboot-suniv/patches/0001-arm-arm926ejs-start.S-port-save_boot_params-support-.patch b/package/boot/uboot-suniv/patches/0001-arm-arm926ejs-start.S-port-save_boot_params-support-.patch
new file mode 100644 (file)
index 0000000..ebd013d
--- /dev/null
@@ -0,0 +1,62 @@
+From 1dcc6c61ee650b26b94da4f4d6030d54706d87fe Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Thu, 18 Jan 2018 23:11:20 +0800
+Subject: [PATCH 01/29] arm: arm926ejs: start.S: port save_boot_params support
+ from armv7 code
+
+The ARMv7 start code has support for saving some boot params at the
+entry point, which is used by some SoCs to return to BROM.
+
+Port this to ARM926EJ-S start code.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/cpu/arm926ejs/start.S | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S
+index ff592ba810..9011afed3f 100644
+--- a/arch/arm/cpu/arm926ejs/start.S
++++ b/arch/arm/cpu/arm926ejs/start.S
+@@ -17,6 +17,7 @@
+ #include <asm-offsets.h>
+ #include <config.h>
+ #include <common.h>
++#include <linux/linkage.h>
+ /*
+  *************************************************************************
+@@ -32,8 +33,13 @@
+  */
+       .globl  reset
++      .globl  save_boot_params_ret
++      .type   save_boot_params_ret,%function
+ reset:
++      /* Allow the board to save important registers */
++      b       save_boot_params
++save_boot_params_ret:
+       /*
+        * set the cpu to SVC32 mode
+        */
+@@ -110,3 +116,16 @@ flush_dcache:
+ #endif
+       mov     pc, lr          /* back to my caller */
+ #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
++
++/*************************************************************************
++ *
++ * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
++ *    __attribute__((weak));
++ *
++ * Stack pointer is not yet initialized at this moment
++ * Don't save anything to stack even if compiled with -O0
++ *
++ *************************************************************************/
++WEAK(save_boot_params)
++      b       save_boot_params_ret    /* back to my caller */
++ENDPROC(save_boot_params)
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0002-arm-arm926ej-s-add-sunxi-code.patch b/package/boot/uboot-suniv/patches/0002-arm-arm926ej-s-add-sunxi-code.patch
new file mode 100644 (file)
index 0000000..74ac512
--- /dev/null
@@ -0,0 +1,390 @@
+From 3fb67784930f20b3ec271a4277c2875a66717769 Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Thu, 18 Jan 2018 23:14:48 +0800
+Subject: [PATCH 02/29] arm: arm926ej-s: add sunxi code
+
+Some Allwinner SoCs use ARM926EJ-S core.
+
+Add Allwinner/sunXi specific code to ARM926EJ-S CPU dircetory.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/cpu/arm926ejs/Makefile              |   1 +
+ arch/arm/cpu/arm926ejs/sunxi/Makefile        |  16 +++
+ arch/arm/cpu/arm926ejs/sunxi/config.mk       |   6 +
+ arch/arm/cpu/arm926ejs/sunxi/fel_utils.S     |  38 +++++++
+ arch/arm/cpu/arm926ejs/sunxi/lowlevel_init.S |  68 +++++++++++
+ arch/arm/cpu/arm926ejs/sunxi/start.c         |   1 +
+ arch/arm/cpu/arm926ejs/sunxi/timer.c         | 113 +++++++++++++++++++
+ arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds  |  63 +++++++++++
+ 8 files changed, 306 insertions(+)
+ create mode 100644 arch/arm/cpu/arm926ejs/sunxi/Makefile
+ create mode 100644 arch/arm/cpu/arm926ejs/sunxi/config.mk
+ create mode 100644 arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
+ create mode 100644 arch/arm/cpu/arm926ejs/sunxi/lowlevel_init.S
+ create mode 100644 arch/arm/cpu/arm926ejs/sunxi/start.c
+ create mode 100644 arch/arm/cpu/arm926ejs/sunxi/timer.c
+ create mode 100644 arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds
+
+diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile
+index b051025bb0..5b709a216e 100644
+--- a/arch/arm/cpu/arm926ejs/Makefile
++++ b/arch/arm/cpu/arm926ejs/Makefile
+@@ -18,6 +18,7 @@ obj-$(CONFIG_MX25) += mx25/
+ obj-$(CONFIG_MX27) += mx27/
+ obj-$(if $(filter mxs,$(SOC)),y) += mxs/
+ obj-$(if $(filter spear,$(SOC)),y) += spear/
++obj-$(CONFIG_ARCH_SUNXI) += sunxi/
+ # some files can only build in ARM or THUMB2, not THUMB1
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/Makefile b/arch/arm/cpu/arm926ejs/sunxi/Makefile
+new file mode 100644
+index 0000000000..61b9864f6a
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/sunxi/Makefile
+@@ -0,0 +1,16 @@
++#
++# (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
++#
++# Based on some other Makefile
++# (C) Copyright 2000-2003
++# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
++#
++# SPDX-License-Identifier:    GPL-2.0+
++#
++obj-y += timer.o
++obj-y += lowlevel_init.o
++
++ifdef CONFIG_SPL_BUILD
++obj-y += fel_utils.o
++CFLAGS_fel_utils.o := -marm
++endif
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/config.mk b/arch/arm/cpu/arm926ejs/sunxi/config.mk
+new file mode 100644
+index 0000000000..76ffec9df6
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/sunxi/config.mk
+@@ -0,0 +1,6 @@
++# Build a combined spl + u-boot image
++ifdef CONFIG_SPL
++ifndef CONFIG_SPL_BUILD
++ALL-y += u-boot-sunxi-with-spl.bin
++endif
++endif
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
+new file mode 100644
+index 0000000000..ca91377008
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
+@@ -0,0 +1,38 @@
++/*
++ * Utility functions for FEL mode.
++ *
++ * Copyright (c) 2015 Google, Inc
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#include <asm-offsets.h>
++#include <config.h>
++#include <asm/system.h>
++#include <linux/linkage.h>
++
++ENTRY(save_boot_params)
++      ldr     r0, =fel_stash
++      str     sp, [r0, #0]
++      str     lr, [r0, #4]
++      mrs     lr, cpsr                @ Read CPSR
++      str     lr, [r0, #8]
++      mrc     p15, 0, lr, c1, c0, 0   @ Read CP15 SCTLR Register
++      str     lr, [r0, #12]
++      mrc     p15, 0, lr, c1, c0, 0   @ Read CP15 Control Register
++      str     lr, [r0, #16]
++      b       save_boot_params_ret
++ENDPROC(save_boot_params)
++
++ENTRY(return_to_fel)
++      mov     sp, r0
++      mov     lr, r1
++      ldr     r0, =fel_stash
++      ldr     r1, [r0, #16]
++      mcr     p15, 0, r1, c1, c0, 0   @ Write CP15 Control Register
++      ldr     r1, [r0, #12]
++      mcr     p15, 0, r1, c1, c0, 0   @ Write CP15 SCTLR Register
++      ldr     r1, [r0, #8]
++      msr     cpsr, r1                @ Write CPSR
++      bx      lr
++ENDPROC(return_to_fel)
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/lowlevel_init.S b/arch/arm/cpu/arm926ejs/sunxi/lowlevel_init.S
+new file mode 100644
+index 0000000000..2bfd907026
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/sunxi/lowlevel_init.S
+@@ -0,0 +1,68 @@
++/*
++ * A lowlevel_init function that sets up the stack to call a C function to
++ * perform further init.
++ *
++ * Based on lowlevel_init.S in armv7 directory, which is:
++ *   (C) Copyright 2010 Texas Instruments, <www.ti.com>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#include <asm-offsets.h>
++#include <config.h>
++#include <linux/linkage.h>
++
++.pushsection .text.s_init, "ax"
++WEAK(s_init)
++      bx      lr
++ENDPROC(s_init)
++.popsection
++
++.pushsection .text.lowlevel_init, "ax"
++WEAK(lowlevel_init)
++      /*
++       * Setup a temporary stack. Global data is not available yet.
++       */
++#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
++      ldr     sp, =CONFIG_SPL_STACK
++#else
++      ldr     sp, =CONFIG_SYS_INIT_SP_ADDR
++#endif
++      bic     sp, sp, #7 /* 8-byte alignment for ABI compliance */
++#ifdef CONFIG_SPL_DM
++      mov     r9, #0
++#else
++      /*
++       * Set up global data for boards that still need it. This will be
++       * removed soon.
++       */
++#ifdef CONFIG_SPL_BUILD
++      ldr     r9, =gdata
++#else
++      sub     sp, sp, #GD_SIZE
++      bic     sp, sp, #7
++      mov     r9, sp
++#endif
++#endif
++      /*
++       * Save the old lr(passed in ip) and the current lr to stack
++       */
++      push    {ip, lr}
++
++      /*
++       * Call the very early init function. This should do only the
++       * absolute bare minimum to get started. It should not:
++       *
++       * - set up DRAM
++       * - use global_data
++       * - clear BSS
++       * - try to start a console
++       *
++       * For boards with SPL this should be empty since SPL can do all of
++       * this init in the SPL board_init_f() function which is called
++       * immediately after this.
++       */
++      bl      s_init
++      pop     {ip, pc}
++ENDPROC(lowlevel_init)
++.popsection
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/start.c b/arch/arm/cpu/arm926ejs/sunxi/start.c
+new file mode 100644
+index 0000000000..6b392fa835
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/sunxi/start.c
+@@ -0,0 +1 @@
++/* Intentionally empty. Only needed to get FEL SPL link line right */
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/timer.c b/arch/arm/cpu/arm926ejs/sunxi/timer.c
+new file mode 100644
+index 0000000000..36263896d8
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/sunxi/timer.c
+@@ -0,0 +1,113 @@
++/*
++ * (C) Copyright 2007-2011
++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
++ * Tom Cubie <tangliang@allwinnertech.com>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm/arch/timer.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define TIMER_MODE   (0x0 << 7)       /* continuous mode */
++#define TIMER_DIV    (0x0 << 4)       /* pre scale 1 */
++#define TIMER_SRC    (0x1 << 2)       /* osc24m */
++#define TIMER_RELOAD (0x1 << 1)       /* reload internal value */
++#define TIMER_EN     (0x1 << 0)       /* enable timer */
++
++#define TIMER_CLOCK           (24 * 1000 * 1000)
++#define COUNT_TO_USEC(x)      ((x) / 24)
++#define USEC_TO_COUNT(x)      ((x) * 24)
++#define TICKS_PER_HZ          (TIMER_CLOCK / CONFIG_SYS_HZ)
++#define TICKS_TO_HZ(x)                ((x) / TICKS_PER_HZ)
++
++#define TIMER_LOAD_VAL                0xffffffff
++
++#define TIMER_NUM             0       /* we use timer 0 */
++
++/* read the 32-bit timer */
++static ulong read_timer(void)
++{
++      struct sunxi_timer_reg *timers =
++              (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
++      struct sunxi_timer *timer = &timers->timer[TIMER_NUM];
++
++      /*
++       * The hardware timer counts down, therefore we invert to
++       * produce an incrementing timer.
++       */
++      return ~readl(&timer->val);
++}
++
++/* init timer register */
++int timer_init(void)
++{
++      struct sunxi_timer_reg *timers =
++              (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
++      struct sunxi_timer *timer = &timers->timer[TIMER_NUM];
++      writel(TIMER_LOAD_VAL, &timer->inter);
++      writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN,
++             &timer->ctl);
++
++      return 0;
++}
++
++/* timer without interrupts */
++ulong get_timer(ulong base)
++{
++      return get_timer_masked() - base;
++}
++
++ulong get_timer_masked(void)
++{
++      /* current tick value */
++      ulong now = TICKS_TO_HZ(read_timer());
++
++      if (now >= gd->arch.lastinc)    /* normal (non rollover) */
++              gd->arch.tbl += (now - gd->arch.lastinc);
++      else {
++              /* rollover */
++              gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL)
++                              - gd->arch.lastinc) + now;
++      }
++      gd->arch.lastinc = now;
++
++      return gd->arch.tbl;
++}
++
++/* delay x useconds */
++void __udelay(unsigned long usec)
++{
++      long tmo = USEC_TO_COUNT(usec);
++      ulong now, last = read_timer();
++
++      while (tmo > 0) {
++              now = read_timer();
++              if (now > last) /* normal (non rollover) */
++                      tmo -= now - last;
++              else            /* rollover */
++                      tmo -= TIMER_LOAD_VAL - last + now;
++              last = now;
++      }
++}
++
++/*
++ * This function is derived from PowerPC code (read timebase as long long).
++ * On ARM it just returns the timer value.
++ */
++unsigned long long get_ticks(void)
++{
++      return get_timer(0);
++}
++
++/*
++ * This function is derived from PowerPC code (timebase clock frequency).
++ * On ARM it returns the number of timer ticks per second.
++ */
++ulong get_tbclk(void)
++{
++      return CONFIG_SYS_HZ;
++}
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds
+new file mode 100644
+index 0000000000..1b667807db
+--- /dev/null
++++ b/arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds
+@@ -0,0 +1,63 @@
++/*
++ * (C) Copyright 2018
++ * Icenowy Zheng <icenowy@aosc.io>
++ *
++ * Based on arch/arm/cpu/armv7/sunxi/u-boot-spl.lds:
++ *
++ * (C) Copyright 2012
++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
++ * Tom Cubie <tangliang@allwinnertech.com>
++ *
++ * Based on omap-common/u-boot-spl.lds:
++ *
++ * (C) Copyright 2002
++ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
++ *
++ * (C) Copyright 2010
++ * Texas Instruments, <www.ti.com>
++ *    Aneesh V <aneesh@ti.com>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
++              LENGTH = CONFIG_SPL_MAX_SIZE }
++MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
++              LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
++
++OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
++OUTPUT_ARCH(arm)
++ENTRY(_start)
++SECTIONS
++{
++      .text      :
++      {
++              __start = .;
++              *(.vectors)
++              arch/arm/cpu/arm926ejs/start.o  (.text)
++              *(.text*)
++      } > .sram
++
++      . = ALIGN(4);
++      .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
++
++      . = ALIGN(4);
++      .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
++
++      . = ALIGN(4);
++      .u_boot_list : {
++              KEEP(*(SORT(.u_boot_list*)));
++      } > .sram
++
++      . = ALIGN(4);
++      __image_copy_end = .;
++      _end = .;
++
++      .bss :
++      {
++              . = ALIGN(4);
++              __bss_start = .;
++              *(.bss*)
++              . = ALIGN(4);
++              __bss_end = .;
++      } > .sdram
++}
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0003-sunxi-add-support-for-suniv-architecture.patch b/package/boot/uboot-suniv/patches/0003-sunxi-add-support-for-suniv-architecture.patch
new file mode 100644 (file)
index 0000000..9f4e5c2
--- /dev/null
@@ -0,0 +1,1450 @@
+From a2800766ac52b835fa2dcf6fad395cf42f32ae69 Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Thu, 18 Jan 2018 23:18:57 +0800
+Subject: [PATCH 03/29] sunxi: add support for suniv architecture
+
+Add support for the suniv architecture, which is newer ARM9 SoCs by
+Allwinner. The design of it seems to be a mixture of sun3i, sun4i and
+sun6i.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/dts/suniv-f1c100s.dtsi               |   6 +
+ arch/arm/dts/suniv.dtsi                       | 183 +++++++
+ arch/arm/include/asm/arch-sunxi/clock.h       |   2 +-
+ arch/arm/include/asm/arch-sunxi/clock_sun6i.h |  21 +
+ arch/arm/include/asm/arch-sunxi/cpu_sun4i.h   |   8 +
+ arch/arm/include/asm/arch-sunxi/dram.h        |   2 +
+ arch/arm/include/asm/arch-sunxi/dram_suniv.h  |  47 ++
+ arch/arm/include/asm/arch-sunxi/gpio.h        |   1 +
+ arch/arm/mach-sunxi/Kconfig                   |  14 +-
+ arch/arm/mach-sunxi/Makefile                  |   2 +
+ arch/arm/mach-sunxi/board.c                   |   7 +-
+ arch/arm/mach-sunxi/clock.c                   |   3 +-
+ arch/arm/mach-sunxi/clock_sun6i.c             |  47 +-
+ arch/arm/mach-sunxi/cpu_info.c                |   2 +
+ arch/arm/mach-sunxi/dram_helpers.c            |   4 +
+ arch/arm/mach-sunxi/dram_suniv.c              | 496 ++++++++++++++++++
+ board/sunxi/board.c                           |   4 +-
+ include/configs/suniv.h                       |  17 +
+ include/configs/sunxi-common.h                |  64 ++-
+ include/dt-bindings/clock/suniv-ccu.h         |  69 +++
+ include/dt-bindings/reset/suniv-ccu.h         |  37 ++
+ 21 files changed, 1011 insertions(+), 25 deletions(-)
+ create mode 100644 arch/arm/dts/suniv-f1c100s.dtsi
+ create mode 100644 arch/arm/dts/suniv.dtsi
+ create mode 100644 arch/arm/include/asm/arch-sunxi/dram_suniv.h
+ create mode 100644 arch/arm/mach-sunxi/dram_suniv.c
+ create mode 100644 include/configs/suniv.h
+ create mode 100644 include/dt-bindings/clock/suniv-ccu.h
+ create mode 100644 include/dt-bindings/reset/suniv-ccu.h
+
+diff --git a/arch/arm/dts/suniv-f1c100s.dtsi b/arch/arm/dts/suniv-f1c100s.dtsi
+new file mode 100644
+index 0000000000..f084bc8dd1
+--- /dev/null
++++ b/arch/arm/dts/suniv-f1c100s.dtsi
+@@ -0,0 +1,6 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR X11)
++/*
++ * Copyright 2018 Icenowy Zheng <icenowy@aosc.io>
++ */
++
++#include "suniv.dtsi"
+diff --git a/arch/arm/dts/suniv.dtsi b/arch/arm/dts/suniv.dtsi
+new file mode 100644
+index 0000000000..5bca082d2e
+--- /dev/null
++++ b/arch/arm/dts/suniv.dtsi
+@@ -0,0 +1,183 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR X11)
++/*
++ * Copyright 2018 Icenowy Zheng <icenowy@aosc.io>
++ */
++
++#include <dt-bindings/clock/suniv-ccu.h>
++#include <dt-bindings/reset/suniv-ccu.h>
++
++/ {
++      #address-cells = <1>;
++      #size-cells = <1>;
++      interrupt-parent = <&intc>;
++
++      clocks {
++              #address-cells = <1>;
++              #size-cells = <1>;
++              ranges;
++
++              osc24M: clk-24M {
++                      #clock-cells = <0>;
++                      compatible = "fixed-clock";
++                      clock-frequency = <24000000>;
++                      clock-output-names = "osc24M";
++              };
++
++              osc32k: clk-32k {
++                      #clock-cells = <0>;
++                      compatible = "fixed-clock";
++                      clock-frequency = <32768>;
++                      clock-output-names = "osc32k";
++              };
++
++              fake100M: clk-100M {
++                      #clock-cells = <0>;
++                      compatible = "fixed-clock";
++                      clock-frequency = <100000000>;
++                      clock-output-names = "fake-100M";
++              };
++      };
++
++      cpus {
++              #address-cells = <0>;
++              #size-cells = <0>;
++
++              cpu {
++                      compatible = "arm,arm926ej-s";
++                      device_type = "cpu";
++              };
++      };
++
++      soc {
++              compatible = "simple-bus";
++              #address-cells = <1>;
++              #size-cells = <1>;
++              ranges;
++
++              sram-controller@1c00000 {
++                      compatible = "allwinner,sun4i-a10-sram-controller";
++                      reg = <0x01c00000 0x30>;
++                      #address-cells = <1>;
++                      #size-cells = <1>;
++                      ranges;
++
++                      sram_d: sram@10000 {
++                              compatible = "mmio-sram";
++                              reg = <0x00010000 0x1000>;
++                              #address-cells = <1>;
++                              #size-cells = <1>;
++                              ranges = <0 0x00010000 0x1000>;
++
++                              otg_sram: sram-section@0 {
++                                      compatible = "allwinner,sun4i-a10-sram-d";
++                                      reg = <0x0000 0x1000>;
++                                      status = "disabled";
++                              };
++                      };
++              };
++
++              ccu: clock@1c20000 {
++                      compatible = "allwinner,suniv-ccu";
++                      reg = <0x01c20000 0x400>;
++                      clocks = <&osc24M>, <&osc32k>;
++                      clock-names = "hosc", "losc";
++                      #clock-cells = <1>;
++                      #reset-cells = <1>;
++              };
++
++              intc: interrupt-controller@1c20400 {
++                      compatible = "allwinner,suniv-ic";
++                      reg = <0x01c20400 0x400>;
++                      interrupt-controller;
++                      #interrupt-cells = <1>;
++              };
++
++              pio: pinctrl@1c20800 {
++                      compatible = "allwinner,suniv-pinctrl";
++                      reg = <0x01c20800 0x400>;
++                      interrupts = <38>, <39>, <40>;
++                      clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
++                      clock-names = "apb", "hosc", "losc";
++                      gpio-controller;
++                      interrupt-controller;
++                      #interrupt-cells = <3>;
++                      #gpio-cells = <3>;
++
++                      uart0_pins_a: uart-pins-pe {
++                              pins = "PE0", "PE1";
++                              function = "uart0";
++                      };
++              };
++
++              timer@1c20c00 {
++                      compatible = "allwinner,sun4i-a10-timer";
++                      reg = <0x01c20c00 0x90>;
++                      interrupts = <13>;
++                      clocks = <&osc24M>;
++              };
++
++              wdt: watchdog@1c20ca0 {
++                      compatible = "allwinner,sun6i-a31-wdt";
++                      reg = <0x01c20ca0 0x20>;
++              };
++
++              uart0: serial@1c25000 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x01c25000 0x400>;
++                      interrupts = <1>;
++                      reg-shift = <2>;
++                      reg-io-width = <4>;
++                      clocks = <&ccu CLK_BUS_UART0>;
++                      resets = <&ccu RST_BUS_UART0>;
++                      status = "disabled";
++              };
++
++              uart1: serial@1c25400 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x01c25400 0x400>;
++                      interrupts = <2>;
++                      reg-shift = <2>;
++                      reg-io-width = <4>;
++                      clocks = <&ccu CLK_BUS_UART1>;
++                      resets = <&ccu RST_BUS_UART1>;
++                      status = "disabled";
++              };
++
++              uart2: serial@1c25800 {
++                      compatible = "snps,dw-apb-uart";
++                      reg = <0x01c25800 0x400>;
++                      interrupts = <3>;
++                      reg-shift = <2>;
++                      reg-io-width = <4>;
++                      clocks = <&ccu CLK_BUS_UART2>;
++                      resets = <&ccu RST_BUS_UART2>;
++                      status = "disabled";
++              };
++
++              usb_otg: usb@1c13000 {
++                      compatible = "allwinner,suniv-musb";
++                      reg = <0x01c13000 0x0400>;
++                      clocks = <&ccu CLK_BUS_OTG>;
++                      resets = <&ccu RST_BUS_OTG>;
++                      interrupts = <26>;
++                      interrupt-names = "mc";
++                      phys = <&usbphy 0>;
++                      phy-names = "usb";
++                      extcon = <&usbphy 0>;
++                      allwinner,sram = <&otg_sram 1>;
++                      status = "disabled";
++              };
++
++              usbphy: phy@1c13400 {
++                      compatible = "allwinner,suniv-usb-phy";
++                      reg = <0x01c13400 0x10>;
++                      reg-names = "phy_ctrl";
++                      clocks = <&ccu CLK_USB_PHY0>;
++                      clock-names = "usb0_phy";
++                      resets = <&ccu RST_USB_PHY0>;
++                      reset-names = "usb0_reset";
++                      #phy-cells = <1>;
++                      status = "disabled";
++              };
++      };
++};
+diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
+index 5994130e6b..97b45d34ba 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock.h
++++ b/arch/arm/include/asm/arch-sunxi/clock.h
+@@ -19,7 +19,7 @@
+ #elif defined(CONFIG_MACH_SUN50I_H6)
+ #include <asm/arch/clock_sun50i_h6.h>
+ #elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
+-      defined(CONFIG_MACH_SUN50I)
++      defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
+ #include <asm/arch/clock_sun6i.h>
+ #elif defined(CONFIG_MACH_SUN9I)
+ #include <asm/arch/clock_sun9i.h>
+diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+index ee387127f3..0d6168c430 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+@@ -168,6 +168,14 @@ struct sunxi_ccm_reg {
+       u32 pll_lock_ctrl;      /* 0x320 PLL lock control, R40 only */
+ };
++/* apb1 bit field */
++#ifdef CONFIG_MACH_SUNIV
++#define APB1_GATE_UART_SHIFT  (20)
++#define APB1_GATE_UART_MASK           (0x7 << APB1_GATE_UART_SHIFT)
++#define APB1_GATE_TWI_SHIFT   (16)
++#define APB1_GATE_TWI_MASK            (0x7 << APB1_GATE_TWI_SHIFT)
++#endif
++
+ /* apb2 bit field */
+ #define APB2_CLK_SRC_LOSC             (0x0 << 24)
+ #define APB2_CLK_SRC_OSC24M           (0x1 << 24)
+@@ -226,7 +234,12 @@ struct sunxi_ccm_reg {
+ #define CCM_PLL5_CTRL_SIGMA_DELTA_EN  (0x1 << 24)
+ #define CCM_PLL5_CTRL_EN              (0x1 << 31)
++#if !defined(CONFIG_MACH_SUNIV)
+ #define PLL6_CFG_DEFAULT              0x90041811 /* 600 MHz */
++#else
++/* suniv pll6 doesn't have postdiv 2, so k is set to 0 */
++#define PLL6_CFG_DEFAULT              0x90041800
++#endif
+ #define CCM_PLL6_CTRL_N_SHIFT         8
+ #define CCM_PLL6_CTRL_N_MASK          (0x1f << CCM_PLL6_CTRL_N_SHIFT)
+@@ -488,6 +501,14 @@ struct sunxi_ccm_reg {
+ #define AHB_RESET_OFFSET_EPHY         2
+ #define AHB_RESET_OFFSET_LVDS         0
++/* apb1 reset */
++#ifdef CONFIG_MACH_SUNIV
++#define APB1_RESET_UART_SHIFT (20)
++#define APB1_RESET_UART_MASK          (0x7 << APB1_RESET_UART_SHIFT)
++#define APB1_RESET_TWI_SHIFT  (16)
++#define APB1_RESET_TWI_MASK           (0x7 << APB1_RESET_TWI_SHIFT)
++#endif
++
+ /* apb2 reset */
+ #define APB2_RESET_UART_SHIFT         (16)
+ #define APB2_RESET_UART_MASK          (0xff << APB2_RESET_UART_SHIFT)
+diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+index 02ce73954d..bfc5a7692a 100644
+--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+@@ -111,6 +111,12 @@ defined(CONFIG_MACH_SUN50I)
+ #define SUNXI_SJTAG_BASE              0x01c23c00
++#ifdef CONFIG_MACH_SUNIV
++#define SUNXI_UART0_BASE              0x01c25000
++#define SUNXI_UART1_BASE              0x01c25400
++#define SUNXI_UART2_BASE              0x01c25800
++#endif
++
+ #define SUNXI_TP_BASE                 0x01c25000
+ #define SUNXI_PMU_BASE                        0x01c25400
+@@ -118,9 +124,11 @@ defined(CONFIG_MACH_SUN50I)
+ #define SUNXI_CPUCFG_BASE             0x01c25c00
+ #endif
++#ifndef CONFIG_MACH_SUNIV
+ #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
+diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
+index 8002b7efdc..523dd71cc9 100644
+--- a/arch/arm/include/asm/arch-sunxi/dram.h
++++ b/arch/arm/include/asm/arch-sunxi/dram.h
+@@ -29,6 +29,8 @@
+ #include <asm/arch/dram_sun9i.h>
+ #elif defined(CONFIG_MACH_SUN50I_H6)
+ #include <asm/arch/dram_sun50i_h6.h>
++#elif defined(CONFIG_MACH_SUNIV)
++#include <asm/arch/dram_suniv.h>
+ #else
+ #include <asm/arch/dram_sun4i.h>
+ #endif
+diff --git a/arch/arm/include/asm/arch-sunxi/dram_suniv.h b/arch/arm/include/asm/arch-sunxi/dram_suniv.h
+new file mode 100644
+index 0000000000..088eb5b9eb
+--- /dev/null
++++ b/arch/arm/include/asm/arch-sunxi/dram_suniv.h
+@@ -0,0 +1,47 @@
++/*
++ * suniv DRAM controller register definition
++ *
++ * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
++ *
++ * Based on xboot's arch/arm32/mach-f1c100s/sys-dram.c, which is:
++ *
++ * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#define PIO_SDRAM_DRV                 (0x2c0)
++#define PIO_SDRAM_PULL                        (0x2c4)
++
++#define DRAM_SCONR                    (0x00)
++#define DRAM_STMG0R                   (0x04)
++#define DRAM_STMG1R                   (0x08)
++#define DRAM_SCTLR                    (0x0c)
++#define DRAM_SREFR                    (0x10)
++#define DRAM_SEXTMR                   (0x14)
++#define DRAM_DDLYR                    (0x24)
++#define DRAM_DADRR                    (0x28)
++#define DRAM_DVALR                    (0x2c)
++#define DRAM_DRPTR0                   (0x30)
++#define DRAM_DRPTR1                   (0x34)
++#define DRAM_DRPTR2                   (0x38)
++#define DRAM_DRPTR3                   (0x3c)
++#define DRAM_SEFR                     (0x40)
++#define DRAM_MAE                      (0x44)
++#define DRAM_ASPR                     (0x48)
++#define DRAM_SDLY0                    (0x4C)
++#define DRAM_SDLY1                    (0x50)
++#define DRAM_SDLY2                    (0x54)
++#define DRAM_MCR0                     (0x100)
++#define DRAM_MCR1                     (0x104)
++#define DRAM_MCR2                     (0x108)
++#define DRAM_MCR3                     (0x10c)
++#define DRAM_MCR4                     (0x110)
++#define DRAM_MCR5                     (0x114)
++#define DRAM_MCR6                     (0x118)
++#define DRAM_MCR7                     (0x11c)
++#define DRAM_MCR8                     (0x120)
++#define DRAM_MCR9                     (0x124)
++#define DRAM_MCR10                    (0x128)
++#define DRAM_MCR11                    (0x12c)
++#define DRAM_BWCR                     (0x140)
+diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
+index a646ea6a3c..88018ae568 100644
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -177,6 +177,7 @@ enum sunxi_gpio_number {
+ #define SUNXI_GPD_LVDS0               3
+ #define SUNXI_GPD_PWM         2
++#define SUNIV_GPE_UART0               5
+ #define SUN5I_GPE_SDC2                3
+ #define SUN8I_GPE_TWI2                3
+ #define SUN50I_GPE_TWI2               3
+diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
+index 16d41b83af..8a9258b32d 100644
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -1,7 +1,8 @@
+ if ARCH_SUNXI
+ config SPL_LDSCRIPT
+-      default "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds" if !ARM64
++      default "arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds" if MACH_SUNIV
++      default "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds" if !ARM64 && !MACH_SUNIV
+ config IDENT_STRING
+       default " Allwinner Technology"
+@@ -150,6 +151,12 @@ choice
+       prompt "Sunxi SoC Variant"
+       optional
++config MACH_SUNIV
++      bool "suniv (Allwinner F1C100s/F1C200s/F1C600/R6)"
++      select CPU_ARM926EJS
++      select SUNXI_GEN_SUN6I
++      select SUPPORT_SPL
++
+ config MACH_SUN4I
+       bool "sun4i (Allwinner A10)"
+       select CPU_V7A
+@@ -533,6 +540,7 @@ config DRAM_ODT_CORRECTION
+ endif
+ config SYS_CLK_FREQ
++      default 408000000 if MACH_SUNIV
+       default 1008000000 if MACH_SUN4I
+       default 1008000000 if MACH_SUN5I
+       default 1008000000 if MACH_SUN6I
+@@ -543,6 +551,7 @@ config SYS_CLK_FREQ
+       default 888000000 if MACH_SUN50I_H6
+ config SYS_CONFIG_NAME
++      default "suniv" if MACH_SUNIV
+       default "sun4i" if MACH_SUN4I
+       default "sun5i" if MACH_SUN5I
+       default "sun6i" if MACH_SUN6I
+@@ -767,7 +776,7 @@ config VIDEO_SUNXI
+ config VIDEO_HDMI
+       bool "HDMI output support"
+-      depends on VIDEO_SUNXI && !MACH_SUN8I
++      depends on VIDEO_SUNXI && !MACH_SUN8I && !MACH_SUNIV
+       default y
+       ---help---
+       Say Y here to add support for outputting video over HDMI.
+@@ -982,6 +991,7 @@ config GMAC_TX_DELAY
+       Set the GMAC Transmit Clock Delay Chain value.
+ config SPL_STACK_R_ADDR
++      default 0x81e00000 if MACH_SUNIV
+       default 0x4fe00000 if MACH_SUN4I
+       default 0x4fe00000 if MACH_SUN5I
+       default 0x4fe00000 if MACH_SUN6I
+diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
+index d129f33479..5fca0073f3 100644
+--- a/arch/arm/mach-sunxi/Makefile
++++ b/arch/arm/mach-sunxi/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_SUN6I_P2WI)     += p2wi.o
+ obj-$(CONFIG_SUN6I_PRCM)      += prcm.o
+ obj-$(CONFIG_AXP_PMIC_BUS)    += pmic_bus.o
+ obj-$(CONFIG_SUN8I_RSB)               += rsb.o
++obj-$(CONFIG_MACH_SUNIV)      += clock_sun6i.o
+ obj-$(CONFIG_MACH_SUN4I)      += clock_sun4i.o
+ obj-$(CONFIG_MACH_SUN5I)      += clock_sun4i.o
+ obj-$(CONFIG_MACH_SUN6I)      += clock_sun6i.o
+@@ -29,6 +30,7 @@ obj-$(CONFIG_MACH_SUN9I)     += clock_sun9i.o gtbus_sun9i.o
+ obj-$(CONFIG_MACH_SUN50I_H6)  += clock_sun50i_h6.o
+ ifdef CONFIG_SPL_BUILD
++obj-$(CONFIG_MACH_SUNIV)      += dram_suniv.o
+ obj-$(CONFIG_DRAM_SUN4I)      += dram_sun4i.o
+ obj-$(CONFIG_DRAM_SUN6I)      += dram_sun6i.o
+ obj-$(CONFIG_DRAM_SUN8I_A23)  += dram_sun8i_a23.o
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index aa1d2230c9..35cd16bb44 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -83,6 +83,10 @@ static int gpio_init(void)
+       sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0);
+ #endif
+       sunxi_gpio_set_pull(SUNXI_GPF(4), 1);
++#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUNIV)
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(0), SUNIV_GPE_UART0);
++      sunxi_gpio_set_cfgpin(SUNXI_GPE(1), SUNIV_GPE_UART0);
++      sunxi_gpio_set_pull(SUNXI_GPE(1), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || \
+                                defined(CONFIG_MACH_SUN7I) || \
+                                defined(CONFIG_MACH_SUN8I_R40))
+@@ -199,7 +203,8 @@ void s_init(void)
+       /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */
+ #endif
+-#if !defined(CONFIG_ARM_CORTEX_CPU_IS_UP) && !defined(CONFIG_ARM64)
++#if !defined(CONFIG_ARM_CORTEX_CPU_IS_UP) && !defined(CONFIG_ARM64) && \
++      !defined(CONFIG_MACH_SUNIV)
+       /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
+       asm volatile(
+               "mrc p15, 0, r0, c1, c0, 1\n"
+diff --git a/arch/arm/mach-sunxi/clock.c b/arch/arm/mach-sunxi/clock.c
+index f591affebf..636b3b6b02 100644
+--- a/arch/arm/mach-sunxi/clock.c
++++ b/arch/arm/mach-sunxi/clock.c
+@@ -36,7 +36,8 @@ int clock_init(void)
+ }
+ /* These functions are shared between various SoCs so put them here. */
+-#if defined CONFIG_SUNXI_GEN_SUN6I && !defined CONFIG_MACH_SUN9I
++#if defined CONFIG_SUNXI_GEN_SUN6I && !defined CONFIG_MACH_SUN9I && \
++      !defined CONFIG_MACH_SUNIV
+ int clock_twi_onoff(int port, int state)
+ {
+       struct sunxi_ccm_reg *const ccm =
+diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c
+index 6ca38f73d9..64b2d54d71 100644
+--- a/arch/arm/mach-sunxi/clock_sun6i.c
++++ b/arch/arm/mach-sunxi/clock_sun6i.c
+@@ -21,7 +21,8 @@ void clock_init_safe(void)
+       struct sunxi_ccm_reg * const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+-#if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I)
++#if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I) && \
++      !defined(CONFIG_MACH_SUNIV)
+       struct sunxi_prcm_reg * const prcm =
+               (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+@@ -47,9 +48,11 @@ void clock_init_safe(void)
+       writel(AHB1_ABP1_DIV_DEFAULT, &ccm->ahb1_apb1_div);
++#ifndef CONFIG_MACH_SUNIV
+       writel(MBUS_CLK_DEFAULT, &ccm->mbus0_clk_cfg);
+       if (IS_ENABLED(CONFIG_MACH_SUN6I))
+               writel(MBUS_CLK_DEFAULT, &ccm->mbus1_clk_cfg);
++#endif
+ #if defined(CONFIG_MACH_SUN8I_R40) && defined(CONFIG_SUNXI_AHCI)
+       setbits_le32(&ccm->sata_pll_cfg, CCM_SATA_PLL_DEFAULT);
+@@ -85,6 +88,7 @@ void clock_init_uart(void)
+       struct sunxi_ccm_reg *const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
++#ifndef CONFIG_MACH_SUNIV
+       /* uart clock source is apb2 */
+       writel(APB2_CLK_SRC_OSC24M|
+              APB2_CLK_RATE_N_1|
+@@ -100,6 +104,24 @@ void clock_init_uart(void)
+       setbits_le32(&ccm->apb2_reset_cfg,
+                    1 << (APB2_RESET_UART_SHIFT +
+                          CONFIG_CONS_INDEX - 1));
++#else
++      /* suniv doesn't have apb2, so uart clock source is apb1 */
++      writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg);
++      while (!(readl(&ccm->pll6_cfg) & CCM_PLL6_CTRL_LOCK))
++              ;
++
++      writel(AHB1_ABP1_DIV_DEFAULT, &ccm->ahb1_apb1_div);
++
++      /* open the clock for uart */
++      setbits_le32(&ccm->apb1_gate,
++                   CLK_GATE_OPEN << (APB1_GATE_UART_SHIFT +
++                                     CONFIG_CONS_INDEX - 1));
++
++      /* deassert uart reset */
++      setbits_le32(&ccm->apb1_reset_cfg,
++                   1 << (APB1_RESET_UART_SHIFT +
++                         CONFIG_CONS_INDEX - 1));
++#endif
+ #else
+       /* enable R_PIO and R_UART clocks, and de-assert resets */
+       prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_UART);
+@@ -123,10 +145,15 @@ void clock_set_pll1(unsigned int clk)
+       }
+       /* Switch to 24MHz clock while changing PLL1 */
++#ifndef CONFIG_MACH_SUNIV
+       writel(AXI_DIV_3 << AXI_DIV_SHIFT |
+              ATB_DIV_2 << ATB_DIV_SHIFT |
+              CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT,
+              &ccm->cpu_axi_cfg);
++#else
++      writel(CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT,
++             &ccm->cpu_axi_cfg);
++#endif
+       /*
+        * sun6i: PLL1 rate = ((24000000 * n * k) >> 0) / m   (p is ignored)
+@@ -135,13 +162,27 @@ void clock_set_pll1(unsigned int clk)
+       writel(CCM_PLL1_CTRL_EN | CCM_PLL1_CTRL_P(p) |
+              CCM_PLL1_CTRL_N(clk / (24000000 * k / m)) |
+              CCM_PLL1_CTRL_K(k) | CCM_PLL1_CTRL_M(m), &ccm->pll1_cfg);
++#ifndef CONFIG_MACH_SUNIV
+       sdelay(200);
++#else
++      do {
++              /* ARM926EJ-S code do not have sdelay */
++              volatile int i = 200;
++
++              while (i > 0) i--;
++      } while(0);
++#endif
+       /* Switch CPU to PLL1 */
++#ifndef CONFIG_MACH_SUNIV
+       writel(AXI_DIV_3 << AXI_DIV_SHIFT |
+              ATB_DIV_2 << ATB_DIV_SHIFT |
+              CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT,
+              &ccm->cpu_axi_cfg);
++#else
++      writel(CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT,
++             &ccm->cpu_axi_cfg);
++#endif
+ }
+ #endif
+@@ -315,7 +356,11 @@ unsigned int clock_get_pll6(void)
+       uint32_t rval = readl(&ccm->pll6_cfg);
+       int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1;
+       int k = ((rval & CCM_PLL6_CTRL_K_MASK) >> CCM_PLL6_CTRL_K_SHIFT) + 1;
++#ifndef CONFIG_MACH_SUNIV
+       return 24000000 * n * k / 2;
++#else
++      return 24000000 * n * k;
++#endif
+ }
+ unsigned int clock_get_mipi_pll(void)
+diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c
+index ae4745bfec..b201df82d7 100644
+--- a/arch/arm/mach-sunxi/cpu_info.c
++++ b/arch/arm/mach-sunxi/cpu_info.c
+@@ -56,6 +56,8 @@ int print_cpuinfo(void)
+ {
+ #ifdef CONFIG_MACH_SUN4I
+       puts("CPU:   Allwinner A10 (SUN4I)\n");
++#elif defined CONFIG_MACH_SUNIV
++      puts("CPU:   Allwinner F Series (SUNIV)\n");
+ #elif defined CONFIG_MACH_SUN5I
+       u32 val = readl(SUNXI_SID_BASE + 0x08);
+       switch ((val >> 12) & 0xf) {
+diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
+index 520b597fcc..2c873192e6 100644
+--- a/arch/arm/mach-sunxi/dram_helpers.c
++++ b/arch/arm/mach-sunxi/dram_helpers.c
+@@ -26,7 +26,10 @@ void mctl_await_completion(u32 *reg, u32 mask, u32 val)
+ /*
+  * Test if memory at offset offset matches memory at begin of DRAM
++ *
++ * Note: dsb() is not available on ARMv5 in Thumb mode
+  */
++#ifndef CONFIG_MACH_SUNIV
+ bool mctl_mem_matches(u32 offset)
+ {
+       /* Try to write different values to RAM at two addresses */
+@@ -37,3 +40,4 @@ bool mctl_mem_matches(u32 offset)
+       return readl(CONFIG_SYS_SDRAM_BASE) ==
+              readl((ulong)CONFIG_SYS_SDRAM_BASE + offset);
+ }
++#endif
+diff --git a/arch/arm/mach-sunxi/dram_suniv.c b/arch/arm/mach-sunxi/dram_suniv.c
+new file mode 100644
+index 0000000000..40aebf6eba
+--- /dev/null
++++ b/arch/arm/mach-sunxi/dram_suniv.c
+@@ -0,0 +1,496 @@
++/*
++ * suniv DRAM initialization
++ *
++ * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
++ *
++ * Based on xboot's arch/arm32/mach-f1c100s/sys-dram.c, which is:
++ *
++ * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/io.h>
++#include <asm/arch/clock.h>
++#include <asm/arch/dram.h>
++#include <asm/arch/gpio.h>
++
++#define SDR_T_CAS                     (0x2)
++#define SDR_T_RAS                     (0x8)
++#define SDR_T_RCD                     (0x3)
++#define SDR_T_RP                      (0x3)
++#define SDR_T_WR                      (0x3)
++#define SDR_T_RFC                     (0xd)
++#define SDR_T_XSR                     (0xf9)
++#define SDR_T_RC                      (0xb)
++#define SDR_T_INIT                    (0x8)
++#define SDR_T_INIT_REF                        (0x7)
++#define SDR_T_WTR                     (0x2)
++#define SDR_T_RRD                     (0x2)
++#define SDR_T_XP                      (0x0)
++
++enum dram_type
++{
++      DRAM_TYPE_SDR   = 0,
++      DRAM_TYPE_DDR   = 1,
++      /* Not supported yet. */
++      DRAM_TYPE_MDDR  = 2,
++};
++
++struct dram_para
++{
++      u32 size;               /* dram size (unit: MByte) */
++      u32 clk;                /* dram work clock (unit: MHz) */
++      u32 access_mode;        /* 0: interleave mode 1: sequence mode */
++      u32 cs_num;             /* dram chip count  1: one chip  2: two chip */
++      u32 ddr8_remap;         /* for 8bits data width DDR 0: normal  1: 8bits */
++      enum dram_type sdr_ddr;
++      u32 bwidth;             /* dram bus width */
++      u32 col_width;          /* column address width */
++      u32 row_width;          /* row address width */
++      u32 bank_size;          /* dram bank count */
++      u32 cas;                /* dram cas */
++};
++
++struct dram_para suniv_dram_para = {
++      .size = 32,
++      .clk = 156,
++      .access_mode = 1,
++      .cs_num = 1,
++      .ddr8_remap = 0,
++      .sdr_ddr = DRAM_TYPE_DDR,
++      .bwidth = 16,
++      .col_width = 10,
++      .row_width = 13,
++      .bank_size = 4,
++      .cas = 0x3,
++};
++
++static int dram_initial(void)
++{
++      unsigned int time = 0xffffff;
++
++      setbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR, 0x1);
++      while((readl(SUNXI_DRAMC_BASE + DRAM_SCTLR) & 0x1) && time--)
++      {
++              if(time == 0)
++                      return 0;
++      }
++      return 1;
++}
++
++static int dram_delay_scan(void)
++{
++      unsigned int time = 0xffffff;
++
++      setbits_le32(SUNXI_DRAMC_BASE + DRAM_DDLYR, 0x1);
++      while((readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) & 0x1) && time--)
++      {
++              if(time == 0)
++                      return 0;
++      }
++      return 1;
++}
++
++static void dram_set_autofresh_cycle(u32 clk)
++{
++      u32 val = 0;
++      u32 row = 0;
++      u32 temp = 0;
++
++      row = readl(SUNXI_DRAMC_BASE + DRAM_SCONR);
++      row &= 0x1e0;
++      row >>= 0x5;
++
++      if(row == 0xc)
++      {
++              if(clk >= 1000000)
++              {
++                      temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5);
++                      while(temp >= (10000000 >> 6))
++                      {
++                              temp -= (10000000 >> 6);
++                              val++;
++                      }
++              }
++              else
++              {
++                      val = (clk * 499) >> 6;
++              }
++      }
++      else if(row == 0xb)
++      {
++              if(clk >= 1000000)
++              {
++                      temp = clk + (clk >> 3) + (clk >> 4) + (clk >> 5);
++                      while(temp >= (10000000 >> 7))
++                      {
++                              temp -= (10000000 >> 7);
++                              val++;
++                      }
++              }
++              else
++              {
++                      val = (clk * 499) >> 5;
++              }
++      }
++      writel(val, SUNXI_DRAMC_BASE + DRAM_SREFR);
++}
++
++static int dram_para_setup(struct dram_para * para)
++{
++      u32 val = 0;
++
++      val = (para->ddr8_remap) | (0x1 << 1) |
++            ((para->bank_size >> 2) << 3) |
++            ((para->cs_num >> 1) << 4) |
++            ((para->row_width - 1) << 5) |
++            ((para->col_width - 1) << 9) |
++            ((para->sdr_ddr ? (para->bwidth >> 4) : (para->bwidth >> 5)) << 13) |
++            (para->access_mode << 15) |
++            (para->sdr_ddr << 16);
++
++      writel(val, SUNXI_DRAMC_BASE + DRAM_SCONR);
++      setbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR, 0x1 << 19);
++      return dram_initial();
++}
++
++static u32 dram_check_delay(u32 bwidth)
++{
++      u32 dsize;
++      int i,j;
++      u32 num = 0;
++      u32 dflag = 0;
++
++      dsize = ((bwidth == 16) ? 4 : 2);
++      for(i = 0; i < dsize; i++)
++      {
++              if(i == 0)
++                      dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR0);
++              else if(i == 1)
++                      dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR1);
++              else if(i == 2)
++                      dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR2);
++              else if(i == 3)
++                      dflag = readl(SUNXI_DRAMC_BASE + DRAM_DRPTR3);
++
++              for(j = 0; j < 32; j++)
++              {
++                      if(dflag & 0x1)
++                              num++;
++                      dflag >>= 1;
++              }
++      }
++      return num;
++}
++
++static int sdr_readpipe_scan(void)
++{
++      u32 k = 0;
++
++      for(k = 0; k < 32; k++)
++      {
++              writel(k, CONFIG_SYS_SDRAM_BASE + 4 * k);
++      }
++      for(k = 0; k < 32; k++)
++      {
++              if(readl(CONFIG_SYS_SDRAM_BASE + 4 * k) != k)
++                      return 0;
++      }
++      return 1;
++}
++
++static u32 sdr_readpipe_select(void)
++{
++      u32 value = 0;
++      u32 i = 0;
++      for(i = 0; i < 8; i++)
++      {
++              clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
++                              0x7 << 6, i << 6);
++              if(sdr_readpipe_scan())
++              {
++                      value = i;
++                      return value;
++              }
++      }
++      return value;
++}
++
++static u32 dram_check_type(struct dram_para * para)
++{
++      u32 times = 0;
++      int i;
++
++      for(i = 0; i < 8; i++)
++      {
++              clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
++                              0x7 << 6, i << 6);
++              dram_delay_scan();
++              if(readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) & 0x30)
++                      times++;
++      }
++
++      if(times == 8)
++      {
++              para->sdr_ddr = DRAM_TYPE_SDR;
++              return 0;
++      }
++      else
++      {
++              para->sdr_ddr = DRAM_TYPE_DDR;
++              return 1;
++      }
++}
++
++static u32 dram_scan_readpipe(struct dram_para * para)
++{
++      u32 rp_best = 0, rp_val = 0;
++      u32 readpipe[8];
++      int i;
++
++      if(para->sdr_ddr == DRAM_TYPE_DDR)
++      {
++              for(i = 0; i < 8; i++)
++              {
++                      clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
++                                      0x7 << 6, i << 6);
++                      dram_delay_scan();
++                      readpipe[i] = 0;
++                      if((((readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) >> 4) & 0x3) == 0x0) &&
++                              (((readl(SUNXI_DRAMC_BASE + DRAM_DDLYR) >> 4) & 0x1) == 0x0))
++                      {
++                              readpipe[i] = dram_check_delay(para->bwidth);
++                      }
++                      if(rp_val < readpipe[i])
++                      {
++                              rp_val = readpipe[i];
++                              rp_best = i;
++                      }
++              }
++              clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
++                              0x7 << 6, rp_best << 6);
++              dram_delay_scan();
++      }
++      else
++      {
++              clrbits_le32(SUNXI_DRAMC_BASE + DRAM_SCONR,
++                           (0x1 << 16) | (0x3 << 13));
++              rp_best = sdr_readpipe_select();
++              clrsetbits_le32(SUNXI_DRAMC_BASE + DRAM_SCTLR,
++                              0x7 << 6, rp_best << 6);
++      }
++      return 0;
++}
++
++static u32 dram_get_dram_size(struct dram_para * para)
++{
++      u32 colflag = 10, rowflag = 13;
++      u32 val1 = 0;
++      u32 count = 0;
++      u32 addr1, addr2;
++      int i;
++
++      para->col_width = colflag;
++      para->row_width = rowflag;
++      dram_para_setup(para);
++      dram_scan_readpipe(para);
++      for(i = 0; i < 32; i++)
++      {
++              *((u8 *)(CONFIG_SYS_SDRAM_BASE + 0x200 + i)) = 0x11;
++              *((u8 *)(CONFIG_SYS_SDRAM_BASE + 0x600 + i)) = 0x22;
++      }
++      for(i = 0; i < 32; i++)
++      {
++              val1 = *((u8 *)(CONFIG_SYS_SDRAM_BASE + 0x200 + i));
++              if(val1 == 0x22)
++                      count++;
++      }
++      if(count == 32)
++      {
++              colflag = 9;
++      }
++      else
++      {
++              colflag = 10;
++      }
++      count = 0;
++      para->col_width = colflag;
++      para->row_width = rowflag;
++      dram_para_setup(para);
++      if(colflag == 10)
++      {
++              addr1 = CONFIG_SYS_SDRAM_BASE + 0x400000;
++              addr2 = CONFIG_SYS_SDRAM_BASE + 0xc00000;
++      }
++      else
++      {
++              addr1 = CONFIG_SYS_SDRAM_BASE + 0x200000;
++              addr2 = CONFIG_SYS_SDRAM_BASE + 0x600000;
++      }
++      for(i = 0; i < 32; i++)
++      {
++              *((u8 *)(addr1 + i)) = 0x33;
++              *((u8 *)(addr2 + i)) = 0x44;
++      }
++      for(i = 0; i < 32; i++)
++      {
++              val1 = *((u8 *)(addr1 + i));
++              if(val1 == 0x44)
++              {
++                      count++;
++              }
++      }
++      if(count == 32)
++      {
++              rowflag = 12;
++      }
++      else
++      {
++              rowflag = 13;
++      }
++      para->col_width = colflag;
++      para->row_width = rowflag;
++      if(para->row_width != 13)
++      {
++              para->size = 16;
++      }
++      else if(para->col_width == 10)
++      {
++              para->size = 64;
++      }
++      else
++      {
++              para->size = 32;
++      }
++      dram_set_autofresh_cycle(para->clk);
++      para->access_mode = 0;
++      dram_para_setup(para);
++
++      return 0;
++}
++
++static void simple_dram_check(void)
++{
++      volatile u32 *dram = (u32*) CONFIG_SYS_SDRAM_BASE;
++      int i;
++
++      for(i = 0; i < 0x40; i++)
++      {
++              dram[i] = i;
++      }
++
++      for(i = 0; i < 0x40; i++)
++      {
++              if (dram[i] != i) {
++                      printf("DRAM initialization failed: dram[0x%x] != 0x%x.", i, dram[i]);
++                      while(1) {}
++              }
++      }
++
++      for(i = 0; i < 0x10000; i += 0x40)
++      {
++              dram[i] = i;
++      }
++
++      for(i = 0; i < 0x10000; i += 0x40)
++      {
++              if (dram[i] != i) {
++                      printf("DRAM initialization failed: dram[0x%x] != 0x%x.", i, dram[i]);
++                      while(1) {}
++              }
++      }
++}
++
++static void do_dram_init(struct dram_para * para)
++{
++      struct sunxi_ccm_reg * const ccm =
++              (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
++      u32 val;
++      u8 m; /* PLL_DDR clock factor */
++
++      sunxi_gpio_set_cfgpin(SUNXI_GPB(3), 0x7);
++      udelay(5000);
++      /* TODO: dig out what's them... some analog register? */
++      if(((para->cas) >> 3) & 0x1)
++      {
++              setbits_le32(SUNXI_PIO_BASE + 0x2c4, (0x1 << 23) | (0x20 << 17));
++      }
++
++      if((para->clk >= 144) && (para->clk <= 180))
++      {
++              writel(0xaaa, SUNXI_PIO_BASE + 0x2c0);
++      }
++      if(para->clk >= 180)
++      {
++              writel(0xfff, SUNXI_PIO_BASE + 0x2c0);
++      }
++
++      if(para->cas & BIT(4))
++      {
++              writel(0xd1303333, &ccm->pll5_pattern_cfg);
++      }
++      else if(para->cas & BIT(5))
++      {
++              writel(0xcce06666, &ccm->pll5_pattern_cfg);
++      }
++      else if(para->cas & BIT(6))
++      {
++              writel(0xc8909999, &ccm->pll5_pattern_cfg);
++      }
++      else if(para->cas & BIT(7))
++      {
++              writel(0xc440cccc, &ccm->pll5_pattern_cfg);
++      }
++
++      if((para->clk) <= 96)
++              m = 2;
++      else
++              m = 1;
++
++      val = CCM_PLL5_CTRL_EN | CCM_PLL5_CTRL_UPD |
++            CCM_PLL5_CTRL_N((para->clk * 2) / (24 / m)) |
++            CCM_PLL5_CTRL_K(1) | CCM_PLL5_CTRL_M(m);
++      if(para->cas & GENMASK(7, 4))
++      {
++              val |= CCM_PLL5_CTRL_SIGMA_DELTA_EN;
++      }
++      writel(val, &ccm->pll5_cfg);
++      setbits_le32(&ccm->pll5_cfg, CCM_PLL5_CTRL_UPD);
++      mctl_await_completion(&ccm->pll5_cfg, BIT(28), BIT(28));
++      udelay(5000);
++
++      setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_MCTL));
++      clrbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_RESET_OFFSET_MCTL));
++      udelay(50);
++      setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_RESET_OFFSET_MCTL));
++
++      clrsetbits_le32(SUNXI_PIO_BASE + 0x2c4, (1 << 16),
++                      ((para->sdr_ddr == DRAM_TYPE_DDR) << 16));
++
++      val = (SDR_T_CAS << 0) | (SDR_T_RAS << 3) | (SDR_T_RCD << 7) |
++            (SDR_T_RP << 10) | (SDR_T_WR << 13) | (SDR_T_RFC << 15) |
++            (SDR_T_XSR << 19) | (SDR_T_RC << 28);
++      writel(val, SUNXI_DRAMC_BASE + DRAM_STMG0R);
++      val = (SDR_T_INIT << 0) | (SDR_T_INIT_REF << 16) | (SDR_T_WTR << 20) |
++            (SDR_T_RRD << 22) | (SDR_T_XP << 25);
++      writel(val, SUNXI_DRAMC_BASE + DRAM_STMG1R);
++      dram_para_setup(para);
++      dram_check_type(para);
++
++      clrsetbits_le32(SUNXI_PIO_BASE + 0x2c4, (1 << 16),
++                      ((para->sdr_ddr == DRAM_TYPE_DDR) << 16));
++
++      dram_set_autofresh_cycle(para->clk);
++      dram_scan_readpipe(para);
++      dram_get_dram_size(para);
++      simple_dram_check();
++}
++
++unsigned long sunxi_dram_init(void)
++{
++      do_dram_init(&suniv_dram_para);
++
++      return suniv_dram_para.size * 1024 * 1024;
++}
+diff --git a/board/sunxi/board.c b/board/sunxi/board.c
+index b9450a0e36..48ef12e514 100644
+--- a/board/sunxi/board.c
++++ b/board/sunxi/board.c
+@@ -221,7 +221,7 @@ int board_init(void)
+       gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
+-#ifndef CONFIG_ARM64
++#if !defined(CONFIG_ARM64) && !defined(CONFIG_MACH_SUNIV)
+       asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
+       debug("id_pfr1: 0x%08x\n", id_pfr1);
+       /* Generic Timer Extension available? */
+@@ -248,7 +248,7 @@ int board_init(void)
+ #endif
+               }
+       }
+-#endif /* !CONFIG_ARM64 */
++#endif /* !CONFIG_ARM64 && !CONFIG_MACH_SUNIV */
+       ret = axp_gpio_init();
+       if (ret)
+diff --git a/include/configs/suniv.h b/include/configs/suniv.h
+new file mode 100644
+index 0000000000..e6aca3ec4b
+--- /dev/null
++++ b/include/configs/suniv.h
+@@ -0,0 +1,17 @@
++/*
++ * Configuration settings for new Allwinner F-series (suniv) CPU
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_SUNXI_USB_PHYS 1
++
++/*
++ * Include common sunxi configuration where most the settings are
++ */
++#include <configs/sunxi-common.h>
++
++#endif /* __CONFIG_H */
+diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
+index 0ef289fd64..cb427004b6 100644
+--- a/include/configs/sunxi-common.h
++++ b/include/configs/sunxi-common.h
+@@ -38,7 +38,12 @@
+ /* Serial & console */
+ #define CONFIG_SYS_NS16550_SERIAL
+ /* ns16550 reg in the low bits of cpu reg */
++#ifndef CONFIG_MACH_SUNIV
+ #define CONFIG_SYS_NS16550_CLK                24000000
++#else
++/* suniv doesn't have apb2 and uart is connected to apb1 */
++#define CONFIG_SYS_NS16550_CLK                100000000
++#endif
+ #ifndef CONFIG_DM_SERIAL
+ # define CONFIG_SYS_NS16550_REG_SIZE  -4
+ # define CONFIG_SYS_NS16550_COM1              SUNXI_UART0_BASE
+@@ -67,6 +72,16 @@
+  * we get warnings if the Kconfig value mismatches. */
+ #define CONFIG_SPL_STACK_R_ADDR               0x2fe00000
+ #define CONFIG_SPL_BSS_START_ADDR     0x2ff80000
++#elif defined(CONFIG_MACH_SUNIV)
++#define SDRAM_OFFSET(x) 0x8##x
++#define CONFIG_SYS_SDRAM_BASE         0x80000000
++#define CONFIG_SYS_LOAD_ADDR          0x81000000 /* default load address */
++#define CONFIG_SYS_TEXT_BASE          0x81700000
++/* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here 
++ * since it needs to fit in with the other values. By also #defining it
++ * we get warnings if the Kconfig value mismatches. */
++#define CONFIG_SPL_STACK_R_ADDR               0x81e00000
++#define CONFIG_SPL_BSS_START_ADDR     0x81f80000
+ #else
+ #define SDRAM_OFFSET(x) 0x4##x
+ #define CONFIG_SYS_SDRAM_BASE         0x40000000
+@@ -144,12 +159,15 @@
+ #define CONFIG_SYS_MMC_MAX_DEVICE     4
+ #endif
+-#ifndef CONFIG_MACH_SUN8I_V3S
+-/* 64MB of malloc() pool */
+-#define CONFIG_SYS_MALLOC_LEN         (CONFIG_ENV_SIZE + (64 << 20))
+-#else
++#if defined(CONFIG_MACH_SUN8I_V3S)
+ /* 2MB of malloc() pool */
+ #define CONFIG_SYS_MALLOC_LEN         (CONFIG_ENV_SIZE + (2 << 20))
++#elif defined(CONFIG_MACH_SUNIV)
++/* 1MB of malloc() pool */
++#define CONFIG_SYS_MALLOC_LEN         (CONFIG_ENV_SIZE + (1 << 20))
++#else
++/* 64MB of malloc() pool */
++#define CONFIG_SYS_MALLOC_LEN         (CONFIG_ENV_SIZE + (64 << 20))
+ #endif
+ /*
+@@ -301,19 +319,7 @@ extern int soft_i2c_gpio_scl;
+ #define RAMDISK_ADDR_R        __stringify(SDRAM_OFFSET(FE00000))
+ #else
+-/*
+- * 160M RAM (256M minimum minus 64MB heap + 32MB for u-boot, stack, fb, etc.
+- * 32M uncompressed kernel, 16M compressed kernel, 1M fdt,
+- * 1M script, 1M pxe and the ramdisk at the end.
+- */
+-#ifndef CONFIG_MACH_SUN8I_V3S
+-#define BOOTM_SIZE     __stringify(0xa000000)
+-#define KERNEL_ADDR_R  __stringify(SDRAM_OFFSET(2000000))
+-#define FDT_ADDR_R     __stringify(SDRAM_OFFSET(3000000))
+-#define SCRIPT_ADDR_R  __stringify(SDRAM_OFFSET(3100000))
+-#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(3200000))
+-#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(3300000))
+-#else
++#if defined(CONFIG_MACH_SUN8I_V3S)
+ /*
+  * 64M RAM minus 2MB heap + 16MB for u-boot, stack, fb, etc.
+  * 16M uncompressed kernel, 8M compressed kernel, 1M fdt,
+@@ -325,6 +331,30 @@ extern int soft_i2c_gpio_scl;
+ #define SCRIPT_ADDR_R  __stringify(SDRAM_OFFSET(1900000))
+ #define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(1A00000))
+ #define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(1B00000))
++#elif defined(CONFIG_MACH_SUNIV)
++/*
++ * 32M RAM minus 1MB heap + 8MB for u-boot, stack, fb, etc.
++ * 8M uncompressed kernel, 4M compressed kernel, 512K fdt,
++ * 512K script, 512K pxe and the ramdisk at the end.
++ */
++#define BOOTM_SIZE     __stringify(0x1700000)
++#define KERNEL_ADDR_R  __stringify(SDRAM_OFFSET(0500000))
++#define FDT_ADDR_R     __stringify(SDRAM_OFFSET(0C00000))
++#define SCRIPT_ADDR_R  __stringify(SDRAM_OFFSET(0C50000))
++#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(0D00000))
++#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(0D50000))
++#else
++/*
++ * 160M RAM (256M minimum minus 64MB heap + 32MB for u-boot, stack, fb, etc.
++ * 32M uncompressed kernel, 16M compressed kernel, 1M fdt,
++ * 1M script, 1M pxe and the ramdisk at the end.
++ */
++#define BOOTM_SIZE     __stringify(0xa000000)
++#define KERNEL_ADDR_R  __stringify(SDRAM_OFFSET(2000000))
++#define FDT_ADDR_R     __stringify(SDRAM_OFFSET(3000000))
++#define SCRIPT_ADDR_R  __stringify(SDRAM_OFFSET(3100000))
++#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(3200000))
++#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(3300000))
+ #endif
+ #endif
+diff --git a/include/dt-bindings/clock/suniv-ccu.h b/include/dt-bindings/clock/suniv-ccu.h
+new file mode 100644
+index 0000000000..9c22d70b2c
+--- /dev/null
++++ b/include/dt-bindings/clock/suniv-ccu.h
+@@ -0,0 +1,69 @@
++/*
++ * Copyright (c) 2018 Icenowy Zheng <icenowy@aosc.xyz>
++ *
++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++ */
++
++#ifndef _DT_BINDINGS_CLK_SUNIV_H_
++#define _DT_BINDINGS_CLK_SUNIV_H_
++
++#define CLK_CPU                       11
++
++#define CLK_BUS_MMC0          14
++#define CLK_BUS_MMC1          15
++#define CLK_BUS_DRAM          16
++#define CLK_BUS_SPI0          17
++#define CLK_BUS_SPI1          18
++#define CLK_BUS_OTG           19
++#define CLK_BUS_VE            20
++#define CLK_BUS_LCD           21
++#define CLK_BUS_DEINTERLACE   22
++#define CLK_BUS_CSI           23
++#define CLK_BUS_TVD           24
++#define CLK_BUS_TVE           25
++#define CLK_BUS_DE_BE         26
++#define CLK_BUS_DE_FE         27
++#define CLK_BUS_CODEC         28
++#define CLK_BUS_SPDIF         29
++#define CLK_BUS_IR            30
++#define CLK_BUS_RSB           31
++#define CLK_BUS_I2S0          32
++#define CLK_BUS_I2C0          33
++#define CLK_BUS_I2C1          34
++#define CLK_BUS_I2C2          35
++#define CLK_BUS_PIO           36
++#define CLK_BUS_UART0         37
++#define CLK_BUS_UART1         38
++#define CLK_BUS_UART2         39
++
++#define CLK_MMC0              40
++#define CLK_MMC0_SAMPLE               41
++#define CLK_MMC0_OUTPUT               42
++#define CLK_MMC1              43
++#define CLK_MMC1_SAMPLE               44
++#define CLK_MMC1_OUTPUT               45
++#define CLK_I2S                       46
++#define CLK_SPDIF             47
++
++#define CLK_USB_PHY0          48
++
++#define CLK_DRAM_VE           49
++#define CLK_DRAM_CSI          50
++#define CLK_DRAM_DEINTERLACE  51
++#define CLK_DRAM_TVD          52
++#define CLK_DRAM_DE_FE                53
++#define CLK_DRAM_DE_BE                54
++
++#define CLK_DE_BE             55
++#define CLK_DE_FE             56
++#define CLK_TCON              57
++#define CLK_DEINTERLACE               58
++#define CLK_TVE2_CLK          59
++#define CLK_TVE1_CLK          60
++#define CLK_TVD                       61
++#define CLK_CSI                       62
++#define CLK_VE                        63
++#define CLK_CODEC             64
++#define CLK_AVS                       65
++
++#endif
+diff --git a/include/dt-bindings/reset/suniv-ccu.h b/include/dt-bindings/reset/suniv-ccu.h
+new file mode 100644
+index 0000000000..993f6b5381
+--- /dev/null
++++ b/include/dt-bindings/reset/suniv-ccu.h
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.xyz>
++ *
++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++ */
++
++#ifndef _DT_BINDINGS_RST_SUNIV_H_
++#define _DT_BINDINGS_RST_SUNIV_H_
++
++#define RST_USB_PHY0          0
++#define RST_BUS_MMC0          1
++#define RST_BUS_MMC1          2
++#define RST_BUS_DRAM          3
++#define RST_BUS_SPI0          4
++#define RST_BUS_SPI1          5
++#define RST_BUS_OTG           6
++#define RST_BUS_VE            7
++#define RST_BUS_LCD           8
++#define RST_BUS_DEINTERLACE           9
++#define RST_BUS_CSI           10
++#define RST_BUS_TVD           11
++#define RST_BUS_TVE           12
++#define RST_BUS_DE_BE         13
++#define RST_BUS_DE_FE         14
++#define RST_BUS_CODEC         15
++#define RST_BUS_SPDIF         16
++#define RST_BUS_IR            17
++#define RST_BUS_RSB           18
++#define RST_BUS_I2S0          19
++#define RST_BUS_I2C0          20
++#define RST_BUS_I2C1          21
++#define RST_BUS_I2C2          22
++#define RST_BUS_UART0         23
++#define RST_BUS_UART1         24
++#define RST_BUS_UART2         25
++
++#endif /* _DT_BINDINGS_RST_SUNIV_H_ */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0004-sunxi-suniv-add-support-for-Lichee-Pi-Nano.patch b/package/boot/uboot-suniv/patches/0004-sunxi-suniv-add-support-for-Lichee-Pi-Nano.patch
new file mode 100644 (file)
index 0000000..b298fc9
--- /dev/null
@@ -0,0 +1,95 @@
+From 42174df1977bd0e1052eacd6c7094db630d15cca Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Thu, 18 Jan 2018 23:37:02 +0800
+Subject: [PATCH 04/29] sunxi: suniv: add support for Lichee Pi Nano
+
+Lichee Pi Nano is a board based on F1C100s.
+
+Add support for it.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/dts/suniv-f1c100s-licheepi-nano.dts | 43 ++++++++++++++++++++
+ configs/licheepi_nano_defconfig              |  9 ++++
+ 2 files changed, 52 insertions(+)
+ create mode 100644 arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+ create mode 100644 configs/licheepi_nano_defconfig
+
+diff --git a/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+new file mode 100644
+index 0000000000..d54cded8e3
+--- /dev/null
++++ b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+@@ -0,0 +1,43 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR X11)
++/*
++ * Copyright 2018 Icenowy Zheng <icenowy@aosc.io>
++ */
++
++/dts-v1/;
++#include "suniv-f1c100s.dtsi"
++
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++      model = "Lichee Pi Nano";
++      compatible = "licheepi,licheepi-nano", "allwinner,suniv-f1c100s",
++                   "allwinner,suniv";
++
++      aliases {
++              serial0 = &uart0;
++      };
++
++      chosen {
++              stdout-path = "serial0:115200n8";
++      };
++};
++
++&otg_sram {
++      status = "okay";
++};
++
++&uart0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart0_pins_a>;
++      status = "okay";
++};
++
++&usb_otg {
++      dr_mode = "otg";
++      status = "okay";
++};
++
++&usbphy {
++      usb0_id_det-gpio = <&pio 4 2 GPIO_ACTIVE_HIGH>; /* PE2 */
++      status = "okay";
++};
+diff --git a/configs/licheepi_nano_defconfig b/configs/licheepi_nano_defconfig
+new file mode 100644
+index 0000000000..6e455baadf
+--- /dev/null
++++ b/configs/licheepi_nano_defconfig
+@@ -0,0 +1,9 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_MACH_SUNIV=y
++CONFIG_DRAM_CLK=156
++CONFIG_DRAM_ZQ=0
++# CONFIG_VIDEO_SUNXI is not set
++CONFIG_DEFAULT_DEVICE_TREE="suniv-f1c100s-licheepi-nano"
++CONFIG_SPL=y
++# CONFIG_SPL_DM_SERIAL is not set
+-- 
+2.20.1
+
+--- u-boot-2019.04/arch/arm/dts/Makefile.old   2019-04-09 03:40:40.000000000 +0200
++++ u-boot-2019.04/arch/arm/dts/Makefile       2021-01-19 23:38:54.383599354 +0100
+@@ -485,6 +485,8 @@
+       sun9i-a80-optimus.dtb \
+       sun9i-a80-cubieboard4.dtb \
+       sun9i-a80-cx-a99.dtb
++dtb-$(CONFIG_MACH_SUNIV) += \
++      suniv-f1c100s-licheepi-nano.dtb
+ dtb-$(CONFIG_VF610) += vf500-colibri.dtb \
+       vf610-colibri.dtb \
diff --git a/package/boot/uboot-suniv/patches/0005-sunxi-suniv-add-boot-sequence-for-SPL-to-try.patch b/package/boot/uboot-suniv/patches/0005-sunxi-suniv-add-boot-sequence-for-SPL-to-try.patch
new file mode 100644 (file)
index 0000000..5ee4802
--- /dev/null
@@ -0,0 +1,51 @@
+From 2d6e643e5d0e42dd5d6a0c56ca66c6d1055b4e8d Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Fri, 19 Jan 2018 23:26:58 +0800
+Subject: [PATCH] sunxi: suniv: add boot sequence for SPL to try
+
+The BROM of suniv do not pass the info of boot media to SPL.
+
+Add boot sequence for SPL to try again for the available boot media.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/mach-sunxi/board.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index 35cd16bb44a..d20cf2dc38f 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -271,10 +271,32 @@ uint32_t sunxi_get_boot_device(void)
+       return sector;
+ }
++
++#ifndef CONFIG_MACH_SUNIV
+ u32 spl_boot_device(void)
+ {
+       return sunxi_get_boot_device();
+ }
++#else
++/*
++ * suniv BROM do not pass the boot media type to SPL, so we try with the
++ * boot sequence in BROM: mmc0->spinor->fail.
++ */
++void board_boot_order(u32 *spl_boot_list)
++{
++      /*
++       * See the comments above in sunxi_get_boot_device() for infomation
++       * about FEL boot.
++       */
++      if (!is_boot0_magic(SPL_ADDR + 4)) {
++              spl_boot_list[0] = BOOT_DEVICE_BOARD;
++              return;
++      }
++
++      spl_boot_list[0] = BOOT_DEVICE_MMC1;
++      spl_boot_list[1] = BOOT_DEVICE_SPI;
++}
++#endif
+ void board_init_f(ulong dummy)
+ {
diff --git a/package/boot/uboot-suniv/patches/0006-sunxi-spi-spl-add-support-for-SUNIV.patch b/package/boot/uboot-suniv/patches/0006-sunxi-spi-spl-add-support-for-SUNIV.patch
new file mode 100644 (file)
index 0000000..644437c
--- /dev/null
@@ -0,0 +1,95 @@
+From ffa272ca154c1fb1d035f102551c1fbbdce45f9f Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Fri, 19 Jan 2018 23:51:29 +0800
+Subject: [PATCH 06/29] sunxi: spi-spl: add support for SUNIV
+
+The suniv SoC come with a sun6i-style SPI controller at the base address
+of sun4i SPI controller. The module clock of the SPI controller is also
+missing.
+
+Add support for it.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+--- u-boot-2020.04/arch/arm/mach-sunxi/spl_spi_sunxi.c.orig    2020-04-13 17:02:18.000000000 +0200
++++ u-boot-2020.04/arch/arm/mach-sunxi/spl_spi_sunxi.c 2021-01-21 18:20:58.405677129 +0100
+@@ -85,6 +85,7 @@
+ #define SPI0_CLK_DIV_BY_2           0x1000
+ #define SPI0_CLK_DIV_BY_4           0x1001
++#define SPI0_CLK_DIV_BY_32          0x100f
+ /*****************************************************************************/
+@@ -151,11 +152,17 @@
+       if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+               setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
++#ifndef CONFIG_MACH_SUNIV
+       /* 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);
++#else
++      /* Divide by 32, clock source is AHB clock 200MHz */
++      writel(SPI0_CLK_DIV_BY_32, IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ?
++                              SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL);
++#endif
+       if (is_sun6i_gen_spi()) {
+               /* Enable SPI in the master mode and do a soft reset */
+@@ -185,8 +192,10 @@
+               clrbits_le32(base + SUN4I_SPI0_CTL, SUN4I_CTL_MASTER |
+                                            SUN4I_CTL_ENABLE);
++#ifndef CONFIG_MACH_SUNIV
+       /* Disable the SPI0 clock */
+       writel(0, CCM_SPI0_CLK);
++#endif
+       /* Close the SPI0 gate */
+       if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+@@ -208,6 +217,19 @@
+           IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+               pin_function = SUN50I_GPC_SPI0;
++      if (IS_ENABLED(CONFIG_MACH_SUNIV))
++              pin_function = SUNIV_GPC_SPI0;
++
++      /*
++       * suniv comes with a sun6i-style SPI controller at the
++       * sun4i SPI base address
++       */
++      if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) &&
++          !IS_ENABLED(CONFIG_MACH_SUNIV))
++              spi0_base = 0x01c68000;
++      else
++              spi0_base = 0x01c05000;
++
+       spi0_pinmux_setup(pin_function);
+       spi0_enable_clock();
+ }
+--- u-boot-2020.04/arch/arm/mach-sunxi/Kconfig.orig    2021-01-21 18:22:23.275147206 +0100
++++ u-boot-2020.04/arch/arm/mach-sunxi/Kconfig 2021-01-21 18:25:42.245215848 +0100
+@@ -1004,7 +1004,7 @@
+ 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 || MACH_SUN50I_H6
++      depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || MACH_SUN50I_H6 || MACH_SUNIV
+       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/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
+index 88018ae5689..43088e2f547 100644
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -169,6 +169,7 @@ enum sunxi_gpio_number {
+ #define SUNXI_GPC_NAND                2
+ #define SUNXI_GPC_SPI0                3
+ #define SUNXI_GPC_SDC2                3
++#define SUNIV_GPC_SPI0                2
+ #define SUN6I_GPC_SDC3                4
+ #define SUN50I_GPC_SPI0               4
diff --git a/package/boot/uboot-suniv/patches/0007-sunxi-add-missing-AHB_GATE_OFFSET_SPIx-defines-for-s.patch b/package/boot/uboot-suniv/patches/0007-sunxi-add-missing-AHB_GATE_OFFSET_SPIx-defines-for-s.patch
new file mode 100644 (file)
index 0000000..697bbf1
--- /dev/null
@@ -0,0 +1,46 @@
+From 315c1010ff3861f2f3018004847f7a7f49a06c31 Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@synkhronix.com>
+Date: Fri, 10 Feb 2017 12:04:17 +0000
+Subject: [PATCH 07/29] sunxi: add missing AHB_GATE_OFFSET_SPIx defines for
+ sun6i/sun9i
+
+Added missing AHB_GATE_OFFSET_SPIx defines to enable/disable clock gating for
+SPI on the sun6i and sun9i platforms.
+
+Signed-off-by: S.J.R. van Schaik <stephan@whiteboxsystems.nl>
+---
+ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 2 ++
+ arch/arm/include/asm/arch-sunxi/clock_sun9i.h | 4 ++++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+index 0d6168c430..6b9458f895 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+@@ -323,6 +323,8 @@ struct sunxi_ccm_reg {
+ #define AHB_GATE_OFFSET_USB0          25
+ #define AHB_GATE_OFFSET_SATA          24
+ #endif
++#define AHB_GATE_OFFSET_SPI1          21
++#define AHB_GATE_OFFSET_SPI0          20
+ #define AHB_GATE_OFFSET_MCTL          14
+ #define AHB_GATE_OFFSET_GMAC          17
+ #define AHB_GATE_OFFSET_NAND0         13
+diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
+index 530e0dd73b..181cb5194c 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
+@@ -194,6 +194,10 @@ struct sunxi_ccm_reg {
+ /* ahb gate1 field */
+ #define AHB_GATE_OFFSET_DMA           24
++#define AHB_GATE_OFFSET_SPI3          23
++#define AHB_GATE_OFFSET_SPI2          22
++#define AHB_GATE_OFFSET_SPI1          21
++#define AHB_GATE_OFFSET_SPI0          20
+ /* apb1_gate fields */
+ #define APB1_GATE_UART_SHIFT          16
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0008-sunxi-add-SPI-register-definitions-for-sun4i-sun7i.patch b/package/boot/uboot-suniv/patches/0008-sunxi-add-SPI-register-definitions-for-sun4i-sun7i.patch
new file mode 100644 (file)
index 0000000..b286a69
--- /dev/null
@@ -0,0 +1,113 @@
+From 10ca61bb6b41dd7a645a3fd03717d9125cb3963f Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@synkhronix.com>
+Date: Fri, 10 Feb 2017 11:24:37 +0000
+Subject: [PATCH 08/29] sunxi: add SPI register definitions for sun4i/sun7i
+
+Introduces SPI registers for sun4i/sun7i by adding struct sunxi_spi_regs
+and flags.
+
+Signed-off-by: S.J.R. van Schaik <stephan@whiteboxsystems.nl>
+---
+ arch/arm/include/asm/arch-sunxi/spi.h       | 29 +++++++++++
+ arch/arm/include/asm/arch-sunxi/spi_sun4i.h | 53 +++++++++++++++++++++
+ 2 files changed, 82 insertions(+)
+ create mode 100644 arch/arm/include/asm/arch-sunxi/spi.h
+ create mode 100644 arch/arm/include/asm/arch-sunxi/spi_sun4i.h
+
+diff --git a/arch/arm/include/asm/arch-sunxi/spi.h b/arch/arm/include/asm/arch-sunxi/spi.h
+new file mode 100644
+index 0000000000..66301b24d5
+--- /dev/null
++++ b/arch/arm/include/asm/arch-sunxi/spi.h
+@@ -0,0 +1,29 @@
++/*
++ * (C) Copyright 2017 Whitebox Systems / Northend Systems B.V.
++ * S.J.R. van Schaik <stephan@whiteboxsystems.nl>
++ * M.B.W. Wajer <merlijn@whiteboxsystems.nl>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#ifndef _SUNXI_SPI_H
++#define _SUNXI_SPI_H
++
++#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
++      defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I)
++#include <asm/arch/spi_sun6i.h>
++#else
++#include <asm/arch/spi_sun4i.h>
++#endif
++
++#define SUNXI_SPI_BURST_CNT(cnt)      ((cnt) & 0xffffff)
++#define SUNXI_SPI_XMIT_CNT(cnt)               ((cnt) & 0xffffff)
++
++#define SUNXI_SPI_CLK_CTL_CDR2_MASK   0xff
++#define SUNXI_SPI_CLK_CTL_CDR2(div)   ((div) & SUNXI_SPI_CLK_CTL_CDR2_MASK)
++#define SUNXI_SPI_CLK_CTL_CDR1_MASK   0xf
++#define SUNXI_SPI_CLK_CTL_CDR1(div)           \
++      (((div) & SUNXI_SPI_CLK_CTL_CDR1_MASK) << 8)
++#define SUNXI_SPI_CLK_CTL_DRS         BIT(12)
++
++#endif /* _SUNXI_SPI_H */
+diff --git a/arch/arm/include/asm/arch-sunxi/spi_sun4i.h b/arch/arm/include/asm/arch-sunxi/spi_sun4i.h
+new file mode 100644
+index 0000000000..c94519651f
+--- /dev/null
++++ b/arch/arm/include/asm/arch-sunxi/spi_sun4i.h
+@@ -0,0 +1,53 @@
++/*
++ * (C) Copyright 2017 Whitebox Systems / Northend Systems B.V.
++ * S.J.R. van Schaik <stephan@whiteboxsystems.nl>
++ * M.B.W. Wajer <merlijn@whiteboxsystems.nl>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#ifndef _SUNXI_SPI_SUN4I_H
++#define _SUNXI_SPI_SUN4I_H
++
++struct sunxi_spi_regs {
++      uint32_t rx_data;       /* 0x00 */
++      uint32_t tx_data;       /* 0x04 */
++      union {
++              uint32_t glb_ctl;
++              uint32_t xfer_ctl;
++              uint32_t fifo_ctl;
++              uint32_t burst_ctl;
++      };                      /* 0x08 */
++      uint32_t int_ctl;       /* 0x0c */
++      uint32_t int_sta;       /* 0x10 */
++      uint32_t dma_ctl;       /* 0x14 */
++      uint32_t wait;          /* 0x18 */
++      uint32_t clk_ctl;       /* 0x1c */
++      uint32_t burst_cnt;     /* 0x20 */
++      uint32_t xmit_cnt;      /* 0x24 */
++      uint32_t fifo_sta;      /* 0x28 */
++};
++
++#define SUNXI_SPI_CTL_SRST            0
++
++#define SUNXI_SPI_CTL_ENABLE          BIT(0)
++#define SUNXI_SPI_CTL_MASTER          BIT(1)
++#define SUNXI_SPI_CTL_CPHA            BIT(2)
++#define SUNXI_SPI_CTL_CPOL            BIT(3)
++#define SUNXI_SPI_CTL_CS_ACTIVE_LOW   BIT(4)
++#define SUNXI_SPI_CTL_TF_RST          BIT(8)
++#define SUNXI_SPI_CTL_RF_RST          BIT(9)
++#define SUNXI_SPI_CTL_XCH             BIT(10)
++#define SUNXI_SPI_CTL_CS_MASK         0x3000
++#define SUNXI_SPI_CTL_CS(cs)          (((cs) << 12) & SUNXI_SPI_CTL_CS_MASK)
++#define SUNXI_SPI_CTL_DHB             BIT(15)
++#define SUNXI_SPI_CTL_CS_MANUAL               BIT(16)
++#define SUNXI_SPI_CTL_CS_LEVEL                BIT(17)
++#define SUNXI_SPI_CTL_TP              BIT(18)
++
++#define SUNXI_SPI_FIFO_RF_CNT_MASK    0x7f
++#define SUNXI_SPI_FIFO_RF_CNT_BITS    0
++#define SUNXI_SPI_FIFO_TF_CNT_MASK    0x7f
++#define SUNXI_SPI_FIFO_TF_CNT_BITS    16
++
++#endif /* _SUNXI_SPI_SUN4I_H */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0009-sunxi-add-SPI-register-definitions-for-sun6i-sun8i-s.patch b/package/boot/uboot-suniv/patches/0009-sunxi-add-SPI-register-definitions-for-sun6i-sun8i-s.patch
new file mode 100644 (file)
index 0000000..e3ecd8b
--- /dev/null
@@ -0,0 +1,80 @@
+From f4c5f2f12c027600c3dc15f14c495e9a9449522f Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@synkhronix.com>
+Date: Fri, 10 Feb 2017 11:25:56 +0000
+Subject: [PATCH 09/29] sunxi: add SPI register definitions for
+ sun6i/sun8i/sun9i/sun50i
+
+Introduces SPI registers for sun6i/sun8i/sun9i/sun50i by adding struct
+sunxi_spi_regs and flags.
+
+Signed-off-by: S.J.R. van Schaik <stephan@whiteboxsystems.nl>
+---
+ arch/arm/include/asm/arch-sunxi/spi_sun6i.h | 56 +++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+ create mode 100644 arch/arm/include/asm/arch-sunxi/spi_sun6i.h
+
+diff --git a/arch/arm/include/asm/arch-sunxi/spi_sun6i.h b/arch/arm/include/asm/arch-sunxi/spi_sun6i.h
+new file mode 100644
+index 0000000000..d9241848f9
+--- /dev/null
++++ b/arch/arm/include/asm/arch-sunxi/spi_sun6i.h
+@@ -0,0 +1,56 @@
++/*
++ * (C) Copyright 2017 Whitebox Systems / Northend Systems B.V.
++ * S.J.R. van Schaik <stephan@whiteboxsystems.nl>
++ * M.B.W. Wajer <merlijn@whiteboxsystems.nl>
++ *
++ * SPDX-License-Identifier:   GPL-2.0+
++ */
++
++#ifndef _SUNXI_SPI_SUN6I_H
++#define _SUNXI_SPI_SUN6I_H
++
++struct sunxi_spi_regs {
++      uint32_t unused0[1];
++      uint32_t glb_ctl;       /* 0x04 */
++      uint32_t xfer_ctl;      /* 0x08 */
++      uint32_t unused1[1];
++      uint32_t int_ctl;       /* 0x10 */
++      uint32_t int_sta;       /* 0x14 */
++      uint32_t fifo_ctl;      /* 0x18 */
++      uint32_t fifo_sta;      /* 0x1c */
++      uint32_t wait;          /* 0x20 */
++      uint32_t clk_ctl;       /* 0x24 */
++      uint32_t unused2[2];
++      uint32_t burst_cnt;     /* 0x30 */
++      uint32_t xmit_cnt;      /* 0x34 */
++      uint32_t burst_ctl;     /* 0x38 */
++      uint32_t unused3[113];
++      uint32_t tx_data;       /* 0x200 */
++      uint32_t unused4[63];
++      uint32_t rx_data;       /* 0x300 */
++};
++
++#define SUNXI_SPI_CTL_ENABLE          BIT(0)
++#define SUNXI_SPI_CTL_MASTER          BIT(1)
++#define SUNXI_SPI_CTL_TP              BIT(7)
++#define SUNXI_SPI_CTL_SRST            BIT(31)
++
++#define SUNXI_SPI_CTL_CPHA            BIT(0)
++#define SUNXI_SPI_CTL_CPOL            BIT(1)
++#define SUNXI_SPI_CTL_CS_ACTIVE_LOW   BIT(2)
++#define SUNXI_SPI_CTL_CS_MASK         0x30
++#define SUNXI_SPI_CTL_CS(cs)          (((cs) << 4) & SUNXI_SPI_CTL_CS_MASK)
++#define SUNXI_SPI_CTL_CS_MANUAL               BIT(6)
++#define SUNXI_SPI_CTL_CS_LEVEL                BIT(7)
++#define SUNXI_SPI_CTL_DHB             BIT(8)
++#define SUNXI_SPI_CTL_XCH             BIT(31)
++
++#define SUNXI_SPI_CTL_RF_RST          BIT(15)
++#define SUNXI_SPI_CTL_TF_RST          BIT(31)
++
++#define SUNXI_SPI_FIFO_RF_CNT_MASK    0x7f
++#define SUNXI_SPI_FIFO_RF_CNT_BITS    0
++#define SUNXI_SPI_FIFO_TF_CNT_MASK    0x7f
++#define SUNXI_SPI_FIFO_TF_CNT_BITS    16
++
++#endif /* _SUNXI_SPI_SUN6I_H */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0010-introduce-and-use-sunxi_gpio_setup_dt_pins.patch b/package/boot/uboot-suniv/patches/0010-introduce-and-use-sunxi_gpio_setup_dt_pins.patch
new file mode 100644 (file)
index 0000000..b2d9722
--- /dev/null
@@ -0,0 +1,101 @@
+From 9a0ca4a595f8129904432b67ad1fb7ee815f3d67 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Sun, 12 Feb 2017 14:53:16 +0000
+Subject: [PATCH 10/29] introduce and use sunxi_gpio_setup_dt_pins()
+
+---
+ arch/arm/include/asm/arch-sunxi/gpio.h |  3 ++
+ arch/arm/mach-sunxi/pinmux.c           | 61 ++++++++++++++++++++++++++
+ 2 files changed, 64 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
+index 43088e2f54..723c553a8c 100644
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -250,4 +250,7 @@ int axp_gpio_init(void);
+ static inline int axp_gpio_init(void) { return 0; }
+ #endif
++int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node,
++                           const char * mux_name, int mux_sel);
++
+ #endif /* _SUNXI_GPIO_H */
+diff --git a/arch/arm/mach-sunxi/pinmux.c b/arch/arm/mach-sunxi/pinmux.c
+index 642483f06c..6ffba3910b 100644
+--- a/arch/arm/mach-sunxi/pinmux.c
++++ b/arch/arm/mach-sunxi/pinmux.c
+@@ -8,6 +8,9 @@
+ #include <common.h>
+ #include <asm/io.h>
+ #include <asm/arch/gpio.h>
++#include <fdtdec.h>
++#include <fdt_support.h>
++#include <dt-bindings/pinctrl/sun4i-a10.h>
+ void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val)
+ {
+@@ -68,3 +71,61 @@ int sunxi_gpio_set_pull(u32 pin, u32 val)
+       return 0;
+ }
++
++int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node,
++                           const char * mux_name, int mux_sel)
++{
++      int drive, pull, pin, i;
++      const char *pin_name;
++      int offset;
++
++      offset = fdtdec_lookup_phandle(fdt_blob, node, "pinctrl-0");
++      if (offset < 0)
++              return offset;
++
++      drive = fdt_getprop_u32_default_node(fdt_blob, offset, 0,
++                                           "drive-strength", 0);
++      if (drive) {
++              if (drive <= 10)
++                      drive = SUN4I_PINCTRL_10_MA;
++              else if (drive <= 20)
++                      drive = SUN4I_PINCTRL_20_MA;
++              else if (drive <= 30)
++                      drive = SUN4I_PINCTRL_30_MA;
++              else
++                      drive = SUN4I_PINCTRL_40_MA;
++      } else {
++              drive = fdt_getprop_u32_default_node(fdt_blob, offset, 0,
++                                                   "allwinner,drive", 4);
++      }
++
++      if (fdt_get_property(fdt_blob, offset, "bias-pull-up", NULL))
++              pull = SUN4I_PINCTRL_PULL_UP;
++      else if (fdt_get_property(fdt_blob, offset, "bias-disable", NULL))
++              pull = SUN4I_PINCTRL_NO_PULL;
++      else if (fdt_get_property(fdt_blob, offset, "bias-pull-down", NULL))
++              pull = SUN4I_PINCTRL_PULL_DOWN;
++      else
++              pull = fdt_getprop_u32_default_node(fdt_blob, offset, 0,
++                                                  "allwinner,pull", 0);
++
++      for (i = 0; ; i++) {
++              pin_name = fdt_stringlist_get(fdt_blob, offset,
++                                            "allwinner,pins", i, NULL);
++              if (!pin_name) {
++                      pin_name = fdt_stringlist_get(fdt_blob, offset,
++                                                    "pins", i, NULL);
++                      if (!pin_name)
++                              break;
++              }
++              pin = sunxi_name_to_gpio(pin_name);
++              if (pin < 0)
++                      continue;
++
++              sunxi_gpio_set_cfgpin(pin, mux_sel);
++              sunxi_gpio_set_drv(pin, drive);
++              sunxi_gpio_set_pull(pin, pull);
++      }
++
++      return i;
++}
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0011-sunxi-add-SPI-Flash-block-size-for-env-storage.patch b/package/boot/uboot-suniv/patches/0011-sunxi-add-SPI-Flash-block-size-for-env-storage.patch
new file mode 100644 (file)
index 0000000..dca71d5
--- /dev/null
@@ -0,0 +1,26 @@
+From 40715e23667d0ce5bfe81dae029ca99564031681 Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Sat, 20 Jan 2018 12:19:12 +0800
+Subject: [PATCH 11/29] sunxi: add SPI Flash block size for env storage
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ include/configs/sunxi-common.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
+index cb427004b6..6d754269cc 100644
+--- a/include/configs/sunxi-common.h
++++ b/include/configs/sunxi-common.h
+@@ -157,6 +157,8 @@
+ #define CONFIG_SYS_MMC_ENV_DEV                0
+ #endif
+ #define CONFIG_SYS_MMC_MAX_DEVICE     4
++#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
++#define CONFIG_ENV_SECT_SIZE 0x1000
+ #endif
+ #if defined(CONFIG_MACH_SUN8I_V3S)
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0012-spi-sunxi_spi-Add-DM-SPI-driver-for-A31-A80-A64.patch b/package/boot/uboot-suniv/patches/0012-spi-sunxi_spi-Add-DM-SPI-driver-for-A31-A80-A64.patch
new file mode 100644 (file)
index 0000000..bc9a337
--- /dev/null
@@ -0,0 +1,618 @@
+From 052334272e5268769a43689b636f895e524033ff Mon Sep 17 00:00:00 2001
+From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+Date: Wed, 1 Mar 2017 22:29:06 +0100
+Subject: [PATCH 12/29] spi: sunxi_spi: Add DM SPI driver for A31/A80/A64
+
+This adds a rewrite of the SPI driver we had in use for the A31-uQ7
+(sun6i), A80-Q7 (sun9i) and A64-uQ7 (sun50i) boards, which includes
+support for:
+ * cs-gpios (i.e. GPIOs as additional chip-selects)
+
+Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/include/asm/arch-sunxi/clock_sun6i.h |   2 +
+ drivers/spi/Kconfig                           |  14 +
+ drivers/spi/Makefile                          |   1 +
+ drivers/spi/sun6i_spi.c                       | 539 ++++++++++++++++++
+ 4 files changed, 556 insertions(+)
+ create mode 100644 drivers/spi/sun6i_spi.c
+
+diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+index 6b9458f895..5ecdf58bd5 100644
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+@@ -473,6 +473,8 @@ struct sunxi_ccm_reg {
+ #ifdef CONFIG_MACH_SUN8I_R40
+ #define AHB_RESET_OFFSET_SATA         24
+ #endif
++#define AHB_RESET_OFFSET_SPI1         21
++#define AHB_RESET_OFFSET_SPI0         20
+ #define AHB_RESET_OFFSET_GMAC         17
+ #define AHB_RESET_OFFSET_MCTL         14
+ #define AHB_RESET_OFFSET_MMC3         11
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 8588866489..2d2f447a54 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -282,6 +282,20 @@ config STM32_SPI
+         SoCs. This uses driver model and requires a device tree binding to
+         operate.
++config SUN6I_SPI
++      bool "Allwinner (sun6i+) SPI driver"
++      help
++        Enable the SPI driver for new Allwinner SoCs.
++
++        This driver can be used to access the SPI NOR flash on for
++        communciation with SPI peripherals platforms embedding the
++        Allwinner SoC.  This driver supports the device-model (only)
++        and has support for GPIOs as additional chip-selects.
++
++        For recent platforms (e.g. sun50i), dual-IO receive mode is
++        also supported, when configured for a SPI-NOR flash in the
++        device tree.
++
+ config TEGRA114_SPI
+       bool "nVidia Tegra114 SPI driver"
+       help
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index ae4f2958f8..ed49f39c34 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -50,6 +50,7 @@ obj-$(CONFIG_PL022_SPI) += pl022_spi.o
+ obj-$(CONFIG_RENESAS_RPC_SPI) += renesas_rpc_spi.o
+ obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
+ obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
++obj-$(CONFIG_SUN6I_SPI) += sun6i_spi.o
+ obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o
+ obj-$(CONFIG_SPI_SUNXI) += spi-sunxi.o
+ obj-$(CONFIG_SH_SPI) += sh_spi.o
+diff --git a/drivers/spi/sun6i_spi.c b/drivers/spi/sun6i_spi.c
+new file mode 100644
+index 0000000000..750c4d8819
+--- /dev/null
++++ b/drivers/spi/sun6i_spi.c
+@@ -0,0 +1,539 @@
++/*
++ * SPI driver for Allwinner sunxi SoCs
++ *
++ * Copyright (C) 2015-2017 Theobroma Systems Design und Consulting GmbH
++ *
++ * 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.
++ */
++
++#include <common.h>
++#ifdef CONFIG_DM_GPIO
++#include <asm/gpio.h>
++#endif
++#include <asm/io.h>
++#include <asm/arch/clock.h>
++#include <dm.h>
++#include <errno.h>
++#include <fdtdec.h>
++#include <wait_bit.h>
++#include <reset.h>
++#include <spi.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++struct sunxi_spi_platdata {
++      void *base;
++      unsigned int max_hz;
++
++      /* We could do with a single delay counter, but it won't do harm
++         to have two, as the same is the case for most other driver. */
++      uint deactivate_delay_us;       /* Delay to wait after deactivate */
++      uint activate_delay_us;         /* Delay to wait after activate */
++
++#if defined(CONFIG_DM_GPIO)
++      int cs_gpios_num;
++      struct gpio_desc *cs_gpios;
++#endif
++};
++
++struct sunxi_spi_driverdata {
++      unsigned int  fifo_depth;
++};
++
++struct sunxi_spi_privdata {
++      ulong last_transaction_us;      /* Time of last transaction end */
++      unsigned int hz_requested;      /* last requested bitrate */
++      unsigned int hz_actual;         /* currently set bitrate */
++};
++
++struct sunxi_spi_reg {
++      u8      _rsvd[0x4];
++      u32     GCR;   /* SPI Global Control register */
++      u32     TCR;   /* SPI Transfer Control register */
++      u8      _rsvd1[0x4];
++      u32     IER;   /* SPI Interrupt Control register */
++      u32     ISR;   /* SPI Interrupt Status register */
++      u32     FCR;   /* SPI FIFO Control register */
++      u32     FSR;   /* SPI FIFO Status register */
++      u32     WCR;   /* SPI Wait Clock Counter register */
++      u32     CCR;   /* SPI Clock Rate Control register */
++      u8      _rsvd2[0x8];
++      u32     MBC;   /* SPI Burst Counter register */
++      u32     MTC;   /* SPI Transmit Counter register */
++      u32     BCC;   /* SPI Burst Control register */
++      u8      _rsvd3[0x4c];
++      u32     NDMA_MODE_CTL;
++      u8      _rsvd4[0x174];
++      u32     TXD;   /* SPI TX Data register */
++      u8      _rsvd5[0xfc];
++      u32     RXD;   /* SPI RX Data register */
++};
++
++
++#define GCR_MASTER     BIT(1)
++#define GCR_EN                 BIT(0)
++
++#define TCR_XCH          BIT(31)
++#define TCR_SDC          BIT(11)
++#define TCR_DHB          BIT(8)
++#define TCR_SSSEL_SHIFT  (4)
++#define TCR_SSSEL_MASK   (0x3 << TCR_SSSEL_SHIFT)
++#define TCR_SSLEVEL      BIT(7)
++#define TCR_SSOWNER      BIT(6)
++#define TCR_CPOL         BIT(1)
++#define TCR_CPHA         BIT(0)
++
++#define FCR_RX_FIFO_RST  BIT(31)
++#define FCR_TX_FIFO_RST  BIT(15)
++
++#define BCC_STC_MASK     (0x00FFFFFF)
++
++#define CCTL_SEL_CDR1    0
++#define CCTL_SEL_CDR2    BIT(12)
++#define CDR1(n)          ((n & 0xf) << 8)
++#define CDR2(n)          (((n/2) - 1) & 0xff)
++
++static int sunxi_spi_cs_activate(struct udevice *dev, unsigned cs)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      struct sunxi_spi_reg *spi = (struct sunxi_spi_reg *)plat->base;
++      struct sunxi_spi_privdata *priv = dev_get_priv(bus);
++      int ret = 0;
++
++      debug("%s (%s): cs %d cs_gpios_num %d cs_gpios %p\n",
++            dev->name, __func__, cs, plat->cs_gpios_num, plat->cs_gpios);
++
++      /* If it's too soon to do another transaction, wait... */
++      if (plat->deactivate_delay_us && priv->last_transaction_us) {
++              ulong delay_us;
++              delay_us = timer_get_us() - priv->last_transaction_us;
++              if (delay_us < plat->deactivate_delay_us)
++                      udelay(plat->deactivate_delay_us - delay_us);
++      }
++
++#if defined(CONFIG_DM_GPIO)
++      /* Use GPIOs as chip selects? */
++      if (plat->cs_gpios) {
++              /* Guard against out-of-bounds accesses */
++              if (!(cs < plat->cs_gpios_num))
++                      return -ENOENT;
++
++              if (dm_gpio_is_valid(&plat->cs_gpios[cs])) {
++                      ret = dm_gpio_set_value(&plat->cs_gpios[cs], 1);
++                      goto done;
++              }
++      }
++#endif
++      /* The hardware can control up to 4 CS, however not all of
++         them will be going to pads. We don't try to second-guess
++         the DT or higher-level drivers though and just test against
++         the hard limit. */
++
++      if (!(cs < 4))
++              return -ENOENT;
++
++      /* Control the positional CS output */
++      clrsetbits_le32(&spi->TCR, TCR_SSSEL_MASK, cs << TCR_SSSEL_SHIFT);
++      clrsetbits_le32(&spi->TCR, TCR_SSLEVEL, TCR_SSOWNER);
++
++done:
++      /* We'll delay, even it this is an error return... */
++      if (plat->activate_delay_us)
++              udelay(plat->activate_delay_us);
++
++      return ret;
++}
++
++static void sunxi_spi_cs_deactivate(struct udevice *dev, unsigned cs)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      struct sunxi_spi_reg *spi = (struct sunxi_spi_reg *)plat->base;
++      struct sunxi_spi_privdata *priv = dev_get_priv(bus);
++
++#if defined(CONFIG_DM_GPIO)
++      /* Use GPIOs as chip selects? */
++      if (plat->cs_gpios) {
++              if (dm_gpio_is_valid(&plat->cs_gpios[cs])) {
++                      dm_gpio_set_value(&plat->cs_gpios[cs], 0);
++                      return;
++              }
++      }
++#endif
++
++      /* We have only the hardware chip select, so use those */
++      setbits_le32(&spi->TCR, TCR_SSLEVEL | TCR_SSOWNER);
++
++      /* Remember time of this transaction for the next delay */
++      if (plat->deactivate_delay_us)
++              priv->last_transaction_us = timer_get_us();
++}
++
++static inline uint8_t *spi_fill_writefifo(struct sunxi_spi_reg *spi,
++                                        uint8_t *dout, int cnt)
++{
++      debug("%s: dout = %p, cnt = %d\n", __func__, dout, cnt);
++
++      if (dout) {
++              int i;
++
++              for (i = 0; i < cnt; i++)
++                      writeb(dout[i], &spi->TXD);
++
++              dout += cnt;
++      }
++
++      return dout;
++}
++
++static inline uint8_t *spi_drain_readfifo(struct sunxi_spi_reg *spi,
++                                        uint8_t *din, int cnt)
++{
++      debug("%s: din = %p, cnt = %d\n", __func__, din, cnt);
++
++      if (din) {
++              int i;
++
++              for (i = 0; i < cnt; i++)
++                      din[i] = readb(&spi->RXD);
++
++              din += cnt;
++      }
++
++      return din;
++}
++
++static int sunxi_spi_xfer(struct udevice *dev, unsigned int bitlen,
++                        const void *out, void *in, unsigned long flags)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      struct sunxi_spi_privdata *priv = dev_get_priv(bus);
++      struct sunxi_spi_reg *spi = (struct sunxi_spi_reg *)plat->base;
++      struct sunxi_spi_driverdata *data =
++              (struct sunxi_spi_driverdata *)dev_get_driver_data(dev->parent);
++      struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
++      uint8_t *dout = (uint8_t *)out;
++      uint8_t *din = (uint8_t *)in;
++      int fifo_depth = data->fifo_depth;
++      unsigned int n_bytes = DIV_ROUND_UP(bitlen, 8);
++      int ret = 0;
++      /*
++       * We assume that 1ms (for any delays within the module to
++       * start the transfer) + 2x the time to transfer a full FIFO
++       * (for the data- and bitrate-dependent part) is a reasonable
++       * timeout to detect the module being stuck.
++       */
++      ulong timeout_ms =
++              (DIV_ROUND_UP(fifo_depth * 16000, priv->hz_actual)) + 1;
++
++      debug("%s (%s): regs %p bitlen %d din %p flags %lx fifo_depth %d\n",
++            dev->name, __func__, spi, bitlen, din, flags, fifo_depth);
++
++      if (flags & SPI_XFER_BEGIN) {
++              ret = sunxi_spi_cs_activate(dev, slave->cs);
++              if (ret < 0) {
++                      printf("%s: failed to activate chip-select %d\n",
++                             dev->name, slave->cs);
++                      return ret;
++              }
++      }
++
++      /* Reset FIFO */
++      writel(FCR_RX_FIFO_RST | FCR_TX_FIFO_RST, &spi->FCR);
++      /* Wait until the FIFO reset autoclears */
++      ret = wait_for_bit(dev->name, &spi->FCR,
++                         FCR_RX_FIFO_RST | FCR_TX_FIFO_RST,
++                         false, 10, true);
++      if (ret < 0) {
++              printf("%s: failed to reset FIFO within 10ms\n", bus->name);
++              return ret;
++      }
++
++      /* Set the discard burst bits depending on whether we are receiving */
++      clrbits_le32(&spi->TCR, TCR_DHB);
++      if (!din)
++              setbits_le32(&spi->TCR, TCR_DHB);
++
++      /* Transfer in blocks of FIFO_DEPTH */
++      while (n_bytes > 0) {
++              int cnt = (n_bytes < fifo_depth) ? n_bytes : fifo_depth;
++              int txcnt = dout ? cnt : 0;
++
++              /* We need to set up the transfer counters in every
++                 iteration, as the hardware block counts those down
++                 to 0 and leaves the 0 in the register (i.e. there's
++                 no shadow register within the controller that these
++                 values are copied into). */
++
++              /* master burst counter:     total length (tx + rx + dummy) */
++              writel(cnt, &spi->MBC);
++              /* master transmit counter:  tx */
++              writel(txcnt, &spi->MTC);
++              /* burst control counter:    single-mode tx */
++              clrsetbits_le32(&spi->BCC, BCC_STC_MASK, txcnt & BCC_STC_MASK);
++
++              dout = spi_fill_writefifo(spi, dout, txcnt);
++
++              /* Start transfer ... */
++              setbits_le32(&spi->TCR, TCR_XCH);
++              /* ... and wait until it finshes. */
++              ret = wait_for_bit(dev->name, &spi->TCR, TCR_XCH,
++                                 false, timeout_ms, true);
++              if (ret < 0) {
++                      printf("%s: stuck in XCH for %ld ms\n",
++                             bus->name, timeout_ms);
++                      goto fail;
++              }
++
++              din = spi_drain_readfifo(spi, din, cnt);
++
++              n_bytes -= cnt;
++      }
++
++ fail:
++      if (flags & SPI_XFER_END)
++              sunxi_spi_cs_deactivate(dev, slave->cs);
++
++      return 0;
++};
++
++static int sunxi_spi_ofdata_to_platdata(struct udevice *dev)
++{
++      struct sunxi_spi_platdata *plat = dev_get_platdata(dev);
++      const void *blob = gd->fdt_blob;
++      int node = dev_of_offset(dev);
++      fdt_addr_t addr;
++      fdt_size_t size;
++
++      debug("%s: %p\n", __func__, dev);
++
++      addr = fdtdec_get_addr_size_auto_noparent(blob, node, "reg", 0,
++                                                &size, false);
++      if (addr == FDT_ADDR_T_NONE) {
++              debug("%s: failed to find base address\n", dev->name);
++              return -ENODEV;
++      }
++      plat->base = (void *)addr;
++      plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0);
++      plat->activate_delay_us = fdtdec_get_int(blob, node,
++                                               "spi-activate_delay", 0);
++      plat->deactivate_delay_us = fdtdec_get_int(blob, node,
++                                                 "spi-deactivate-delay", 0);
++
++#if defined(CONFIG_DM_GPIO)
++      plat->cs_gpios_num = gpio_get_list_count(dev, "cs-gpios");
++      if (plat->cs_gpios_num > 0) {
++              int i;
++
++              plat->cs_gpios = calloc(plat->cs_gpios_num,
++                                      sizeof(struct gpio_desc));
++              if (!plat->cs_gpios)
++                      return -ENOMEM;
++
++              for (i = 0; i < plat->cs_gpios_num; ++i)
++                      gpio_request_by_name(dev, "cs-gpios", i,
++                                           &plat->cs_gpios[i], 0);
++      }
++#endif
++      return 0;
++}
++
++static int sunxi_spi_probe(struct udevice *dev)
++{
++      unsigned int pin_func = SUNXI_GPC_SPI0;
++      int ret;
++
++      if (IS_ENABLED(CONFIG_MACH_SUN50I))
++              pin_func = SUN50I_GPC_SPI0;
++
++      if (IS_ENABLED(CONFIG_MACH_SUNIV))
++              pin_func = SUNIV_GPC_SPI0;
++
++      ret = sunxi_gpio_setup_dt_pins(gd->fdt_blob, dev_of_offset(dev),
++                                     NULL, pin_func);
++
++      if (ret < 0) {
++              printf("SPI: pinctrl node not found.\n");
++      } else if (!ret) {
++              printf("SPI: pinctrl node not valid.\n");
++      }
++
++      return (ret <= 0) ? -EINVAL : 0;
++}
++
++static int sunxi_spi_claim_bus(struct udevice *dev)
++{
++      struct sunxi_spi_platdata *plat = dev_get_platdata(dev->parent);
++      struct spi_slave *spi_slave = dev_get_parent_priv(dev);
++      struct sunxi_spi_reg *spi = (struct sunxi_spi_reg *)plat->base;
++
++      debug("%s: %p %p\n", __func__, dev, dev->parent);
++
++      /* Enable in master-mode */
++      setbits_le32(&spi->GCR, GCR_MASTER | GCR_EN);
++      /* All CS control is manual and set them to inactive */
++      clrbits_le32(&spi->TCR, TCR_SSSEL_MASK);
++      setbits_le32(&spi->TCR, TCR_SSOWNER);
++      /* Apply polarity and phase from the mode bits */
++      if (spi_slave->mode & SPI_CPOL)
++              setbits_le32(&spi->TCR, TCR_CPOL);
++      if (spi_slave->mode & SPI_CPHA)
++              setbits_le32(&spi->TCR, TCR_CPHA);
++
++#if defined(DM_GPIO)
++      /* Set all cs-gpios to inactive */
++      for (i = 0; i < plat->cs_gpios_num; ++i)
++              if (dm_gpio_is_valid(&plat->cs_gpios[i]))
++                      dm_gpio_set_value(&plat->cs_gpios[i], 0);
++#endif
++
++
++      return 0;
++}
++
++static int sunxi_spi_release_bus(struct udevice *dev)
++{
++      struct sunxi_spi_platdata *plat = dev_get_platdata(dev->parent);
++      struct sunxi_spi_reg *spi = (struct sunxi_spi_reg *)plat->base;
++
++      clrbits_le32(&spi->GCR, GCR_EN);
++
++      return 0;
++}
++
++static int sunxi_spi_set_speed(struct udevice *bus, unsigned int hz)
++{
++      struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      struct sunxi_spi_reg *spi = (struct sunxi_spi_reg *)plat->base;
++      struct sunxi_spi_privdata *priv = dev_get_priv(bus);
++      unsigned sclk_shift, hz_ahb, hz_sclk, target_freq;
++
++      debug("%s: %p, %d\n", __func__, bus, hz);
++
++      if (plat->max_hz && (hz > plat->max_hz)) {
++              debug("%s: selected speed (%d) exceeds maximum of %d\n",
++                    bus->name, hz, plat->max_hz);
++              hz = plat->max_hz;
++      }
++
++      /* If the last request was for the same speed, we're done */
++      if (priv->hz_requested == hz)
++              return 0;
++
++      /* The CCU section in the manual recommends to have the module
++         reset deasserted before the module clock gate is opened. */
++      setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_SPI0);
++
++
++      /* Enable and set the module clock.
++       *
++       * At least for the A31, there's a requirements to provide at
++       * least 2x the sample clock, so we should never go below that
++       * ratio between the AHB clock and the (ampling) SCLK. On the
++       * low end of the clock, we use the provide two step-downs for
++       * clocks on the low end (below 375kHz).
++       *
++       * However, testing shows that for high-speed modes (on the
++       * A64), we may not divide SCLK from the AHB clock.
++       */
++#ifndef CONFIG_MACH_SUNIV
++      if (hz < 100000)
++              sclk_shift = 8;
++      else if (hz < 50000000)
++              sclk_shift = 2;
++      else
++              sclk_shift = 0;
++
++      setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_SPI0);
++
++      /* Program the SPI clock control */
++      writel(CCTL_SEL_CDR1 | CDR1(sclk_shift), &spi->CCR);
++
++      target_freq = hz * (1 << sclk_shift);
++
++      if (target_freq < 24000000) {
++              writel(BIT(31) | max(24000000 / target_freq - 1, 0xf),
++                     &ccm->spi0_clk_cfg);
++              hz_ahb = 24000000 / ((readl(&ccm->spi0_clk_cfg) & 0xf) + 1);
++      } else {
++              writel(BIT(31) | (0x01 << 24) | max(600000000 / target_freq - 1, 0xf),
++                     &ccm->spi0_clk_cfg);
++              hz_ahb = 600000000 / ((readl(&ccm->spi0_clk_cfg) & 0xf) + 1);
++      }
++#else
++      hz_ahb = target_freq = 200000000; /* AHB clock on suniv */
++      sclk_shift = 0;
++      while(target_freq > hz && sclk_shift < 0xf) {
++              target_freq >>= 1;
++              sclk_shift += 1;
++      };
++
++      setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_SPI0);
++
++      writel(CCTL_SEL_CDR1 | CDR1(sclk_shift), &spi->CCR);
++#endif
++
++      hz_sclk = hz_ahb >> sclk_shift;
++      priv->hz_actual = hz_sclk;
++      debug("%s: hz_ahb %d  hz_sclk %d\n", bus->name, hz_ahb, hz_sclk);
++
++      /* If this is a high-speed mode (which we define---based upon
++         empirical testing---to be above 50 MHz), we need to move the
++         sampling point during data read. */
++      if (hz_sclk > 50000000)
++              setbits_le32(&spi->TCR, TCR_SDC);
++      else
++              clrbits_le32(&spi->TCR, TCR_SDC);
++
++      return 0;
++};
++
++static int sunxi_spi_set_mode(struct udevice *bus, unsigned int mode)
++{
++      return 0;
++};
++
++static const struct dm_spi_ops sunxi_spi_ops = {
++      .claim_bus      = sunxi_spi_claim_bus,
++      .release_bus    = sunxi_spi_release_bus,
++      .xfer           = sunxi_spi_xfer,
++      .set_speed      = sunxi_spi_set_speed,
++      .set_mode       = sunxi_spi_set_mode,
++      /*
++       * cs_info is not needed, since we require all chip selects to be
++       * in the device tree explicitly
++       */
++};
++
++static struct sunxi_spi_driverdata  sun6i_a31_data = {
++      .fifo_depth = 128,
++};
++
++static struct sunxi_spi_driverdata  sun50i_a64_data = {
++      .fifo_depth = 64,
++};
++
++static const struct udevice_id sunxi_spi_ids[] = {
++      { .compatible = "allwinner,sun6i-a31-spi",
++        .data = (uintptr_t)&sun6i_a31_data },
++      { .compatible = "allwinner,sun8i-h3-spi",
++        .data = (uintptr_t)&sun50i_a64_data },
++      { }
++};
++
++U_BOOT_DRIVER(sunxi_spi) = {
++      .name = "sunxi_spi",
++      .id = UCLASS_SPI,
++      .of_match = sunxi_spi_ids,
++      .ofdata_to_platdata = sunxi_spi_ofdata_to_platdata,
++      .platdata_auto_alloc_size = sizeof(struct sunxi_spi_platdata),
++      .priv_auto_alloc_size = sizeof(struct sunxi_spi_privdata),
++      .probe = sunxi_spi_probe,
++      .ops = &sunxi_spi_ops,
++};
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0013-sunxi-add-SPI0-node-for-suniv.patch b/package/boot/uboot-suniv/patches/0013-sunxi-add-SPI0-node-for-suniv.patch
new file mode 100644 (file)
index 0000000..16cea3e
--- /dev/null
@@ -0,0 +1,53 @@
+From c5a5bf586bbd0290837f7297f8181aa83b4e1f85 Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Sat, 20 Jan 2018 11:57:56 +0800
+Subject: [PATCH 13/29] sunxi: add SPI0 node for suniv
+
+The suniv SoC has two SPI controllers, in which SPI0 is bootable.
+
+Add device tree node of the controller and its bootable pinmux node.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/dts/suniv.dtsi | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/arch/arm/dts/suniv.dtsi b/arch/arm/dts/suniv.dtsi
+index 5bca082d2e..10da83b53a 100644
+--- a/arch/arm/dts/suniv.dtsi
++++ b/arch/arm/dts/suniv.dtsi
+@@ -76,6 +76,19 @@
+                       };
+               };
++              spi0: spi@1c05000 {
++                      compatible = "allwinner,suniv-spi",
++                                   "allwinner,sun8i-h3-spi";
++                      reg = <0x01c05000 0x1000>;
++                      interrupts = <10>;
++                      clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_BUS_SPI0>;
++                      clock-names = "ahb", "mod";
++                      resets = <&ccu RST_BUS_SPI0>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
+               ccu: clock@1c20000 {
+                       compatible = "allwinner,suniv-ccu";
+                       reg = <0x01c20000 0x400>;
+@@ -103,6 +116,11 @@
+                       #interrupt-cells = <3>;
+                       #gpio-cells = <3>;
++                      spi0_pins_a: spi0-pins-pc {
++                              pins = "PC0", "PC1", "PC2", "PC3";
++                              function = "spi0";
++                      };
++
+                       uart0_pins_a: uart-pins-pe {
+                               pins = "PE0", "PE1";
+                               function = "uart0";
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0014-sunxi-enable-SPI-NOR-on-Lichee-Pi-Nano.patch b/package/boot/uboot-suniv/patches/0014-sunxi-enable-SPI-NOR-on-Lichee-Pi-Nano.patch
new file mode 100644 (file)
index 0000000..b9ce622
--- /dev/null
@@ -0,0 +1,50 @@
+From f08fe4e963b095d9aa015749f87a262c29b6eab0 Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Sat, 20 Jan 2018 12:02:25 +0800
+Subject: [PATCH 14/29] sunxi: enable SPI NOR on Lichee Pi Nano
+
+The Lichee Pi Nano board has a Winbond W25Q128 SPI flash on it.
+
+Enable it.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/dts/suniv-f1c100s-licheepi-nano.dts | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+index d54cded8e3..9c111e6228 100644
+--- a/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
++++ b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+@@ -15,6 +15,7 @@
+       aliases {
+               serial0 = &uart0;
++              spi0 = &spi0;
+       };
+       chosen {
+@@ -26,6 +27,20 @@
+       status = "okay";
+ };
++&spi0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&spi0_pins_a>;
++      status = "okay";
++
++      flash@0 {
++              #address-cells = <1>;
++              #size-cells = <1>;
++              compatible = "winbond,w25q128", "jedec,spi-nor";
++              reg = <0>;
++              spi-max-frequency = <40000000>;
++      };
++};
++
+ &uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0015-sunxi-add-defconfig-for-Lichee-Pi-Nano-with-SPI-Flas.patch b/package/boot/uboot-suniv/patches/0015-sunxi-add-defconfig-for-Lichee-Pi-Nano-with-SPI-Flas.patch
new file mode 100644 (file)
index 0000000..89e9c06
--- /dev/null
@@ -0,0 +1,46 @@
+From af302872077323de681f7be76cf35becc6153f38 Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Sat, 20 Jan 2018 21:00:50 +0800
+Subject: [PATCH 15/29] sunxi: add defconfig for Lichee Pi Nano with SPI Flash
+ support
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ configs/licheepi_nano_spiflash_defconfig | 25 ++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+ create mode 100644 configs/licheepi_nano_spiflash_defconfig
+
+diff --git a/configs/licheepi_nano_spiflash_defconfig b/configs/licheepi_nano_spiflash_defconfig
+new file mode 100644
+index 0000000000..07b6a27dbe
+--- /dev/null
++++ b/configs/licheepi_nano_spiflash_defconfig
+@@ -0,0 +1,25 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_ENV_SIZE=0x8000
++CONFIG_ENV_OFFSET=0xf8000
++CONFIG_MACH_SUNIV=y
++CONFIG_DRAM_CLK=156
++CONFIG_DRAM_ZQ=0
++# CONFIG_VIDEO_SUNXI is not set
++CONFIG_DEFAULT_DEVICE_TREE="suniv-f1c100s-licheepi-nano"
++CONFIG_SPL=y
++# CONFIG_CMD_FLASH is not set
++# CONFIG_CMD_FPGA is not set
++CONFIG_CMD_SF=y
++CONFIG_CMD_SPI=y
++CONFIG_ENV_IS_IN_SPI_FLASH=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SPI_FLASH=y
++CONFIG_SPI_FLASH_BAR=y
++CONFIG_SPI_FLASH_GIGADEVICE=y
++CONFIG_SPI_FLASH_MACRONIX=y
++CONFIG_SPI_FLASH_WINBOND=y
++CONFIG_SPL_SPI_SUNXI=y
++# CONFIG_SPL_DM_SERIAL is not set
++CONFIG_DM_SPI=y
++CONFIG_SUN6I_SPI=y
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0016-sunxi-add-support-for-UART-at-PF-for-suniv.patch b/package/boot/uboot-suniv/patches/0016-sunxi-add-support-for-UART-at-PF-for-suniv.patch
new file mode 100644 (file)
index 0000000..6fa1d90
--- /dev/null
@@ -0,0 +1,27 @@
+From 5feb0865dab1d81f0dee6cabf9038c12f8139e2f Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Sun, 21 Jan 2018 00:39:27 +0800
+Subject: [PATCH 16/29] sunxi: add support for UART at PF for suniv
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ arch/arm/mach-sunxi/board.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index d20cf2dc38..cedab41f8f 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -75,7 +75,8 @@ static int gpio_init(void)
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUNXI_GPIO_INPUT);
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT);
+ #endif
+-#if defined(CONFIG_MACH_SUN8I) && !defined(CONFIG_MACH_SUN8I_R40)
++#if (defined(CONFIG_MACH_SUN8I) && !defined(CONFIG_MACH_SUN8I_R40)) || \
++    defined(CONFIG_MACH_SUNIV)
+       sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0);
+       sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0);
+ #else
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0017-sunxi-do-not-set-PF-MMC0-pinmux-when-PF-uart-is-used.patch b/package/boot/uboot-suniv/patches/0017-sunxi-do-not-set-PF-MMC0-pinmux-when-PF-uart-is-used.patch
new file mode 100644 (file)
index 0000000..ff3640f
--- /dev/null
@@ -0,0 +1,38 @@
+From 4bd08d34c87d85904f5205241909a3a4d908487f Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Sun, 21 Jan 2018 00:40:14 +0800
+Subject: [PATCH 17/29] sunxi: do not set PF MMC0 pinmux when PF uart is used
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ board/sunxi/board.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/board/sunxi/board.c b/board/sunxi/board.c
+index 48ef12e514..0380d9b77b 100644
+--- a/board/sunxi/board.c
++++ b/board/sunxi/board.c
+@@ -375,17 +375,19 @@ void board_nand_init(void)
+ #ifdef CONFIG_MMC
+ static void mmc_pinmux_setup(int sdc)
+ {
+-      unsigned int pin;
++      __maybe_unused unsigned int pin;
+       __maybe_unused int pins;
+       switch (sdc) {
+       case 0:
+               /* SDC0: PF0-PF5 */
++#ifndef CONFIG_UART0_PORT_F
+               for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) {
+                       sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0);
+                       sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
+                       sunxi_gpio_set_drv(pin, 2);
+               }
++#endif
+               break;
+       case 1:
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0018-sunxi-allow-to-enable-MMC-driver-when-using-PF-UART0.patch b/package/boot/uboot-suniv/patches/0018-sunxi-allow-to-enable-MMC-driver-when-using-PF-UART0.patch
new file mode 100644 (file)
index 0000000..c38ec41
--- /dev/null
@@ -0,0 +1,29 @@
+From 42e14729ccd2aefc6726801554422497016b82bc Mon Sep 17 00:00:00 2001
+From: Icenowy Zheng <icenowy@aosc.io>
+Date: Sun, 21 Jan 2018 00:43:43 +0800
+Subject: [PATCH 18/29] sunxi: allow to enable MMC driver when using PF UART0
+
+As the pinmux setup of MMC0 at PF is masked, the sunxi MMC driver is now
+harmless for PF uart setup, and it may be used for the extra MMC port.
+
+Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
+---
+ drivers/mmc/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
+index 85fd1906bd..93281d8e30 100644
+--- a/drivers/mmc/Kconfig
++++ b/drivers/mmc/Kconfig
+@@ -653,7 +653,7 @@ config ZYNQ_HISPD_BROKEN
+ config MMC_SUNXI
+       bool "Allwinner sunxi SD/MMC Host Controller support"
+-      depends on ARCH_SUNXI && !UART0_PORT_F
++      depends on ARCH_SUNXI
+       default y
+       help
+         This selects support for the SD/MMC Host Controller on
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0019-sunxi-timer-forward-declare-function.patch b/package/boot/uboot-suniv/patches/0019-sunxi-timer-forward-declare-function.patch
new file mode 100644 (file)
index 0000000..b8e4c5f
--- /dev/null
@@ -0,0 +1,26 @@
+From b35aa33d8f831dada5990cb07ac3b696cd9d6a78 Mon Sep 17 00:00:00 2001
+From: florpor <florist.powers@gmail.com>
+Date: Wed, 29 Apr 2020 13:39:00 +0300
+Subject: [PATCH 19/29] sunxi timer forward declare function
+
+---
+ arch/arm/cpu/arm926ejs/sunxi/timer.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/cpu/arm926ejs/sunxi/timer.c b/arch/arm/cpu/arm926ejs/sunxi/timer.c
+index 36263896d8..7baae749c9 100644
+--- a/arch/arm/cpu/arm926ejs/sunxi/timer.c
++++ b/arch/arm/cpu/arm926ejs/sunxi/timer.c
+@@ -28,6 +28,9 @@ DECLARE_GLOBAL_DATA_PTR;
+ #define TIMER_NUM             0       /* we use timer 0 */
++/* forward declaration */
++ulong get_timer_masked(void);
++
+ /* read the 32-bit timer */
+ static ulong read_timer(void)
+ {
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/002-add-olimex-a13-som.patch b/package/boot/uboot-suniv/patches/002-add-olimex-a13-som.patch
new file mode 100644 (file)
index 0000000..c19f378
--- /dev/null
@@ -0,0 +1,20 @@
+--- /dev/null
++++ b/configs/OLIMEX_A13_SOM_defconfig
+@@ -0,0 +1,17 @@
++CONFIG_SPL=y
++CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_MACH_SUN5I=y
++CONFIG_DRAM_CLK=408
++CONFIG_DRAM_ZQ=123
++CONFIG_DRAM_EMR1=0
++# CONFIG_CMD_IMLS is not set
++# CONFIG_CMD_FLASH is not set
++# CONFIG_CMD_FPGA is not set
++CONFIG_DM_SERIAL=y
++CONFIG_USB=y
++CONFIG_DM_USB=y
++CONFIG_SYS_NS16550=y
++CONFIG_SUNXI_NO_PMIC=y
++CONFIG_USB_EHCI_HCD=y
diff --git a/package/boot/uboot-suniv/patches/0020-disable-sunxi-enable_caches-function-for-arm926ejs.patch b/package/boot/uboot-suniv/patches/0020-disable-sunxi-enable_caches-function-for-arm926ejs.patch
new file mode 100644 (file)
index 0000000..11ff4ae
--- /dev/null
@@ -0,0 +1,25 @@
+From 1f42a5fe1414e505cbf0d558de837dcc91f8d7ba Mon Sep 17 00:00:00 2001
+From: florpor <florist.powers@gmail.com>
+Date: Wed, 29 Apr 2020 13:39:57 +0300
+Subject: [PATCH 20/29] disable sunxi enable_caches function for arm926ejs
+
+---
+ arch/arm/mach-sunxi/board.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
+index cedab41f8f..7e088c7e8a 100644
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -343,7 +343,7 @@ void reset_cpu(ulong addr)
+ #endif
+ }
+-#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
++#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && !defined(CONFIG_ARM64) && !defined(CONFIG_CPU_ARM926EJS)
+ void enable_caches(void)
+ {
+       /* Enable D-cache. I-cache is already enabled in start.S */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0022-remove-suniv-config-ubs-phys-define.patch b/package/boot/uboot-suniv/patches/0022-remove-suniv-config-ubs-phys-define.patch
new file mode 100644 (file)
index 0000000..b7e261d
--- /dev/null
@@ -0,0 +1,26 @@
+From 9fcee618a2099677e015f3a1bd8fa1d66f7ac9f3 Mon Sep 17 00:00:00 2001
+From: florpor <florist.powers@gmail.com>
+Date: Wed, 29 Apr 2020 13:57:19 +0300
+Subject: [PATCH 22/29] remove suniv config ubs phys define
+
+it isn't used by the driver anymore and triggers kconfig errors
+---
+ include/configs/suniv.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/include/configs/suniv.h b/include/configs/suniv.h
+index e6aca3ec4b..483c20edc1 100644
+--- a/include/configs/suniv.h
++++ b/include/configs/suniv.h
+@@ -7,8 +7,6 @@
+ #ifndef __CONFIG_H
+ #define __CONFIG_H
+-#define CONFIG_SUNXI_USB_PHYS 1
+-
+ /*
+  * Include common sunxi configuration where most the settings are
+  */
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0023-fix-sun6i-spi-driver-wait_for_bit.patch b/package/boot/uboot-suniv/patches/0023-fix-sun6i-spi-driver-wait_for_bit.patch
new file mode 100644 (file)
index 0000000..70cbed7
--- /dev/null
@@ -0,0 +1,34 @@
+From 92cd8a878ddd2948447b447305183e3df896f58d Mon Sep 17 00:00:00 2001
+From: florpor <florist.powers@gmail.com>
+Date: Wed, 29 Apr 2020 13:57:56 +0300
+Subject: [PATCH 23/29] fix sun6i spi driver wait_for_bit
+
+---
+ drivers/spi/sun6i_spi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/sun6i_spi.c b/drivers/spi/sun6i_spi.c
+index 750c4d8819..74146f8f2f 100644
+--- a/drivers/spi/sun6i_spi.c
++++ b/drivers/spi/sun6i_spi.c
+@@ -246,7 +246,7 @@ static int sunxi_spi_xfer(struct udevice *dev, unsigned int bitlen,
+       /* Reset FIFO */
+       writel(FCR_RX_FIFO_RST | FCR_TX_FIFO_RST, &spi->FCR);
+       /* Wait until the FIFO reset autoclears */
+-      ret = wait_for_bit(dev->name, &spi->FCR,
++      ret = wait_for_bit_32(&spi->FCR,
+                          FCR_RX_FIFO_RST | FCR_TX_FIFO_RST,
+                          false, 10, true);
+       if (ret < 0) {
+@@ -282,7 +282,7 @@ static int sunxi_spi_xfer(struct udevice *dev, unsigned int bitlen,
+               /* Start transfer ... */
+               setbits_le32(&spi->TCR, TCR_XCH);
+               /* ... and wait until it finshes. */
+-              ret = wait_for_bit(dev->name, &spi->TCR, TCR_XCH,
++              ret = wait_for_bit_32(&spi->TCR, TCR_XCH,
+                                  false, timeout_ms, true);
+               if (ret < 0) {
+                       printf("%s: stuck in XCH for %ld ms\n",
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0024-ensure-correct-spi-driver-is-loaded.patch b/package/boot/uboot-suniv/patches/0024-ensure-correct-spi-driver-is-loaded.patch
new file mode 100644 (file)
index 0000000..a7db9f4
--- /dev/null
@@ -0,0 +1,42 @@
+From 182334907bbf9fc3f14ea8c13f59171bdddecac4 Mon Sep 17 00:00:00 2001
+From: florpor <florist.powers@gmail.com>
+Date: Wed, 29 Apr 2020 14:01:05 +0300
+Subject: [PATCH 24/29] ensure correct spi driver is loaded
+
+---
+ drivers/spi/spi-sunxi.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c
+index dbfeac77ee..6e32d034b2 100644
+--- a/drivers/spi/spi-sunxi.c
++++ b/drivers/spi/spi-sunxi.c
+@@ -598,14 +598,6 @@ static const struct sun4i_spi_variant sun6i_a31_spi_variant = {
+       .has_burst_ctl          = true,
+ };
+-static const struct sun4i_spi_variant sun8i_h3_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[] = {
+       {
+         .compatible = "allwinner,sun4i-a10-spi",
+@@ -615,10 +607,6 @@ static const struct udevice_id sun4i_spi_ids[] = {
+         .compatible = "allwinner,sun6i-a31-spi",
+         .data = (ulong)&sun6i_a31_spi_variant,
+       },
+-      {
+-        .compatible = "allwinner,sun8i-h3-spi",
+-        .data = (ulong)&sun8i_h3_spi_variant,
+-      },
+       { /* sentinel */ }
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0025-add-suniv-pinctrl-compatibility-to-sunxi-gpio-driver.patch b/package/boot/uboot-suniv/patches/0025-add-suniv-pinctrl-compatibility-to-sunxi-gpio-driver.patch
new file mode 100644 (file)
index 0000000..935ce98
--- /dev/null
@@ -0,0 +1,24 @@
+From d3e6ffc3500df261617bf52676dfb548edc5fa68 Mon Sep 17 00:00:00 2001
+From: florpor <florist.powers@gmail.com>
+Date: Wed, 29 Apr 2020 14:02:04 +0300
+Subject: [PATCH 25/29] add suniv-pinctrl compatibility to sunxi gpio driver
+
+---
+ drivers/gpio/sunxi_gpio.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
+index 719efc2cef..be816c688c 100644
+--- a/drivers/gpio/sunxi_gpio.c
++++ b/drivers/gpio/sunxi_gpio.c
+@@ -355,6 +355,7 @@ static const struct udevice_id sunxi_gpio_ids[] = {
+       ID("allwinner,sun9i-a80-pinctrl",       a_all),
+       ID("allwinner,sun50i-a64-pinctrl",      a_all),
+       ID("allwinner,sun50i-h6-pinctrl",       a_all),
++      ID("allwinner,suniv-pinctrl",           a_all),
+       ID("allwinner,sun6i-a31-r-pinctrl",     l_2),
+       ID("allwinner,sun8i-a23-r-pinctrl",     l_1),
+       ID("allwinner,sun8i-a83t-r-pinctrl",    l_1),
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0028-sunxi-suniv-add-device-tree-nodes-for-f1c100s-MMC-co.patch b/package/boot/uboot-suniv/patches/0028-sunxi-suniv-add-device-tree-nodes-for-f1c100s-MMC-co.patch
new file mode 100644 (file)
index 0000000..161e05a
--- /dev/null
@@ -0,0 +1,80 @@
+From 42966ff87a183f6299ebc6d3f5db2b1f2bb02a1e Mon Sep 17 00:00:00 2001
+From: George Hilliard <thirtythreeforty@gmail.com>
+Date: Sun, 21 Jul 2019 15:21:18 -0500
+Subject: [PATCH 28/29] sunxi: suniv: add device tree nodes for f1c100s MMC
+ controllers
+
+The f1c100s has two MMC controllers.  Add device tree nodes for them.
+
+Signed-off-by: George Hilliard <thirtythreeforty@gmail.com>
+---
+ arch/arm/dts/suniv.dtsi | 47 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+diff --git a/arch/arm/dts/suniv.dtsi b/arch/arm/dts/suniv.dtsi
+index 10da83b53a..660eb3d49c 100644
+--- a/arch/arm/dts/suniv.dtsi
++++ b/arch/arm/dts/suniv.dtsi
+@@ -125,6 +125,11 @@
+                               pins = "PE0", "PE1";
+                               function = "uart0";
+                       };
++
++                      mmc0_pins: mmc0-pins {
++                              pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
++                              function = "mmc0";
++                      };
+               };
+               timer@1c20c00 {
+@@ -197,5 +202,47 @@
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
++
++              mmc0: mmc@1c0f000 {
++                      compatible = "allwinner,suniv-f1c100s-mmc",
++                                   "allwinner,sun7i-a20-mmc";
++                      reg = <0x01c0f000 0x1000>;
++                      clocks = <&ccu CLK_BUS_MMC0>,
++                               <&ccu CLK_MMC0>,
++                               <&ccu CLK_MMC0_OUTPUT>,
++                               <&ccu CLK_MMC0_SAMPLE>;
++                      clock-names = "ahb",
++                                    "mmc",
++                                    "output",
++                                    "sample";
++                      resets = <&ccu RST_BUS_MMC0>;
++                      reset-names = "ahb";
++                      interrupts = <23>;
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&mmc0_pins>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
++              mmc2: mmc@1c10000 {
++                      compatible = "allwinner,suniv-f1c100s-mmc",
++                                   "allwinner,sun7i-a20-mmc";
++                      reg = <0x01c10000 0x1000>;
++                      clocks = <&ccu CLK_BUS_MMC1>,
++                               <&ccu CLK_MMC1>,
++                               <&ccu CLK_MMC1_OUTPUT>,
++                               <&ccu CLK_MMC1_SAMPLE>;
++                      clock-names = "ahb",
++                                    "mmc",
++                                    "output",
++                                    "sample";
++                      resets = <&ccu RST_BUS_MMC1>;
++                      reset-names = "ahb";
++                      interrupts = <24>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
+       };
+ };
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/0029-licheepi-nano-dts-enable-mmc0.patch b/package/boot/uboot-suniv/patches/0029-licheepi-nano-dts-enable-mmc0.patch
new file mode 100644 (file)
index 0000000..169b67f
--- /dev/null
@@ -0,0 +1,38 @@
+From 9f068e10bb9ddb4c9610427662be9048e75bcd6a Mon Sep 17 00:00:00 2001
+From: florpor <florist.powers@gmail.com>
+Date: Wed, 29 Apr 2020 14:07:19 +0300
+Subject: [PATCH 29/29] licheepi nano dts - enable mmc0
+
+---
+ arch/arm/dts/suniv-f1c100s-licheepi-nano.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+index 9c111e6228..0145fa027a 100644
+--- a/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
++++ b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+@@ -5,6 +5,7 @@
+ /dts-v1/;
+ #include "suniv-f1c100s.dtsi"
++#include "sunxi-common-regulators.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
+@@ -41,6 +42,13 @@
+       };
+ };
++&mmc0 {
++      vmmc-supply = <&reg_vcc3v3>;
++      bus-width = <4>;
++      broken-cd;
++      status = "okay";
++};
++
+ &uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+-- 
+2.20.1
+
diff --git a/package/boot/uboot-suniv/patches/003-add-theobroma-a31-pangolin.patch b/package/boot/uboot-suniv/patches/003-add-theobroma-a31-pangolin.patch
new file mode 100644 (file)
index 0000000..29969a7
--- /dev/null
@@ -0,0 +1,375 @@
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -455,6 +455,7 @@ dtb-$(CONFIG_MACH_SUN6I) += \
+       sun6i-a31-m9.dtb \
+       sun6i-a31-mele-a1000g-quad.dtb \
+       sun6i-a31-mixtile-loftq.dtb \
++      sun6i-a31-pangolin.dtb \
+       sun6i-a31s-colorfly-e708-q1.dtb \
+       sun6i-a31s-cs908.dtb \
+       sun6i-a31s-inet-q972.dtb \
+--- a/arch/arm/dts/sun6i-a31.dtsi
++++ b/arch/arm/dts/sun6i-a31.dtsi
+@@ -641,6 +641,11 @@
+                               function = "lcd0";
+                       };
++                      i2c3_pins_a: i2c3@0 {
++                              allwinner,pins = "PB5", "PB6";
++                              allwinner,function = "i2c3";
++                      };
++
+                       mmc0_pins_a: mmc0@0 {
+                               pins = "PF0", "PF1", "PF2",
+                                                "PF3", "PF4", "PF5";
+--- /dev/null
++++ b/arch/arm/dts/sun6i-a31-pangolin.dts
+@@ -0,0 +1,292 @@
++/*
++ * Copyright 2015, Theobroma Systems Design und Consulting GmbH
++ *
++ * This file is dual-licensed: you can use it either under the terms
++ * of the GPL or the X11 license, at your option. Note that this dual
++ * licensing only applies to this file, and not this project as a
++ * whole.
++ *
++ *  a) This file 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 file 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.
++ *
++ * Or, alternatively,
++ *
++ *  b) Permission is hereby granted, free of charge, to any person
++ *     obtaining a copy of this software and associated documentation
++ *     files (the "Software"), to deal in the Software without
++ *     restriction, including without limitation the rights to use,
++ *     copy, modify, merge, publish, distribute, sublicense, and/or
++ *     sell copies of the Software, and to permit persons to whom the
++ *     Software is furnished to do so, subject to the following
++ *     conditions:
++ *
++ *     The above copyright notice and this permission notice shall be
++ *     included in all copies or substantial portions of the Software.
++ *
++ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
++ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
++ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ *     OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/dts-v1/;
++#include "sun6i-a31.dtsi"
++#include "sunxi-common-regulators.dtsi"
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/pinctrl/sun4i-a10.h>
++
++/ {
++      model = "Theobroma Systems A31 Pangolin";
++      compatible = "tsd,a31-pangolin", "allwinner,sun6i-a31";
++
++      aliases {
++              serial0 = &uart0;
++              serial2 = &uart2;
++              spi0 = &spi0;
++              spi1 = &spi1;
++              spi2 = &spi2;
++              spi3 = &spi3;
++      };
++
++      chosen {
++              stdout-path = "serial2:115200n8";
++      };
++};
++
++&ehci0 {
++      status = "okay";
++};
++
++&ohci0 {
++      status = "okay";
++};
++
++&ehci1 {
++      status = "okay";
++};
++
++&ohci1 {
++      status = "okay";
++};
++
++&ohci2 {
++      status = "okay";
++};
++
++&gmac {
++      pinctrl-names = "default";
++      pinctrl-0 = <&gmac_pins_rgmii_a>;
++      phy = <&phy1>;
++      phy-mode = "rgmii";
++      snps,reset-gpio = <&pio 0 7 GPIO_ACTIVE_LOW>;
++      snps,reset-active-low;
++      snps,reset-delays-us = <0 10000 30000>;
++      status = "okay";
++
++      phy1: ethernet-phy@4 {
++              reg = <4>;
++      };
++};
++
++&i2c0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c0_pins_a>;
++      status = "okay";
++};
++
++&i2c1 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c1_pins_a>;
++      status = "okay";
++};
++
++&i2c2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c2_pins_a>;
++      status = "okay";
++};
++
++&i2c3 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&i2c3_pins_a>;
++      status = "okay";
++
++      rtc_twi: rtc@6f {
++       compatible = "isil,isl1208";
++       reg = <0x6f>;
++      };
++      fan: fan@18 {
++              compatible = "ti,amc6821";
++              reg = <0x18>;
++              cooling-min-state = <0>;
++              cooling-max-state = <9>;
++              #cooling-cells = <2>;
++      };
++};
++
++&spi0 {
++      status = "okay";
++
++      flash: flash@0 {
++              compatible = "spansion,m25p40";
++              spi-max-frequency = <16000000>;
++              spi-cpol;
++              spi-cpha;
++      };
++};
++
++&spi1 {
++      status = "okay";
++};
++
++&ir {
++      pinctrl-names = "default";
++      pinctrl-0 = <&ir_pins_a>;
++      status = "okay";
++};
++
++&mmc0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_pangolin>;
++      vmmc-supply = <&reg_vcc3v0>;
++      bus-width = <4>;
++      cd-gpios = <&pio 2 19 GPIO_ACTIVE_LOW>; /* PC19 */
++      status = "okay";
++};
++
++&mmc0_pins_a {
++      /* external pull-ups missing for some pins */
++      allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
++};
++
++&mmc2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&mmc2_pins_a>;
++      vmmc-supply = <&reg_vcc3v0>;
++      bus-width = <8>;
++      non-removable;
++      status = "okay";
++};
++
++&pio {
++      mmc0_cd_pin_pangolin: mmc0_cd_pin@0 {
++              allwinner,pins = "PC19";
++              allwinner,function = "gpio_in";
++              allwinner,drive = <SUN4I_PINCTRL_10_MA>;
++              allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
++      };
++
++      leds_pins_pangolin: led_pins@0 {
++              allwinner,pins = "PH7", "PC16";
++              allwinner,function = "gpio_out";
++              allwinner,drive = <SUN4I_PINCTRL_20_MA>;
++              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
++      };
++
++      mmc2_pins_a: mmc2@0 {
++              allwinner,pins = "PC6","PC7","PC8","PC9","PC10","PC11",
++                              "PC12","PC13","PC14","PC15";
++              allwinner,function = "mmc2";
++              allwinner,drive = <SUN4I_PINCTRL_30_MA>;
++              allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
++      };
++};
++
++&p2wi {
++      status = "okay";
++
++      axp221: pmic@68 {
++              compatible = "x-powers,axp221";
++              reg = <0x68>;
++              interrupt-parent = <&nmi_intc>;
++              interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
++              interrupt-controller;
++              #interrupt-cells = <1>;
++              dcdc1-supply = <&vcc_3v0>;
++              dcdc5-supply = <&vcc_dram>;
++
++              regulators {
++                      x-powers,dcdc-freq = <3000>;
++
++                      vcc_3v0: dcdc1 {
++                              regulator-always-on;
++                              regulator-min-microvolt = <3000000>;
++                              regulator-max-microvolt = <3000000>;
++                              regulator-name = "vcc-3v0";
++                      };
++
++                      vdd_cpu: dcdc2 {
++                              regulator-always-on;
++                              regulator-min-microvolt = <700000>;
++                              regulator-max-microvolt = <1320000>;
++                              regulator-name = "vdd-cpu";
++                      };
++
++                      vdd_gpu: dcdc3 {
++                              regulator-always-on;
++                              regulator-min-microvolt = <700000>;
++                              regulator-max-microvolt = <1320000>;
++                              regulator-name = "vdd-gpu";
++                      };
++
++                      vdd_sys_dll: dcdc4 {
++                              regulator-always-on;
++                              regulator-min-microvolt = <1100000>;
++                              regulator-max-microvolt = <1100000>;
++                              regulator-name = "vdd-sys-dll";
++                      };
++
++                      vcc_dram: dcdc5 {
++                              regulator-always-on;
++                              regulator-min-microvolt = <1500000>;
++                              regulator-max-microvolt = <1500000>;
++                              regulator-name = "vcc-dram";
++                      };
++
++                      vcc_wifi: aldo1 {
++                              regulator-min-microvolt = <3300000>;
++                              regulator-max-microvolt = <3300000>;
++                              regulator-name = "vcc_wifi";
++                      };
++
++                      avcc: aldo3 {
++                              regulator-always-on;
++                              regulator-min-microvolt = <3000000>;
++                              regulator-max-microvolt = <3000000>;
++                              regulator-name = "avcc";
++                      };
++              };
++      };
++};
++
++&uart0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart0_pins_a>;
++      status = "okay";
++};
++
++&usb1_vbus_pin_a {
++      allwinner,pins = "PD23";
++};
++
++&reg_usb1_vbus {
++      gpio = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD 23 */
++      status = "okay";
++};
++
++&usbphy {
++      status = "okay";
++      usb1_vbus-supply = <&reg_usb1_vbus>;
++};
+--- /dev/null
++++ b/configs/pangolin_defconfig
+@@ -0,0 +1,36 @@
++CONFIG_SUNXI_PANGOLIN=y
++CONFIG_SPL=y
++CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC,RGMII"
++CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-pangolin"
++CONFIG_VIDEO_VGA_VIA_LCD=y
++CONFIG_VIDEO_VGA_EXTERNAL_DAC_EN="PH25"
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_MACH_SUN6I=y
++CONFIG_DRAM_CHANNELS=1
++CONFIG_DRAM_CLK=360
++CONFIG_DRAM_ZQ=70
++CONFIG_AXP_DCDC1_VOLT=3300
++CONFIG_AXP_ALDO1_VOLT=0
++CONFIG_AXP_ALDO2_VOLT=1800
++CONFIG_AXP_ALDO3_VOLT=3000
++CONFIG_AXP_DLDO4_VOLT=3300
++CONFIG_AXP_ELDO1_VOLT=1200
++CONFIG_AXP_ELDO2_VOLT=2500
++CONFIG_AXP_ELDO3_VOLT=3300
++CONFIG_MMC_SUNXI_SLOT_EXTRA=2
++CONFIG_CONS_INDEX=3
++# Vbus gpio for usb1
++CONFIG_USB1_VBUS_PIN=""
++# No Vbus gpio for usb2
++CONFIG_USB2_VBUS_PIN=""
++CONFIG_USB=y
++CONFIG_DM_USB=y
++CONFIG_USB_EHCI=y
++CONFIG_USB_KEYBOARD=y
++CONFIG_DM_ETH=y
++CONFIG_CMD_IMLS=n
++CONFIG_ETH_DESIGNWARE=y
++CONFIG_DM_SPI=y
++CONFIG_DM_SPI_FLASH=y
++CONFIG_SUNXI_SPI=y
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -896,6 +896,14 @@ config VIDEO_LCD_PANEL_I2C_SCL
+       Set the SCL pin for the LCD i2c interface. This takes a string in the
+       format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
++choice
++      prompt "Sunxi Board Variant"
++      optional
++
++config SUNXI_PANGOLIN
++      bool "Theobroma A31 uQ7 Board"
++
++endchoice
+ # Note only one of these may be selected at a time! But hidden choices are
+ # not supported by Kconfig
diff --git a/package/boot/uboot-suniv/patches/062-A20-improve-gmac-upload.patch b/package/boot/uboot-suniv/patches/062-A20-improve-gmac-upload.patch
new file mode 100644 (file)
index 0000000..b805bbd
--- /dev/null
@@ -0,0 +1,12 @@
+  GNU nano 2.7.4                                                    File: 062-A20-improve-gmac-upload.patch
+
+--- a/configs/A20-OLinuXino-Lime2_defconfig
++++ b/configs/A20-OLinuXino-Lime2_defconfig
+@@ -22,6 +22,7 @@ CONFIG_ETH_DESIGNWARE=y
+ CONFIG_RGMII=y
+ CONFIG_MII=y
+ CONFIG_SUN7I_GMAC=y
++CONFIG_GMAC_TX_DELAY=1
+ CONFIG_AXP_ALDO3_VOLT=2800
+ CONFIG_AXP_ALDO3_VOLT_SLOPE_08=y
+ CONFIG_AXP_ALDO3_INRUSH_QUIRK=y
diff --git a/package/boot/uboot-suniv/patches/063-fix-lime2-revK-add-micrel-PHY.patch b/package/boot/uboot-suniv/patches/063-fix-lime2-revK-add-micrel-PHY.patch
new file mode 100644 (file)
index 0000000..e1ed58e
--- /dev/null
@@ -0,0 +1,44 @@
+--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
++++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+@@ -8,6 +8,8 @@ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
+ CONFIG_USB0_VBUS_PIN="PC17"
+ CONFIG_USB0_VBUS_DET="PH5"
+ CONFIG_I2C1_ENABLE=y
++CONFIG_PHY_MICREL=y
++CONFIG_PHY_MICREL_KSZ90X1=y
+ CONFIG_SATAPWR="PC3"
+ CONFIG_SPL_SPI_SUNXI=y
+ CONFIG_AHCI=y
+--- a/configs/A20-OLinuXino-Lime2_defconfig
++++ b/configs/A20-OLinuXino-Lime2_defconfig
+@@ -7,6 +7,8 @@ CONFIG_MMC0_CD_PIN="PH1"
+ CONFIG_USB0_VBUS_PIN="PC17"
+ CONFIG_USB0_VBUS_DET="PH5"
+ CONFIG_I2C1_ENABLE=y
++CONFIG_PHY_MICREL=y
++CONFIG_PHY_MICREL_KSZ90X1=y
+ CONFIG_SATAPWR="PC3"
+ CONFIG_AHCI=y
+ # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+--- a/drivers/net/phy/micrel_ksz90x1.c
++++ b/drivers/net/phy/micrel_ksz90x1.c
+@@ -14,6 +14,8 @@
+ #include <errno.h>
+ #include <micrel.h>
+ #include <phy.h>
++#include <asm/io.h>
++#include <asm/arch/clock.h>
+ /*
+  * KSZ9021 - KSZ9031 common
+@@ -344,6 +346,10 @@ static int ksz9031_phy_extwrite(struct p
+ static int ksz9031_config(struct phy_device *phydev)
+ {
+       int ret;
++      struct sunxi_ccm_reg *const ccm =
++              (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
++
++      setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_DELAY(4));
+       ret = ksz9031_of_config(phydev);
+       if (ret)
diff --git a/package/boot/uboot-suniv/patches/091-sun6i-sync-PLL1-multdiv-with-Boot1.patch b/package/boot/uboot-suniv/patches/091-sun6i-sync-PLL1-multdiv-with-Boot1.patch
new file mode 100644 (file)
index 0000000..f2a2b5e
--- /dev/null
@@ -0,0 +1,32 @@
+From a58eb20fb80f478038243e9e0f30f6984725e265 Mon Sep 17 00:00:00 2001
+From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+Date: Tue, 6 Jan 2015 15:47:18 +0100
+Subject: sun6i: Sync PLL1 multipliers/dividers with Boot1
+
+This change syncs up the multipliers and dividers used to initialize
+PLL1 (i.e. the fast clock driving the ARM cores) with the values used
+in Allwinner's Boot1 on sun6i.
+
+More specifically, the following settings are now used:
+ * up to 768MHz:  mul=2, div=2 (was: mul=1, div=1)
+ * up to 1152MHz: mul=3, div=2 (unchanged)
+ * above 1152MHz: mul=4, div=2 (was: mul=2, div=1)
+
+--- a/arch/arm/mach-sunxi/clock_sun6i.c
++++ b/arch/arm/mach-sunxi/clock_sun6i.c
+@@ -112,11 +112,12 @@ void clock_set_pll1(unsigned int clk)
+       struct sunxi_ccm_reg * const ccm =
+               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+       const int p = 0;
+-      int k = 1;
+-      int m = 1;
++      int k = 2;
++      int m = 2;
+       if (clk > 1152000000) {
+-              k = 2;
++              k = 4;
++              m = 2;
+       } else if (clk > 768000000) {
+               k = 4;
+               m = 2;
diff --git a/package/boot/uboot-suniv/patches/093-sun6i-fix-PLL-LDO-voltselect.patch b/package/boot/uboot-suniv/patches/093-sun6i-fix-PLL-LDO-voltselect.patch
new file mode 100644 (file)
index 0000000..b62209e
--- /dev/null
@@ -0,0 +1,69 @@
+From b2b385df5095fff80b4655142f58a2a6801e6c80 Mon Sep 17 00:00:00 2001
+From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+Date: Tue, 6 Jan 2015 21:26:44 +0100
+Subject: sun6i: Fix and document PLL LDO voltage selection
+
+The PRCM_PLL_CTRL_LDO_OUT_L and PRCM_PLL_CTRL_LDO_OUT_H macros had
+their meaning reversed. This is fixed by this change-set. With this
+changed, the PRCM_PLL_CTRL_LDO_OUT_L(1370) now becomes self-evident
+as setting the voltage to 1.37v (which it had done all along, even
+though stating a different target voltage).
+
+After changing the PLL LDO setting, it will take a little while for
+the voltage output to settle. A sdelay()-based loop waits the same
+order of magnitude as Boot1.
+
+Furthermore, a bit of documentation is added to clarify that the
+required setting for the PLL LDO is 1.37v as per the A31 manual.
+
+--- a/arch/arm/mach-sunxi/clock_sun6i.c
++++ b/arch/arm/mach-sunxi/clock_sun6i.c
+@@ -25,13 +25,26 @@ void clock_init_safe(void)
+       struct sunxi_prcm_reg * const prcm =
+               (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+-      /* Set PLL ldo voltage without this PLL6 does not work properly */
++      /* Set PLL ldo voltage without this PLL6 does not work properly.
++       *
++       * As the A31 manual states, that "before enable PLL, PLLVDD
++       * LDO should be set to 1.37v", we need to configure this to 2.5v
++       * in the "PLL Input Power Select" (0 << 15) and (7 << 16).
++       */
+       clrsetbits_le32(&prcm->pll_ctrl1, PRCM_PLL_CTRL_LDO_KEY_MASK,
+                       PRCM_PLL_CTRL_LDO_KEY);
+       clrsetbits_le32(&prcm->pll_ctrl1, ~PRCM_PLL_CTRL_LDO_KEY_MASK,
+               PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN |
+-              PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140));
++              PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1370));
+       clrbits_le32(&prcm->pll_ctrl1, PRCM_PLL_CTRL_LDO_KEY_MASK);
++
++      /* Give the PLL LDO voltage setting some time to take hold.
++       * Notes:
++       *   1) We need to use sdelay() as the timers aren't set up yet.
++       *   2) The 100k iterations come from Boot1, which spin's for 100k
++       *      iterations through a loop.
++       */
++      sdelay(100000);
+ #endif
+ #if defined(CONFIG_MACH_SUN8I_R40) || defined(CONFIG_MACH_SUN50I)
+--- a/arch/arm/include/asm/arch-sunxi/prcm.h
++++ b/arch/arm/include/asm/arch-sunxi/prcm.h
+@@ -110,13 +110,13 @@
+ #define PRCM_PLL_CTRL_LDO_OUT_MASK \
+       __PRCM_PLL_CTRL_LDO_OUT(0x7)
+ /* When using the low voltage 20 mV steps, and high voltage 30 mV steps */
+-#define PRCM_PLL_CTRL_LDO_OUT_L(n) \
+-      __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1000) / 20) & 0x7)
+ #define PRCM_PLL_CTRL_LDO_OUT_H(n) \
++      __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1000) / 20) & 0x7)
++#define PRCM_PLL_CTRL_LDO_OUT_L(n) \
+       __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) - 1160) / 30) & 0x7)
+-#define PRCM_PLL_CTRL_LDO_OUT_LV(n) \
+-      __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 20) + 1000)
+ #define PRCM_PLL_CTRL_LDO_OUT_HV(n) \
++      __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 20) + 1000)
++#define PRCM_PLL_CTRL_LDO_OUT_LV(n) \
+       __PRCM_PLL_CTRL_VDD_LDO_OUT((((n) & 0x7) * 30) + 1160)
+ #define PRCM_PLL_CTRL_LDO_KEY (0xa7 << 24)
+ #define PRCM_PLL_CTRL_LDO_KEY_MASK (0xff << 24)
diff --git a/package/boot/uboot-suniv/patches/100-sun6i-alternate-on-UART2.patch b/package/boot/uboot-suniv/patches/100-sun6i-alternate-on-UART2.patch
new file mode 100644 (file)
index 0000000..a7afa51
--- /dev/null
@@ -0,0 +1,16 @@
+From d7311b6e7cdd1fc0e92665188e650934718cb2b1 Mon Sep 17 00:00:00 2001
+From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+Date: Tue, 16 Jun 2015 10:52:01 +0200
+Subject: sun6i: define alternate-function for UART2 on GPG
+
+
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -190,6 +190,7 @@ enum sunxi_gpio_number {
+ #define SUN6I_GPG_SDC1                2
+ #define SUN8I_GPG_SDC1                2
+ #define SUN6I_GPG_TWI3                2
++#define SUN6I_GPG_UART2         2
+ #define SUN5I_GPG_UART1               4
+ #define SUN6I_GPH_PWM         2
diff --git a/package/boot/uboot-suniv/patches/101-sun6i-support-console-on-UART2.patch b/package/boot/uboot-suniv/patches/101-sun6i-support-console-on-UART2.patch
new file mode 100644 (file)
index 0000000..823c156
--- /dev/null
@@ -0,0 +1,30 @@
+From c058dfb69136d62f88ae8b121104bdb7ce2df03f Mon Sep 17 00:00:00 2001
+From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+Date: Tue, 16 Jun 2015 10:53:11 +0200
+Subject: ARM: sun6i: Support console on UART2 (GPG6/GPG7)
+
+
+--- a/arch/arm/mach-sunxi/board.c
++++ b/arch/arm/mach-sunxi/board.c
+@@ -129,6 +129,10 @@ static int gpio_init(void)
+       sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG_UART1);
+       sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG_UART1);
+       sunxi_gpio_set_pull(SUNXI_GPG(4), SUNXI_GPIO_PULL_UP);
++#elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN6I)
++      sunxi_gpio_set_cfgpin(SUNXI_GPG(6), SUN6I_GPG_UART2);
++      sunxi_gpio_set_cfgpin(SUNXI_GPG(7), SUN6I_GPG_UART2);
++      sunxi_gpio_set_pull(SUNXI_GPG(7), SUNXI_GPIO_PULL_UP);
+ #elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN8I)
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_GPB_UART2);
+       sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
+--- a/include/configs/sunxi-common.h
++++ b/include/configs/sunxi-common.h
+@@ -244,6 +244,8 @@ extern int soft_i2c_gpio_scl;
+ #endif
+ #elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN5I)
+ #define OF_STDOUT_PATH                "/soc@01c00000/serial@01c28400:115200"
++#elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN6I)
++#define OF_STDOUT_PATH          "/soc@01c00000/serial@01c28800:115200"
+ #elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN8I)
+ #define OF_STDOUT_PATH                "/soc@01c00000/serial@01c28800:115200"
+ #elif CONFIG_CONS_INDEX == 5 && defined(CONFIG_MACH_SUN8I)
diff --git a/package/boot/uboot-suniv/patches/102-sunxi-make_CONS_INDEX-configurable.patch b/package/boot/uboot-suniv/patches/102-sunxi-make_CONS_INDEX-configurable.patch
new file mode 100644 (file)
index 0000000..b85e2af
--- /dev/null
@@ -0,0 +1,23 @@
+From 78d5fab8e345b1273ec8c22d06f1a1d27670b518 Mon Sep 17 00:00:00 2001
+From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
+Date: Tue, 16 Jun 2015 10:59:38 +0200
+Subject: ARM: sunxi: Make CONS_INDEX configurable
+
+
+--- a/arch/arm/mach-sunxi/Kconfig
++++ b/arch/arm/mach-sunxi/Kconfig
+@@ -559,6 +559,14 @@ config SYS_BOARD
+ config SYS_SOC
+       default "sunxi"
++config CONS_INDEX
++        int "UART used for console"
++        range 1 5
++        default 1
++        ---help---
++        Defines the UART port used for serial output. It starts at 1 so UART0 is 1,
++        UART1 is 2 and so on.
++
+ config UART0_PORT_F
+       bool "UART0 on MicroSD breakout board"
+       default n
diff --git a/package/boot/uboot-suniv/patches/200-mkimage-check-environment-for-dtc-binary-location.patch b/package/boot/uboot-suniv/patches/200-mkimage-check-environment-for-dtc-binary-location.patch
new file mode 100644 (file)
index 0000000..482aa1a
--- /dev/null
@@ -0,0 +1,35 @@
+From 637800493945ffed2f454756300437a4ec86e3b1 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Wed, 19 Jul 2017 22:23:15 +0200
+Subject: mkimage: check environment for dtc binary location
+
+Currently mkimage assumes the dtc binary is in the path and fails
+otherwise. This patch makes it check the DTC environment variable first
+for the dtc binary and then fall back to the default path. This makes
+it possible to call the u-boot build with make DTC=... and build a fit
+image with the dtc binary not being the the default path.
+
+Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+Cc: Simon Glass <sjg@chromium.org>
+---
+ tools/fit_image.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/tools/fit_image.c
++++ b/tools/fit_image.c
+@@ -726,9 +726,14 @@ static int fit_handle_file(struct image_
+               }
+               *cmd = '\0';
+       } else if (params->datafile) {
++              const char* dtc = getenv("DTC");
++
++              if (!dtc)
++                      dtc = MKIMAGE_DTC;
++
+               /* dtc -I dts -O dtb -p 500 -o tmpfile datafile */
+               snprintf(cmd, sizeof(cmd), "%s %s -o \"%s\" \"%s\"",
+-                       MKIMAGE_DTC, params->dtc, tmpfile, params->datafile);
++                       dtc, params->dtc, tmpfile, params->datafile);
+               debug("Trying to execute \"%s\"\n", cmd);
+       } else {
+               snprintf(cmd, sizeof(cmd), "cp \"%s\" \"%s\"",
diff --git a/package/boot/uboot-suniv/patches/210-sunxi-deactivate-binman.patch b/package/boot/uboot-suniv/patches/210-sunxi-deactivate-binman.patch
new file mode 100644 (file)
index 0000000..5efebbd
--- /dev/null
@@ -0,0 +1,37 @@
+From def280c4792262a368c8861312dc6b376181021f Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Mon, 1 Jan 2018 23:10:56 +0100
+Subject: sunxi: deactivate binman
+
+Use the old way to generate the images instead of binman.
+binman needs python with swig to avoid this host tool dependency use the
+old way of generating images.
+---
+ Makefile | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -1555,8 +1555,10 @@ endif
+ ifneq ($(CONFIG_ARCH_SUNXI),)
+ ifeq ($(CONFIG_ARM64),)
+-u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img u-boot.dtb FORCE
+-      $(call if_changed,binman)
++OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \
++                              --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff
++u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img FORCE
++      $(call if_changed,pad_cat)
+ else
+ u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.itb FORCE
+       $(call if_changed,cat)
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -962,7 +962,6 @@ config ARCH_SOCFPGA
+ config ARCH_SUNXI
+       bool "Support sunxi (Allwinner) SoCs"
+-      select BINMAN
+       select CMD_GPIO
+       select CMD_MMC if MMC
+       select CMD_USB if DISTRO_DEFAULTS
diff --git a/package/boot/uboot-suniv/patches/230-disable-axp209-on-a13-olinuxino.diff b/package/boot/uboot-suniv/patches/230-disable-axp209-on-a13-olinuxino.diff
new file mode 100644 (file)
index 0000000..b846cbf
--- /dev/null
@@ -0,0 +1,19 @@
+--- a/configs/A13-OLinuXino_defconfig
++++ b/configs/A13-OLinuXino_defconfig
+@@ -7,7 +7,6 @@ CONFIG_DRAM_EMR1=0
+ CONFIG_MMC0_CD_PIN="PG0"
+ CONFIG_USB0_VBUS_DET="PG1"
+ CONFIG_USB1_VBUS_PIN="PG11"
+-CONFIG_AXP_GPIO=y
+ # CONFIG_VIDEO_HDMI is not set
+ CONFIG_VIDEO_VGA_VIA_LCD=y
+ CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
+@@ -21,7 +20,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y
+ CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"
+ CONFIG_DFU_RAM=y
+ CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+-CONFIG_AXP_ALDO3_VOLT=3300
++CONFIG_SUNXI_NO_PMIC=y
+ CONFIG_CONS_INDEX=2
+ CONFIG_USB_EHCI_HCD=y
+ CONFIG_USB_OHCI_HCD=y
diff --git a/package/boot/uboot-suniv/patches/240-add-rgl-c64mini.patch b/package/boot/uboot-suniv/patches/240-add-rgl-c64mini.patch
new file mode 100644 (file)
index 0000000..57e1742
--- /dev/null
@@ -0,0 +1,287 @@
+diff -ruN u-boot-2020.04.old/arch/arm/dts/sun7i-a20-rgl-c64mini.dts u-boot-2020.04/arch/arm/dts/sun7i-a20-rgl-c64mini.dts
+--- u-boot-2020.04.old/arch/arm/dts/sun7i-a20-rgl-c64mini.dts  1970-01-01 01:00:00.000000000 +0100
++++ u-boot-2020.04/arch/arm/dts/sun7i-a20-rgl-c64mini.dts      2020-07-07 11:32:47.000000000 +0200
+@@ -0,0 +1,254 @@
++/*
++ * This is based on sun4i-a10-olinuxino-lime.dts
++ *
++ * Copyright 2014 - Hans de Goede <hdegoede@redhat.com>
++ * Copyright (c) 2014 FUKAUMI Naoki <naobsd@gmail.com>
++ *
++ * This file is dual-licensed: you can use it either under the terms
++ * of the GPL or the X11 license, at your option. Note that this dual
++ * licensing only applies to this file, and not this project as a
++ * whole.
++ *
++ *  a) This file 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 file 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.
++ *
++ * Or, alternatively,
++ *
++ *  b) Permission is hereby granted, free of charge, to any person
++ *     obtaining a copy of this software and associated documentation
++ *     files (the "Software"), to deal in the Software without
++ *     restriction, including without limitation the rights to use,
++ *     copy, modify, merge, publish, distribute, sublicense, and/or
++ *     sell copies of the Software, and to permit persons to whom the
++ *     Software is furnished to do so, subject to the following
++ *     conditions:
++ *
++ *     The above copyright notice and this permission notice shall be
++ *     included in all copies or substantial portions of the Software.
++ *
++ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
++ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
++ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ *     OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/dts-v1/;
++#include "sun7i-a20.dtsi"
++#include "sunxi-common-regulators.dtsi"
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++
++/ {
++      model = "Retro Games C=64 Mini";
++      compatible = "rgl,c64-mini", "allwinner,sun7i-a20";
++
++      aliases {
++              serial0 = &uart0;
++      };
++
++      chosen {
++              stdout-path = "serial0:115200n8";
++      };
++
++      hdmi-connector {
++              compatible = "hdmi-connector";
++              type = "a";
++
++              port {
++                      hdmi_con_in: endpoint {
++                              remote-endpoint = <&hdmi_out_con>;
++                      };
++              };
++      };
++
++      leds {
++              compatible = "gpio-leds";
++              pinctrl-names = "default";
++              pinctrl-0 = <&led_pins_olinuxinolime>;
++
++              green {
++                      label = "a20-olinuxino-lime:green:usr";
++                      gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
++                      default-state = "on";
++              };
++      };
++};
++
++&de {
++      status = "okay";
++};
++
++&ehci0 {
++      status = "okay";
++};
++
++&ehci1 {
++      status = "okay";
++};
++
++&hdmi {
++      status = "okay";
++};
++
++&hdmi_out {
++      hdmi_out_con: endpoint {
++              remote-endpoint = <&hdmi_con_in>;
++      };
++};
++
++&i2c0 {
++      status = "okay";
++
++      axp209: pmic@34 {
++              compatible = "x-powers,axp209";
++              reg = <0x34>;
++              interrupt-parent = <&nmi_intc>;
++              interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
++
++              interrupt-controller;
++              #interrupt-cells = <1>;
++      };
++};
++
++&i2c1 {
++      status = "okay";
++
++      eeprom: eeprom@50 {
++              compatible = "atmel,24c16";
++              reg = <0x50>;
++              pagesize = <16>;
++      };
++};
++
++&mmc0 {
++      vmmc-supply = <&reg_vcc3v3>;
++      bus-width = <4>;
++      cd-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>; /* PH1 */
++      status = "okay";
++};
++
++&ohci0 {
++      status = "okay";
++};
++
++&ohci1 {
++      status = "okay";
++};
++
++&otg_sram {
++      status = "okay";
++};
++
++&pio {
++      led_pins_olinuxinolime: led_pins@0 {
++              pins = "PH2";
++              function = "gpio_out";
++              drive-strength = <20>;
++      };
++
++      usb0_id_detect_pin: usb0_id_detect_pin@0 {
++              pins = "PH4";
++              function = "gpio_in";
++              bias-pull-up;
++      };
++
++      usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
++              pins = "PH5";
++              function = "gpio_in";
++              bias-pull-down;
++      };
++
++      nand_pins: nand-pins {
++              pins = "PC0", "PC1", "PC2", "PC5",
++                     "PC8", "PC9", "PC10", "PC11",
++                     "PC12", "PC13", "PC14", "PC15";
++              function = "nand0";
++      };
++
++      nand_pins_cs0: nand-pins-cs0 {
++              pins = "PC4";
++              function = "nand0";
++              bias-pull-up;
++      };
++
++      nand_pins_cs1: nand-pins-cs1 {
++              pins = "PC3";
++              function = "nand0";
++              bias-pull-up;
++      };
++
++      nand_pins_rb0: nand-pins-rb0 {
++              pins = "PC6";
++              function = "nand0";
++              bias-pull-up;
++      };
++
++      nand_pins_rb1: nand-pins-rb1 {
++              pins = "PC7";
++              function = "nand0";
++              bias-pull-up;
++      };
++};
++
++&reg_usb0_vbus {
++      status = "okay";
++};
++
++&reg_usb1_vbus {
++      status = "okay";
++};
++
++&reg_usb2_vbus {
++      status = "okay";
++};
++
++&uart0 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&uart0_pb_pins>;
++      status = "okay";
++};
++
++&usb_otg {
++      dr_mode = "otg";
++      status = "okay";
++};
++
++&usbphy {
++      pinctrl-names = "default";
++      pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
++      usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
++      usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
++      usb0_vbus-supply = <&reg_usb0_vbus>;
++      usb1_vbus-supply = <&reg_usb1_vbus>;
++      usb2_vbus-supply = <&reg_usb2_vbus>;
++      status = "okay";
++};
++
++&nfc {
++      status = "okay";
++      pinctrl-names = "default";
++      pinctrl-0 = <&nand_pins>, <&nand_pins_cs0>, <&nand_pins_rb0>;
++
++      /* ESMT NAND 128MiB 3,3V 8-bit */
++      nand@0 {
++              #address-cells = <1>;
++              #size-cells = <1>;
++              reg = <0>;
++              allwinner,rb = <0>;
++              nand-ecc-mode = "hw";
++              nand-ecc-strength = <16>;
++              nand-ecc-step-size = <1024>;
++      };
++};
+diff -ruN u-boot-2020.04.old/configs/rgl_c64mini_defconfig u-boot-2020.04/configs/rgl_c64mini_defconfig
+--- u-boot-2020.04.old/configs/rgl_c64mini_defconfig   1970-01-01 01:00:00.000000000 +0100
++++ u-boot-2020.04/configs/rgl_c64mini_defconfig       2020-07-07 23:52:25.574583780 +0200
+@@ -0,0 +1,14 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_SPL=y
++CONFIG_MACH_SUN7I=y
++CONFIG_DRAM_CLK=384
++CONFIG_MMC0_CD_PIN="PH1"
++CONFIG_I2C1_ENABLE=y
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_SPL_I2C_SUPPORT=y
++CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-rgl-c64mini"
++CONFIG_AXP_ALDO3_VOLT=2800
++CONFIG_AXP_ALDO4_VOLT=2800
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_OHCI_HCD=y
+diff -ruN a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
+--- a/arch/arm/dts/Makefile    2021-01-18 10:07:44.318693224 +0100
++++ b/arch/arm/dts/Makefile    2021-01-18 10:35:00.953333457 +0100
+@@ -491,6 +491,7 @@
+       sun7i-a20-pcduino3.dtb \
+       sun7i-a20-pcduino3-nano.dtb \
+       sun7i-a20-primo73.dtb \
++      sun7i-a20-rgl-c64mini.dtb \
+       sun7i-a20-wexler-tab7200.dtb \
+       sun7i-a20-wits-pro-a20-dkt.dtb \
+       sun7i-a20-yones-toptech-bd1078.dtb
diff --git a/package/boot/uboot-suniv/patches/250-add-mmc-to-chip.diff b/package/boot/uboot-suniv/patches/250-add-mmc-to-chip.diff
new file mode 100644 (file)
index 0000000..5e24fc4
--- /dev/null
@@ -0,0 +1,43 @@
+diff -ruN a/arch/arm/dts/sun5i-r8-chip.dts b/arch/arm/dts/sun5i-r8-chip.dts
+--- a/arch/arm/dts/sun5i-r8-chip.dts   2019-08-20 00:53:42.243401559 +0200
++++ b/arch/arm/dts/sun5i-r8-chip.dts   2019-08-20 00:34:38.000000000 +0200
+@@ -175,6 +175,16 @@
+       status = "okay";
+ };
++&mmc2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&chip_sdio_pin>;
++      vmmc-supply = <&reg_vcc3v3>;
++/*    mmc-pwrseq = <&mmc2_pwrseq>;*/
++      bus-width = <4>;
++      broken-cd;
++      status = "okay";
++};
++
+ &ohci0 {
+       status = "okay";
+ };
+@@ -204,6 +214,11 @@
+               function = "gpio_in";
+               bias-pull-up;
+       };
++
++      chip_sdio_pin: chip_sdio_pin@0 {
++              pins = "PE4", "PE5", "PE6", "PE7", "PE8", "PE9";
++              function = "mmc2";
++      };
+ };
+ &reg_dcdc2 {
+diff -ruN configs.old/CHIP_defconfig configs/CHIP_defconfig
+--- a/configs/CHIP_defconfig   2019-01-14 23:02:36.000000000 +0100
++++ b/configs/CHIP_defconfig   2019-08-20 01:14:47.076936367 +0200
+@@ -13,7 +13,6 @@
+ # CONFIG_SPL_EFI_PARTITION is not set
+ CONFIG_DEFAULT_DEVICE_TREE="sun5i-r8-chip"
+ CONFIG_DFU_RAM=y
+-# CONFIG_MMC is not set
+ CONFIG_AXP_ALDO3_VOLT=3300
+ CONFIG_AXP_ALDO4_VOLT=3300
+ CONFIG_CONS_INDEX=2
diff --git a/package/boot/uboot-suniv/patches/250-sun8i-h3-zeropi-add-device-tree.patch b/package/boot/uboot-suniv/patches/250-sun8i-h3-zeropi-add-device-tree.patch
new file mode 100644 (file)
index 0000000..4250e4e
--- /dev/null
@@ -0,0 +1,81 @@
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -539,7 +539,8 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \
+       sun8i-h3-orangepi-plus.dtb \
+       sun8i-h3-orangepi-plus2e.dtb \
+       sun8i-h3-orangepi-zero-plus2.dtb \
+-      sun8i-h3-rervision-dvk.dtb
++      sun8i-h3-rervision-dvk.dtb \
++      sun8i-h3-zeropi.dtb
+ dtb-$(CONFIG_MACH_SUN8I_R40) += \
+       sun8i-r40-bananapi-m2-ultra.dtb \
+       sun8i-v40-bananapi-m2-berry.dtb
+--- /dev/null
++++ b/arch/arm/dts/sun8i-h3-zeropi.dts
+@@ -0,0 +1,66 @@
++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
++
++#include "sun8i-h3-nanopi.dtsi"
++
++/ {
++      model = "FriendlyElec ZeroPi";
++      compatible = "friendlyarm,zeropi", "allwinner,sun8i-h3";
++
++      aliases {
++              ethernet0 = &emac;
++      };
++
++      reg_gmac_3v3: gmac-3v3 {
++              compatible = "regulator-fixed";
++              pinctrl-names = "default";
++              pinctrl-0 = <&gmac_power_pin_nanopi>;
++              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>;
++      };
++};
++
++&ehci0 {
++      status = "okay";
++};
++
++&ohci0 {
++      status = "okay";
++};
++
++&pio {
++      gmac_power_pin_nanopi: gmac_power_pin@0 {
++              pins = "PD6";
++              function = "gpio_out";
++      };
++};
++
++&external_mdio {
++      ext_rgmii_phy: ethernet-phy@1 {
++              compatible = "ethernet-phy-ieee802.3-c22";
++              reg = <7>;
++      };
++};
++
++&emac {
++      pinctrl-names = "default";
++      pinctrl-0 = <&emac_rgmii_pins>;
++      phy-supply = <&reg_gmac_3v3>;
++      phy-handle = <&ext_rgmii_phy>;
++      phy-mode = "rgmii";
++
++      allwinner,leds-active-low;
++      status = "okay";
++};
++
++&usb_otg {
++      status = "okay";
++      dr_mode = "peripheral";
++};
++
++&usbphy {
++      usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
++};
diff --git a/package/boot/uboot-suniv/patches/251-sun8i-h3-zeropi-add-defconfig.patch b/package/boot/uboot-suniv/patches/251-sun8i-h3-zeropi-add-defconfig.patch
new file mode 100644 (file)
index 0000000..76e3332
--- /dev/null
@@ -0,0 +1,24 @@
+--- /dev/null
++++ b/configs/zeropi_defconfig
+@@ -0,0 +1,21 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_MACH_SUN8I_H3=y
++CONFIG_DRAM_CLK=408
++CONFIG_DRAM_ZQ=3881979
++CONFIG_DRAM_ODT_EN=y
++CONFIG_MACPWR="PD6"
++# CONFIG_VIDEO_DE2 is not set
++CONFIG_NR_DRAM_BANKS=1
++CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-zeropi"
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_CONSOLE_MUX=y
++CONFIG_SPL=y
++CONFIG_SYS_CLK_FREQ=480000000
++# CONFIG_CMD_IMLS is not set
++# CONFIG_CMD_FLASH is not set
++# CONFIG_CMD_FPGA is not set
++CONFIG_SUN8I_EMAC=y
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_HCD=y
++CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/package/boot/uboot-suniv/patches/252-sunxi-h3-add-support-for-nanopi-r1.patch b/package/boot/uboot-suniv/patches/252-sunxi-h3-add-support-for-nanopi-r1.patch
new file mode 100644 (file)
index 0000000..0db7be5
--- /dev/null
@@ -0,0 +1,198 @@
+From 0e8043aff1aae95d1f7b7422b91b57d9569860d3 Mon Sep 17 00:00:00 2001
+From: Jayantajit Gogoi <jayanta.gogoi525@gmail.com>
+Date: Mon, 12 Oct 2020 18:39:53 +0000
+Subject: [PATCH] sunxi: add support for FriendlyARM NanoPi R1
+
+Signed-off-by: Jayantajit Gogoi <jayanta.gogoi525@gmail.com>
+---
+ arch/arm/dts/Makefile               |   1 +
+ arch/arm/dts/sun8i-h3-nanopi-r1.dts | 146 ++++++++++++++++++++++++++++
+ configs/nanopi_r1_defconfig         |  22 +++++
+ 3 files changed, 169 insertions(+)
+ create mode 100644 arch/arm/dts/sun8i-h3-nanopi-r1.dts
+ create mode 100644 configs/nanopi_r1_defconfig
+
+--- a/arch/arm/dts/Makefile
++++ b/arch/arm/dts/Makefile
+@@ -531,6 +531,7 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \
+       sun8i-h3-nanopi-m1-plus.dtb \
+       sun8i-h3-nanopi-neo.dtb \
+       sun8i-h3-nanopi-neo-air.dtb \
++      sun8i-h3-nanopi-r1.dtb \
+       sun8i-h3-orangepi-2.dtb \
+       sun8i-h3-orangepi-lite.dtb \
+       sun8i-h3-orangepi-one.dtb \
+--- /dev/null
++++ b/arch/arm/dts/sun8i-h3-nanopi-r1.dts
+@@ -0,0 +1,146 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (C) 2019 Igor Pecovnik <igor@armbian.com>
++ * Copyright (C) 2020 Jayantajit Gogoi <jayanta.gogoi525@gmail.com>
++ */
++
++/* NanoPi R1 is based on the NanoPi-H3 design from FriendlyARM */
++#include "sun8i-h3-nanopi.dtsi"
++
++/ {
++      model = "FriendlyARM NanoPi R1";
++      compatible = "friendlyarm,nanopi-r1", "allwinner,sun8i-h3";
++
++      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>;
++      };
++
++      vdd_cpux: gpio-regulator {
++              compatible = "regulator-gpio";
++              pinctrl-names = "default";
++              regulator-name = "vdd-cpux";
++              regulator-type = "voltage";
++              regulator-boot-on;
++              regulator-always-on;
++              regulator-min-microvolt = <1100000>;
++              regulator-max-microvolt = <1300000>;
++              regulator-ramp-delay = <50>;
++              gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>;
++              gpios-states = <0x1>;
++              states = <1100000 0x0
++                        1300000 0x1>;
++      };
++
++      wifi_pwrseq: wifi_pwrseq {
++              compatible = "mmc-pwrseq-simple";
++              pinctrl-names = "default";
++              reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;
++      };
++
++      leds {
++              /delete-node/ pwr;
++              status {
++                      label = "nanopi:red:status";
++                      gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>;
++                      linux,default-trigger = "heartbeat";
++              };
++
++              wan {
++                      label = "nanopi:green:wan";
++                      gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>;
++              };
++
++              lan {
++                      label = "nanopi:green:lan";
++                      gpios = <&pio 0 9 GPIO_ACTIVE_HIGH>;
++              };
++      };
++
++      r_gpio_keys {
++              pinctrl-names = "default";
++              pinctrl-0 = <&sw_r_npi>;
++
++              /delete-node/ k1;
++              reset {
++                      label = "reset";
++                      linux,code = <KEY_RESTART>;
++                      gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
++              };
++      };
++};
++
++&cpu0 {
++      cpu-supply = <&vdd_cpux>;
++};
++
++&ehci1 {
++      status = "okay";
++};
++
++&ehci2 {
++      status = "okay";
++};
++
++&emac {
++      pinctrl-names = "default";
++      pinctrl-0 = <&emac_rgmii_pins>;
++      phy-supply = <&reg_gmac_3v3>;
++      phy-handle = <&ext_rgmii_phy>;
++      phy-mode = "rgmii";
++      status = "okay";
++};
++
++&external_mdio {
++      ext_rgmii_phy: ethernet-phy@1 {
++              compatible = "ethernet-phy-ieee802.3-c22";
++              reg = <7>;
++      };
++};
++
++&mmc1 {
++      vmmc-supply = <&reg_vcc3v3>;
++      vqmmc-supply = <&reg_vcc3v3>;
++      mmc-pwrseq = <&wifi_pwrseq>;
++      bus-width = <4>;
++      non-removable;
++      status = "okay";
++
++      sdio_wifi: sdio_wifi@1 {
++              reg = <1>;
++              compatible = "brcm,bcm4329-fmac";
++              interrupt-parent = <&pio>;
++              interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>;
++              interrupt-names = "host-wake";
++      };
++};
++
++&mmc2 {
++      pinctrl-names = "default";
++      pinctrl-0 = <&mmc2_8bit_pins>;
++      vmmc-supply = <&reg_vcc3v3>;
++      vqmmc-supply = <&reg_vcc3v3>;
++      bus-width = <8>;
++      non-removable;
++      status = "okay";
++};
++
++&ohci1 {
++      status = "okay";
++};
++
++&ohci2 {
++      status = "okay";
++};
++
++&r_pio {
++      sw_r_npi: key_pins {
++              pins = "PL3";
++              function = "gpio_in";
++      };
++};
+--- /dev/null
++++ b/configs/nanopi_r1_defconfig
+@@ -0,0 +1,22 @@
++CONFIG_ARM=y
++CONFIG_ARCH_SUNXI=y
++CONFIG_SPL=y
++CONFIG_MACH_SUN8I_H3=y
++CONFIG_DRAM_CLK=408
++CONFIG_DRAM_ZQ=3881979
++CONFIG_DRAM_ODT_EN=y
++CONFIG_MACPWR="PD6"
++# CONFIG_VIDEO_DE2 is not set
++CONFIG_NR_DRAM_BANKS=1
++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
++CONFIG_CONSOLE_MUX=y
++CONFIG_SYS_CLK_FREQ=480000000
++# CONFIG_CMD_FLASH is not set
++# CONFIG_SPL_DOS_PARTITION is not set
++# CONFIG_SPL_EFI_PARTITION is not set
++CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-r1"
++CONFIG_SUN8I_EMAC=y
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_OHCI_HCD=y
++CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
++CONFIG_MMC_SUNXI_SLOT_EXTRA=2
diff --git a/package/boot/uboot-suniv/uEnv-default.txt b/package/boot/uboot-suniv/uEnv-default.txt
new file mode 100644 (file)
index 0000000..e024954
--- /dev/null
@@ -0,0 +1,6 @@
+setenv fdt_high ffffffff
+setenv loadkernel fatload mmc 0 \$kernel_addr_r uImage
+setenv loaddtb fatload mmc 0 \$fdt_addr_r dtb
+setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait
+setenv uenvcmd run loadkernel \&\& run loaddtb \&\& bootm \$kernel_addr_r - \$fdt_addr_r
+run uenvcmd
diff --git a/target/linux/suniv/Makefile b/target/linux/suniv/Makefile
new file mode 100644 (file)
index 0000000..2aa64f0
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2021 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+ARCH:=arm
+BOARD:=suniv
+BOARDNAME:=Allwinner F1C-series
+FEATURES:=gpio ramdisk rtc squashfs
+DEVICE_TYPE:=developerboard
+SUBTARGETS:=arm926ej-s
+
+MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
+
+KERNEL_PATCHVER:=5.10
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += \
+       kmod-button-hotplug kmod-input-gpio-keys-polled \
+       kmod-ledtrig-timer kmod-leds-gpio uboot-envtools
+
+KERNELNAME:=zImage dtbs
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/suniv/arm926ej-s/config-5.4 b/target/linux/suniv/arm926ej-s/config-5.4
new file mode 100644 (file)
index 0000000..0b36970
--- /dev/null
@@ -0,0 +1,15 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HAS_BINFMT_FLAT=y
+CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_DWMAC_SUN8I=y
+# CONFIG_MACH_SUN4I is not set
+# CONFIG_MACH_SUN5I is not set
+CONFIG_MDIO_BUS_MUX=y
+# CONFIG_PINCTRL_SUN50I_A64 is not set
+# CONFIG_PINCTRL_SUN50I_A64_R is not set
+# CONFIG_PINCTRL_SUN50I_H5 is not set
+# CONFIG_PINCTRL_SUN50I_H6 is not set
+# CONFIG_PINCTRL_SUN50I_H6_R is not set
+CONFIG_UNWINDER_ARM=y
diff --git a/target/linux/suniv/arm926ej-s/target.mk b/target/linux/suniv/arm926ej-s/target.mk
new file mode 100644 (file)
index 0000000..516fd76
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Copyright (C) 2017 Hauke Mehrtens
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+BOARDNAME:=Allwinner F1C100s
+CPU_TYPE:=arm926ej-s
diff --git a/target/linux/suniv/base-files/etc/board.d/02_network b/target/linux/suniv/base-files/etc/board.d/02_network
new file mode 100755 (executable)
index 0000000..03e138c
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+# Copyright (C) 2013-2019 OpenWrt.org
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+board=$(board_name)
+
+case "$board" in
+*)
+       ucidef_set_interface_lan 'eth0'
+       ;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/suniv/base-files/lib/upgrade/platform.sh b/target/linux/suniv/base-files/lib/upgrade/platform.sh
new file mode 100644 (file)
index 0000000..ea8672b
--- /dev/null
@@ -0,0 +1,9 @@
+REQUIRE_IMAGE_METADATA=1
+
+platform_check_image() {
+       return 0
+}
+
+platform_do_upgrade() {
+       return 0
+}
diff --git a/target/linux/suniv/config-5.10 b/target/linux/suniv/config-5.10
new file mode 100644 (file)
index 0000000..8ce34b7
--- /dev/null
@@ -0,0 +1,510 @@
+CONFIG_AHCI_SUNXI=m
+# CONFIG_AIO is not set
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_CPU_AUTO=y
+# CONFIG_ARCH_MULTI_V4 is not set
+# CONFIG_ARCH_MULTI_V4T is not set
+CONFIG_ARCH_MULTI_V4_V5=y
+CONFIG_ARCH_MULTI_V5=y
+CONFIG_ARCH_NR_GPIO=416
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM=y
+# CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM is not set
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ATA=y
+CONFIG_ATAGS=y
+# CONFIG_ATA_SFF is not set
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_AXP20X_POWER=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BINFMT_MISC=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_PM=y
+CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_BOUNCE=y
+CONFIG_CAN=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLK_SUNXI=y
+CONFIG_CLK_SUNXI_CLOCKS=y
+CONFIG_CLK_SUNXI_PRCM_SUN6I=y
+CONFIG_CLK_SUNXI_PRCM_SUN8I=y
+CONFIG_CLK_SUNXI_PRCM_SUN9I=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONNECTOR=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_COREDUMP=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_ARM926T=y
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_USE_DOMAINS=y
+CONFIG_CRASH_CORE=y
+CONFIG_CRASH_DUMP=y
+CONFIG_CRC16=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CRCT10DIF=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_DEV_SUN4I_SS=y
+CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_LIB_DES=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_REMAP=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_DWMAC_GENERIC=y
+# CONFIG_DWMAC_SUN8I is not set
+CONFIG_DWMAC_SUNXI=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_ELF_CORE=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_F2FS_FS=y
+CONFIG_FAT_FS=y
+CONFIG_FB=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_CMDLINE=y
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_LITTLE_ENDIAN=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SIMPLE=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FRAME_WARN=2048
+CONFIG_FREEZER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=y
+CONFIG_HZ=100
+CONFIG_HZ_100=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_IIO=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INPUT_AXP20X_PEK=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IPV6=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+# CONFIG_IPV6_PIMSM_V2 is not set
+# CONFIG_IPV6_SEG6_LWTUNNEL is not set
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_COMMON=y
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_UNCOMPRESSED=y
+CONFIG_KEXEC=y
+CONFIG_KEXEC_CORE=y
+CONFIG_KEYBOARD_SUN4I_LRADC=y
+CONFIG_KSM=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_MACH_SUNIV=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_SUN4I=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_AXP20X=y
+CONFIG_MFD_AXP20X_I2C=y
+CONFIG_MFD_AXP20X_RSB=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SUN6I_PRCM=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_SUNXI=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_KUSER_HELPERS=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_NETFILTER_INGRESS=y
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_NAT=m
+CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_VENDOR_ALLWINNER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_RTCACHE=m
+CONFIG_NF_CONNTRACK_ZONES=y
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_DEFRAG_IPV6=m
+CONFIG_NF_FLOW_TABLE=m
+CONFIG_NF_FLOW_TABLE_HW=m
+CONFIG_NF_LOG_COMMON=m
+CONFIG_NF_LOG_IPV4=m
+CONFIG_NF_LOG_IPV6=m
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_MASQUERADE=y
+CONFIG_NF_NAT_REDIRECT=y
+CONFIG_NF_REJECT_IPV4=m
+CONFIG_NF_REJECT_IPV6=m
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SUNXI_SID=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PHY_SUN4I_USB=y
+# CONFIG_PHY_SUN6I_MIPI_DPHY is not set
+# CONFIG_PHY_SUN9I_USB is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_AXP209=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PINCTRL_SUN4I_A10 is not set
+# CONFIG_PINCTRL_SUN50I_A64 is not set
+# CONFIG_PINCTRL_SUN50I_A64_R is not set
+# CONFIG_PINCTRL_SUN50I_H5 is not set
+# CONFIG_PINCTRL_SUN50I_H6 is not set
+# CONFIG_PINCTRL_SUN50I_H6_R is not set
+# CONFIG_PINCTRL_SUN5I is not set
+# CONFIG_PINCTRL_SUN6I_A31 is not set
+# CONFIG_PINCTRL_SUN6I_A31_R is not set
+# CONFIG_PINCTRL_SUN8I_A23 is not set
+# CONFIG_PINCTRL_SUN8I_A23_R is not set
+# CONFIG_PINCTRL_SUN8I_A33 is not set
+# CONFIG_PINCTRL_SUN8I_A83T is not set
+# CONFIG_PINCTRL_SUN8I_A83T_R is not set
+# CONFIG_PINCTRL_SUN8I_H3 is not set
+# CONFIG_PINCTRL_SUN8I_H3_R is not set
+# CONFIG_PINCTRL_SUN8I_V3S is not set
+# CONFIG_PINCTRL_SUN9I_A80 is not set
+# CONFIG_PINCTRL_SUN9I_A80_R is not set
+CONFIG_PINCTRL_SUNIV_F1C100S=y
+CONFIG_PINCTRL_SUNXI=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_OPP=y
+CONFIG_PM_SLEEP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPP=m
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPS=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPTION=y
+CONFIG_PREEMPT_COUNT=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_EVENTS=y
+CONFIG_PROC_VMCORE=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PWM=y
+CONFIG_PWM_SUN4I=y
+CONFIG_PWM_SYSFS=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_REFCOUNT_FULL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_IRQ=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_SY8106A=y
+CONFIG_RELAY=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_SIMPLE=y
+CONFIG_RESET_SUNXI=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_SATA_AHCI_PLATFORM=m
+CONFIG_SATA_PMP=y
+CONFIG_SCSI=y
+CONFIG_SDIO_UART=y
+CONFIG_SECURITYFS=y
+# CONFIG_SENSORS_DRIVETEMP is not set
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SG_POOL=y
+CONFIG_SLHC=m
+CONFIG_SND=y
+CONFIG_SND_COMPRESS_OFFLOAD=y
+CONFIG_SND_JACK=y
+CONFIG_SND_JACK_INPUT_DEV=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SUN4I_I2S is not set
+# CONFIG_SND_SUN4I_SPDIF is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_SUN4I=y
+# CONFIG_SPI_SUN6I is not set
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+CONFIG_SRCU=y
+CONFIG_STACKPROTECTOR=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+# CONFIG_STMMAC_SELFTESTS is not set
+CONFIG_SUN4I_EMAC=m
+CONFIG_SUN4I_TIMER=y
+# CONFIG_SUN8I_A83T_CCU is not set
+CONFIG_SUN8I_DE2_CCU=y
+CONFIG_SUN8I_R_CCU=y
+CONFIG_SUNIV_F1C100S_CCU=y
+CONFIG_SUNXI_CCU=y
+CONFIG_SUNXI_RSB=y
+CONFIG_SUNXI_SRAM=y
+CONFIG_SUNXI_WATCHDOG=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWCONFIG=y
+CONFIG_SWCONFIG_B53=y
+CONFIG_SWCONFIG_B53_PHY_DRIVER=y
+CONFIG_SWCONFIG_B53_PHY_FIXUP=y
+CONFIG_SWPHY=y
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_TOUCHSCREEN_SUN4I=y
+CONFIG_TREE_SRCU=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_DWC2_HOST=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_NET_DRIVERS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USERIO=y
+CONFIG_USE_OF=y
+CONFIG_VFAT_FS=y
+CONFIG_VFP=y
+CONFIG_VHOST=y
+CONFIG_VHOST_NET=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XXHASH=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
diff --git a/target/linux/suniv/image/Config.in b/target/linux/suniv/image/Config.in
new file mode 100644 (file)
index 0000000..1146d94
--- /dev/null
@@ -0,0 +1,5 @@
+config SUNXI_SD_BOOT_PARTSIZE
+       int "Boot (SD Card) filesystem partition size (in MB)"
+       depends on TARGET_suniv
+       default 20
+
diff --git a/target/linux/suniv/image/Makefile b/target/linux/suniv/image/Makefile
new file mode 100644 (file)
index 0000000..01e9742
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2013-2016 OpenWrt.org
+# Copyright (C) 2016 Yousong Zhou
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+FAT32_BLOCK_SIZE=1024
+FAT32_BLOCKS=$(shell echo $$(($(CONFIG_SUNXI_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE))))
+
+DEVICE_VARS := SUNXI_DTS SUNXI_DTS_DIR
+KERNEL_LOADADDR:=0x40008000
+
+define Build/sunxi-sdcard
+       rm -f $@.boot
+       mkfs.fat $@.boot -C $(FAT32_BLOCKS)
+
+       mcopy -i $@.boot $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-boot.scr ::boot.scr
+       mcopy -i $@.boot $(DTS_DIR)/$(SUNXI_DTS).dtb ::dtb
+       mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage
+       ./gen_sunxi_sdcard_img.sh $@ \
+               $@.boot \
+               $(IMAGE_ROOTFS) \
+               $(CONFIG_SUNXI_SD_BOOT_PARTSIZE) \
+               $(CONFIG_TARGET_ROOTFS_PARTSIZE) \
+               $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-u-boot-with-spl.bin
+       rm -f $@.boot
+endef
+
+# why \x00\x00\x00\x00 for zImage-initramfs
+define Device/Default
+  PROFILES := Default
+  KERNEL_NAME := zImage
+  KERNEL := kernel-bin | uImage none
+  IMAGES := sdcard.img.gz
+  IMAGE/sdcard.img.gz := sunxi-sdcard | append-metadata | gzip
+  SUPPORTED_DEVICES := $(subst _,$(comma),$(1))
+  SUNXI_DTS_DIR :=
+  SUNXI_DTS = $$(SUNXI_DTS_DIR)$$(SOC)-$(lastword $(subst _, ,$(1)))
+endef
+
+include $(SUBTARGET).mk
+
+$(eval $(call BuildImage))
diff --git a/target/linux/suniv/image/arm926ej-s.mk b/target/linux/suniv/image/arm926ej-s.mk
new file mode 100644 (file)
index 0000000..958447d
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2013-2021 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Device/licheepi-nano
+  DEVICE_VENDOR := LicheePi
+  DEVICE_MODEL := Nano
+  DEVICE_PACKAGES:=kmod-rtc-sunxi kmod-rtl8192cu
+  SOC := suniv-f1c100s
+endef
+TARGET_DEVICES += licheepi-nano
+
+#define Device/cubietech_a10-cubieboard
+#  DEVICE_VENDOR := Cubietech
+#  DEVICE_MODEL := Cubieboard
+#  DEVICE_PACKAGES:=kmod-ata-sunxi kmod-sun4i-emac kmod-rtc-sunxi
+#  SOC := sun4i
+#endef
+#TARGET_DEVICES += cubietech_a10-cubieboard
+
diff --git a/target/linux/suniv/image/gen_sunxi_sdcard_img.sh b/target/linux/suniv/image/gen_sunxi_sdcard_img.sh
new file mode 100755 (executable)
index 0000000..7dc2276
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+set -ex
+[ $# -eq 6 ] || {
+    echo "SYNTAX: $0 <file> <bootfs image> <rootfs image> <bootfs size> <rootfs size> <u-boot image>"
+    exit 1
+}
+
+OUTPUT="$1"
+BOOTFS="$2"
+ROOTFS="$3"
+BOOTFSSIZE="$4"
+ROOTFSSIZE="$5"
+UBOOT="$6"
+
+head=4
+sect=63
+
+set $(ptgen -o $OUTPUT -h $head -s $sect -l 1024 -t c -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M)
+
+BOOTOFFSET="$(($1 / 512))"
+BOOTSIZE="$(($2 / 512))"
+ROOTFSOFFSET="$(($3 / 512))"
+ROOTFSSIZE="$(($4 / 512))"
+
+dd bs=1024 if="$UBOOT" of="$OUTPUT" seek=8 conv=notrunc
+dd bs=512 if="$BOOTFS" of="$OUTPUT" seek="$BOOTOFFSET" conv=notrunc
+dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFSOFFSET" conv=notrunc
diff --git a/target/linux/suniv/patches-5.10/0001-series.patch b/target/linux/suniv/patches-5.10/0001-series.patch
new file mode 100644 (file)
index 0000000..3140564
--- /dev/null
@@ -0,0 +1,57 @@
+Allwinner ARMv5 F1C100s has similar sram controller to sun4i A10
+Add compatible strings for it.
+
+Signed-off-by: Mesih Kilinc <mesihkilinc@gmail.com>
+Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
+---
+ drivers/soc/sunxi/sunxi_sram.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
+index b4b0f34..27f0607 100644
+--- a/drivers/soc/sunxi/sunxi_sram.c
++++ b/drivers/soc/sunxi/sunxi_sram.c
+@@ -99,6 +99,10 @@ static const struct of_device_id sunxi_sram_dt_ids[] = {
+               .compatible     = "allwinner,sun50i-a64-sram-c",
+               .data           = &sun50i_a64_sram_c.data,
+       },
++      {
++              .compatible     = "allwinner,suniv-f1c100s-sram-d",
++              .data           = &sun4i_a10_sram_d.data,
++      },
+       {}
+ };
+@@ -389,6 +393,10 @@ static const struct of_device_id sunxi_sram_dt_match[] = {
+               .compatible = "allwinner,sun50i-a64-system-control",
+               .data = &sun50i_a64_sramc_variant,
+       },
++      {
++              .compatible = "allwinner,suniv-f1c100s-system-control",
++              .data = &sun4i_a10_sramc_variant,
++      },
+       { },
+ };
+ MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
+
+Allwinner ARMv5 F1C100s has similar watchdog timer to sun6i A31.
+Add compatible string for it.
+
+Signed-off-by: Mesih Kilinc <mesihkilinc@gmail.com>
+---
+ drivers/watchdog/sunxi_wdt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
+index c6c7365..bc70742 100644
+--- a/drivers/watchdog/sunxi_wdt.c
++++ b/drivers/watchdog/sunxi_wdt.c
+@@ -227,6 +227,7 @@ static const struct sunxi_wdt_reg sun6i_wdt_reg = {
+ static const struct of_device_id sunxi_wdt_dt_ids[] = {
+       { .compatible = "allwinner,sun4i-a10-wdt", .data = &sun4i_wdt_reg },
+       { .compatible = "allwinner,sun6i-a31-wdt", .data = &sun6i_wdt_reg },
++      { .compatible = "allwinner,suniv-f1c100s-wdt", .data = &sun6i_wdt_reg },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids);
+