uboot-sunxi: add spi flash support
authorHauke Mehrtens <hauke@hauke-m.de>
Sat, 13 Jan 2018 20:02:35 +0000 (21:02 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 22 Sep 2018 19:30:01 +0000 (21:30 +0200)
This adds SPI flash support for the sunxi SoCs to U-boot.
This code is taken from here:
https://github.com/StephanvanSchaik/u-boot/tree/sunxi-spi

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
12 files changed:
package/boot/uboot-sunxi/patches/400-spl-sunxi-remove-dependency-on-CONFIG_SPL_SPI_FLASH_.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/401-sunxi-add-missing-AHB_GATE_OFFSET_SPIx-defines-for-s.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/402-sunxi-add-SPI-register-definitions-for-sun4i-sun7i.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/403-sunxi-add-SPI-register-definitions-for-sun6i-sun8i-s.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/404-sunxi-add-SPI-driver-for-Allwinner-devices-sunxi.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/405-introduce-and-use-sunxi_gpio_parse_pin_name.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/406-introduce-and-use-sunxi_gpio_setup_dt_pins.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/407-sunxi-spi-set-up-GPIO-pins-using-pinctrl.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/408-sunxi-dts-enable-SPI0-controller-for-A20-OLinuXino-L.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/409-sunxi-dts-enable-SPI0-controller-for-Orange-Pi-Zero.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/410-sunxi-dts-enable-SPI0-controller-for-Pine64.patch [new file with mode: 0644]
package/boot/uboot-sunxi/patches/414-sunxi-set-bootcmd-when-spi-boot-is-activated.patch [new file with mode: 0644]

diff --git a/package/boot/uboot-sunxi/patches/400-spl-sunxi-remove-dependency-on-CONFIG_SPL_SPI_FLASH_.patch b/package/boot/uboot-sunxi/patches/400-spl-sunxi-remove-dependency-on-CONFIG_SPL_SPI_FLASH_.patch
new file mode 100644 (file)
index 0000000..33d38d7
--- /dev/null
@@ -0,0 +1,12 @@
+--- a/drivers/mtd/spi/Makefile
++++ b/drivers/mtd/spi/Makefile
+@@ -12,7 +12,9 @@ obj-$(CONFIG_SPL_SPI_BOOT)   += fsl_espi_s
+ obj-$(CONFIG_SPL_SPI_SUNXI)   += sunxi_spi_spl.o
+ endif
++ifndef CONFIG_SPL_SPI_SUNXI
+ obj-$(CONFIG_SPI_FLASH) += sf_probe.o spi_flash.o spi_flash_ids.o sf.o
+ obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
+ obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
+ obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
++endif
diff --git a/package/boot/uboot-sunxi/patches/401-sunxi-add-missing-AHB_GATE_OFFSET_SPIx-defines-for-s.patch b/package/boot/uboot-sunxi/patches/401-sunxi-add-missing-AHB_GATE_OFFSET_SPIx-defines-for-s.patch
new file mode 100644 (file)
index 0000000..1b5103a
--- /dev/null
@@ -0,0 +1,38 @@
+From bc7fe28b76b7e99a0bfc23bdb7dbcecc82069fa9 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: 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(+)
+
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+@@ -290,6 +290,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
+--- a/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
++++ b/arch/arm/include/asm/arch-sunxi/clock_sun9i.h
+@@ -195,6 +195,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
diff --git a/package/boot/uboot-sunxi/patches/402-sunxi-add-SPI-register-definitions-for-sun4i-sun7i.patch b/package/boot/uboot-sunxi/patches/402-sunxi-add-SPI-register-definitions-for-sun4i-sun7i.patch
new file mode 100644 (file)
index 0000000..52cbb4c
--- /dev/null
@@ -0,0 +1,104 @@
+From 14b309992da44fab80fe4552b8f5bdef630f6f1f 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: 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
+
+--- /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 */
+--- /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 */
diff --git a/package/boot/uboot-sunxi/patches/403-sunxi-add-SPI-register-definitions-for-sun6i-sun8i-s.patch b/package/boot/uboot-sunxi/patches/403-sunxi-add-SPI-register-definitions-for-sun6i-sun8i-s.patch
new file mode 100644 (file)
index 0000000..56f2b97
--- /dev/null
@@ -0,0 +1,73 @@
+From 2be081c6d037107dd8bc2e824ae61d4429aa64a1 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: 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
+
+--- /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 */
diff --git a/package/boot/uboot-sunxi/patches/404-sunxi-add-SPI-driver-for-Allwinner-devices-sunxi.patch b/package/boot/uboot-sunxi/patches/404-sunxi-add-SPI-driver-for-Allwinner-devices-sunxi.patch
new file mode 100644 (file)
index 0000000..53cfd9f
--- /dev/null
@@ -0,0 +1,397 @@
+From 34e5d3bc4e50233cdd445ef371f06d33ce71e4b0 Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@synkhronix.com>
+Date: Fri, 10 Feb 2017 12:32:49 +0000
+Subject: sunxi: add SPI driver for Allwinner devices (sunxi)
+
+Implements a driver model SPI driver for Allwinner devices (sunxi).
+
+Signed-off-by: S.J.R. van Schaik <stephan@whiteboxsystems.nl>
+---
+ drivers/spi/Kconfig     |   5 +
+ drivers/spi/Makefile    |   1 +
+ drivers/spi/sunxi_spi.c | 355 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 361 insertions(+)
+ create mode 100644 drivers/spi/sunxi_spi.c
+
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -148,6 +148,11 @@ config STM32_QSPI
+         used to access the SPI NOR flash chips on platforms embedding
+         this ST IP core.
++config SUNXI_SPI
++      bool "Allwinner SPI driver"
++      help
++        Enable the Allwinner SPI driver.
++
+ config TEGRA114_SPI
+       bool "nVidia Tegra114 SPI driver"
+       help
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -44,6 +44,7 @@ obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi
+ obj-$(CONFIG_SH_SPI) += sh_spi.o
+ obj-$(CONFIG_SH_QSPI) += sh_qspi.o
+ obj-$(CONFIG_STM32_QSPI) += stm32_qspi.o
++obj-$(CONFIG_SUNXI_SPI) += sunxi_spi.o
+ obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o
+ obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o
+ obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o
+--- /dev/null
++++ b/drivers/spi/sunxi_spi.c
+@@ -0,0 +1,355 @@
++/*
++ * (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+
++ */
++
++#include <common.h>
++#include <dm.h>
++#include <errno.h>
++#include <spi.h>
++
++#include <asm/bitops.h>
++#include <asm/gpio.h>
++#include <asm/io.h>
++
++#include <asm/arch/clock.h>
++#include <asm/arch/spi.h>
++
++#define SUNXI_SPI_MAX_RATE (24 * 1000 * 1000)
++#define SUNXI_SPI_MIN_RATE (3 * 1000)
++
++struct sunxi_spi_platdata {
++      struct sunxi_spi_regs *regs;
++      unsigned int activate_delay_us;
++      unsigned int deactivate_delay_us;
++      uint32_t freq;
++};
++
++struct sunxi_spi_priv {
++      struct sunxi_spi_regs *regs;
++      unsigned int max_freq;
++      unsigned int last_transaction_us;
++};
++
++DECLARE_GLOBAL_DATA_PTR;
++
++static void sunxi_spi_setup_pinmux(unsigned int pin_func)
++{
++      unsigned int pin;
++
++      for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(2); pin++)
++              sunxi_gpio_set_cfgpin(pin, pin_func);
++
++      if (IS_ENABLED(CONFIG_MACH_SUN4I) || IS_ENABLED(CONFIG_MACH_SUN7I)) {
++              sunxi_gpio_set_cfgpin(SUNXI_GPC(23), pin_func);
++      } else {
++              sunxi_gpio_set_cfgpin(SUNXI_GPC(3), pin_func);
++      }
++}
++
++static void sunxi_spi_enable_clock(struct udevice *bus)
++{
++      struct sunxi_ccm_reg * const ccm =
++              (struct sunxi_ccm_reg * const)SUNXI_CCM_BASE;
++
++#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
++      defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I)
++      setbits_le32(&ccm->ahb_reset0_cfg,
++              (1 << AHB_GATE_OFFSET_SPI0));
++#endif
++
++      setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0));
++      writel((1 << 31), &ccm->spi0_clk_cfg);
++}
++
++static void sunxi_spi_disable_clock(void)
++{
++      struct sunxi_ccm_reg * const ccm =
++              (struct sunxi_ccm_reg * const)SUNXI_CCM_BASE;
++
++      writel(0, &ccm->spi0_clk_cfg);
++      clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_SPI0));
++
++#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
++      defined(CONFIG_MACH_SUN9I) || defined(CONFIG_MACH_SUN50I)
++      clrbits_le32(&ccm->ahb_reset0_cfg,
++              (1 << AHB_GATE_OFFSET_SPI0));
++#endif
++}
++
++static void sunxi_spi_cs_activate(struct udevice *dev, unsigned int cs)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++      uint32_t reg;
++
++      /* If it is too soon to perform another transaction, wait. */
++      if (plat->deactivate_delay_us && priv->last_transaction_us) {
++              unsigned int 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);
++      }
++
++      debug("%s: activate cs: %u, bus: '%s'\n", __func__, cs, bus->name);
++
++      reg = readl(&priv->regs->xfer_ctl);
++      reg &= ~(SUNXI_SPI_CTL_CS_MASK | SUNXI_SPI_CTL_CS_LEVEL);
++      reg |= SUNXI_SPI_CTL_CS(cs);
++      writel(reg, &priv->regs->xfer_ctl);
++
++      if (plat->activate_delay_us)
++              udelay(plat->activate_delay_us);
++}
++
++static void sunxi_spi_cs_deactivate(struct udevice *dev, unsigned int cs)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++      uint32_t reg;
++
++      debug("%s: deactivate cs: %u, bus: '%s'\n", __func__, cs, bus->name);
++      
++      reg = readl(&priv->regs->xfer_ctl);
++      reg &= ~SUNXI_SPI_CTL_CS_MASK;
++      reg |= SUNXI_SPI_CTL_CS_LEVEL;
++      writel(reg, &priv->regs->xfer_ctl);
++
++      /* 
++       * Remember the time of this transaction so that we can honour the bus
++       * delay.
++       */
++      if (plat->deactivate_delay_us)
++              priv->last_transaction_us = timer_get_us();
++}
++
++static int sunxi_spi_ofdata_to_platdata(struct udevice *bus)
++{
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      const void *blob = gd->fdt_blob;
++      int node = dev_of_offset(bus);
++
++      plat->regs = (struct sunxi_spi_regs *)devfdt_get_addr(bus);
++      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);
++
++      debug("%s: regs=%p, activate-delay=%u, deactivate-delay=%u\n",
++              __func__, plat->regs, plat->activate_delay_us,
++              plat->deactivate_delay_us);
++
++      return 0;
++}
++
++static int sunxi_spi_probe(struct udevice *bus)
++{
++      struct sunxi_spi_platdata *plat = dev_get_platdata(bus);
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++
++      debug("%s: probe\n", __func__);
++
++      priv->regs = plat->regs;
++      priv->last_transaction_us = timer_get_us();
++
++      return 0;
++}
++
++static int sunxi_spi_claim_bus(struct udevice *dev)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++      unsigned int pin_func = SUNXI_GPC_SPI0;
++
++      debug("%s: claiming bus\n", __func__);
++
++      if (IS_ENABLED(CONFIG_MACH_SUN50I))
++              pin_func = SUN50I_GPC_SPI0;
++
++      sunxi_spi_setup_pinmux(pin_func);
++      sunxi_spi_enable_clock(bus);
++      setbits_le32(&priv->regs->glb_ctl, SUNXI_SPI_CTL_MASTER |
++              SUNXI_SPI_CTL_ENABLE | SUNXI_SPI_CTL_TP | SUNXI_SPI_CTL_SRST);
++
++      if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
++              while (readl(&priv->regs->glb_ctl) & SUNXI_SPI_CTL_SRST)
++                      ;
++
++      setbits_le32(&priv->regs->xfer_ctl, SUNXI_SPI_CTL_CS_MANUAL |
++              SUNXI_SPI_CTL_CS_LEVEL);
++      setbits_le32(&priv->regs->fifo_ctl, SUNXI_SPI_CTL_RF_RST |
++              SUNXI_SPI_CTL_TF_RST);
++
++      return 0;
++}
++
++static int sunxi_spi_release_bus(struct udevice *dev)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++
++      debug("%s: releasing bus\n", __func__);
++
++      clrbits_le32(&priv->regs->glb_ctl, SUNXI_SPI_CTL_MASTER |
++              SUNXI_SPI_CTL_ENABLE);
++      sunxi_spi_disable_clock();
++
++      return 0;
++}
++
++static void sunxi_spi_write(struct udevice *dev, const char *tx_buf,
++      size_t nbytes)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++      size_t i;
++      char byte;
++
++      if (!tx_buf)
++              nbytes = 0;
++
++      writel(SUNXI_SPI_XMIT_CNT(nbytes), &priv->regs->xmit_cnt);
++
++      if (IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I))
++              writel(SUNXI_SPI_BURST_CNT(nbytes), &priv->regs->burst_ctl);
++
++      for (i = 0; i < nbytes; ++i) {
++              byte = tx_buf ? *tx_buf++ : 0;
++              writeb(byte, &priv->regs->tx_data);
++      }
++}
++
++static int sunxi_spi_xfer(struct udevice *dev, unsigned int bitlen,
++      const void *dout, void *din, unsigned long flags)
++{
++      struct udevice *bus = dev->parent;
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++      struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
++      const char *tx_buf = dout;
++      char *rx_buf = din;
++      size_t len = bitlen / 8;
++      size_t i, nbytes;
++      char byte;
++
++      if (bitlen % 8) {
++              debug("%s: non byte-aligned SPI transfer.\n", __func__);
++              return -1;
++      }
++
++      if (flags & SPI_XFER_BEGIN)
++              sunxi_spi_cs_activate(dev, slave_plat->cs);
++
++      while (len) {
++              nbytes = min(len, (size_t)64 - 1);
++
++              writel(SUNXI_SPI_BURST_CNT(nbytes), &priv->regs->burst_cnt);
++              sunxi_spi_write(dev, tx_buf, nbytes);
++              setbits_le32(&priv->regs->xfer_ctl, SUNXI_SPI_CTL_XCH);
++
++              while (((readl(&priv->regs->fifo_sta) &
++                      SUNXI_SPI_FIFO_RF_CNT_MASK) >>
++                      SUNXI_SPI_FIFO_RF_CNT_BITS) < nbytes)
++                      ;
++
++              for (i = 0; i < nbytes; ++i) {
++                      byte = readb(&priv->regs->rx_data);
++
++                      if (rx_buf)
++                              *rx_buf++ = byte;
++              }
++
++              len -= nbytes;
++      }
++
++      if (flags & SPI_XFER_END)
++              sunxi_spi_cs_deactivate(dev, slave_plat->cs);
++
++      return 0;
++}
++
++static int sunxi_spi_set_speed(struct udevice *bus, uint speed)
++{
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++      unsigned int div;
++      uint32_t reg;
++
++      speed = min(speed, (unsigned int)SUNXI_SPI_MAX_RATE);
++      speed = max((unsigned int)SUNXI_SPI_MIN_RATE, speed);
++
++      div = SUNXI_SPI_MAX_RATE / (2 * speed);
++
++      if (div <= (SUNXI_SPI_CLK_CTL_CDR2_MASK + 1)) {
++              if (div > 0)
++                      div--;
++
++              reg = SUNXI_SPI_CLK_CTL_CDR2(div) | SUNXI_SPI_CLK_CTL_DRS;
++      } else {
++              div = __ilog2(SUNXI_SPI_MAX_RATE) - __ilog2(speed);
++              reg = SUNXI_SPI_CLK_CTL_CDR1(div);
++      }
++
++      writel(reg, &priv->regs->clk_ctl);
++
++      debug("%s: speed=%u\n", __func__, speed);
++
++      return 0;
++}
++
++static int sunxi_spi_set_mode(struct udevice *bus, uint mode)
++{
++      struct sunxi_spi_priv *priv = dev_get_priv(bus);
++      uint32_t reg;
++
++      reg = readl(&priv->regs->xfer_ctl);
++      reg &= ~(SUNXI_SPI_CTL_CPOL | SUNXI_SPI_CTL_CPHA |
++              SUNXI_SPI_CTL_CS_ACTIVE_LOW);
++
++      if (mode & SPI_CPOL)
++              reg |= SUNXI_SPI_CTL_CPOL;
++
++      if (mode & SPI_CPHA)
++              reg |= SUNXI_SPI_CTL_CPHA;
++
++      if (!(mode & SPI_CS_HIGH))
++              reg |= SUNXI_SPI_CTL_CS_ACTIVE_LOW;
++
++      writel(reg, &priv->regs->xfer_ctl);
++
++      debug("%s: mode=%d\n", __func__, 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,
++};
++
++static const struct udevice_id sunxi_spi_ids[] = {
++      { .compatible = "allwinner,sun4i-a10-spi" },
++      { .compatible = "allwinner,sun6i-a31-spi" },
++      { .compatible = "allwinner,sun8i-h3-spi" },
++      { .compatible = "allwinner,sun50i-a64-spi" },
++      { }
++};
++
++U_BOOT_DRIVER(sunxi_spi) = {
++      .name   = "sunxi_spi",
++      .id     = UCLASS_SPI,
++      .of_match = sunxi_spi_ids,
++      .ops    = &sunxi_spi_ops,
++      .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_priv),
++      .probe  = sunxi_spi_probe,
++};
diff --git a/package/boot/uboot-sunxi/patches/405-introduce-and-use-sunxi_gpio_parse_pin_name.patch b/package/boot/uboot-sunxi/patches/405-introduce-and-use-sunxi_gpio_parse_pin_name.patch
new file mode 100644 (file)
index 0000000..2d17938
--- /dev/null
@@ -0,0 +1,59 @@
+From 051559e7cb1ad072277dfeafcebf91632582da1a Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Sun, 12 Feb 2017 14:53:15 +0000
+Subject: introduce and use sunxi_gpio_parse_pin_name()
+
+---
+ arch/arm/include/asm/arch-sunxi/gpio.h |  2 ++
+ arch/arm/mach-sunxi/pinmux.c           | 16 ++++++++++++++++
+ drivers/net/sun8i_emac.c               |  7 ++-----
+ 3 files changed, 20 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -241,4 +241,6 @@ int axp_gpio_init(void);
+ static inline int axp_gpio_init(void) { return 0; }
+ #endif
++int sunxi_gpio_parse_pin_name(const char *pin_name);
++
+ #endif /* _SUNXI_GPIO_H */
+--- a/arch/arm/mach-sunxi/pinmux.c
++++ b/arch/arm/mach-sunxi/pinmux.c
+@@ -69,3 +69,19 @@ int sunxi_gpio_set_pull(u32 pin, u32 val
+       return 0;
+ }
++
++int sunxi_gpio_parse_pin_name(const char *pin_name)
++{
++      int pin;
++
++      if (pin_name[0] != 'P')
++              return -1;
++
++      if (pin_name[1] < 'A' || pin_name[1] > 'Z')
++              return -1;
++
++      pin = (pin_name[1] - 'A') << 5;
++      pin += simple_strtol(&pin_name[2], NULL, 10);
++
++      return pin;
++}
+--- a/drivers/net/sun8i_emac.c
++++ b/drivers/net/sun8i_emac.c
+@@ -475,12 +475,9 @@ static int parse_phy_pins(struct udevice
+                                             "allwinner,pins", i, NULL);
+               if (!pin_name)
+                       break;
+-              if (pin_name[0] != 'P')
++              pin = sunxi_gpio_parse_pin_name(pin_name);
++              if (pin < 0)
+                       continue;
+-              pin = (pin_name[1] - 'A') << 5;
+-              if (pin >= 26 << 5)
+-                      continue;
+-              pin += simple_strtol(&pin_name[2], NULL, 10);
+               sunxi_gpio_set_cfgpin(pin, SUN8I_GPD8_GMAC);
+               sunxi_gpio_set_drv(pin, drive);
diff --git a/package/boot/uboot-sunxi/patches/406-introduce-and-use-sunxi_gpio_setup_dt_pins.patch b/package/boot/uboot-sunxi/patches/406-introduce-and-use-sunxi_gpio_setup_dt_pins.patch
new file mode 100644 (file)
index 0000000..1d24787
--- /dev/null
@@ -0,0 +1,94 @@
+From fa5767ca356bcdfdb1bfa055851579a858a5ed25 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Sun, 12 Feb 2017 14:53:16 +0000
+Subject: introduce and use sunxi_gpio_setup_dt_pins()
+
+---
+ arch/arm/include/asm/arch-sunxi/gpio.h |  2 ++
+ arch/arm/mach-sunxi/pinmux.c           | 61 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+)
+
+--- a/arch/arm/include/asm/arch-sunxi/gpio.h
++++ b/arch/arm/include/asm/arch-sunxi/gpio.h
+@@ -242,5 +242,7 @@ static inline int axp_gpio_init(void) {
+ #endif
+ int sunxi_gpio_parse_pin_name(const char *pin_name);
++int sunxi_gpio_setup_dt_pins(const void * volatile fdt_blob, int node,
++                           const char * mux_name, int mux_sel);
+ #endif /* _SUNXI_GPIO_H */
+--- a/arch/arm/mach-sunxi/pinmux.c
++++ b/arch/arm/mach-sunxi/pinmux.c
+@@ -9,6 +9,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)
+ {
+@@ -85,3 +88,61 @@ int sunxi_gpio_parse_pin_name(const char
+       return pin;
+ }
++
++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_gpio_parse_pin_name(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;
++}
diff --git a/package/boot/uboot-sunxi/patches/407-sunxi-spi-set-up-GPIO-pins-using-pinctrl.patch b/package/boot/uboot-sunxi/patches/407-sunxi-spi-set-up-GPIO-pins-using-pinctrl.patch
new file mode 100644 (file)
index 0000000..dad8574
--- /dev/null
@@ -0,0 +1,60 @@
+From 0c87fe5938e5c7c089b84962a7c7ee3505910ffc Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@whiteboxsystems.nl>
+Date: Thu, 23 Feb 2017 12:11:42 +0000
+Subject: sunxi: spi: set up GPIO pins using pinctrl
+
+---
+ drivers/spi/sunxi_spi.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+--- a/drivers/spi/sunxi_spi.c
++++ b/drivers/spi/sunxi_spi.c
+@@ -36,18 +36,28 @@ struct sunxi_spi_priv {
+ DECLARE_GLOBAL_DATA_PTR;
+-static void sunxi_spi_setup_pinmux(unsigned int pin_func)
++static int sunxi_spi_parse_pins(struct udevice *bus)
+ {
+-      unsigned int pin;
++      unsigned int pin_func = SUNXI_GPC_SPI0;
++      int ret;
++
++      if (IS_ENABLED(CONFIG_MACH_SUN50I))
++              pin_func = SUN50I_GPC_SPI0;
++
++      ret = sunxi_gpio_setup_dt_pins(gd->fdt_blob, dev_of_offset(bus), NULL,
++              pin_func);
+-      for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(2); pin++)
+-              sunxi_gpio_set_cfgpin(pin, pin_func);
++      if (ret < 0) {
++              printf("WARNING: sunxi-spi: cannot find pinctrl-0 node\n");
++              return ret;
++      }
+-      if (IS_ENABLED(CONFIG_MACH_SUN4I) || IS_ENABLED(CONFIG_MACH_SUN7I)) {
+-              sunxi_gpio_set_cfgpin(SUNXI_GPC(23), pin_func);
+-      } else {
+-              sunxi_gpio_set_cfgpin(SUNXI_GPC(3), pin_func);
++      if (!ret) {
++              printf("WARNING: sunxi-spi: cannot find pins property\n");
++              return -2;
+       }
++
++      return ret;
+ }
+ static void sunxi_spi_enable_clock(struct udevice *bus)
+@@ -170,10 +180,7 @@ static int sunxi_spi_claim_bus(struct ud
+       debug("%s: claiming bus\n", __func__);
+-      if (IS_ENABLED(CONFIG_MACH_SUN50I))
+-              pin_func = SUN50I_GPC_SPI0;
+-
+-      sunxi_spi_setup_pinmux(pin_func);
++      sunxi_spi_parse_pins(bus);
+       sunxi_spi_enable_clock(bus);
+       setbits_le32(&priv->regs->glb_ctl, SUNXI_SPI_CTL_MASTER |
+               SUNXI_SPI_CTL_ENABLE | SUNXI_SPI_CTL_TP | SUNXI_SPI_CTL_SRST);
diff --git a/package/boot/uboot-sunxi/patches/408-sunxi-dts-enable-SPI0-controller-for-A20-OLinuXino-L.patch b/package/boot/uboot-sunxi/patches/408-sunxi-dts-enable-SPI0-controller-for-A20-OLinuXino-L.patch
new file mode 100644 (file)
index 0000000..a375b06
--- /dev/null
@@ -0,0 +1,39 @@
+From 835dd2f28d3f5c88d226622fef283e6ca48f8818 Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@synkhronix.com>
+Date: Thu, 9 Feb 2017 21:42:16 +0000
+Subject: sunxi: dts: enable SPI0 controller for A20 OLinuXino LIME 2
+
+---
+ arch/arm/dts/sun7i-a20-olinuxino-lime2.dts | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/arm/dts/sun7i-a20-olinuxino-lime2.dts
++++ b/arch/arm/dts/sun7i-a20-olinuxino-lime2.dts
+@@ -54,6 +54,7 @@
+       aliases {
+               serial0 = &uart0;
++              spi0 = &spi0;
+       };
+       chosen {
+@@ -81,6 +82,19 @@
+       };
+ };
++&pio {
++      spi0_pins: pinctrl {
++              pins = "PC0", "PC1", "PC2", "PC23";
++              drive-strength = <10>;
++              bias-disable;
++      };
++};
++
++&spi0 {
++      pinctrl-0 = <&spi0_pins>;
++      status = "okay";
++};
++
+ &ahci {
+       target-supply = <&reg_ahci_5v>;
+       status = "okay";
diff --git a/package/boot/uboot-sunxi/patches/409-sunxi-dts-enable-SPI0-controller-for-Orange-Pi-Zero.patch b/package/boot/uboot-sunxi/patches/409-sunxi-dts-enable-SPI0-controller-for-Orange-Pi-Zero.patch
new file mode 100644 (file)
index 0000000..ebe9e93
--- /dev/null
@@ -0,0 +1,57 @@
+From eb2fee739650a8fe5534d6b38d84713817f83c6d Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@whiteboxsystems.nl>
+Date: Thu, 23 Feb 2017 11:49:43 +0000
+Subject: sunxi: dts: enable SPI0 controller for Orange Pi Zero
+
+---
+ arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts | 14 ++++++++++++++
+ arch/arm/dts/sun8i-h3.dtsi                   |  8 ++++++++
+ 2 files changed, 22 insertions(+)
+
+--- a/arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts
++++ b/arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts
+@@ -59,6 +59,7 @@
+               serial0 = &uart0;
+               /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
+               ethernet1 = &xr819;
++              spi0 = &spi0;
+       };
+       chosen {
+@@ -95,6 +96,19 @@
+       };
+ };
++&pio {
++      spi0_pins: pinctrl {
++              pins = "PC0", "PC1", "PC2", "PC3";
++              drive-strength = <10>;
++              bias-disable;
++      };
++};
++
++&spi0 {
++      pinctrl-0 = <&spi0_pins>;
++      status = "okay";
++};
++
+ &ehci1 {
+       status = "okay";
+ };
+--- a/arch/arm/dts/sun8i-h3.dtsi
++++ b/arch/arm/dts/sun8i-h3.dtsi
+@@ -158,6 +158,14 @@
+                       #dma-cells = <1>;
+               };
++              spi0: spi@01c68000 {
++                      compatible = "allwinner,sun8i-h3-spi";
++                      reg = <0x01c68000 0x1000>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
++
+               mmc0: mmc@01c0f000 {
+                       compatible = "allwinner,sun7i-a20-mmc",
+                                    "allwinner,sun5i-a13-mmc";
diff --git a/package/boot/uboot-sunxi/patches/410-sunxi-dts-enable-SPI0-controller-for-Pine64.patch b/package/boot/uboot-sunxi/patches/410-sunxi-dts-enable-SPI0-controller-for-Pine64.patch
new file mode 100644 (file)
index 0000000..bd10bde
--- /dev/null
@@ -0,0 +1,56 @@
+From 04bfe04a88b8c491e6567d9f779b4d62932b13ad Mon Sep 17 00:00:00 2001
+From: "S.J.R. van Schaik" <stephan@whiteboxsystems.nl>
+Date: Thu, 23 Feb 2017 11:50:04 +0000
+Subject: sunxi: dts: enable SPI0 controller for Pine64+
+
+---
+ arch/arm/dts/sun50i-a64-orangepi-win.dts | 14 ++++++++++++++
+ arch/arm/dts/sun50i-a64.dtsi             |  8 ++++++++
+ 2 files changed, 22 insertions(+)
+
+--- a/arch/arm/dts/sun50i-a64-orangepi-win.dts
++++ b/arch/arm/dts/sun50i-a64-orangepi-win.dts
+@@ -52,6 +52,7 @@
+       aliases {
+               serial0 = &uart0;
++              spi0 = &spi0;
+       };
+       chosen {
+@@ -70,6 +71,19 @@
+        status = "okay";
+ };
++&pio {
++      spi0_pins: pinctrl {
++              pins = "PC0", "PC1", "PC2", "PC3";
++              drive-strength = <10>;
++              bias-disabled;
++      };
++};
++
++&spi0 {
++      pinctrl-0 = <&spi0_pins>;
++      status = "okay";
++};
++
+ &mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins>;
+--- a/arch/arm/dts/sun50i-a64.dtsi
++++ b/arch/arm/dts/sun50i-a64.dtsi
+@@ -445,5 +445,13 @@
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+               };
++
++              spi0: spi@01c68000 {
++                      compatible = "allwinner,sun50i-a64-spi";
++                      reg = <0x01c68000 0x1000>;
++                      status = "disabled";
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++              };
+       };
+ };
diff --git a/package/boot/uboot-sunxi/patches/414-sunxi-set-bootcmd-when-spi-boot-is-activated.patch b/package/boot/uboot-sunxi/patches/414-sunxi-set-bootcmd-when-spi-boot-is-activated.patch
new file mode 100644 (file)
index 0000000..fcefddd
--- /dev/null
@@ -0,0 +1,23 @@
+From 9e101257c1bc1243495559b255ebdd33929f4fa3 Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sun, 14 Jan 2018 18:58:47 +0100
+Subject: sunxi: set bootcmd when spi boot is activated
+
+---
+ include/configs/sunxi-common.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/include/configs/sunxi-common.h
++++ b/include/configs/sunxi-common.h
+@@ -447,6 +447,11 @@ extern int soft_i2c_gpio_scl;
+ #define BOOTCMD_SUNXI_COMPAT
+ #endif
++#if CONFIG_SPI_BOOT
++/* u-boot env in serial flash, by default is bus 0 and cs 0 */
++#define CONFIG_ENV_SECT_SIZE          0x010000
++#endif
++
+ #include <config_distro_bootcmd.h>
+ #ifdef CONFIG_USB_KEYBOARD