Skip to contentSkip to conversation

nand: sunxi: Add SPL support for booting from NAND.

PATCH New Daniel Kochmański 6 participants 26 messages Apr 29, 2015 – May 18, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover nand: sunxi: Add SPL support for booting from NAND.

This patchset adds minimal SPL driver for reading from A20 nand partitions utilizing DMA controller. It supports randomization and syndrome partitions.

Since BROM reads second syndrome partition, if first SPL checksum doesn't match, additional U-Boot offset may be provided to load backup U-boot from second block of second page.

To simplify loading many files (devicetree, kernel, sourcable boot script) additional parameter is added, which allows preloading multiboot image into memory directly from SPL.

Additionally conveniance function a20_nandread has been added, which utilizes SPL driver on normal U-Boot.

Best regards,
Daniel Kochma?ski

Daniel Kochma?ski (5):
nand: sunxi: change BLOCK_SIZE in mksunxiboot to match NAND block size
nand: sunxi: Add support for booting from internal NAND memory
nand: sunxi: Add secondary U-Boot offset on second syndrome partition
nand: sunxi: Add multiimage preload option
nand: sunxi: And a20_nandread command utilizing spl nand read driver

 README                           |  10 ++
 arch/arm/cpu/armv7/sunxi/board.c |  12 ++-
 board/sunxi/Kconfig              |  12 +++
 board/sunxi/Makefile             |   1 +
 board/sunxi/nand.c               | 219 +++++++++++++++++++++++++++++++++++++++
 common/Kconfig                   |   7 ++
 common/Makefile                  |   1 +
 common/cmd_a20_nandread.c        |  27 +++++
 common/spl/spl_nand.c            |  51 +++++++--
 include/configs/sunxi-common.h   |  12 +++
 tools/mksunxiboot.c              |   2 +-
 11 files changed, 344 insertions(+), 10 deletions(-)
 create mode 100644 board/sunxi/nand.c
 create mode 100644 common/cmd_a20_nandread.c
Signature · 1 line
2.3.6
#1 lore raw

PATCH 1/5 nand: sunxi: change BLOCK_SIZE in mksunxiboot to match NAND block size

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).

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 tools/mksunxiboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/mksunxiboot.c +1 -1
index 0035f6e..bef0c79 100644
@@ -65,7 +65,7 @@ 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
+#define BLOCK_SIZE 0x2000
 
 struct boot_img {
 	struct boot_file_head header;
Signature · 1 line
2.3.6
#2 lore raw

PATCH 1/5 nand: sunxi: change BLOCK_SIZE in mksunxiboot to match NAND block size

Quoted 3 lines · Daniel Kochma?ski

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).

I'm inferring here that for MMC boot this checksum is ignored by the BROM? If that is the case then I think it should be explicitly mentioned.

As well as the checksum this also changes the header's length field, FWIW.

Quoted 21 lines
Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 tools/mksunxiboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/mksunxiboot.c +1 -1
index 0035f6e..bef0c79 100644
@@ -65,7 +65,7 @@ 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
+#define BLOCK_SIZE 0x2000
 
 struct boot_img {
 	struct boot_file_head header;
#3 lore raw

PATCH 1/5 nand: sunxi: change BLOCK_SIZE in mksunxiboot to match NAND block size

Quoted 8 lines · Ian Campbell
Quoted 3 lines · Daniel Kochma?ski

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).

I'm inferring here that for MMC boot this checksum is ignored by the BROM? If that is the case then I think it should be explicitly mentioned.

It isn't ignored, just larger block is taken into checksum and put in header (which is read by BROM). I think, that in NAND case BROM just ignores length field in header, and calculates checksum for whole page (8KB), while on MMC it respects this field, hence 0x2000 works for both.

I've tried to put garbage into checksum field, and MMC doesn't boot if checksum isn't correct.

Quoted 4 lines

As well as the checksum this also changes the header's length field, FWIW.

Yes, this is true. Should I change it to set block size conditionally depending on defines - if it's SPL NAND boot, then use 0x2000, in other occasion use 0x200? Whole u-boot-sunxi-with-spl.bin size doesn't increase tough (probably because of space between spl and proper u-boot).

Quoted 22 lines
Quoted 22 lines
Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 tools/mksunxiboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/mksunxiboot.c +1 -1
index 0035f6e..bef0c79 100644
@@ -65,7 +65,7 @@ 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
+#define BLOCK_SIZE 0x2000
 
 struct boot_img {
 	struct boot_file_head header;
Signature · 4 lines
Daniel Kochma?ski | Pozna?, Poland
;; aka jackdaniel

"Be the change that you wish to see in the world." - Mahatma Gandhi
#4 lore raw

PATCH 1/5 nand: sunxi: change BLOCK_SIZE in mksunxiboot to match NAND block size

Quoted 11 lines · Daniel Kochma?ski
Quoted 8 lines · Ian Campbell
Quoted 3 lines · Daniel Kochma?ski

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).

I'm inferring here that for MMC boot this checksum is ignored by the BROM? If that is the case then I think it should be explicitly mentioned.

Quoted 5 lines

It isn't ignored, just larger block is taken into checksum and put in header (which is read by BROM). I think, that in NAND case BROM just ignores length field in header, and calculates checksum for whole page (8KB), while on MMC it respects this field, hence 0x2000 works for both.

OK, please add an explanation along these lines to the commit message.

Quoted 10 lines

I've tried to put garbage into checksum field, and MMC doesn't boot if checksum isn't correct.

Quoted 4 lines

As well as the checksum this also changes the header's length field, FWIW.

Yes, this is true. Should I change it to set block size conditionally depending on defines - if it's SPL NAND boot, then use 0x2000, in other occasion use 0x200?

I don't think that is necessary assuming...

Quoted 3 lines

Whole u-boot-sunxi-with-spl.bin size doesn't
increase tough (probably because of space between spl and proper u-boot).

... this is actually the case, then you could just say it in the commit log.

#5 lore raw

PATCH 2/5 nand: sunxi: Add support for booting from internal NAND memory

In reply to Daniel Kochmański

Adds minimal DMA NAND driver for booting from NAND internal memory. New config option SPL_NAND_SUPPORT is created for sunxi board, which enables introduced driver and sets ENV_IS_NOWHERE (instead of ENV_IS_IN_MMC).

NAND driver utilizes DMA interface to flash controller, which supports randomization. Reading from both syndrome and non-syndrom partitions is supported. Writing to flash isn't implemented for time being.

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 arch/arm/cpu/armv7/sunxi/board.c |  12 ++-
 board/sunxi/Kconfig              |  12 +++
 board/sunxi/Makefile             |   1 +
 board/sunxi/nand.c               | 219 +++++++++++++++++++++++++++++++++++++++
 common/spl/spl_nand.c            |  13 +--
 include/configs/sunxi-common.h   |   9 ++
 6 files changed, 258 insertions(+), 8 deletions(-)
 create mode 100644 board/sunxi/nand.c
arch/arm/cpu/armv7/sunxi/board.c +10 -2
index c1b4cf5..ba81557 100644
@@ -112,8 +112,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)
 {
@@ -123,6 +125,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
board/sunxi/Kconfig +12 -0
index 88e3358..1a30684 100644
@@ -239,6 +239,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 ""
board/sunxi/Makefile +1 -0
index 43766e0..7ad7412 100644
@@ -9,6 +9,7 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 obj-y	+= board.o
+obj-$(CONFIG_NAND_SUNXI)	+= nand.o
 obj-$(CONFIG_SUNXI_GMAC)	+= gmac.o
 obj-$(CONFIG_SUNXI_AHCI)	+= ahci.o
 obj-$(CONFIG_MACH_SUN4I)	+= dram_sun4i_auto.o
board/sunxi/nand.c new file +219 -0

219 lines not on this page · raw message

common/spl/spl_nand.c +7 -6
index b8c369d..9d59fbb 100644
@@ -74,24 +74,25 @@ void spl_nand_load_image(void)
 #endif
 #ifdef CONFIG_NAND_ENV_DST
 	nand_spl_load_image(CONFIG_ENV_OFFSET,
-		sizeof(*header), (void *)header);
+			    sizeof(*header), (void *)header);
 	spl_parse_image_header(header);
 	nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
-		(void *)spl_image.load_addr);
+			    (void *)spl_image.load_addr);
 #ifdef CONFIG_ENV_OFFSET_REDUND
 	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
-		sizeof(*header), (void *)header);
+			    sizeof(*header), (void *)header);
 	spl_parse_image_header(header);
 	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
-		(void *)spl_image.load_addr);
+			    (void *)spl_image.load_addr);
 #endif
 #endif
 	/* Load u-boot */
 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-		sizeof(*header), (void *)header);
+			    sizeof(*header), (void *)header);
 	spl_parse_image_header(header);
 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-		spl_image.size, (void *)(unsigned long)spl_image.load_addr);
+			    spl_image.size,
+			    (void *)(unsigned long)spl_image.load_addr);
 	nand_deselect();
 }
 #endif
include/configs/sunxi-common.h +9 -0
index 365d9a5..b40cdd3 100644
@@ -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 */
@@ -323,6 +325,13 @@ extern int soft_i2c_gpio_scl;
 #define CONFIG_ENV_IS_NOWHERE
 #endif
 
+#ifdef CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_NAND
+#define CONFIG_NAND_SUNXI
+#define CONFIG_CMD_SPL_WRITE_SIZE		0x000400
+#define CONFIG_SYS_NAND_U_BOOT_OFFS		0x008000
+#endif /* CONFIG_SPL_NAND_SUPPORT */
+
 #define CONFIG_MISC_INIT_R
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
 
Signature · 1 line
2.3.6
#6 lore raw

PATCH 2/5 nand: sunxi: Add support for booting from internal NAND memory

Quoted 9 lines · Daniel Kochma?ski
board/sunxi/Kconfig +1 -0
index 88e3358..1a30684 100644
@@ -239,6 +239,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

board/sunxi/Kconfig config MMC_SUNXI_SLOT_EXTRA · line 252

Quoted 10 lines
board/sunxi/Kconfig +10 -0
+	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.

Is this last bit a bug in the s/w or a hardware thing? Does this mean that MMC is not available in the main u-boot image too when NAND support is enabled?

board/sunxi/Makefile line 12

Quoted 13 lines
board/sunxi/Kconfig +1 -0
+
 config USB0_VBUS_PIN
 	string "Vbus enable pin for usb0 (otg)"
 	default ""
board/sunxi/Makefile +1 -0
index 43766e0..7ad7412 100644
@@ -9,6 +9,7 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 obj-y	+= board.o
+obj-$(CONFIG_NAND_SUNXI)	+= nand.o

CONFIG_SUNXI_NAND would be more consistent with the rest I think.

board/sunxi/Makefile

Quoted 6 lines
board/sunxi/Makefile +3 -0
 obj-$(CONFIG_SUNXI_GMAC)	+= gmac.o
 obj-$(CONFIG_SUNXI_AHCI)	+= ahci.o
 
+void nand_set_clocks(void)
+{
+	W32(PORTC_BASE + 0x48, 0x22222222);

u-boot style is to declare a struct which matches the register layout and to do something like:

        struct nand_ctrl_foo *mcf = (void *)NANCFLASHC_BASE;

And use writel, set_bits, setclr_bits and friends.

Please also try and give sensible names to all the magic numbers, or at least include a comment explaining that these are magic numbers derived from $SOMEWHERE and we don't know what they mean (if that is the case).

Both of these apply to several bits of the code too.

Quoted 8 lines
board/sunxi/Makefile +8 -0
+	W32(PORTC_BASE + 0x4C, 0x22222222);
+	W32(PORTC_BASE + 0x50, 0x2222222);
+	W32(PORTC_BASE + 0x54, 0x2);
+	W32(PORTC_BASE + 0x5C, 0x55555555);
+	W32(PORTC_BASE + 0x60, 0x15555);
+	W32(PORTC_BASE + 0x64, 0x5140);
+	W32(PORTC_BASE + 0x68, 0x4016);
+

board/sunxi/Makefile

Quoted 10 lines
board/sunxi/Makefile +10 -0
+	uint32_t val = R32(CCMU_BASE + 0x60);
+	W32(CCMU_BASE + 0x60, 0x2000 | val);
+	val = R32(CCMU_BASE + 0x80);
+	W32(CCMU_BASE + 0x80, val | 0x80000000 | 0x1);
+}
+
+int initialized = 0;
+void nand_init(void)
+{
+	initialized = 1;

Please call this from somewhere during init e.g. board.c rather than from nand_read with a latch.

board/sunxi/Makefile

Quoted 10 lines
board/sunxi/Makefile +10 -0
+	uint32_t val;
+	nand_set_clocks();
+	val = R32(NANDFLASHC_BASE + 0x00);
+	/* CTL = (1<<0 <-EN    1<<1 RESET) */
+	W32(NANDFLASHC_BASE + 0x00, val | 0x3);	/* enable and reset CTL */
+	do {
+		val = R32(NANDFLASHC_BASE + 0x00);
+		if (val & (1<<1))
+			break;
+	} while (1);

Potentially infinite loop?

There were some similar instances below which had a t/o. Perhaps combine them all into a helper similar to the dram code's mctl_await_completion()?

board/sunxi/Makefile

Quoted 10 lines
board/sunxi/Makefile +10 -0
+uint32_t ecc_errors = 0;
+
+/* read 0x400 bytes from real_addr to temp_buf */
+void nand_read_block(unsigned int real_addr, int syndrome)
+{
+	uint32_t val;
+	if (!initialized)
+		nand_init();
+
+	memset((void *)temp_buf, 0, 0x400); /* clear temp_buf */

Can we not avoid going via this global temp_buf by setting DMAC_BASE + 0x308 to the correct address on each read?

Ian.

#7 lore raw

PATCH 2/5 nand: sunxi: Add support for booting from internal NAND memory

Quoted 9 lines · Ian Campbell
Quoted 8 lines · Daniel Kochma?ski
board/sunxi/Kconfig +0 -0
index 88e3358..1a30684 100644
@@ -239,6 +239,18 @@ config MMC_SUNXI_SLOT_EXTRA
 	slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
 	support for this.
 
Quoted 16 lines

board/sunxi/Kconfig config MMC_SUNXI_SLOT_EXTRA · line 252

Quoted 11 lines
board/sunxi/Kconfig +11 -0
+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.

Is this last bit a bug in the s/w or a hardware thing? Does this mean that MMC is not available in the main u-boot image too when NAND support is enabled?

I'm not sure what is a reason, but controller can't initialize MMC when SPL is loaded. MMC works in main u-boot allowing to boot from it and perform any other option (rescan, part, info, etc.). It is only SPL relevant.

Quoted 7 lines
Quoted 7 lines
board/sunxi/Kconfig +1 -0
+
 config USB0_VBUS_PIN
 	string "Vbus enable pin for usb0 (otg)"
 	default ""
board/sunxi/Makefile +0 -1
index 43766e0..7ad7412 100644
--- a/board/sunxi/Makefile
Quoted 9 lines

board/sunxi/Makefile line 12

Quoted 6 lines

+++ b/board/sunxi/Makefile

board/sunxi/Makefile +1 -0
@@ -9,6 +9,7 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 obj-y	+= board.o
+obj-$(CONFIG_NAND_SUNXI)	+= nand.o

CONFIG_SUNXI_NAND would be more consistent with the rest I think.

OK.

Quoted 9 lines

board/sunxi/Makefile

Quoted 6 lines
board/sunxi/Makefile +3 -0
 obj-$(CONFIG_SUNXI_GMAC)	+= gmac.o
 obj-$(CONFIG_SUNXI_AHCI)	+= ahci.o
 
+void nand_set_clocks(void)
+{
+	W32(PORTC_BASE + 0x48, 0x22222222);

u-boot style is to declare a struct which matches the register layout and to do something like:

Quoted 3 lines
        struct nand_ctrl_foo *mcf = (void *)NANCFLASHC_BASE;

And use writel, set_bits, setclr_bits and friends.

OK, I'll read about it and try to adjust driver.

Quoted 6 lines

Please also try and give sensible names to all the magic numbers, or at least include a comment explaining that these are magic numbers derived from $SOMEWHERE and we don't know what they mean (if that is the case).

Both of these apply to several bits of the code too.

This work is mainly based on register guess-work from here:
http://rhombus-tech.net/allwinner_a10/A10_register_guide/A10_NAND/ - so I can gather names from there and put them in source.

Quoted 14 lines
Quoted 14 lines
board/sunxi/Makefile +13 -0
+	W32(PORTC_BASE + 0x4C, 0x22222222);
+	W32(PORTC_BASE + 0x50, 0x2222222);
+	W32(PORTC_BASE + 0x54, 0x2);
+	W32(PORTC_BASE + 0x5C, 0x55555555);
+	W32(PORTC_BASE + 0x60, 0x15555);
+	W32(PORTC_BASE + 0x64, 0x5140);
+	W32(PORTC_BASE + 0x68, 0x4016);
+
+	uint32_t val = R32(CCMU_BASE + 0x60);
+	W32(CCMU_BASE + 0x60, 0x2000 | val);
+	val = R32(CCMU_BASE + 0x80);
+	W32(CCMU_BASE + 0x80, val | 0x80000000 | 0x1);
+}
Quoted 9 lines

board/sunxi/Makefile

Quoted 5 lines
board/sunxi/Makefile +5 -0
+
+int initialized = 0;
+void nand_init(void)
+{
+	initialized = 1;

Please call this from somewhere during init e.g. board.c rather than from nand_read with a latch.

Sure.

Quoted 13 lines

board/sunxi/Makefile

Quoted 10 lines
board/sunxi/Makefile +10 -0
+	uint32_t val;
+	nand_set_clocks();
+	val = R32(NANDFLASHC_BASE + 0x00);
+	/* CTL = (1<<0 <-EN    1<<1 RESET) */
+	W32(NANDFLASHC_BASE + 0x00, val | 0x3);	/* enable and reset CTL */
+	do {
+		val = R32(NANDFLASHC_BASE + 0x00);
+		if (val & (1<<1))
+			break;
+	} while (1);

Potentially infinite loop?

Quoted 4 lines

There were some similar instances below which had a t/o. Perhaps combine them all into a helper similar to the dram code's mctl_await_completion()?

Ok, I'll look into that.

Quoted 5 lines
Quoted 5 lines
board/sunxi/Makefile +5 -0
+uint32_t ecc_errors = 0;
+
+/* read 0x400 bytes from real_addr to temp_buf */
+void nand_read_block(unsigned int real_addr, int syndrome)
+{
Quoted 9 lines

board/sunxi/Makefile

Quoted 5 lines
board/sunxi/Makefile +5 -0
+	uint32_t val;
+	if (!initialized)
+		nand_init();
+
+	memset((void *)temp_buf, 0, 0x400); /* clear temp_buf */

Can we not avoid going via this global temp_buf by setting DMAC_BASE + 0x308 to the correct address on each read?

I'll check this, I think I had problems with that, but if it works w/o temp_buf on both SPL and main U-Boot builds, then I'll get rid of it.

Quoted 1 line

Ian.

Signature · 4 lines
Daniel Kochma?ski | Pozna?, Poland
;; aka jackdaniel

"Be the change that you wish to see in the world." - Mahatma Gandhi
#8 lore raw

PATCH 2/5 nand: sunxi: Add support for booting from internal NAND memory

In reply to Ian Campbell

(sorry for resending, used wrong mail here - not sure how mailing list will handle that).

Quoted 9 lines · Ian Campbell
Quoted 8 lines · Daniel Kochma?ski
board/sunxi/Kconfig +0 -0
index 88e3358..1a30684 100644
@@ -239,6 +239,18 @@ config MMC_SUNXI_SLOT_EXTRA
 	slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
 	support for this.
 
Quoted 16 lines

board/sunxi/Kconfig config MMC_SUNXI_SLOT_EXTRA · line 252

Quoted 11 lines
board/sunxi/Kconfig +11 -0
+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.

Is this last bit a bug in the s/w or a hardware thing? Does this mean that MMC is not available in the main u-boot image too when NAND support is enabled?

I'm not sure what is a reason, but controller can't initialize MMC when SPL is loaded. MMC works in main u-boot allowing to boot from it and perform any other option (rescan, part, info, etc.). It is only SPL relevant.

Quoted 7 lines
Quoted 7 lines
board/sunxi/Kconfig +1 -0
+
 config USB0_VBUS_PIN
 	string "Vbus enable pin for usb0 (otg)"
 	default ""
board/sunxi/Makefile +0 -1
index 43766e0..7ad7412 100644
--- a/board/sunxi/Makefile
Quoted 9 lines

board/sunxi/Makefile line 12

Quoted 6 lines

+++ b/board/sunxi/Makefile

board/sunxi/Makefile +1 -0
@@ -9,6 +9,7 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 obj-y	+= board.o
+obj-$(CONFIG_NAND_SUNXI)	+= nand.o

CONFIG_SUNXI_NAND would be more consistent with the rest I think.

OK.

Quoted 9 lines

board/sunxi/Makefile

Quoted 6 lines
board/sunxi/Makefile +3 -0
 obj-$(CONFIG_SUNXI_GMAC)	+= gmac.o
 obj-$(CONFIG_SUNXI_AHCI)	+= ahci.o
 
+void nand_set_clocks(void)
+{
+	W32(PORTC_BASE + 0x48, 0x22222222);

u-boot style is to declare a struct which matches the register layout and to do something like:

Quoted 3 lines
        struct nand_ctrl_foo *mcf = (void *)NANCFLASHC_BASE;

And use writel, set_bits, setclr_bits and friends.

OK, I'll read about it and try to adjust driver.

Quoted 6 lines

Please also try and give sensible names to all the magic numbers, or at least include a comment explaining that these are magic numbers derived from $SOMEWHERE and we don't know what they mean (if that is the case).

Both of these apply to several bits of the code too.

This work is mainly based on register guess-work from here:
http://rhombus-tech.net/allwinner_a10/A10_register_guide/A10_NAND/ - so I can gather names from there and put them in source.

Quoted 14 lines
Quoted 14 lines
board/sunxi/Makefile +13 -0
+	W32(PORTC_BASE + 0x4C, 0x22222222);
+	W32(PORTC_BASE + 0x50, 0x2222222);
+	W32(PORTC_BASE + 0x54, 0x2);
+	W32(PORTC_BASE + 0x5C, 0x55555555);
+	W32(PORTC_BASE + 0x60, 0x15555);
+	W32(PORTC_BASE + 0x64, 0x5140);
+	W32(PORTC_BASE + 0x68, 0x4016);
+
+	uint32_t val = R32(CCMU_BASE + 0x60);
+	W32(CCMU_BASE + 0x60, 0x2000 | val);
+	val = R32(CCMU_BASE + 0x80);
+	W32(CCMU_BASE + 0x80, val | 0x80000000 | 0x1);
+}
Quoted 9 lines

board/sunxi/Makefile

Quoted 5 lines
board/sunxi/Makefile +5 -0
+
+int initialized = 0;
+void nand_init(void)
+{
+	initialized = 1;

Please call this from somewhere during init e.g. board.c rather than from nand_read with a latch.

Sure.

Quoted 13 lines

board/sunxi/Makefile

Quoted 10 lines
board/sunxi/Makefile +10 -0
+	uint32_t val;
+	nand_set_clocks();
+	val = R32(NANDFLASHC_BASE + 0x00);
+	/* CTL = (1<<0 <-EN    1<<1 RESET) */
+	W32(NANDFLASHC_BASE + 0x00, val | 0x3);	/* enable and reset CTL */
+	do {
+		val = R32(NANDFLASHC_BASE + 0x00);
+		if (val & (1<<1))
+			break;
+	} while (1);

Potentially infinite loop?

Quoted 4 lines

There were some similar instances below which had a t/o. Perhaps combine them all into a helper similar to the dram code's mctl_await_completion()?

Ok, I'll look into that.

Quoted 5 lines
Quoted 5 lines
board/sunxi/Makefile +5 -0
+uint32_t ecc_errors = 0;
+
+/* read 0x400 bytes from real_addr to temp_buf */
+void nand_read_block(unsigned int real_addr, int syndrome)
+{
Quoted 9 lines

board/sunxi/Makefile

Quoted 5 lines
board/sunxi/Makefile +5 -0
+	uint32_t val;
+	if (!initialized)
+		nand_init();
+
+	memset((void *)temp_buf, 0, 0x400); /* clear temp_buf */

Can we not avoid going via this global temp_buf by setting DMAC_BASE + 0x308 to the correct address on each read?

I'll check this, I think I had problems with that, but if it works w/o temp_buf on both SPL and main U-Boot builds, then I'll get rid of it.

Quoted 1 line

Ian.

Signature · 4 lines
Daniel Kochma?ski | Pozna?, Poland
;; aka jackdaniel

"Be the change that you wish to see in the world." - Mahatma Gandhi
#9 lore raw

PATCH 2/5 nand: sunxi: Add support for booting from internal NAND memory

Quoted 31 lines · Daniel Kochma?ski

(sorry for resending, used wrong mail here - not sure how mailing list will handle that).

Quoted 9 lines · Ian Campbell
Quoted 8 lines · Daniel Kochma?ski
board/sunxi/Kconfig +0 -0
index 88e3358..1a30684 100644
@@ -239,6 +239,18 @@ config MMC_SUNXI_SLOT_EXTRA
 	slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
 	support for this.
 
Quoted 16 lines

board/sunxi/Kconfig config MMC_SUNXI_SLOT_EXTRA · line 252

Quoted 11 lines
board/sunxi/Kconfig +11 -0
+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.

Is this last bit a bug in the s/w or a hardware thing? Does this mean that MMC is not available in the main u-boot image too when NAND support is enabled?

Quoted 4 lines

I'm not sure what is a reason, but controller can't initialize MMC when SPL is loaded. MMC works in main u-boot allowing to boot from it and perform any other option (rescan, part, info, etc.). It is only SPL relevant.

How strange! Hans, do you have any ideas about why this might be the case? Is there some overlap between MMC and NAND? I can't think what...

#10 lore raw

PATCH 2/5 nand: sunxi: Add support for booting from internal NAND memory

Hi,

Quoted 32 lines · Ian Campbell
Quoted 31 lines · Daniel Kochma?ski

(sorry for resending, used wrong mail here - not sure how mailing list will handle that).

Quoted 25 lines · Ian Campbell
Quoted 9 lines · Daniel Kochma?ski
board/sunxi/Kconfig +1 -0
index 88e3358..1a30684 100644
@@ -239,6 +239,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

board/sunxi/Kconfig config MMC_SUNXI_SLOT_EXTRA · line 252

Quoted 10 lines
board/sunxi/Kconfig +10 -0
+	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.

Is this last bit a bug in the s/w or a hardware thing? Does this mean that MMC is not available in the main u-boot image too when NAND support is enabled?

Quoted 7 lines
Quoted 4 lines

I'm not sure what is a reason, but controller can't initialize MMC when SPL is loaded. MMC works in main u-boot allowing to boot from it and perform any other option (rescan, part, info, etc.). It is only SPL relevant.

How strange! Hans, do you have any ideas about why this might be the case? Is there some overlap between MMC and NAND? I can't think what...

Nope, I've no clue, things should work with both build-in, first thing which comes to mind is that we're running out of stack space / internal sram.

Second thing is, how did you test the SPL code with both build-in ? Did you boot from MMC or from NAND? It could be that the MMC code relies on some MMC setup done by the BROM, so that it will not work when booting from NAND.

Regards,

Hans

#11 lore raw

PATCH 2/5 nand: sunxi: Add support for booting from internal NAND memory

In reply to Daniel Kochmański
Quoted 14 lines · Daniel Kochma?ski

Adds minimal DMA NAND driver for booting from NAND internal memory. New config option SPL_NAND_SUPPORT is created for sunxi board, which enables introduced driver and sets ENV_IS_NOWHERE (instead of ENV_IS_IN_MMC).

NAND driver utilizes DMA interface to flash controller, which supports randomization. Reading from both syndrome and non-syndrom partitions is supported. Writing to flash isn't implemented for time being.

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

Quoted 8 lines
 arch/arm/cpu/armv7/sunxi/board.c |  12 ++-
 board/sunxi/Kconfig              |  12 +++
 board/sunxi/Makefile             |   1 +
 board/sunxi/nand.c               | 219 +++++++++++++++++++++++++++++++++++++++
 common/spl/spl_nand.c            |  13 +--
 include/configs/sunxi-common.h   |   9 ++
 6 files changed, 258 insertions(+), 8 deletions(-)
 create mode 100644 board/sunxi/nand.c

NAND drivers go in drivers/mtd/nand (with "spl" in the name since it's an SPL driver).

-Scott

#12 lore raw

PATCH 3/5 nand: sunxi: Add secondary U-Boot offset on second syndrome partition

In reply to Daniel Kochmański

Introduces CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS, pointing to backup U-Boot instance in nand memory. In case if first header doesn't match, tries to load bootloader from this offset. In case of both failing, hang() is called.

Additionally define offset of backup U-boot for sunxi at start of second syndrome partition.

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 README                         |  4 ++++
 common/spl/spl_nand.c          | 28 +++++++++++++++++++++++++---
 include/configs/sunxi-common.h |  1 +
 3 files changed, 30 insertions(+), 3 deletions(-)
README +4 -0
index ee65fdb..4ccf3cb 100644
@@ -3722,6 +3722,10 @@ FIT uImage format:
 		CONFIG_SYS_NAND_U_BOOT_OFFS
 		Location in NAND to read U-Boot from
 
+		CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS
+		Location in NAND to read backup U-Boot from, if first
+		location doesn't contain valid image.
+
 		CONFIG_SYS_NAND_U_BOOT_DST
 		Location in memory to load U-Boot to
 
common/spl/spl_nand.c +25 -3
index 9d59fbb..7c44de1 100644
@@ -2,6 +2,9 @@
  * Copyright (C) 2011
  * Corscience GmbH & Co. KG - Simon Schwarz <[email protected]>
  *
+ * Copyright (C) 2015
+ * Turtle Solutions - Daniel Kochma?ski <[email protected]>
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
@@ -90,9 +93,28 @@ void spl_nand_load_image(void)
 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
 			    sizeof(*header), (void *)header);
 	spl_parse_image_header(header);
-	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-			    spl_image.size,
-			    (void *)(unsigned long)spl_image.load_addr);
+	if (header->ih_os == IH_OS_U_BOOT) {
+		nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+				    spl_image.size,
+				    (void *)(unsigned long)spl_image.load_addr);
+		nand_deselect();
+		return;
+	}
+	puts("U-boot header didn't match.\n");
+#ifdef CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS
+	puts("Trying to start backup u-boot now...\n");
+	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,
+			    sizeof(*header), (void *)header);
+	spl_parse_image_header(header);
+	if (header->ih_os == IH_OS_U_BOOT) {
+		nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,
+				    spl_image.size,
+				    (void *)(unsigned long)spl_image.load_addr);
+		nand_deselect();
+		return;
+	}
+#endif
+	puts("No valid u-boot image found.\n");
 	nand_deselect();
 }
 #endif
include/configs/sunxi-common.h +1 -0
index b40cdd3..15fe512 100644
@@ -330,6 +330,7 @@ extern int soft_i2c_gpio_scl;
 #define CONFIG_NAND_SUNXI
 #define CONFIG_CMD_SPL_WRITE_SIZE		0x000400
 #define CONFIG_SYS_NAND_U_BOOT_OFFS		0x008000
+#define CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS	0x208000
 #endif /* CONFIG_SPL_NAND_SUPPORT */
 
 #define CONFIG_MISC_INIT_R
Signature · 1 line
2.3.6
#13 lore raw

PATCH 3/5 nand: sunxi: Add secondary U-Boot offset on second syndrome partition

Quoted 8 lines · Daniel Kochma?ski

Introduces CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS, pointing to backup U-Boot instance in nand memory. In case if first header doesn't match, tries to load bootloader from this offset. In case of both failing, hang() is called.

Additionally define offset of backup U-boot for sunxi at start of second syndrome partition.

Quoted 7 lines
Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 README                         |  4 ++++
 common/spl/spl_nand.c          | 28 +++++++++++++++++++++++++---

This needs an ack from the maintainer of this file rather than Hans or I.

Adding CC of Simon who is mentioned in the header plus some people who touched the file recently in the hopes of finding out who that is.

Ian.

#14 lore raw

PATCH 3/5 nand: sunxi: Add secondary U-Boot offset on second syndrome partition

In reply to Daniel Kochmański
Quoted 69 lines · Daniel Kochma?ski

Introduces CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS, pointing to backup U-Boot instance in nand memory. In case if first header doesn't match, tries to load bootloader from this offset. In case of both failing, hang() is called.

Additionally define offset of backup U-boot for sunxi at start of second syndrome partition.

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 README                         |  4 ++++
 common/spl/spl_nand.c          | 28 +++++++++++++++++++++++++---
 include/configs/sunxi-common.h |  1 +
 3 files changed, 30 insertions(+), 3 deletions(-)
README +4 -0
index ee65fdb..4ccf3cb 100644
@@ -3722,6 +3722,10 @@ FIT uImage format:
                CONFIG_SYS_NAND_U_BOOT_OFFS
                Location in NAND to read U-Boot from
 
+               CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS
+               Location in NAND to read backup U-Boot from, if first
+               location doesn't contain valid image.
+
                CONFIG_SYS_NAND_U_BOOT_DST
                Location in memory to load U-Boot to
 
common/spl/spl_nand.c +18 -3
index 9d59fbb..7c44de1 100644
@@ -2,6 +2,9 @@
  * Copyright (C) 2011
  * Corscience GmbH & Co. KG - Simon Schwarz <[email protected]>
  *
+ * Copyright (C) 2015
+ * Turtle Solutions - Daniel Kochma?ski <[email protected]>
+ *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
@@ -90,9 +93,28 @@ void spl_nand_load_image(void)
        nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
                            sizeof(*header), (void *)header);
        spl_parse_image_header(header);
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-                           spl_image.size,
-                           (void *)(unsigned long)spl_image.load_addr);
+       if (header->ih_os == IH_OS_U_BOOT) {
+               nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                                   spl_image.size,
+                                   (void *)(unsigned long)spl_image.load_addr);
+               nand_deselect();
+               return;
+       }
+       puts("U-boot header didn't match.\n");
+#ifdef CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS
+       puts("Trying to start backup u-boot now...\n");
+       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,
+                           sizeof(*header), (void *)header);
+       spl_parse_image_header(header);
+       if (header->ih_os == IH_OS_U_BOOT) {
+               nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,

common/spl/spl_nand.c void spl_nand_load_image(void) · line 120

Quoted 10 lines
common/spl/spl_nand.c +7 -0
+                                   spl_image.size,
+                                   (void *)(unsigned long)spl_image.load_addr);
+               nand_deselect();
+               return;
+       }
+#endif
+       puts("No valid u-boot image found.\n");
        nand_deselect();
 }
 #endif

Daniel,

Under what circumstances would header->ih_os not be IH_OS_U_BOOT? It seems to me only if CONFIG_SYS_NAND_U_BOOT_OFFS pointed to the wrong place but wouldn't this be a board configuration error?

Are you trying to put some redundancy in for detecting a corrupted image? It seems to me that you would want to do more than check the header type in that case.

Tim

#15 lore raw

PATCH 3/5 nand: sunxi: Add secondary U-Boot offset on second syndrome partition

Hi,

Quoted 84 lines · Tim Harvey
Quoted 69 lines · Daniel Kochma?ski

Introduces CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS, pointing to backup U-Boot instance in nand memory. In case if first header doesn't match, tries to load bootloader from this offset. In case of both failing, hang() is called.

Additionally define offset of backup U-boot for sunxi at start of second syndrome partition.

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 README                         |  4 ++++
 common/spl/spl_nand.c          | 28 +++++++++++++++++++++++++---
 include/configs/sunxi-common.h |  1 +
 3 files changed, 30 insertions(+), 3 deletions(-)
README +4 -0
index ee65fdb..4ccf3cb 100644
@@ -3722,6 +3722,10 @@ FIT uImage format:
                CONFIG_SYS_NAND_U_BOOT_OFFS
                Location in NAND to read U-Boot from
 
+               CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS
+               Location in NAND to read backup U-Boot from, if first
+               location doesn't contain valid image.
+
                CONFIG_SYS_NAND_U_BOOT_DST
                Location in memory to load U-Boot to
 
common/spl/spl_nand.c +18 -3
index 9d59fbb..7c44de1 100644
@@ -2,6 +2,9 @@
  * Copyright (C) 2011
  * Corscience GmbH & Co. KG - Simon Schwarz <[email protected]>
  *
+ * Copyright (C) 2015
+ * Turtle Solutions - Daniel Kochma?ski <[email protected]>
+ *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
@@ -90,9 +93,28 @@ void spl_nand_load_image(void)
        nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
                            sizeof(*header), (void *)header);
        spl_parse_image_header(header);
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-                           spl_image.size,
-                           (void *)(unsigned long)spl_image.load_addr);
+       if (header->ih_os == IH_OS_U_BOOT) {
+               nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                                   spl_image.size,
+                                   (void *)(unsigned long)spl_image.load_addr);
+               nand_deselect();
+               return;
+       }
+       puts("U-boot header didn't match.\n");
+#ifdef CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS
+       puts("Trying to start backup u-boot now...\n");
+       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,
+                           sizeof(*header), (void *)header);
+       spl_parse_image_header(header);
+       if (header->ih_os == IH_OS_U_BOOT) {
+               nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,

common/spl/spl_nand.c void spl_nand_load_image(void) · line 120

Quoted 10 lines
common/spl/spl_nand.c +7 -0
+                                   spl_image.size,
+                                   (void *)(unsigned long)spl_image.load_addr);
+               nand_deselect();
+               return;
+       }
+#endif
+       puts("No valid u-boot image found.\n");
        nand_deselect();
 }
 #endif

Daniel,

Quoted 3 lines

Under what circumstances would header->ih_os not be IH_OS_U_BOOT? It seems to me only if CONFIG_SYS_NAND_U_BOOT_OFFS pointed to the wrong place but wouldn't this be a board configuration error?

In case of sunxi boards so-called BROM when it reads bootloader from NAND it tries to load it from first block of NAND, and if header/checksum doesn't match, then it tries to read it from second one.

Quoted 4 lines

Are you trying to put some redundancy in for detecting a corrupted image? It seems to me that you would want to do more than check the header type in that case.

SPL can't detect, from which offset it was loaded, therefore even if image is correct and is placed on second block, it needs to check, if something it reads is actual U-Boot. If not, then it is placed at second one, and it should read U-Boot from second offset.

Quoted 2 lines

Tim

Signature · 4 lines
Daniel Kochma?ski | Pozna?, Poland
;; aka jackdaniel

"Be the change that you wish to see in the world." - Mahatma Gandhi
#16 lore raw

PATCH 3/5 nand: sunxi: Add secondary U-Boot offset on second syndrome partition

In reply to Daniel Kochmański
Quoted 32 lines · Daniel Kochma?ski
common/spl/spl_nand.c +14 -3
index 9d59fbb..7c44de1 100644
@@ -2,6 +2,9 @@
  * Copyright (C) 2011
  * Corscience GmbH & Co. KG - Simon Schwarz <[email protected]>
  *
+ * Copyright (C) 2015
+ * Turtle Solutions - Daniel Kochma?ski <[email protected]>
+ *
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
@@ -90,9 +93,28 @@ void spl_nand_load_image(void)
 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
 			    sizeof(*header), (void *)header);
 	spl_parse_image_header(header);
-	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-			    spl_image.size,
-			    (void *)(unsigned long)spl_image.load_addr);
+	if (header->ih_os == IH_OS_U_BOOT) {
+		nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+				    spl_image.size,
+				    (void *)(unsigned long)spl_image.load_addr);
+		nand_deselect();
+		return;
+	}
+	puts("U-boot header didn't match.\n");
+#ifdef CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS
+	puts("Trying to start backup u-boot now...\n");
+	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,

common/spl/spl_nand.c void spl_nand_load_image(void) · line 116

Quoted 10 lines
common/spl/spl_nand.c +10 -0
+			    sizeof(*header), (void *)header);
+	spl_parse_image_header(header);
+	if (header->ih_os == IH_OS_U_BOOT) {
+		nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS,
+				    spl_image.size,
+				    (void *)(unsigned long)spl_image.load_addr);
+		nand_deselect();
+		return;
+	}
+#endif

Factor this code into a function that is called twice rather than repeating everything.

-Scott

#17 lore raw

PATCH 4/5 nand: sunxi: Add multiimage preload option

In reply to Daniel Kochmański

Patch adds support in spl_nand for preloading multiimage before loading u-boot into memory. It might be used in example to put in memory single image containing boot script, kernel and device tree.

Behavior is triggered, if CONFIG_SPL_NAND_MULTI_PRELOAD is defined - multiimage is loaded from CONFIG_SYS_NAND_MULTI_OFFS to address specified on image creation.

Additionally defines it in sunxi-common.h conditionally when CONFIG_SPL_NAND_SUPPORT is enabled. SPL tries to preload image from beginning of non-syndrome area.

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 README                         |  6 ++++++
 common/spl/spl_nand.c          | 14 ++++++++++++++
 include/configs/sunxi-common.h |  2 ++
 3 files changed, 22 insertions(+)
README +6 -0
index 4ccf3cb..444b02f 100644
@@ -3719,6 +3719,9 @@ FIT uImage format:
 		CONFIG_SPL_NAND_BOOT
 		Add support NAND boot
 
+		CONFIG_SPL_NAND_MULTI_PRELOAD
+		Preload multiimage from predefined offset in NAND.
+
 		CONFIG_SYS_NAND_U_BOOT_OFFS
 		Location in NAND to read U-Boot from
 
@@ -3735,6 +3738,9 @@ FIT uImage format:
 		CONFIG_SYS_NAND_U_BOOT_START
 		Entry point in loaded image to jump to
 
+		CONFIG_SYS_NAND_MULTI_OFFS
+		Location in NAND to read multiimage from.
+
 		CONFIG_SYS_NAND_HW_ECC_OOBFIRST
 		Define this if you need to first read the OOB and then the
 		data. This is used, for example, on davinci platforms.
common/spl/spl_nand.c +14 -0
index 7c44de1..f87db0a 100644
@@ -89,6 +89,20 @@ void spl_nand_load_image(void)
 			    (void *)spl_image.load_addr);
 #endif
 #endif
+#ifdef CONFIG_SPL_NAND_MULTI_PRELOAD
+	/* Load multiimage */
+	puts("Preloading multiimage.\n");
+	nand_spl_load_image(CONFIG_SYS_NAND_MULTI_OFFS,
+			    sizeof(*header), (void *)header);
+	spl_parse_image_header(header);
+	if (header->ih_type == IH_TYPE_MULTI) {
+		nand_spl_load_image(CONFIG_SYS_NAND_MULTI_OFFS,
+				    spl_image.size,
+				    (void *)(unsigned long)spl_image.load_addr);
+	} else {
+		puts("Multiimage header didn't match.\n");
+	}
+#endif /* CONFIG_SPL_NAND_MULTI_PRELOAD */
 	/* Load u-boot */
 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
 			    sizeof(*header), (void *)header);
include/configs/sunxi-common.h +2 -0
index 15fe512..0b4ea7e 100644
@@ -328,9 +328,11 @@ extern int soft_i2c_gpio_scl;
 #ifdef CONFIG_SPL_NAND_SUPPORT
 #define CONFIG_NAND
 #define CONFIG_NAND_SUNXI
+#define CONFIG_SPL_NAND_MULTI_PRELOAD
 #define CONFIG_CMD_SPL_WRITE_SIZE		0x000400
 #define CONFIG_SYS_NAND_U_BOOT_OFFS		0x008000
 #define CONFIG_SYS_NAND_U_BOOT_BACKUP_OFFS	0x208000
+#define CONFIG_SYS_NAND_MULTI_OFFS		0x400000
 #endif /* CONFIG_SPL_NAND_SUPPORT */
 
 #define CONFIG_MISC_INIT_R
Signature · 1 line
2.3.6
#18 lore raw

PATCH 4/5 nand: sunxi: Add multiimage preload option

Quoted 13 lines · Daniel Kochma?ski

Patch adds support in spl_nand for preloading multiimage before loading u-boot into memory. It might be used in example to put in memory single image containing boot script, kernel and device tree.

Behavior is triggered, if CONFIG_SPL_NAND_MULTI_PRELOAD is defined - multiimage is loaded from CONFIG_SYS_NAND_MULTI_OFFS to address specified on image creation.

Additionally defines it in sunxi-common.h conditionally when CONFIG_SPL_NAND_SUPPORT is enabled. SPL tries to preload image from beginning of non-syndrome area.

Quoted 7 lines
Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 README                         |  6 ++++++
 common/spl/spl_nand.c          | 14 ++++++++++++++

As with the previous patch this likely needs an Ack from someone else.

Ian.

#19 lore raw

PATCH 4/5 nand: sunxi: Add multiimage preload option

In reply to Daniel Kochmański
Quoted 4 lines · Daniel Kochma?ski

Patch adds support in spl_nand for preloading multiimage before loading u-boot into memory. It might be used in example to put in memory single image containing boot script, kernel and device tree.

Why can't the main U-Boot load it?

Quoted 23 lines

Behavior is triggered, if CONFIG_SPL_NAND_MULTI_PRELOAD is defined - multiimage is loaded from CONFIG_SYS_NAND_MULTI_OFFS to address specified on image creation.

Additionally defines it in sunxi-common.h conditionally when CONFIG_SPL_NAND_SUPPORT is enabled. SPL tries to preload image from beginning of non-syndrome area.

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 README                         |  6 ++++++
 common/spl/spl_nand.c          | 14 ++++++++++++++
 include/configs/sunxi-common.h |  2 ++
 3 files changed, 22 insertions(+)
README +0 -0
index 4ccf3cb..444b02f 100644

README FIT uImage format: · line 3723

Quoted 5 lines
README +2 -0
@@ -3719,6 +3719,9 @@ FIT uImage format:
 		CONFIG_SPL_NAND_BOOT
 		Add support NAND boot
 
+		CONFIG_SPL_NAND_MULTI_PRELOAD
+		Preload multiimage from predefined offset in NAND.

Why is this not implied by CONFIG_SYS_NAND_MULTI_OFFS not being defined?

README FIT uImage format: · line 3742

Quoted 10 lines
README +3 -0
+
 		CONFIG_SYS_NAND_U_BOOT_OFFS
 		Location in NAND to read U-Boot from
 
@@ -3735,6 +3738,9 @@ FIT uImage format:
 		CONFIG_SYS_NAND_U_BOOT_START
 		Entry point in loaded image to jump to
 
+		CONFIG_SYS_NAND_MULTI_OFFS
+		Location in NAND to read multiimage from.

Why SYS and not SPL? Why not using kconfig?

Quoted 9 lines
README +1 -0
+
 		CONFIG_SYS_NAND_HW_ECC_OOBFIRST
 		Define this if you need to first read the OOB and then the
 		data. This is used, for example, on davinci platforms.
common/spl/spl_nand.c +0 -0
index 7c44de1..f87db0a 100644

common/spl/spl_nand.c void spl_nand_load_image(void) · line 94

Quoted 6 lines
common/spl/spl_nand.c +3 -0
@@ -89,6 +89,20 @@ void spl_nand_load_image(void)
 			    (void *)spl_image.load_addr);
 #endif
 #endif
+#ifdef CONFIG_SPL_NAND_MULTI_PRELOAD
+	/* Load multiimage */
+	puts("Preloading multiimage.\n");

This function isn't this verbose for any of the other images...

-Scott

#20 lore raw

PATCH 5/5 nand: sunxi: And a20_nandread command utilizing spl nand read driver

In reply to Daniel Kochmański

This patch adds a20_nandread command. It is simple function utilizing function from SPL nand driver nand_spl_load_image.

Usage: a20_nandread <address> <offset> <bytes>

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 common/Kconfig            |  7 +++++++
 common/Makefile           |  1 +
 common/cmd_a20_nandread.c | 27 +++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 common/cmd_a20_nandread.c
common/Kconfig +7 -0
index 5d7e48a..8edabb6 100644
@@ -204,6 +204,13 @@ config CMD_NAND
 	help
 	  NAND support.
 
+config CMD_A20_NANDREAD
+	depends on SPL_NAND_SUPPORT
+	bool "a20_nandread"
+	help
+	  NAND read support for A20 SoC. Depends on SPL driver.
+	  Usage: a20_nandread <address> <offset> <size>
+
 config CMD_SPI
 	bool "sspi"
 	help
common/Makefile +1 -0
index fba3830..9286518 100644
@@ -138,6 +138,7 @@ obj-$(CONFIG_CMD_MMC) += cmd_mmc.o
 obj-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 obj-$(CONFIG_MP) += cmd_mp.o
 obj-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
+obj-$(CONFIG_CMD_A20_NANDREAD) += cmd_a20_nandread.o
 obj-$(CONFIG_CMD_NAND) += cmd_nand.o
 obj-$(CONFIG_CMD_NET) += cmd_net.o
 obj-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
common/cmd_a20_nandread.c new file +27 -0
new file mode 100644
index 0000000..7361be7
@@ -0,0 +1,27 @@
+#include <common.h>
+#include <command.h>
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest);
+
+static int do_a20_nandread(cmd_tbl_t *cmdtp, int flag,
+			   int argc, char *const argv[])
+{
+	if (argc != 4) {
+		printf("usage: a20_nandread <address> <offset> <bytes>\n");
+		return 1;
+	}
+
+	uint32_t dst = simple_strtoul(argv[1], NULL, 16);
+	uint32_t src = simple_strtoul(argv[2], NULL, 16);
+	uint32_t cnt = simple_strtoul(argv[3], NULL, 16);
+	printf("Loading 0x%08XB @ 0x%08X -> 0x%08X...\n", cnt, src, dst);
+	nand_spl_load_image(src, cnt, (void *)dst);
+	return 0;
+}
+
+U_BOOT_CMD(
+	a20_nandread,	CONFIG_SYS_MAXARGS,	3,	do_a20_nandread,
+	"a20_nandread",
+	"[offset size bytes]\n"
+	"   "
+);
Signature · 1 line
2.3.6
#21 lore raw

PATCH 5/5 nand: sunxi: And a20_nandread command utilizing spl nand read driver

Quoted 4 lines · Daniel Kochma?ski

This patch adds a20_nandread command. It is simple function utilizing function from SPL nand driver nand_spl_load_image.

Usage: a20_nandread <address> <offset> <bytes>

This stuff should really be integrated with cmd_nand.c rather than adding an adhoc SoC specific interface.

Quoted 75 lines
Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

 common/Kconfig            |  7 +++++++
 common/Makefile           |  1 +
 common/cmd_a20_nandread.c | 27 +++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 common/cmd_a20_nandread.c
common/Kconfig +7 -0
index 5d7e48a..8edabb6 100644
@@ -204,6 +204,13 @@ config CMD_NAND
 	help
 	  NAND support.
 
+config CMD_A20_NANDREAD
+	depends on SPL_NAND_SUPPORT
+	bool "a20_nandread"
+	help
+	  NAND read support for A20 SoC. Depends on SPL driver.
+	  Usage: a20_nandread <address> <offset> <size>
+
 config CMD_SPI
 	bool "sspi"
 	help
common/Makefile +1 -0
index fba3830..9286518 100644
@@ -138,6 +138,7 @@ obj-$(CONFIG_CMD_MMC) += cmd_mmc.o
 obj-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 obj-$(CONFIG_MP) += cmd_mp.o
 obj-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
+obj-$(CONFIG_CMD_A20_NANDREAD) += cmd_a20_nandread.o
 obj-$(CONFIG_CMD_NAND) += cmd_nand.o
 obj-$(CONFIG_CMD_NET) += cmd_net.o
 obj-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
common/cmd_a20_nandread.c new file +27 -0
new file mode 100644
index 0000000..7361be7
@@ -0,0 +1,27 @@
+#include <common.h>
+#include <command.h>
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest);
+
+static int do_a20_nandread(cmd_tbl_t *cmdtp, int flag,
+			   int argc, char *const argv[])
+{
+	if (argc != 4) {
+		printf("usage: a20_nandread <address> <offset> <bytes>\n");
+		return 1;
+	}
+
+	uint32_t dst = simple_strtoul(argv[1], NULL, 16);
+	uint32_t src = simple_strtoul(argv[2], NULL, 16);
+	uint32_t cnt = simple_strtoul(argv[3], NULL, 16);
+	printf("Loading 0x%08XB @ 0x%08X -> 0x%08X...\n", cnt, src, dst);
+	nand_spl_load_image(src, cnt, (void *)dst);
+	return 0;
+}
+
+U_BOOT_CMD(
+	a20_nandread,	CONFIG_SYS_MAXARGS,	3,	do_a20_nandread,
+	"a20_nandread",
+	"[offset size bytes]\n"
+	"   "
+);
#22 lore raw

PATCH 5/5 nand: sunxi: And a20_nandread command utilizing spl nand read driver

Hi,

Quoted 8 lines · Ian Campbell
Quoted 4 lines · Daniel Kochma?ski

This patch adds a20_nandread command. It is simple function utilizing function from SPL nand driver nand_spl_load_image.

Usage: a20_nandread <address> <offset> <bytes>

This stuff should really be integrated with cmd_nand.c rather than adding an adhoc SoC specific interface.

I want to go even further and I see that this really needs to be integrated with the blkdev code so that one can just do:

ls nand 0:1

And things will just work, these way we can also just have the standard boot cmds from config_distro_bootcmd.h work rather then needing special nand boot commands.

Regards,

Hans

Quoted 78 lines
Quoted 76 lines
Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

  common/Kconfig            |  7 +++++++
  common/Makefile           |  1 +
  common/cmd_a20_nandread.c | 27 +++++++++++++++++++++++++++
  3 files changed, 35 insertions(+)

create mode 100644 common/cmd_a20_nandread.c

common/Kconfig +7 -0
index 5d7e48a..8edabb6 100644
@@ -204,6 +204,13 @@ config CMD_NAND
  	help
  	  NAND support.
 
+config CMD_A20_NANDREAD
+	depends on SPL_NAND_SUPPORT
+	bool "a20_nandread"
+	help
+	  NAND read support for A20 SoC. Depends on SPL driver.
+	  Usage: a20_nandread <address> <offset> <size>
+
  config CMD_SPI
  	bool "sspi"
  	help
common/Makefile +1 -0
index fba3830..9286518 100644
@@ -138,6 +138,7 @@ obj-$(CONFIG_CMD_MMC) += cmd_mmc.o
  obj-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
  obj-$(CONFIG_MP) += cmd_mp.o
  obj-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
+obj-$(CONFIG_CMD_A20_NANDREAD) += cmd_a20_nandread.o
  obj-$(CONFIG_CMD_NAND) += cmd_nand.o
  obj-$(CONFIG_CMD_NET) += cmd_net.o
  obj-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
common/cmd_a20_nandread.c new file +27 -0
new file mode 100644
index 0000000..7361be7
@@ -0,0 +1,27 @@
+#include <common.h>
+#include <command.h>
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest);
+
+static int do_a20_nandread(cmd_tbl_t *cmdtp, int flag,
+			   int argc, char *const argv[])
+{
+	if (argc != 4) {
+		printf("usage: a20_nandread <address> <offset> <bytes>\n");
+		return 1;
+	}
+
+	uint32_t dst = simple_strtoul(argv[1], NULL, 16);
+	uint32_t src = simple_strtoul(argv[2], NULL, 16);
+	uint32_t cnt = simple_strtoul(argv[3], NULL, 16);
+	printf("Loading 0x%08XB @ 0x%08X -> 0x%08X...\n", cnt, src, dst);
+	nand_spl_load_image(src, cnt, (void *)dst);
+	return 0;
+}
+
+U_BOOT_CMD(
+	a20_nandread,	CONFIG_SYS_MAXARGS,	3,	do_a20_nandread,
+	"a20_nandread",
+	"[offset size bytes]\n"
+	"   "
+);
#23 lore raw

PATCH 5/5 nand: sunxi: And a20_nandread command utilizing spl nand read driver

Quoted 17 lines · Hans de Goede

Hi,

Quoted 8 lines · Ian Campbell
Quoted 4 lines · Daniel Kochma?ski

This patch adds a20_nandread command. It is simple function utilizing function from SPL nand driver nand_spl_load_image.

Usage: a20_nandread <address> <offset> <bytes>

This stuff should really be integrated with cmd_nand.c rather than adding an adhoc SoC specific interface.

I want to go even further and I see that this really needs to be integrated with the blkdev code so that one can just do:

ls nand 0:1

Quoted 8 lines

And things will just work, these way we can also just have the standard boot cmds from config_distro_bootcmd.h work rather then needing special nand boot commands.

Regards,

Hans

It was more a convenient function then proper integration. I'll look into that, but it may take time - I'm quite unfamiliar with U-Boot nand interface.

Quoted 80 lines
Quoted 80 lines
Quoted 78 lines
Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>

---

  common/Kconfig            |  7 +++++++
  common/Makefile           |  1 +
  common/cmd_a20_nandread.c | 27 +++++++++++++++++++++++++++
  3 files changed, 35 insertions(+)

create mode 100644 common/cmd_a20_nandread.c

common/Kconfig +7 -0
index 5d7e48a..8edabb6 100644
@@ -204,6 +204,13 @@ config CMD_NAND
  	help
  	  NAND support.
 
+config CMD_A20_NANDREAD
+	depends on SPL_NAND_SUPPORT
+	bool "a20_nandread"
+	help
+	  NAND read support for A20 SoC. Depends on SPL driver.
+	  Usage: a20_nandread <address> <offset> <size>
+
  config CMD_SPI
  	bool "sspi"
  	help
common/Makefile +1 -0
index fba3830..9286518 100644
@@ -138,6 +138,7 @@ obj-$(CONFIG_CMD_MMC) += cmd_mmc.o
  obj-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
  obj-$(CONFIG_MP) += cmd_mp.o
  obj-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
+obj-$(CONFIG_CMD_A20_NANDREAD) += cmd_a20_nandread.o
  obj-$(CONFIG_CMD_NAND) += cmd_nand.o
  obj-$(CONFIG_CMD_NET) += cmd_net.o
  obj-$(CONFIG_CMD_ONENAND) += cmd_onenand.o
common/cmd_a20_nandread.c new file +27 -0
new file mode 100644
index 0000000..7361be7
@@ -0,0 +1,27 @@
+#include <common.h>
+#include <command.h>
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest);
+
+static int do_a20_nandread(cmd_tbl_t *cmdtp, int flag,
+			   int argc, char *const argv[])
+{
+	if (argc != 4) {
+		printf("usage: a20_nandread <address> <offset> <bytes>\n");
+		return 1;
+	}
+
+	uint32_t dst = simple_strtoul(argv[1], NULL, 16);
+	uint32_t src = simple_strtoul(argv[2], NULL, 16);
+	uint32_t cnt = simple_strtoul(argv[3], NULL, 16);
+	printf("Loading 0x%08XB @ 0x%08X -> 0x%08X...\n", cnt, src, dst);
+	nand_spl_load_image(src, cnt, (void *)dst);
+	return 0;
+}
+
+U_BOOT_CMD(
+	a20_nandread,	CONFIG_SYS_MAXARGS,	3,	do_a20_nandread,
+	"a20_nandread",
+	"[offset size bytes]\n"
+	"   "
+);
Signature · 4 lines
Daniel Kochma?ski | Pozna?, Poland
;; aka jackdaniel

"Be the change that you wish to see in the world." - Mahatma Gandhi
#24 lore raw

PATCH 5/5 nand: sunxi: And a20_nandread command utilizing spl nand read driver

Hi,

Quoted 24 lines · Daniel Kochma?ski
Quoted 21 lines · Hans de Goede

Hi,

Quoted 8 lines · Ian Campbell
Quoted 4 lines · Daniel Kochma?ski

This patch adds a20_nandread command. It is simple function utilizing function from SPL nand driver nand_spl_load_image.

Usage: a20_nandread <address> <offset> <bytes>

This stuff should really be integrated with cmd_nand.c rather than adding an adhoc SoC specific interface.

I want to go even further and I see that this really needs to be integrated with the blkdev code so that one can just do:

ls nand 0:1

And things will just work, these way we can also just have the standard boot cmds from config_distro_bootcmd.h work rather then needing special nand boot commands.

Quoted 6 lines
Quoted 4 lines

Regards,

Hans

It was more a convenient function then proper integration.

I understand but for upstream nand support we really want a proper solution, note that I'm find with having the nand support being read only, but it should really be integrated enough that things like:

ls nand 0:1

Will work.

Quoted 3 lines

I'll look
into that, but it may take time - I'm quite unfamiliar with U-Boot nand interface.

Thanks!

Regards,

Hans

#25 lore raw

PATCH 5/5 nand: sunxi: And a20_nandread command utilizing spl nand read driver

In reply to Daniel Kochmański
Quoted 8 lines · Daniel Kochma?ski

This patch adds a20_nandread command. It is simple function utilizing function from SPL nand driver nand_spl_load_image.

Usage: a20_nandread <address> <offset> <bytes>

Cc Ian Campbell <[email protected]>
Cc Hans De Goede <[email protected]>
Quoted 7 lines

---

 common/Kconfig            |  7 +++++++
 common/Makefile           |  1 +
 common/cmd_a20_nandread.c | 27 +++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)
 create mode 100644 common/cmd_a20_nandread.c

Obviously a real NAND driver would be preferred (even if some functionality is missing at first), but if for some reason we do need to support simple read-only access using SPL code in the main U-Boot, what is a20-specific about this file beyond the use case?

-Scott