Hi,

On 21-05-15 15:59, Roy Spliet wrote:
From: Daniel KochmaƄski <[email protected]>

V2:
- Rename config option
- Move to separate driver
- fix DMA directly into RAM
- Many readability upgrades
- Drop R32 and W32 macros in favour of readl/writel respectively
- Use standard port controller methods for pinctl
- Make many NAND options semi-configurable

Signed-off-by: Roy Spliet <[email protected]>
---
  arch/arm/cpu/armv7/sunxi/board.c       |  12 +-
  arch/arm/include/asm/arch-sunxi/gpio.h |   2 +
  board/sunxi/Kconfig                    |  12 ++
  board/sunxi/board.c                    |  27 +++
  drivers/mtd/nand/Makefile              |   1 +
  drivers/mtd/nand/sunxi_nand_spl.c      | 290 +++++++++++++++++++++++++++++++++
  include/configs/sun4i.h                |   1 +
  include/configs/sun5i.h                |   3 +
  include/configs/sun7i.h                |   2 +
  include/configs/sun8i.h                |   6 +
  include/configs/sunxi-common.h         |  20 +++
  11 files changed, 374 insertions(+), 2 deletions(-)
  create mode 100644 drivers/mtd/nand/sunxi_nand_spl.c

diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 6718ae2..70f413f 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -111,8 +111,10 @@ void s_init(void)
  #ifdef CONFIG_SPL_BUILD
  /* The sunxi internal brom will try to loader external bootloader
   * from mmc0, nand flash, mmc2.
- * Unfortunately we can't check how SPL was loaded so assume
- * it's always the first SD/MMC controller
+ *
+ * Unfortunately we can't check how SPL was loaded so assume it's
+ * always the first SD/MMC controller, unless it was explicitly
+ * stated that SPL is on nand flash.
   */
  u32 spl_boot_device(void)
  {
@@ -122,6 +124,12 @@ u32 spl_boot_device(void)
         * enabled build. It has many restrictions and can only boot over USB.
         */
        return BOOT_DEVICE_BOARD;
+#elif defined(CONFIG_SPL_NAND_SUPPORT)
+       /*
+        * This is compile time configuration informing SPL, that it
+        * was loaded from nand flash.
+        */
+       return BOOT_DEVICE_NAND;
  #else
        /*
         * When booting from the SD card, the "eGON.BT0" signature is expected
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h 
b/arch/arm/include/asm/arch-sunxi/gpio.h
index 59d8210..2b49616 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -156,6 +156,8 @@ enum sunxi_gpio_number {
  #define SUN4I_GPB_UART0               2
  #define SUN5I_GPB_UART0               2

+#define SUNXI_GPC_NAND         2
+
  #define SUNXI_GPC_SDC2                3
  #define SUN6I_GPC_SDC3                4

diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index a60d028..cf58d73 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -269,6 +269,18 @@ config MMC_SUNXI_SLOT_EXTRA
        slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
        support for this.

+config SPL_NAND_SUPPORT
+       bool "SPL/NAND mode support"
+       depends on SPL
+       default n
+       ---help---
+         This enables support for booting from NAND internal
+         memory. U-Boot SPL doesn't detect where is it load from,
+         therefore this option is needed to properly load image from
+         flash. Option also disables MMC functionality on U-Boot due to
+         initialization errors encountered, when both controllers are
+         enabled.
+
  config USB0_VBUS_PIN
        string "Vbus enable pin for usb0 (otg)"
        default ""

There is a way to figure out if you're booting from sdcard or nand
actually, simply check if an sdcard is there and if it has the boot0
signature, if that is true, then we should be booting from sd, as those
are the checks the brom does itself to determine what to boot (*).

Since we support booting from internal emmc on boars which have it.
and those are connected to mmc2 rather then mmc0 we already have code
to check for this, see board/sunxi/board.c: board_mmc_init(), adapting this
for use to determine whether to look u-boot.bin from nand or mmc on
systems which have nand rather an emmc should be trivial.

So we should be able to build uniform SPL (and u-boot) binaries which work
for both nand and sdcard. Note that this is jyst FYI, I'm fine with merging
the patch as is and fixing this in a follow up patch.

*) Note this is not true on the A31 which prefers nand over sdcard unless
the fel pin is pulled down (or was it up), but is true on all other SoCs


diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index d9f7691..121e655 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -22,6 +22,9 @@
  #ifdef CONFIG_AXP221_POWER
  #include <axp221.h>
  #endif
+#ifdef CONFIG_NAND_SUNXI
+#include <nand.h>
+#endif
  #include <asm/arch/clock.h>
  #include <asm/arch/cpu.h>
  #include <asm/arch/display.h>
@@ -34,6 +37,8 @@
  #include <linux/usb/musb.h>
  #include <net.h>

+#define CCMU_BASE                      0x01c20000
+

Ugh no please, see below.

  #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
  /* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */
  int soft_i2c_gpio_sda;
@@ -315,6 +320,28 @@ int board_mmc_init(bd_t *bis)
  }
  #endif

+void board_nand_init(void)
+{
+       uint32_t val;
+       unsigned int pin;
+       static u8 ports[] = CONFIG_NAND_SUNXI_GPC_PORTS;
+
+       /* Configure AHB muxes to connect output pins with NAND controller */
+       for (pin = 0; pin < 16; pin++)
+               sunxi_gpio_set_cfgpin(SUNXI_GPC(pin), SUNXI_GPC_NAND);
+
+       for (pin = 0; pin < ARRAY_SIZE(ports); pin++)
+               sunxi_gpio_set_cfgpin(SUNXI_GPC(ports[pin]), SUNXI_GPC_NAND);
+
+       /* "un-gate" NAND clock and clock source
+        * This assumes that the clock was already correctly configured by
+        * BootROM */
+       val = readl(CCMU_BASE + 0x60);
+       writel((val | 0x00002000), CCMU_BASE + 0x60);
+       val = readl(CCMU_BASE + 0x80);
+       writel((val | 0x80000000), CCMU_BASE + 0x80);
+}
+

2 remarks here:

1) The ccmu poking needs to be done in the same way it is done everywhere else,
see e.g. drivers/mmc/sunxi_mmc.c which does:

        struct sunxi_ccm_reg * const ccm =
                        (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

        /* config ahb clock */
        setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no));
#ifdef CONFIG_SUNXI_GEN_SUN6I
        /* unassert reset */
        setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no));
#endif

Also why are you doing this in the board init code? All other sunxi code
only does pinmux setup in the board_init code and does the clk gating
stuff in the actual driver code.

Last: "This assumes that the clock was already correctly configured by BROM"
that will need to be fixed (eventually, can be in a follow up patch), as
in u-boot.bin we will want to support reading nand while booted from sdcard
(for the unified binaries)

  void i2c_init_board(void)
  {
  #ifdef CONFIG_I2C0_ENABLE
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 347ea62..a0cf4d5 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -73,5 +73,6 @@ obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
  obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
  obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
  obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
+obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o

  endif # drivers
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c 
b/drivers/mtd/nand/sunxi_nand_spl.c
new file mode 100644
index 0000000..b8d7a7a
--- /dev/null
+++ b/drivers/mtd/nand/sunxi_nand_spl.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2014, Antmicro Ltd <www.antmicro.com>
+ * Copyright (c) 2015, Turtle Solutions <www.turtle-solutions.eu>
+ * Copyright (c) 2015, Roy Spliet <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * \todo Detect chip parameters (page size, ECC mode, randomisation...)
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <nand.h>
+
+/* DMAC */
+#define DMAC_BASE                      0x01c02000

Please use the base address define from 
arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
or add one there if necessary.


+#define DMAC_REG(a)                    (DMAC_BASE + a)


+
+#define DMAC_INT                       DMAC_REG(0x000)
+#define DMAC_DDMA_CFG                  DMAC_REG(0x300)
+#define DMAC_DDMA_SRC                  DMAC_REG(0x304)
+#define DMAC_DDMA_DST                  DMAC_REG(0x308)
+#define DMAC_DDMA_BYTE_COUNT           DMAC_REG(0x30C)
+#define DMAC_DDMA_PARAM                        DMAC_REG(0x318)
+
+/* NAND controller */
+#define NANDFLASHC_BASE                        0x01c03000
+#define NREG(a)                                (0x01c03000 + a)
+
+#define NANDFLASHC_CTL                 NREG(0x00)
+#define NANDFLASHC_CTL_EN              0x00000001
+#define NANDFLASHC_CTL_RST             0x00000002
+#define NANDFLASHC_CTL_RAM_METHOD      0x00004000
+
+#define NANDFLASHC_ST                  NREG(0x004)
+#define NANDFLASHC_INT                 NREG(0x008)
+#define NANDFLASHC_TIMING_CTL          NREG(0x00C)
+#define NANDFLASHC_TIMING_CFG          NREG(0x010)
+#define NANDFLASHC_ADDR_LOW            NREG(0x014)
+#define NANDFLASHC_ADDR_HIGH           NREG(0x018)
+#define NANDFLASHC_SECTOR_NUM          NREG(0x01C)
+#define NANDFLASHC_CNT                 NREG(0x020)
+
+#define NANDFLASHC_CMD                 NREG(0x024)
+#define NANDFLASHC_SEND_CMD1           (1 << 22)
+#define NANDFLASHC_WAIT_FLAG           (1 << 23)
+
+#define NANDFLASHC_RCMD_SET            NREG(0x028)
+#define NANDFLASHC_WCMD_SET            NREG(0x02C)
+#define NANDFLASHC_IO_DATA             NREG(0x030)
+#define NANDFLASHC_ECC_CTL             NREG(0x034)
+#define NANDFLASHC_ECC_ST              NREG(0x038)
+#define NANDFLASHC_DEBUG               NREG(0x03c)
+#define NANDFLASHC_ECC_CNT0            NREG(0x040)
+#define NANDFLASHC_ECC_CNT1            NREG(0x044)
+#define NANDFLASHC_ECC_CNT2            NREG(0x048)
+#define NANDFLASHC_ECC_CNT3            NREG(0x04c)
+#define NANDFLASHC_USER_DATA_BASE      NREG(0x050)
+#define NANDFLASHC_EFNAND_STATUS       NREG(0x090)
+#define NANDFLASHC_SPARE_AREA          NREG(0x0A0)
+#define NANDFLASHC_PATTERN_ID          NREG(0x0A4)
+#define NANDFLASHC_RAM0_BASE           NREG(0x400)
+#define NANDFLASHC_RAM1_BASE           NREG(0x800)

Please create a struct reflecting the register layout and
then initialize a ptr to this struct from the base-address
and get register addresses this way, this is how we deal
with this in pretty much all other sunxi code, see e.g.:

arch/arm/include/asm/arch-sunxi/mmc.h



+
+void
+nand_init(void)
+{
+       uint32_t val;
+
+       board_nand_init();
+       val = readl(NANDFLASHC_CTL);
+       val |= NANDFLASHC_CTL_RST;
+       writel(val, NANDFLASHC_CTL);
+
+       /* Wait until reset pin is deasserted */
+       do {
+               val = readl(NANDFLASHC_CTL);
+               if (!(val & NANDFLASHC_CTL_RST))
+                       break;
+       } while (1);

Please put a timeout on all waits, see mctl_await_completion()
from arch/arm/cpu/armv7/sunxi/dram_helpers.c, or just use
that outright. It is intended for use during dram init, but
it should work fine for things like this too.

+
+       /** \todo Chip select, currently kind of static */
+       val = readl(NANDFLASHC_CTL);
+       val &= 0xf0fff0f2;
+       val |= NANDFLASHC_CTL_EN;
+       val |= (3 << 8);
+       writel(val, NANDFLASHC_CTL);
+
+       writel(0x100, NANDFLASHC_TIMING_CTL);
+       writel(0x7ff, NANDFLASHC_TIMING_CFG);
+
+       /* reset CMD  */
+       val = NANDFLASHC_SEND_CMD1 | NANDFLASHC_WAIT_FLAG | NAND_CMD_RESET;
+       writel(val, NANDFLASHC_CMD);
+       do {
+               val = readl(NANDFLASHC_ST);
+               if (val & (1<<1))
+                       break;
+               udelay(1000);
+       } while (1);

Idem. Also the udelay buys you nothing.


+
+       printf("Nand initialised\n");
+}
+
+/* random seed */
+static const uint16_t random_seed[128] = {
+       0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72,
+       0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436,
+       0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d,
+       0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130,
+       0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56,
+       0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55,
+       0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb,
+       0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17,
+       0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62,
+       0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064,
+       0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126,
+       0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e,
+       0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3,
+       0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b,
+       0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d,
+       0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db,
+};
+
+uint32_t ecc_errors = 0;
+
+int nand_waid_cmd_fifo_free(void)
+{
+       do {
+               if (!(readl(NANDFLASHC_ST) & 0x8))
+                       return 0;
+       } while (1);

Idem.

+       return -1;
+}
+
+static void
+nand_config_ecc(uint32_t page, int syndrome)
+{
+       static u8 strength[] = {16, 24, 28, 32, 40, 48, 56, 60, 64};
+       int i;
+       uint32_t ecc_mode;
+       u32 ecc;
+
+       for (i = 0; i < ARRAY_SIZE(strength); i++) {
+               if (CONFIG_NAND_SUNXI_ECC_STRENGTH == strength[i]) {
+                       ecc_mode = i;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(strength)) {
+               printf("ECC strength unsupported\n");
+               return;
+       }
+
+       ecc = 1 | (1<<3) | (1 << 9) | (ecc_mode << 12);
+
+       if (CONFIG_NAND_SUNXI_ECC_STEP == 512)
+               ecc |= 1 << 5;
+
+       if (syndrome)
+               ecc |= (0x4A80 << 16);
+       else
+               ecc |= (random_seed[page % ARRAY_SIZE(random_seed)] << 16);
+
+       writel(ecc, NANDFLASHC_ECC_CTL);
+}
+
+/* read CONFIG_NAND_SUNXI_ECC_STEP bytes from real_addr to temp_buf */
+void
+nand_read_block(phys_addr_t src, dma_addr_t dst, int syndrome)
+{
+       uint32_t shift;
+       uint32_t page;
+       uint32_t addr;
+       uint32_t oob_offset;
+       uint32_t ecc_bytes;
+       u32 val;
+       u32 cmd;
+
+       page = src / CONFIG_NAND_SUNXI_PAGE_SIZE;
+       if (page > 0xFFFF) {
+               /* TODO: currently this is not supported */
+               printf("Reading from address >= %08X is not allowed.\n",
+                      0xFFFF * CONFIG_NAND_SUNXI_PAGE_SIZE);
+               return;
+       }
+
+       shift = src % CONFIG_NAND_SUNXI_PAGE_SIZE;
+       writel(0, NANDFLASHC_ECC_ST);
+
+       /* ECC_CTL, randomization */
+       ecc_bytes = CONFIG_NAND_SUNXI_ECC_STRENGTH *
+                       fls(CONFIG_NAND_SUNXI_ECC_STEP * 8);
+       ecc_bytes = DIV_ROUND_UP(ecc_bytes, 8);
+       ecc_bytes += (ecc_bytes & 1); /* Align to 2-bytes */
+       ecc_bytes += 4;
+
+       nand_config_ecc(page, syndrome);
+       if (syndrome) {
+               /* shift every 1kB in syndrome */
+               shift += (shift / CONFIG_NAND_SUNXI_ECC_STEP) * ecc_bytes;
+               oob_offset = CONFIG_NAND_SUNXI_ECC_STEP + shift;
+       } else {
+               oob_offset = CONFIG_NAND_SUNXI_PAGE_SIZE  +
+                       (shift / CONFIG_NAND_SUNXI_ECC_STEP) * ecc_bytes;
+       }
+
+       addr = (page << 16) | shift;
+
+       /* DMA */
+       val = readl(NANDFLASHC_CTL);
+       writel(val | NANDFLASHC_CTL_RAM_METHOD, NANDFLASHC_CTL);
+
+       writel(oob_offset, NANDFLASHC_SPARE_AREA);
+
+       /* DMAC
+        * \todo Separate this into a tidy driver */
+       writel(0x0, DMAC_INT); /* clear dma interrupts */
+       writel(NANDFLASHC_IO_DATA, DMAC_DDMA_SRC);
+       writel(dst               , DMAC_DDMA_DST);
+       writel(0x00007F0F        , DMAC_DDMA_PARAM);
+       writel(CONFIG_NAND_SUNXI_ECC_STEP, DMAC_DDMA_BYTE_COUNT);
+       /*
+        * [ 0: 4] Source     - NAND
+        * [ 5: 6] Mode       - IO
+        * [ 9:10] Dada width - 32-bits
+        * [16:20] Dest       - SDRAM
+        * [25:26] Data width - 32-bits
+        * [   31] Enable
+        */
+       writel(0x84010423, DMAC_DDMA_CFG);
+
+       writel(0x00E00530, NANDFLASHC_RCMD_SET);
+       nand_waid_cmd_fifo_free();
+       writel(1, NANDFLASHC_SECTOR_NUM);
+       writel(addr, NANDFLASHC_ADDR_LOW);
+       writel(0, NANDFLASHC_ADDR_HIGH);
+
+       /* CMD (PAGE READ) */
+       cmd = 0x85E80000;
+       cmd |= ((CONFIG_NAND_SUNXI_ADDR_CYCLES - 1) << 16);
+       cmd |= (syndrome ? 0x02000000 : 0x0);
+       writel(cmd, NANDFLASHC_CMD);
+
+       do { /* wait for dma irq */
+               val = readl(NANDFLASHC_ST);
+               if (val & (1<<2))
+                       break;
+               udelay(1000);
+       } while (1);
+
+       do {/* make sure cmd is finished */
+               val = readl(DMAC_BASE + 0x300);
+               if (!(val & 0x80000000))
+                       break;
+               udelay(1000);
+       } while (1);
+
+       if (readl(NANDFLASHC_ECC_ST))
+               ecc_errors++;
+}
+
+int
+nand_spl_load_image(uint32_t offs, unsigned int size, void *dest)
+{
+       dma_addr_t dst_block;
+       dma_addr_t dst_end;
+       phys_addr_t addr = offs;
+
+       dst_end = ((dma_addr_t) dest) + size;
+
+       memset((void *)dest, 0x0, size);
+       ecc_errors = 0;
+       for (dst_block = (dma_addr_t) dest; dst_block < dst_end;
+                       dst_block += CONFIG_NAND_SUNXI_ECC_STEP,
+                       addr += CONFIG_NAND_SUNXI_ECC_STEP) {
+               /* syndrome read first 4MiB to match Allwinner BootROM */
+               nand_read_block(addr, dst_block, addr < 0x400000);
+       }
+
+       if (ecc_errors)
+               printf("Error: %d ECC failures detected\n", ecc_errors);
+       return ecc_errors == 0;
+}
+
+void
+nand_deselect(void)
+{}
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
index ea079eb..a3c9408 100644
--- a/include/configs/sun4i.h
+++ b/include/configs/sun4i.h
@@ -18,6 +18,7 @@
  #endif

  #define CONFIG_SUNXI_USB_PHYS 3
+#define CONFIG_NAND_SUNXI_GPC_PORTS    {16, 17, 18, 19, 20, 21, 22, 24}

  /*
   * Include common sunxi configuration where most the settings are
diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
index d257659..8e13df5 100644
--- a/include/configs/sun5i.h
+++ b/include/configs/sun5i.h
@@ -19,6 +19,9 @@

  #define CONFIG_SUNXI_USB_PHYS 2

+/* \todo A13 only defines port 19, whereas A10s requires each of these */
+#define CONFIG_NAND_SUNXI_GPC_PORTS    {16, 17, 18, 19}
+
  /*
   * Include common sunxi configuration where most the settings are
   */
diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h
index 56101a9..3d26ce8 100644
--- a/include/configs/sun7i.h
+++ b/include/configs/sun7i.h
@@ -24,6 +24,8 @@
  #define CONFIG_ARMV7_SECURE_BASE      SUNXI_SRAM_B_BASE
  #define CONFIG_TIMER_CLK_FREQ         24000000

+#define CONFIG_NAND_SUNXI_GPC_PORTS    {16, 17, 18, 19, 20, 21, 22, 24}
+
  /*
   * Include common sunxi configuration where most the settings are
   */
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 7111c63..cd33758 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -20,6 +20,12 @@

  #define CONFIG_SUNXI_USB_PHYS 2

+#if defined(CONFIG_MACH_SUN8I_A23)
+#define CONFIG_NAND_SUNXI_GPC_PORTS    {16, 17, 18}
+#elif defined(CONFIG_MACH_SUN8I_A33)
+#define CONFIG_NAND_SUNXI_GPC_PORTS    {16}
+#endif
+
  /*
   * Include common sunxi configuration where most the settings are
   */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index c8ebb54..cce0441 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -106,8 +106,10 @@
  #define CONFIG_CMD_MMC
  #define CONFIG_MMC_SUNXI
  #define CONFIG_MMC_SUNXI_SLOT         0
+#if !defined(CONFIG_SPL_NAND_SUPPORT)
  #define CONFIG_ENV_IS_IN_MMC
  #define CONFIG_SYS_MMC_ENV_DEV                0       /* first detected MMC 
controller */
+#endif /* CONFIG_SPL_NAND_SUPPORT */
  #endif

  /* 4MB of malloc() pool */
@@ -324,6 +326,24 @@ extern int soft_i2c_gpio_scl;
  #define CONFIG_ENV_IS_NOWHERE
  #endif

+#ifdef CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_NAND
+#define CONFIG_SYS_NAND_SELF_INIT
+#define CONFIG_NAND_SUNXI
+#define CONFIG_CMD_SPL_WRITE_SIZE              0x000400
+#define CONFIG_SYS_NAND_U_BOOT_OFFS            0x008000
+
+/* \todo Make these parameterisable in kernel config ? */
+#define CONFIG_NAND_SUNXI_PAGE_SIZE            8192
+#define CONFIG_NAND_SUNXI_ECC_STEP             1024
+#define CONFIG_NAND_SUNXI_ECC_STRENGTH         40
+#define CONFIG_NAND_SUNXI_ADDR_CYCLES          5
+
+#ifndef CONFIG_NAND_SUNXI_GPC_PORTS
+#error "No NAND GPC ports defined, NAND unsupported"
+#endif
+#endif /* CONFIG_SPL_NAND_SUPPORT */
+
  #define CONFIG_MISC_INIT_R
  #define CONFIG_SYS_CONSOLE_IS_IN_ENV



Otherwise this looks like a good start, with the coding
style issues fixed I would not be opposed against merging
this as a first step to growing proper nand support.

Ian, is that ok with you ?

Regards,

Hans

--
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to