Discussion:
[linux-sunxi] Proposal to add NAND-boot support for Sunxi SPL
Roy Spliet
2015-05-21 13:59:23 UTC
Permalink
The following patches take the work by Daniel Kochmánski, and make some
heavy modifications for readability and functionality, based on Boris
Brezillon's Linux driver. Tested on an Olimex Lime w/ A20.
Patches are sent as RFC. Open questions:
- Config options added are partially NAND-chip specific. Some options can
be autodetected based on the NAND ID, others require either brute-forcing
or config options like these. Do they belong in sunxi-common? Should
we make a Kconfig option for this? If bikeshedding is desired, are defines
in sunxi-common.h good enough for now?
- Style is mostly kernel-like. Satisfied?
- Daniel: do you think we can work from here?

Please comment away!

Roy
--
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roy Spliet
2015-05-21 13:59:24 UTC
Permalink
From: Daniel Kochmański <***@turtle-solutions.eu>

This change is necessary to calculate correct checksum for NAND
boot. Works both for MMC and NAND. Without it BROM rejects boot image
as invalid (bad checksum). (Changes block size from 0x200 to 0x2000).

V2: Document decision in source too

Signed-off-by: Daniel Kochmański <***@turtle-solutions.eu>
Cc: Ian Campbell <***@hellion.org.uk>
Cc: Hans De Goede <***@redhat.com>
Signed-off-by: Roy Spliet <***@ultimaker.com>
---
tools/mksunxiboot.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c
index 0035f6e..3361251 100644
--- a/tools/mksunxiboot.c
+++ b/tools/mksunxiboot.c
@@ -65,7 +65,13 @@ int gen_check_sum(struct boot_file_head *head_p)

#define SUN4I_SRAM_SIZE 0x7600 /* 0x7748+ is used by BROM */
#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(struct boot_file_head))
-#define BLOCK_SIZE 512
+
+/*
+ * BROM (at least on A10 and A20) requires NAND-images to be explicitly aligned
+ * to a multiple of 8K, and rejects the image otherwise. MMC-images are fine
+ * with 512B blocks. To cater for both, align to the largest of the two.
+ */
+#define BLOCK_SIZE 0x2000

struct boot_img {
struct boot_file_head header;
--
2.1.0
--
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-21 18:12:59 UTC
Permalink
Hi,
Post by Roy Spliet
This change is necessary to calculate correct checksum for NAND
boot. Works both for MMC and NAND. Without it BROM rejects boot image
as invalid (bad checksum). (Changes block size from 0x200 to 0x2000).
V2: Document decision in source too
Looks good: Reviewed-by: Hans de Goede <***@redhat.com>

Regards,

Hans
Post by Roy Spliet
---
tools/mksunxiboot.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c
index 0035f6e..3361251 100644
--- a/tools/mksunxiboot.c
+++ b/tools/mksunxiboot.c
@@ -65,7 +65,13 @@ int gen_check_sum(struct boot_file_head *head_p)
#define SUN4I_SRAM_SIZE 0x7600 /* 0x7748+ is used by BROM */
#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(struct boot_file_head))
-#define BLOCK_SIZE 512
+
+/*
+ * BROM (at least on A10 and A20) requires NAND-images to be explicitly aligned
+ * to a multiple of 8K, and rejects the image otherwise. MMC-images are fine
+ * with 512B blocks. To cater for both, align to the largest of the two.
+ */
+#define BLOCK_SIZE 0x2000
struct boot_img {
struct boot_file_head header;
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roy Spliet
2015-05-21 13:59:25 UTC
Permalink
From: Daniel Kochmański <***@turtle-solutions.eu>

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 <***@ultimaker.com>
---
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 ""
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
+
#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);
+}
+
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 <***@ultimaker.com>
+ *
+ * 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
+#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)
+
+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);
+
+ /** \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);
+
+ 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);
+ 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
--
2.1.0
--
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-21 18:39:33 UTC
Permalink
Hi,
Post by Roy Spliet
- 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
---
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
Post by Roy Spliet
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.
Post by Roy Spliet
#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)
Post by Roy Spliet
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>
+ *
+ * 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.
Post by Roy Spliet
+#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
Post by Roy Spliet
+
+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.
Post by Roy Spliet
+
+ /** \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.
Post by Roy Spliet
+
+ 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.
Post by Roy Spliet
+ 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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Ian Campbell
2015-05-21 19:02:30 UTC
Permalink
On Thu, 2015-05-21 at 20:39 +0200, Hans de Goede wrote:
[...]
Post by Hans de Goede
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
This isn't just sunxi, I believe it is u-boot's preferred way to do
things generally.
[...]
Post by Hans de Goede
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 ?
You mean with the coding style fixed but not (necessarily) all the other
issues you pointed out (timeouts on loops, structs for register
accesses)?

I think at least the structs for register access stuff should be fixed
first, especially given it was already raised in the previous round of
review.

Ian
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-22 07:30:46 UTC
Permalink
Hi,
Post by Ian Campbell
[...]
Post by Hans de Goede
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
This isn't just sunxi, I believe it is u-boot's preferred way to do
things generally.
[...]
Post by Hans de Goede
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 ?
You mean with the coding style fixed but not (necessarily) all the other
issues you pointed out (timeouts on loops, structs for register
accesses)?
Sorry, what I meant is are you ok with starting with merging just
the SPL support without having support for actually reading
the kernel, etc. as a first step. The SPL support would have to
have all the issues (*) I pointed out fixed before merging.

Regards,

Hans

*) Except for those where I explicitly said they can be fixed up
with a follow up commit.
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Ian Campbell
2015-05-22 08:57:43 UTC
Permalink
Post by Hans de Goede
Hi,
Post by Ian Campbell
[...]
Post by Hans de Goede
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
This isn't just sunxi, I believe it is u-boot's preferred way to do
things generally.
[...]
Post by Hans de Goede
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 ?
You mean with the coding style fixed but not (necessarily) all the other
issues you pointed out (timeouts on loops, structs for register
accesses)?
Sorry, what I meant is are you ok with starting with merging just
the SPL support without having support for actually reading
the kernel, etc. as a first step.
Oh yes, that seems completely reasonable.
Post by Hans de Goede
The SPL support would have to
have all the issues (*) I pointed out fixed before merging.
Agreed.

Ian.
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roy Spliet
2015-06-02 06:43:27 UTC
Permalink
Dear Scott,

Thank you for taking your time to feedback. However, it seems to be
about a week and two versions of the patchset too late. Most of your
issues have been addressed in the meanwhile, as you can see in Hans de
Goede's sunxi branch.
Yours,

Roy
Post by Roy Spliet
+#ifdef CONFIG_NAND_SUNXI
+#include <nand.h>
+#endif
Why do you need the ifdef?
+#include <common.h>
Post by Roy Spliet
+#include <config.h>
+#include <asm/io.h>
+#include <nand.h>
+
+/* DMAC */
+#define DMAC_BASE 0x01c02000
+#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)
Shouldn't these be in a header file so they can be shared with a non-
SPL driver?
Post by Roy Spliet
+void
+nand_init(void)
+{
Don't put a newline after the return type.
Post by Roy Spliet
+ 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);
Add a timeout to delay loops.
Post by Roy Spliet
+
+ /** \todo Chip select, currently kind of static */
+ val = readl(NANDFLASHC_CTL);
+ val &= 0xf0fff0f2;
Don't put magic numbers in the code -- use symbolic constants taht
describe what the fields mean.
+/* random seed */
Post by Roy Spliet
+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,
+};
Why is randomness needed?
Post by Roy Spliet
+uint32_t ecc_errors = 0;
Why is this global?
Post by Roy Spliet
+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);
Unnecessary cast.
-Scott
--
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-21 18:08:15 UTC
Permalink
Hi Roy,
Post by Roy Spliet
The following patches take the work by Daniel Kochmánski, and make some
heavy modifications for readability and functionality, based on Boris
Brezillon's Linux driver. Tested on an Olimex Lime w/ A20.
- Config options added are partially NAND-chip specific. Some options can
be autodetected based on the NAND ID, others require either brute-forcing
or config options like these. Do they belong in sunxi-common? Should
we make a Kconfig option for this? If bikeshedding is desired, are defines
in sunxi-common.h good enough for now?
- Style is mostly kernel-like. Satisfied?
- Daniel: do you think we can work from here?
Please comment away!
Cool stuff. Overall this looks good I'll reply with more detailed feedback
to your individual patches, 2 questions:

1) Can you provide a quick howto (at developer level) on how to actually
get the spl and u-boot into the nand, what I'm looking for is unstructions
like this:

a) Take this git repo + branch, build a kernel from it
b) Look at this dts file for a nand settings example, adjust it for your board
c) Once booted into the kernel using an updated dts you should have these
block devices, dd spl to this one, and u-boot to this one.

No more to go more detailed then that :)

2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?

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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
k***@gmail.com
2015-05-22 02:23:26 UTC
Permalink
Hi Roy,

I could definitely use such a howto. I have applied the patches to the
current mainline u-boot head and try to boot my A13-OlinXino Wifi board in
FEL mode.
I can compile and boot into u-boot via FEL. However, I get these errors
when I have CONFIG_SPL_NAND_SUPPORT defined:

U-Boot SPL 2015.07-rc1-00276-g77792f9-dirty (May 21 2015 - 19:15:54)
DRAM: 512 MiB
Failed to set core voltage! Can't set CPU frequency
sunxi board_nand_init()
Nand initialised
Error: 1 ECC failures detected
Error: 512 ECC failures detected

This is my configs/A13-OLinuXino_defconfig looks like this:
CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER,USB_EHCI,SYS_MAX_NAND_DEVICE=1,SYS_NAND_BASE=0x00"
CONFIG_NAND=y

CONFIG_SUNXI_NAND=y

CONFIG_SUNXI_DMA=y

CONFIG_CMD_NAND=y

CONFIG_SPL_NAND_SUPPORT=y

CONFIG_SPL=y

CONFIG_FDTFILE="sun5i-a13-olinuxino.dtb"

CONFIG_USB1_VBUS_PIN="PG11"

CONFIG_VIDEO_HDMI=n

CONFIG_VIDEO_VGA_VIA_LCD=y

CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y

# For use with the Olimex 7" LCD module, adjust timings for other
displays
# Set video-mode=sunxi:800x600-***@60,monitor=lcd in the env. to
enable
CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
CONFIG_VIDEO_LCD_POWER="AXP0-0"

CONFIG_VIDEO_LCD_BL_PWM="PB2"

CONFIG_ARM=y

CONFIG_ARCH_SUNXI=y

CONFIG_MACH_SUN5I=y

CONFIG_DRAM_CLK=408

CONFIG_DRAM_ZQ=123

CONFIG_DRAM_EMR1=0

CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"

I just found out in the sun5i-a13-olinuxino.dts file are no nand settings.
I guess I can find the information in the linux-sunxi 3.4 kernels fex file
for the olinuxio and need to convert to dts, correct?

I am happy about any hints / comments.

Thanks
Alex
Post by Hans de Goede
Hi Roy,
The following patches take the work by Daniel Kochmánski, and make some
heavy modifications for readability and functionality, based on Boris
Brezillon's Linux driver. Tested on an Olimex Lime w/ A20.
- Config options added are partially NAND-chip specific. Some options
can
be autodetected based on the NAND ID, others require either
brute-forcing
or config options like these. Do they belong in sunxi-common? Should
we make a Kconfig option for this? If bikeshedding is desired, are
defines
in sunxi-common.h good enough for now?
- Style is mostly kernel-like. Satisfied?
- Daniel: do you think we can work from here?
Please comment away!
Cool stuff. Overall this looks good I'll reply with more detailed feedback
1) Can you provide a quick howto (at developer level) on how to actually
get the spl and u-boot into the nand, what I'm looking for is unstructions
a) Take this git repo + branch, build a kernel from it
b) Look at this dts file for a nand settings example, adjust it for your board
c) Once booted into the kernel using an updated dts you should have these
block devices, dd spl to this one, and u-boot to this one.
No more to go more detailed then that :)
2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roy Spliet
2015-05-22 07:04:36 UTC
Permalink
Hello,

For my set-up I made use of Boris Brezillon's sunxi-nand tree[1], or
actually I rebased his patches on top of 4.0rc7. This basically adds
support for NAND-chip partitioning, ECC and randomisation. Docs for the
DT specification in Documentation/devicetree/bindings/mtd/sunxi-nand.txt
, and an example can be found in
arch/arm/boot/dts/sun7i-a20-cubietruck.dts . [2] lists the acceptable
configuration options for the boot and boot_rescue partitions, make sure
to pick one of these (which should be no problem for MLC-type nand). The
ECC mode for these boot partitions is called hw_syndrome.

Assuming you now have a Linux set-up kernel based on this tree with NAND
support on an MMC, for U-boot what you should currently do is:
1) in include/configs/sunxi-common.h, adjust the parameters
<CONFIG_NAND_SUNXI_>PAGE_SIZE, ECC_STEP, ECC_STRENGTH to match your NAND
chip and DT configuration.
2) Build
3) Use your MMC to flash u-boot-sunxi-with-spl.bin onto NAND:
# flash_erase /dev/mtd0
# nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin
4) Reboot without the MMC card and see U-boot load

That should be all.

@Alex: To answer your question specifically: It's likely that the
parameters in sunxi-common.h mentioned above might not match your
NAND-chip configuration in the Linux kernel. I can't tell you precisely
how to fetch these details from the 3.4 kernel, sorry. I recall Daniel
using 24-bit strength ECC with otherwise equal parameters, but perhaps
he can help you with this better than I can.

Cheers,

Roy

[1] https://github.com/bbrezillon/linux-sunxi/commits/sunxi-nand
[2] https://linux-sunxi.org/NAND#More_information_on_BROM_NAND
Post by Hans de Goede
Hi Roy,
I could definitely use such a howto. I have applied the patches to the
current mainline u-boot head and try to boot my A13-OlinXino Wifi
board in FEL mode.
I can compile and boot into u-boot via FEL. However, I get these
U-Boot SPL 2015.07-rc1-00276-g77792f9-dirty (May 21 2015 - 19:15:54)
DRAM: 512 MiB
Failed to set core voltage! Can't set CPU frequency
sunxi board_nand_init()
Nand initialised
Error: 1 ECC failures detected
Error: 512 ECC failures detected
CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER,USB_EHCI,SYS_MAX_NAND_DEVICE=1,SYS_NAND_BASE=0x00"
CONFIG_NAND=y
CONFIG_SUNXI_NAND=y
CONFIG_SUNXI_DMA=y
CONFIG_CMD_NAND=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_SPL=y
CONFIG_FDTFILE="sun5i-a13-olinuxino.dtb"
CONFIG_USB1_VBUS_PIN="PG11"
CONFIG_VIDEO_HDMI=n
CONFIG_VIDEO_VGA_VIA_LCD=y
CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
# For use with the Olimex 7" LCD module, adjust timings for other
displays
CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
CONFIG_VIDEO_LCD_POWER="AXP0-0"
CONFIG_VIDEO_LCD_BL_PWM="PB2"
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_MACH_SUN5I=y
CONFIG_DRAM_CLK=408
CONFIG_DRAM_ZQ=123
CONFIG_DRAM_EMR1=0
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"
I just found out in the sun5i-a13-olinuxino.dts file are no nand settings.
I guess I can find the information in the linux-sunxi 3.4 kernels fex
file for the olinuxio and need to convert to dts, correct?
I am happy about any hints / comments.
Thanks
Alex
Hi Roy,
The following patches take the work by Daniel Kochmánski, and
make some
heavy modifications for readability and functionality, based on
Boris
Brezillon's Linux driver. Tested on an Olimex Lime w/ A20.
- Config options added are partially NAND-chip specific. Some
options can
be autodetected based on the NAND ID, others require either
brute-forcing
or config options like these. Do they belong in sunxi-common?
Should
we make a Kconfig option for this? If bikeshedding is desired,
are defines
in sunxi-common.h good enough for now?
- Style is mostly kernel-like. Satisfied?
- Daniel: do you think we can work from here?
Please comment away!
Cool stuff. Overall this looks good I'll reply with more detailed feedback
1) Can you provide a quick howto (at developer level) on how to actually
get the spl and u-boot into the nand, what I'm looking for is unstructions
a) Take this git repo + branch, build a kernel from it
b) Look at this dts file for a nand settings example, adjust it for your board
c) Once booted into the kernel using an updated dts you should have these
block devices, dd spl to this one, and u-boot to this one.
No more to go more detailed then that :)
2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?
Regards,
Hans
--
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-25 18:35:03 UTC
Permalink
Hi,
Post by Roy Spliet
Hello,
For my set-up I made use of Boris Brezillon's sunxi-nand tree[1], or actually I rebased his patches on top of 4.0rc7. This basically adds support for NAND-chip partitioning, ECC and randomisation. Docs for the DT specification in Documentation/devicetree/bindings/mtd/sunxi-nand.txt , and an example can be found in arch/arm/boot/dts/sun7i-a20-cubietruck.dts . [2] lists the acceptable configuration options for the boot and boot_rescue partitions, make sure to pick one of these (which should be no problem for MLC-type nand). The ECC mode for these boot partitions is called hw_syndrome.
1) in include/configs/sunxi-common.h, adjust the parameters <CONFIG_NAND_SUNXI_>PAGE_SIZE, ECC_STEP, ECC_STRENGTH to match your NAND chip and DT configuration.
2) Build
# flash_erase /dev/mtd0
# nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin
4) Reboot without the MMC card and see U-boot load
Ok, it took me way longer then I wanted (see below) but I've this
working now. It is cool to see u-boot load from nand :)
Post by Roy Spliet
That should be all.
@Alex: To answer your question specifically: It's likely that the parameters in sunxi-common.h mentioned above might not match your NAND-chip configuration in the Linux kernel. I can't tell you precisely how to fetch these details from the 3.4 kernel, sorry. I recall Daniel using 24-bit strength ECC with otherwise equal parameters, but perhaps he can help you with this better than I can.
Alex, could it be that you are writing the nand using
a (rebased) version of bbrezillon's sunxi-nand-next branch ?

I started with that too because it is much newer and contains
various bug fixes, but it seems that it also contains a new
bug causing it to write the NAND in such a way that the BROM
and u-boot SPL code will not read it.

I've just pushed a rebased version of the sunxi-nand branch of
Boris here:

https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment

And that works for me, where as before I got the exact same errors
trying to fel load a nand enabled spl.

I'm working on merging over all the changes from the sunxi-nand-next
branch onto my working sunxi-nand-experiment branch 1 by 1 until
I find the one which causes the breakage...

Regards,

Hans
Post by Roy Spliet
Cheers,
Roy
[1] https://github.com/bbrezillon/linux-sunxi/commits/sunxi-nand
[2] https://linux-sunxi.org/NAND#More_information_on_BROM_NAND
Post by Hans de Goede
Hi Roy,
I could definitely use such a howto. I have applied the patches to the current mainline u-boot head and try to boot my A13-OlinXino Wifi board in FEL mode.
U-Boot SPL 2015.07-rc1-00276-g77792f9-dirty (May 21 2015 - 19:15:54)
DRAM: 512 MiB
Failed to set core voltage! Can't set CPU frequency
sunxi board_nand_init()
Nand initialised
Error: 1 ECC failures detected
Error: 512 ECC failures detected
CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER,USB_EHCI,SYS_MAX_NAND_DEVICE=1,SYS_NAND_BASE=0x00"
CONFIG_NAND=y
CONFIG_SUNXI_NAND=y
CONFIG_SUNXI_DMA=y
CONFIG_CMD_NAND=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_SPL=y
CONFIG_FDTFILE="sun5i-a13-olinuxino.dtb"
CONFIG_USB1_VBUS_PIN="PG11"
CONFIG_VIDEO_HDMI=n
CONFIG_VIDEO_VGA_VIA_LCD=y
CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
# For use with the Olimex 7" LCD module, adjust timings for other displays
CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
CONFIG_VIDEO_LCD_POWER="AXP0-0"
CONFIG_VIDEO_LCD_BL_PWM="PB2"
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_MACH_SUN5I=y
CONFIG_DRAM_CLK=408
CONFIG_DRAM_ZQ=123
CONFIG_DRAM_EMR1=0
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"
I just found out in the sun5i-a13-olinuxino.dts file are no nand settings.
I guess I can find the information in the linux-sunxi 3.4 kernels fex file for the olinuxio and need to convert to dts, correct?
I am happy about any hints / comments.
Thanks
Alex
Hi Roy,
Post by Roy Spliet
The following patches take the work by Daniel Kochmánski, and
make some
Post by Roy Spliet
heavy modifications for readability and functionality, based on
Boris
Post by Roy Spliet
Brezillon's Linux driver. Tested on an Olimex Lime w/ A20.
- Config options added are partially NAND-chip specific. Some
options can
Post by Roy Spliet
be autodetected based on the NAND ID, others require either
brute-forcing
Post by Roy Spliet
or config options like these. Do they belong in sunxi-common?
Should
Post by Roy Spliet
we make a Kconfig option for this? If bikeshedding is desired,
are defines
Post by Roy Spliet
in sunxi-common.h good enough for now?
- Style is mostly kernel-like. Satisfied?
- Daniel: do you think we can work from here?
Please comment away!
Cool stuff. Overall this looks good I'll reply with more detailed feedback
1) Can you provide a quick howto (at developer level) on how to actually
get the spl and u-boot into the nand, what I'm looking for is unstructions
a) Take this git repo + branch, build a kernel from it
b) Look at this dts file for a nand settings example, adjust it for your board
c) Once booted into the kernel using an updated dts you should have these
block devices, dd spl to this one, and u-boot to this one.
No more to go more detailed then that :)
2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-25 20:39:04 UTC
Permalink
Hi,
Post by Hans de Goede
Hi,
Post by Roy Spliet
Hello,
For my set-up I made use of Boris Brezillon's sunxi-nand tree[1], or actually I rebased his patches on top of 4.0rc7. This basically adds support for NAND-chip partitioning, ECC and randomisation. Docs for the DT specification in Documentation/devicetree/bindings/mtd/sunxi-nand.txt , and an example can be found in arch/arm/boot/dts/sun7i-a20-cubietruck.dts . [2] lists the acceptable configuration options for the boot and boot_rescue partitions, make sure to pick one of these (which should be no problem for MLC-type nand). The ECC mode for these boot partitions is called hw_syndrome.
1) in include/configs/sunxi-common.h, adjust the parameters <CONFIG_NAND_SUNXI_>PAGE_SIZE, ECC_STEP, ECC_STRENGTH to match your NAND chip and DT configuration.
2) Build
# flash_erase /dev/mtd0
# nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin
4) Reboot without the MMC card and see U-boot load
Ok, it took me way longer then I wanted (see below) but I've this
working now. It is cool to see u-boot load from nand :)
Post by Roy Spliet
That should be all.
@Alex: To answer your question specifically: It's likely that the parameters in sunxi-common.h mentioned above might not match your NAND-chip configuration in the Linux kernel. I can't tell you precisely how to fetch these details from the 3.4 kernel, sorry. I recall Daniel using 24-bit strength ECC with otherwise equal parameters, but perhaps he can help you with this better than I can.
Alex, could it be that you are writing the nand using
a (rebased) version of bbrezillon's sunxi-nand-next branch ?
I started with that too because it is much newer and contains
various bug fixes, but it seems that it also contains a new
bug causing it to write the NAND in such a way that the BROM
and u-boot SPL code will not read it.
I've just pushed a rebased version of the sunxi-nand branch of
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment
And that works for me, where as before I got the exact same errors
trying to fel load a nand enabled spl.
I'm working on merging over all the changes from the sunxi-nand-next
branch onto my working sunxi-nand-experiment branch 1 by 1 until
I find the one which causes the breakage...
Ok, so quick update the breakage was caused by this commit:

https://github.com/bbrezillon/linux-sunxi/commit/7f7324bc6170a45742352070fb45170779a3611c

When it was rebased someone (Boris I guess) forgot to remove the
"chip->read_buf(mtd, NULL, ecc->size);" line at line 1075 (after the patch) and
likewise the "chip->write_buf(mtd, buf + (i * ecc->size), ecc->size);" line at
line 1161. With these 2 lines removed the sunxi-nand-next branch from Boris,
rebased on 4.1-rc1 can write the nand boot parts and the brom / spl can load
the spl / resp. u-boot.bin from there (on a cubieboard2).

I've also tried to get this code running on a cubieboard (non 2 so A10 rather then
A20), the SPL loads fine there (indicating that the kernel bits work), but then
I get:

U-Boot SPL 2015.07-rc1-00287-g050de86-dirty (May 25 2015 - 22:28:19)
DRAM: 1024 MiB
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
Nand initialised
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
...

Which seems to indicate a problem with the SPL nand code on the A10. I'll investigate
this further tomorrow evening.

A cleaned up version of my kernel work on this is available in my
sunxi-wip branch.

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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roy Spliet
2015-05-26 07:34:14 UTC
Permalink
Hello Hans,

Re-sent to everybody instead of just you. Reply inline.
Post by Hans de Goede
Hi,
Post by Hans de Goede
Hi,
Post by Roy Spliet
Hello,
For my set-up I made use of Boris Brezillon's sunxi-nand tree[1], or
actually I rebased his patches on top of 4.0rc7. This basically adds
support for NAND-chip partitioning, ECC and randomisation. Docs for
the DT specification in
Documentation/devicetree/bindings/mtd/sunxi-nand.txt , and an
example can be found in arch/arm/boot/dts/sun7i-a20-cubietruck.dts .
[2] lists the acceptable configuration options for the boot and
boot_rescue partitions, make sure to pick one of these (which should
be no problem for MLC-type nand). The ECC mode for these boot
partitions is called hw_syndrome.
Assuming you now have a Linux set-up kernel based on this tree with
1) in include/configs/sunxi-common.h, adjust the parameters
<CONFIG_NAND_SUNXI_>PAGE_SIZE, ECC_STEP, ECC_STRENGTH to match your
NAND chip and DT configuration.
2) Build
# flash_erase /dev/mtd0
# nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin
4) Reboot without the MMC card and see U-boot load
Ok, it took me way longer then I wanted (see below) but I've this
working now. It is cool to see u-boot load from nand :)
Post by Roy Spliet
That should be all.
@Alex: To answer your question specifically: It's likely that the
parameters in sunxi-common.h mentioned above might not match your
NAND-chip configuration in the Linux kernel. I can't tell you
precisely how to fetch these details from the 3.4 kernel, sorry. I
recall Daniel using 24-bit strength ECC with otherwise equal
parameters, but perhaps he can help you with this better than I can.
Alex, could it be that you are writing the nand using
a (rebased) version of bbrezillon's sunxi-nand-next branch ?
I started with that too because it is much newer and contains
various bug fixes, but it seems that it also contains a new
bug causing it to write the NAND in such a way that the BROM
and u-boot SPL code will not read it.
I've just pushed a rebased version of the sunxi-nand branch of
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment
And that works for me, where as before I got the exact same errors
trying to fel load a nand enabled spl.
I'm working on merging over all the changes from the sunxi-nand-next
branch onto my working sunxi-nand-experiment branch 1 by 1 until
I find the one which causes the breakage...
https://github.com/bbrezillon/linux-sunxi/commit/7f7324bc6170a45742352070fb45170779a3611c
When it was rebased someone (Boris I guess) forgot to remove the
"chip->read_buf(mtd, NULL, ecc->size);" line at line 1075 (after the patch) and
likewise the "chip->write_buf(mtd, buf + (i * ecc->size), ecc->size);" line at
line 1161. With these 2 lines removed the sunxi-nand-next branch from Boris,
rebased on 4.1-rc1 can write the nand boot parts and the brom / spl can load
the spl / resp. u-boot.bin from there (on a cubieboard2).
You're right... I did spot this, but assumed this was my own mistake in
merging these patches with our 4.0RC7 tree. Sorry, could have saved you
some trouble if I were sharper.
Post by Hans de Goede
I've also tried to get this code running on a cubieboard (non 2 so A10 rather then
A20), the SPL loads fine there (indicating that the kernel bits work), but then
U-Boot SPL 2015.07-rc1-00287-g050de86-dirty (May 25 2015 - 22:28:19)
DRAM: 1024 MiB
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
Nand initialised
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
...
Thanks for testing this. I don't own an A10 myself, so I haven't
observed this behaviour.
First thing I would verify personally is whether all the clocks are
properly configured. Could you make U-boot print &ccm->ahb_gate0 and
&ccm->nand0_clk_cfg? For the first, bits 6 (DMA) and 13 (NAND) must be
set, the second must have bit 31 set, bits 24 and 25 cleared (and
otherwise, the accompanying PLL must be configured too... probably
easier to use the OSC24M), and the divide ratios set to 0 (although a
small divider, like 1, shouldn't be a problem either).
I am assuming these values should be correct, but only because BROM
initialised part of it. I am aware of the fact that the SPL driver
doesn't control the DMA gating reg and the NAND post-dividers. It might
be a good idea to do so for as long as we don't have a full DMA driver,
so I'll patch that up today.

Roy
Post by Hans de Goede
Which seems to indicate a problem with the SPL nand code on the A10. I'll investigate
this further tomorrow evening.
A cleaned up version of my kernel work on this is available in my
sunxi-wip branch.
Regards,
Hans
--
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-26 14:52:07 UTC
Permalink
Hi,
Post by Roy Spliet
Hello Hans,
Re-sent to everybody instead of just you. Reply inline.
Post by Hans de Goede
Hi,
Post by Hans de Goede
Hi,
Post by Roy Spliet
Hello,
For my set-up I made use of Boris Brezillon's sunxi-nand tree[1], or actually I rebased his patches on top of 4.0rc7. This basically adds support for NAND-chip partitioning, ECC and randomisation. Docs for the DT specification in Documentation/devicetree/bindings/mtd/sunxi-nand.txt , and an example can be found in arch/arm/boot/dts/sun7i-a20-cubietruck.dts . [2] lists the acceptable configuration options for the boot and boot_rescue partitions, make sure to pick one of these (which should be no problem for MLC-type nand). The ECC mode for these boot partitions is called hw_syndrome.
1) in include/configs/sunxi-common.h, adjust the parameters <CONFIG_NAND_SUNXI_>PAGE_SIZE, ECC_STEP, ECC_STRENGTH to match your NAND chip and DT configuration.
2) Build
# flash_erase /dev/mtd0
# nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin
4) Reboot without the MMC card and see U-boot load
Ok, it took me way longer then I wanted (see below) but I've this
working now. It is cool to see u-boot load from nand :)
Post by Roy Spliet
That should be all.
@Alex: To answer your question specifically: It's likely that the parameters in sunxi-common.h mentioned above might not match your NAND-chip configuration in the Linux kernel. I can't tell you precisely how to fetch these details from the 3.4 kernel, sorry. I recall Daniel using 24-bit strength ECC with otherwise equal parameters, but perhaps he can help you with this better than I can.
Alex, could it be that you are writing the nand using
a (rebased) version of bbrezillon's sunxi-nand-next branch ?
I started with that too because it is much newer and contains
various bug fixes, but it seems that it also contains a new
bug causing it to write the NAND in such a way that the BROM
and u-boot SPL code will not read it.
I've just pushed a rebased version of the sunxi-nand branch of
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment
And that works for me, where as before I got the exact same errors
trying to fel load a nand enabled spl.
I'm working on merging over all the changes from the sunxi-nand-next
branch onto my working sunxi-nand-experiment branch 1 by 1 until
I find the one which causes the breakage...
https://github.com/bbrezillon/linux-sunxi/commit/7f7324bc6170a45742352070fb45170779a3611c
When it was rebased someone (Boris I guess) forgot to remove the
"chip->read_buf(mtd, NULL, ecc->size);" line at line 1075 (after the patch) and
likewise the "chip->write_buf(mtd, buf + (i * ecc->size), ecc->size);" line at
line 1161. With these 2 lines removed the sunxi-nand-next branch from Boris,
rebased on 4.1-rc1 can write the nand boot parts and the brom / spl can load
the spl / resp. u-boot.bin from there (on a cubieboard2).
You're right... I did spot this, but assumed this was my own mistake in merging these patches with our 4.0RC7 tree. Sorry, could have saved you some trouble if I were sharper.
Post by Hans de Goede
I've also tried to get this code running on a cubieboard (non 2 so A10 rather then
A20), the SPL loads fine there (indicating that the kernel bits work), but then
U-Boot SPL 2015.07-rc1-00287-g050de86-dirty (May 25 2015 - 22:28:19)
DRAM: 1024 MiB
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
Nand initialised
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
...
Thanks for testing this. I don't own an A10 myself, so I haven't observed this behaviour.
First thing I would verify personally is whether all the clocks are properly configured. Could you make U-boot print &ccm->ahb_gate0 and &ccm->nand0_clk_cfg? For the first, bits 6 (DMA) and 13 (NAND) must be set, the second must have bit 31 set, bits 24 and 25 cleared (and otherwise, the accompanying PLL must be configured too... probably easier to use the OSC24M), and the divide ratios set to 0 (although a small divider, like 1, shouldn't be a problem either).
I am assuming these values should be correct, but only because BROM initialised part of it. I am aware of the fact that the SPL driver doesn't control the DMA gating reg and the NAND post-dividers. It might be a good idea to do so for as long as we don't have a full DMA driver, so I'll patch that up today.
I've just tried the prelimary v4 of your patch-set from:
https://gitlab.com/turtle-solutions/u-boot/commits/sunxi-nand-wip

And the changes you've made fix these errors on the A10, good job.

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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Alexander Kaplan
2015-05-26 19:56:32 UTC
Permalink
Hi,

I tried both the kernel from
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment

and u-boot from
https://gitlab.com/turtle-solutions/u-boot/commits/sunxi-nand-wip

I can successfully compile and boot them on my A13-OLinuXino but there is
no NAND available. Neither in kernel log nor in the u-boot output there is
anything mentioned about NAND. I tried to enable all the NAND options,
especially the "Support for NAND on Allwinner SoCs" in nconfig but I'm
afraid I still have not found the right configuration.

Would it be possible to share the build configuration files?

Thanks in advance
Alex
Post by Hans de Goede
Hi,
Post by Roy Spliet
Hello Hans,
Re-sent to everybody instead of just you. Reply inline.
Post by Hans de Goede
Hi,
Post by Hans de Goede
Hi,
Post by Roy Spliet
Hello,
For my set-up I made use of Boris Brezillon's sunxi-nand tree[1], or
actually I rebased his patches on top of 4.0rc7. This basically adds
support for NAND-chip partitioning, ECC and randomisation. Docs for the DT
specification in Documentation/devicetree/bindings/mtd/sunxi-nand.txt , and
an example can be found in arch/arm/boot/dts/sun7i-a20-cubietruck.dts . [2]
lists the acceptable configuration options for the boot and boot_rescue
partitions, make sure to pick one of these (which should be no problem for
MLC-type nand). The ECC mode for these boot partitions is called
hw_syndrome.
Assuming you now have a Linux set-up kernel based on this tree with
1) in include/configs/sunxi-common.h, adjust the parameters
<CONFIG_NAND_SUNXI_>PAGE_SIZE, ECC_STEP, ECC_STRENGTH to match your NAND
chip and DT configuration.
2) Build
# flash_erase /dev/mtd0
# nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin
4) Reboot without the MMC card and see U-boot load
Ok, it took me way longer then I wanted (see below) but I've this
working now. It is cool to see u-boot load from nand :)
Post by Roy Spliet
That should be all.
@Alex: To answer your question specifically: It's likely that the
parameters in sunxi-common.h mentioned above might not match your NAND-chip
configuration in the Linux kernel. I can't tell you precisely how to fetch
these details from the 3.4 kernel, sorry. I recall Daniel using 24-bit
strength ECC with otherwise equal parameters, but perhaps he can help you
with this better than I can.
Alex, could it be that you are writing the nand using
a (rebased) version of bbrezillon's sunxi-nand-next branch ?
I started with that too because it is much newer and contains
various bug fixes, but it seems that it also contains a new
bug causing it to write the NAND in such a way that the BROM
and u-boot SPL code will not read it.
I've just pushed a rebased version of the sunxi-nand branch of
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment
And that works for me, where as before I got the exact same errors
trying to fel load a nand enabled spl.
I'm working on merging over all the changes from the sunxi-nand-next
branch onto my working sunxi-nand-experiment branch 1 by 1 until
I find the one which causes the breakage...
https://github.com/bbrezillon/linux-sunxi/commit/7f7324bc6170a45742352070fb45170779a3611c
When it was rebased someone (Boris I guess) forgot to remove the
"chip->read_buf(mtd, NULL, ecc->size);" line at line 1075 (after the patch) and
likewise the "chip->write_buf(mtd, buf + (i * ecc->size), ecc->size);" line at
line 1161. With these 2 lines removed the sunxi-nand-next branch from Boris,
rebased on 4.1-rc1 can write the nand boot parts and the brom / spl can load
the spl / resp. u-boot.bin from there (on a cubieboard2).
You're right... I did spot this, but assumed this was my own mistake in
merging these patches with our 4.0RC7 tree. Sorry, could have saved you
some trouble if I were sharper.
Post by Hans de Goede
I've also tried to get this code running on a cubieboard (non 2 so A10 rather then
A20), the SPL loads fine there (indicating that the kernel bits work), but then
U-Boot SPL 2015.07-rc1-00287-g050de86-dirty (May 25 2015 - 22:28:19)
DRAM: 1024 MiB
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
Nand initialised
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
...
Thanks for testing this. I don't own an A10 myself, so I haven't observed this behaviour.
First thing I would verify personally is whether all the clocks are
properly configured. Could you make U-boot print &ccm->ahb_gate0 and
&ccm->nand0_clk_cfg? For the first, bits 6 (DMA) and 13 (NAND) must be set,
the second must have bit 31 set, bits 24 and 25 cleared (and otherwise, the
accompanying PLL must be configured too... probably easier to use the
OSC24M), and the divide ratios set to 0 (although a small divider, like 1,
shouldn't be a problem either).
I am assuming these values should be correct, but only because BROM
initialised part of it. I am aware of the fact that the SPL driver doesn't
control the DMA gating reg and the NAND post-dividers. It might be a good
idea to do so for as long as we don't have a full DMA driver, so I'll patch
that up today.
https://gitlab.com/turtle-solutions/u-boot/commits/sunxi-nand-wip
And the changes you've made fix these errors on the A10, good job.
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-26 20:20:22 UTC
Permalink
Hi Alexander,
Post by Alexander Kaplan
Hi,
I tried both the kernel from
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment
and u-boot from
https://gitlab.com/turtle-solutions/u-boot/commits/sunxi-nand-wip
I can successfully compile and boot them on my A13-OLinuXino but there is no NAND available. Neither in kernel log nor in the u-boot output there is anything mentioned about NAND. I tried to enable all the NAND options, especially the "Support for NAND on Allwinner SoCs" in nconfig but I'm afraid I still have not found the right configuration.
Would it be possible to share the build configuration files?
I've just finished adding (partial) support for the A13-OLinuxino nand to my sunxi-wip kernel branch,
and just pushed the result mere seconds ago.

I'm using the attached kernel .config file.

Note I've just also joined irc I'm hansg on #linux-sunxi @freenode so we can discuss this in
realtime if you want.

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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Daniel Kochmański
2015-05-26 20:06:00 UTC
Permalink
Hello Alexander,

you have to put correct nand configuration in devicetree in
arch/arm/boot/dts/sun5i-a13-olinuxino.dts of your board. For comparision
you may check sun7i-a20-cubieboard2.dts which has appropriate
definitions. sunxi-nand-wip branch works on a20.

Good luck!
Daniel
Post by Alexander Kaplan
Hi,
I tried both the kernel from
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment
and u-boot from
https://gitlab.com/turtle-solutions/u-boot/commits/sunxi-nand-wip
I can successfully compile and boot them on my A13-OLinuXino but there is
no NAND available. Neither in kernel log nor in the u-boot output there is
anything mentioned about NAND. I tried to enable all the NAND options,
especially the "Support for NAND on Allwinner SoCs" in nconfig but I'm
afraid I still have not found the right configuration.
Would it be possible to share the build configuration files?
Thanks in advance
Alex
Post by Hans de Goede
Hi,
Post by Roy Spliet
Hello Hans,
Re-sent to everybody instead of just you. Reply inline.
Post by Hans de Goede
Hi,
Post by Hans de Goede
Hi,
Post by Roy Spliet
Hello,
For my set-up I made use of Boris Brezillon's sunxi-nand tree[1], or
actually I rebased his patches on top of 4.0rc7. This basically adds
support for NAND-chip partitioning, ECC and randomisation. Docs for the DT
specification in Documentation/devicetree/bindings/mtd/sunxi-nand.txt , and
an example can be found in arch/arm/boot/dts/sun7i-a20-cubietruck.dts . [2]
lists the acceptable configuration options for the boot and boot_rescue
partitions, make sure to pick one of these (which should be no problem for
MLC-type nand). The ECC mode for these boot partitions is called
hw_syndrome.
Assuming you now have a Linux set-up kernel based on this tree with
1) in include/configs/sunxi-common.h, adjust the parameters
<CONFIG_NAND_SUNXI_>PAGE_SIZE, ECC_STEP, ECC_STRENGTH to match your NAND
chip and DT configuration.
2) Build
# flash_erase /dev/mtd0
# nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin
4) Reboot without the MMC card and see U-boot load
Ok, it took me way longer then I wanted (see below) but I've this
working now. It is cool to see u-boot load from nand :)
Post by Roy Spliet
That should be all.
@Alex: To answer your question specifically: It's likely that the
parameters in sunxi-common.h mentioned above might not match your NAND-chip
configuration in the Linux kernel. I can't tell you precisely how to fetch
these details from the 3.4 kernel, sorry. I recall Daniel using 24-bit
strength ECC with otherwise equal parameters, but perhaps he can help you
with this better than I can.
Alex, could it be that you are writing the nand using
a (rebased) version of bbrezillon's sunxi-nand-next branch ?
I started with that too because it is much newer and contains
various bug fixes, but it seems that it also contains a new
bug causing it to write the NAND in such a way that the BROM
and u-boot SPL code will not read it.
I've just pushed a rebased version of the sunxi-nand branch of
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-nand-experiment
And that works for me, where as before I got the exact same errors
trying to fel load a nand enabled spl.
I'm working on merging over all the changes from the sunxi-nand-next
branch onto my working sunxi-nand-experiment branch 1 by 1 until
I find the one which causes the breakage...
https://github.com/bbrezillon/linux-sunxi/commit/7f7324bc6170a45742352070fb45170779a3611c
When it was rebased someone (Boris I guess) forgot to remove the
"chip->read_buf(mtd, NULL, ecc->size);" line at line 1075 (after the patch) and
likewise the "chip->write_buf(mtd, buf + (i * ecc->size), ecc->size);" line at
line 1161. With these 2 lines removed the sunxi-nand-next branch from Boris,
rebased on 4.1-rc1 can write the nand boot parts and the brom / spl can load
the spl / resp. u-boot.bin from there (on a cubieboard2).
You're right... I did spot this, but assumed this was my own mistake in
merging these patches with our 4.0RC7 tree. Sorry, could have saved you
some trouble if I were sharper.
Post by Hans de Goede
I've also tried to get this code running on a cubieboard (non 2 so A10 rather then
A20), the SPL loads fine there (indicating that the kernel bits work), but then
U-Boot SPL 2015.07-rc1-00287-g050de86-dirty (May 25 2015 - 22:28:19)
DRAM: 1024 MiB
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
Nand initialised
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
NAND timeout reading data
...
Thanks for testing this. I don't own an A10 myself, so I haven't observed
this behaviour.
First thing I would verify personally is whether all the clocks are
properly configured. Could you make U-boot print &ccm->ahb_gate0 and
&ccm->nand0_clk_cfg? For the first, bits 6 (DMA) and 13 (NAND) must be set,
the second must have bit 31 set, bits 24 and 25 cleared (and otherwise, the
accompanying PLL must be configured too... probably easier to use the
OSC24M), and the divide ratios set to 0 (although a small divider, like 1,
shouldn't be a problem either).
I am assuming these values should be correct, but only because BROM
initialised part of it. I am aware of the fact that the SPL driver doesn't
control the DMA gating reg and the NAND post-dividers. It might be a good
idea to do so for as long as we don't have a full DMA driver, so I'll patch
that up today.
https://gitlab.com/turtle-solutions/u-boot/commits/sunxi-nand-wip
And the changes you've made fix these errors on the A10, good job.
Regards,
Hans
--
Daniel Kochmański | Poznań, Poland
;; aka jackdaniel

"Be the change that you wish to see in the world." - Mahatma Gandhi
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Michal Suchanek
2015-05-22 07:38:53 UTC
Permalink
Post by Hans de Goede
Hi Roy,
Post by Roy Spliet
The following patches take the work by Daniel Kochmánski, and make some
heavy modifications for readability and functionality, based on Boris
Brezillon's Linux driver. Tested on an Olimex Lime w/ A20.
- Config options added are partially NAND-chip specific. Some options can
be autodetected based on the NAND ID, others require either brute-forcing
or config options like these. Do they belong in sunxi-common? Should
I did not look at the u-boot patches but on the kernel side this is
not completely solved I think.

AFAIK the BROM reads the nand in blocks and takes 1k from the start of
block and discards the rest regardless of block size. On the other
hand, the partition size in the DT is in bytes, not blocks. A person
soldered an uncommon nand chip on an Olinuxino board without nand and
the whole driver fell apart probably due to uncommon block size of the
chip.
Post by Hans de Goede
Post by Roy Spliet
we make a Kconfig option for this? If bikeshedding is desired, are defines
in sunxi-common.h good enough for now?
- Style is mostly kernel-like. Satisfied?
- Daniel: do you think we can work from here?
Please comment away!
Cool stuff. Overall this looks good I'll reply with more detailed feedback
1) Can you provide a quick howto (at developer level) on how to actually
get the spl and u-boot into the nand, what I'm looking for is unstructions
a) Take this git repo + branch, build a kernel from it
I have some extra nand patches here:
https://github.com/hramrach/linux-sunxi/commits/sunxi-nand-next

Unfortunately, this branch does not boot on a20 atm, at least from
mmc. I suspect I picked a few too many clock patches but have to
figure out what exactly breaks it.

However, you can cherry-pick

nand IDs
nand partitions on cubieboards
patch to ignore BBMs in case you have Allwinner formatted nand and it
appears 90%+ bad.

with the bbrezillion sunxi-nand-next and these you should be able to
access the cubieboard nand from Linux.
Post by Hans de Goede
b) Look at this dts file for a nand settings example, adjust it for your board
c) Once booted into the kernel using an updated dts you should have these
block devices, dd spl to this one, and u-boot to this one.
You will probably need mtd-utils mtd_debug/nandwrite/ubiformat/ubiattach/...

There are some tutorials on how to use these but I personally did not
try booting from nand so have no definitive answer what to write
where.

Thanks

Michal
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roy Spliet
2015-05-22 10:12:05 UTC
Permalink
Hello Hans,

Sorry for ignoring the second half of your question so far. Here's
what's on my mind.
Post by Hans de Goede
Hi Roy,
2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?
For the full U-boot I agree we want both MMC and NAND support,
regardless of where it was loaded from. From what I can tell U-boot
already has UBI support. It sounds like a logical step to try and
construct a proper NAND driver for U-boot that either co-exists with
this SPL driver or, even better, shares code. That way, I only assume
that the UBI and UBIFS layers will take care of all the rest.
The NAND framework in u-boot resembles Linux in many ways. I'm currently
in doubt whether we should take Boris' driver as a starting point, or
rather use something heavily reduced that re-uses this SPL code. Either
way, in U-boot we can perform a clean NAND-chip detection, preferably
based on DT definitions as we also use on Linux, and take care of
everything proper like PLL settings and a bunch of parameters which are
now hard-coded or a configuration option in sunxi-common.h.

SPL is a different story. I don't know the exact size restriction, but
for A10 I've heard it might be as little as 30KB. Current SPL with my
patches and without MMC is already 23KiB. I personally think we can
reduce it slightly by taking out support for reading everything other
than the bootloader partition from SPL (so remove non-syndrome mode,
remove the random seeds table...), but it certainly doesn't leave any
room for the full NAND framework to do ID-based NAND chip detection.
I personally think it's acceptable if NAND-SPL does not have MMC support
and vice-versa. For NAND, SPL is only loaded when there is no
first-level bootloader found on the MMC, so I safely dare to assume
U-boot isn't there. MMCs are generally not so tiny that SPL fits but
U-boot doesn't.

Questions, comments?
Cheers,

Roy
Post by Hans de Goede
Regards,
Hans
--
IMAGINE IT >> MAKE IT

Meet us online at Twitter <http://twitter.com/ultimaker>, Facebook
<http://facebook.com/ultimaker>, Google+ <http://google.com/+Ultimaker>

www.ultimaker.com
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-22 13:51:14 UTC
Permalink
Hello Roy,
Post by Roy Spliet
Hello Hans,
Sorry for ignoring the second half of your question so far. Here's what's on my mind.
Post by Hans de Goede
Hi Roy,
2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?
For the full U-boot I agree we want both MMC and NAND support, regardless of where it was loaded from. From what I can tell U-boot already has UBI support. It sounds like a logical step to try and construct a proper NAND driver for U-boot that either co-exists with this SPL driver or, even better, shares code. That way, I only assume that the UBI and UBIFS layers will take care of all the rest.
Ack.
Post by Roy Spliet
The NAND framework in u-boot resembles Linux in many ways. I'm currently in doubt whether we should take Boris' driver as a starting point, or rather use something heavily reduced that re-uses this SPL code. Either way, in U-boot we can perform a clean NAND-chip detection, preferably based on DT definitions as we also use on Linux, and take care of everything proper like PLL settings and a bunch of parameters which are now hard-coded or a configuration option in sunxi-common.h.
Have you seen Yassin Jaffer's work porting Boris' code to u-boot ?

https://github.com/yassinjaffer/u-boot/commits/sunxi-nand

Last time I mailed with Yassin (added to the Cc) he was ok with someone
else picking this up and continuing with it as the does not have time
to work on it.
Post by Roy Spliet
SPL is a different story. I don't know the exact size restriction, but for A10 I've heard it might be as little as 30KB.
Current SPL with my patches and without MMC is already 23KiB.
The BROM loads the SPL to a 32K sram and the stack sits in that same SRAM. Note
I've some patches which switch the SPL from using a fill blown malloc to using
simple-malloc.c which saves a significant amount of space, and the mmc code
is not really that big, so I think we should be able to cram this all into
the SPL.
Post by Roy Spliet
I personally think we can reduce it slightly by taking out support for reading everything other than the bootloader partition from SPL (so remove non-syndrome mode, remove the random seeds table...),
I agree that removing (#if 0 it for now?) non boot partition support makes
sense as a space saving measure.
Post by Roy Spliet
but it certainly doesn't leave any room for the full NAND framework to do ID-based NAND chip detection.
What info do we need when we're only reading ? If the BROM can get away with a fixed
way of reading the nand for booting, we should be able to make the SPL get
away with it too ... I do really believe that we should be able to deal
with different nand chips from a single binaries, with cheap chinese
devices like the mk802 the chances are simply to big that the nand
will differ from one revision to the next.
Post by Roy Spliet
I personally think it's acceptable if NAND-SPL does not have MMC support and vice-versa.
Distros already need to build and distribute a u-boot-with-spl.bin per supported
board. This doubles the number of builds they have to do and the number of
files they need to distribute. If at all possible I would really like
to have a unified SPL binary.
Post by Roy Spliet
For NAND, SPL is only loaded when there is no first-level bootloader found on the MMC, so I safely dare to assume U-boot isn't there. MMCs are generally not so tiny that SPL fits but U-boot doesn't.
Right, this is mostly for distro / end-user convenience (and also to
avoid needing to build all boards twice when preparing a pull-req).

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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-25 07:20:25 UTC
Permalink
Hi Roy,

It seems you've accidentally dropped the mailinglist
from the Cc (I don't see anything private in here),
so I've readded it.
Post by Roy Spliet
Hello Hans,
Comments inline.
Post by Hans de Goede
Hello Roy,
Post by Roy Spliet
Hello Hans,
Sorry for ignoring the second half of your question so far. Here's what's on my mind.
Post by Hans de Goede
Hi Roy,
2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?
For the full U-boot I agree we want both MMC and NAND support, regardless of where it was loaded from. From what I can tell U-boot already has UBI support. It sounds like a logical step to try and construct a proper NAND driver for U-boot that either co-exists with this SPL driver or, even better, shares code. That way, I only assume that the UBI and UBIFS layers will take care of all the rest.
Ack.
Post by Roy Spliet
The NAND framework in u-boot resembles Linux in many ways. I'm currently in doubt whether we should take Boris' driver as a starting point, or rather use something heavily reduced that re-uses this SPL code. Either way, in U-boot we can perform a clean NAND-chip detection, preferably based on DT definitions as we also use on Linux, and take care of everything proper like PLL settings and a bunch of parameters which are now hard-coded or a configuration option in sunxi-common.h.
Have you seen Yassin Jaffer's work porting Boris' code to u-boot ?
https://github.com/yassinjaffer/u-boot/commits/sunxi-nand
Last time I mailed with Yassin (added to the Cc) he was ok with someone
else picking this up and continuing with it as the does not have time
to work on it.
I have seen the pointer to it, but I have the "nasty" habit of preferring to look at simple work rather than complex. Hence I ended up with leveraging Daniel's patches. Considering space limitations, perhaps it would be best if this SPL driver co-exists with a full NAND driver.
Yes I think that given the space limitations that will be the way to go.
Post by Roy Spliet
Even if that means sacrificing code-sharing...?
Yes, as much as I dislike that I think dragging the entire mtd work into
the SPL simply is not going to fly.
Post by Roy Spliet
I might have to get back to you on this once I understand the level of code sharing between the NAND framework for SPL and for U-boot.
Ok.
Post by Roy Spliet
If I were to pick up from Yassin's tree: are there strong reasons why this work hasn't been merged already?
Not that I can remember, the main problem was lack of time from both the
reviewer and submitter side IIRC. ATM I'm quite interested in getting
nand working, so the reviewer side should be covered and I've the
feeling the same goes for the submitter side, so we should be able
to make good progress here.
Post by Roy Spliet
Post by Hans de Goede
Post by Roy Spliet
SPL is a different story. I don't know the exact size restriction, but for A10 I've heard it might be as little as 30KB.
Current SPL with my patches and without MMC is already 23KiB.
The BROM loads the SPL to a 32K sram and the stack sits in that same SRAM. Note
I've some patches which switch the SPL from using a fill blown malloc to using
simple-malloc.c which saves a significant amount of space, and the mmc code
is not really that big, so I think we should be able to cram this all into
the SPL.
That sounds like a good plan, it's good enough for SPL.
Post by Hans de Goede
Post by Roy Spliet
I personally think we can reduce it slightly by taking out support for reading everything other than the bootloader partition from SPL (so remove non-syndrome mode, remove the random seeds table...),
I agree that removing (#if 0 it for now?) non boot partition support makes
sense as a space saving measure.
Post by Roy Spliet
but it certainly doesn't leave any room for the full NAND framework to do ID-based NAND chip detection.
What info do we need when we're only reading ? If the BROM can get away with a fixed
way of reading the nand for booting, we should be able to make the SPL get
away with it too ... I do really believe that we should be able to deal
with different nand chips from a single binaries, with cheap chinese
devices like the mk802 the chances are simply to big that the nand
will differ from one revision to the next.
If we look solely at functionality I agree. It doesn't even make sense giving SPL broader support than BROM. The technical half of me is complaining about their approach though, because as it stands it does not allow booting from <4GB SLC NAND chips. The parameters they try simply don't match what these chips have to offer in terms of page size and OOB area.
I do not think that support things which the BROM does not support makes
sense for the FEL code. OTOH no need to cripple it explicitly if the
same code can support more.

For the full u-boot.bin nand driver supporting more then the BROM does
is fine.
Post by Roy Spliet
Maybe I should try and add an ID read function to at least obtain the page size and access method, this doesn't have to be a lot of code...
I've been looking into this on the kernel side so as to get ecc strength / size
from the id rather then having to extend the in kernel fixed id table as was done
for the cubietruck. I've this working now for samsung nands, but it is not simple
as it differs per vendor and generation of nands, You're free to try and solve
this anyway you want but getting info from the id may be harder then you think.
Post by Roy Spliet
I don't think it's wise to re-use the code in the full NAND framework though because it's simply too elaborate and integrated. We don't care about things like vendor strings in SPL, right?
Right, strings are way too expensive for in the SPL.
Post by Roy Spliet
Are there SPL helper functions to parse a chip ID into some of its parameters (page size, oob size, preferred ECC strength...)?
I'm not familiar with the u-boot (spl) nand code, maybe someone on the list
reading along knows, if not try searching for them in include/* ?
Post by Roy Spliet
Post by Hans de Goede
Post by Roy Spliet
I personally think it's acceptable if NAND-SPL does not have MMC support and vice-versa.
Distros already need to build and distribute a u-boot-with-spl.bin per supported
board. This doubles the number of builds they have to do and the number of
files they need to distribute. If at all possible I would really like
to have a unified SPL binary.
Granted. In this case I take it we should try and prioritise MMC0 over NAND always, matching BROM A10/A20s decisions. Agreed?
Agreed.
Post by Roy Spliet
Regarding MMC2... I'm not sure if we want a binary that supports both MMC2 and NAND given they share a set of pins.
Right some configs will automatically detect whether we are booting from MMC0 or NAND,
and others if we're booting from MMC0 or MMC2, I was just pointing to the existing
MMC0 / MMC2 decision code as an example of how this can be done.
Post by Roy Spliet
I don't know how well switching between the two is going to play out.
No need to worry about that, that is not something which we want to support.
Post by Roy Spliet
I'll see if I can free up some time to do this in a follow-up patch, although I hope it's not a blocker for the patches I sent to the ML last Friday.
As I already indicated in reply to your v1 series posting this is not a blocker.

BTW why is v2 an RFC and not simply a v2 of the series?

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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hans de Goede
2015-05-25 10:10:50 UTC
Permalink
Hi,
Post by Roy Spliet
Hello,
sorry for delay. Comments inline.
Post by Hans de Goede
Hi Roy,
It seems you've accidentally dropped the mailinglist
from the Cc (I don't see anything private in here),
so I've readded it.
Post by Roy Spliet
Hello Hans,
Comments inline.
Post by Hans de Goede
Hello Roy,
Post by Roy Spliet
Hello Hans,
Sorry for ignoring the second half of your question so far. Here's what's on my mind.
Post by Hans de Goede
Hi Roy,
2) What is the plan to add support for loading files from nand in u-boot proper,
so that we can get (e.g.) extlinux.conf + kernel +dtb from a /boot on nand ?
For the full U-boot I agree we want both MMC and NAND support, regardless of where it was loaded from. From what I can tell U-boot already has UBI support. It sounds like a logical step to try and construct a proper NAND driver for U-boot that either co-exists with this SPL driver or, even better, shares code. That way, I only assume that the UBI and UBIFS layers will take care of all the rest.
Ack.
Post by Roy Spliet
The NAND framework in u-boot resembles Linux in many ways. I'm currently in doubt whether we should take Boris' driver as a starting point, or rather use something heavily reduced that re-uses this SPL code. Either way, in U-boot we can perform a clean NAND-chip detection, preferably based on DT definitions as we also use on Linux, and take care of everything proper like PLL settings and a bunch of parameters which are now hard-coded or a configuration option in sunxi-common.h.
Have you seen Yassin Jaffer's work porting Boris' code to u-boot ?
https://github.com/yassinjaffer/u-boot/commits/sunxi-nand
Last time I mailed with Yassin (added to the Cc) he was ok with someone
else picking this up and continuing with it as the does not have time
to work on it.
I have seen the pointer to it, but I have the "nasty" habit of preferring to look at simple work rather than complex. Hence I ended up with leveraging Daniel's patches. Considering space limitations, perhaps it would be best if this SPL driver co-exists with a full NAND driver.
Yes I think that given the space limitations that will be the way to go.
Post by Roy Spliet
Even if that means sacrificing code-sharing...?
Yes, as much as I dislike that I think dragging the entire mtd work into
the SPL simply is not going to fly.
Post by Roy Spliet
I might have to get back to you on this once I understand the level of code sharing between the NAND framework for SPL and for U-boot.
Ok.
Post by Roy Spliet
If I were to pick up from Yassin's tree: are there strong reasons why this work hasn't been merged already?
Not that I can remember, the main problem was lack of time from both the
reviewer and submitter side IIRC. ATM I'm quite interested in getting
nand working, so the reviewer side should be covered and I've the
feeling the same goes for the submitter side, so we should be able
to make good progress here.
Post by Roy Spliet
Post by Hans de Goede
Post by Roy Spliet
SPL is a different story. I don't know the exact size restriction, but for A10 I've heard it might be as little as 30KB.
Current SPL with my patches and without MMC is already 23KiB.
The BROM loads the SPL to a 32K sram and the stack sits in that same SRAM. Note
I've some patches which switch the SPL from using a fill blown malloc to using
simple-malloc.c which saves a significant amount of space, and the mmc code
is not really that big, so I think we should be able to cram this all into
the SPL.
That sounds like a good plan, it's good enough for SPL.
Post by Hans de Goede
Post by Roy Spliet
I personally think we can reduce it slightly by taking out support for reading everything other than the bootloader partition from SPL (so remove non-syndrome mode, remove the random seeds table...),
I agree that removing (#if 0 it for now?) non boot partition support makes
sense as a space saving measure.
That would disable possibility of preloading multiimage with packed boot
script, kernel and devicetree, right? I think code which adds support
for all partitions isn't that big. Or maybe rather loading anything else
then u-boot from u-boot is undesirable?
I guess you mean "loading anything else then u-boot from the spl is undesirable?"

So what you're talking about using a multi-image directly from the SPL, is
basically what is falcon mode, and given the restrictions we've in the SPL
I do not think that supporting something like that for nand is a good idea,
in order to access the non boot partitions we need to know some more
nand parameters, and as said I would really like to avoid coding things
like ecc size into Kconfig since different production runs of the same board
(e.g. the famous mk802 boards) may very well use different nand chips,
and I do not want users to need know which production run they exactly have ...

This means we need to get info like this from the nand id, and I'm not sure
that that is doable from the spl.

So for starters I suggest we simply #if 0 the code, with a comment that this
maybe useful for falcon mode, and then it the future we may replace the
#if 0 with a #if falcon and enable this on select boards ?
Post by Roy Spliet
Post by Hans de Goede
Post by Roy Spliet
Post by Hans de Goede
Post by Roy Spliet
but it certainly doesn't leave any room for the full NAND framework to do ID-based NAND chip detection.
What info do we need when we're only reading ? If the BROM can get away with a fixed
way of reading the nand for booting, we should be able to make the SPL get
away with it too ... I do really believe that we should be able to deal
with different nand chips from a single binaries, with cheap chinese
devices like the mk802 the chances are simply to big that the nand
will differ from one revision to the next.
If we look solely at functionality I agree. It doesn't even make sense giving SPL broader support than BROM. The technical half of me is complaining about their approach though, because as it stands it does not allow booting from <4GB SLC NAND chips. The parameters they try simply don't match what these chips have to offer in terms of page size and OOB area.
I do not think that support things which the BROM does not support makes
sense for the FEL code. OTOH no need to cripple it explicitly if the
same code can support more.
For the full u-boot.bin nand driver supporting more then the BROM does
is fine.
Post by Roy Spliet
Maybe I should try and add an ID read function to at least obtain the page size and access method, this doesn't have to be a lot of code...
I've been looking into this on the kernel side so as to get ecc strength / size
from the id rather then having to extend the in kernel fixed id table as was done
for the cubietruck. I've this working now for samsung nands, but it is not simple
as it differs per vendor and generation of nands, You're free to try and solve
this anyway you want but getting info from the id may be harder then you think.
Post by Roy Spliet
I don't think it's wise to re-use the code in the full NAND framework though because it's simply too elaborate and integrated. We don't care about things like vendor strings in SPL, right?
Right, strings are way too expensive for in the SPL.
Post by Roy Spliet
Are there SPL helper functions to parse a chip ID into some of its parameters (page size, oob size, preferred ECC strength...)?
I'm not familiar with the u-boot (spl) nand code, maybe someone on the list
reading along knows, if not try searching for them in include/* ?
Post by Roy Spliet
Post by Hans de Goede
Post by Roy Spliet
I personally think it's acceptable if NAND-SPL does not have MMC support and vice-versa.
Distros already need to build and distribute a u-boot-with-spl.bin per supported
board. This doubles the number of builds they have to do and the number of
files they need to distribute. If at all possible I would really like
to have a unified SPL binary.
Granted. In this case I take it we should try and prioritise MMC0 over NAND always, matching BROM A10/A20s decisions. Agreed?
Agreed.
Unified binary would be great. I'll check this week if I can boot spl
with MMC support (as I mentioned, it was hanging due to some hairy
initialization error) and try to fix this.
Ack.
Post by Roy Spliet
Post by Hans de Goede
Post by Roy Spliet
Regarding MMC2... I'm not sure if we want a binary that supports both MMC2 and NAND given they share a set of pins.
Right some configs will automatically detect whether we are booting from MMC0 or NAND,
and others if we're booting from MMC0 or MMC2, I was just pointing to the existing
MMC0 / MMC2 decision code as an example of how this can be done.
Post by Roy Spliet
I don't know how well switching between the two is going to play out.
No need to worry about that, that is not something which we want to support.
Post by Roy Spliet
I'll see if I can free up some time to do this in a follow-up patch, although I hope it's not a blocker for the patches I sent to the ML last Friday.
As I already indicated in reply to your v1 series posting this is not a blocker.
BTW why is v2 an RFC and not simply a v2 of the series?
About this, I've just read the cover letters to what is exactly v3 of the series,
and it is in there, so Roy, no need to answer this one.

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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Henrik Nordström
2015-05-27 20:19:35 UTC
Permalink
Post by Hans de Goede
What info do we need when we're only reading ? If the BROM can get away with a fixed
way of reading the nand for booting, we should be able to make the SPL get
away with it too ...
BROM tries at least 4 different strategies in reading the NAND boot
blocks. Two different NAND protocol strategies and two different format
strategies have been observed (4 different access patterns). And ontop
of this it tries both randomizer scrambled and plain access.
Post by Hans de Goede
Distros already need to build and distribute a u-boot-with-spl.bin per supported
board. This doubles the number of builds they have to do and the number of
files they need to distribute. If at all possible I would really like
to have a unified SPL binary.
The SPL shrinks considerably in size if built in thumbs mode.

What I envisioned for sunix u-boot SPL was board-agnostic SPL binaries
with a little configuration header. This way you only need two (or three
is SPI is added) binaries, a list of board configurations and tool for
applying the config and write the resulting binary to the boot device
(NAND/MMC/SPI)

There isn't really that many board specific parameters.

Regards
Henrik
--
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 linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...