Add support for NAND U-boot image upgrade
Subsystems (3)
v2 cover Add support for NAND U-boot image upgrade
This series adds opportunity to write U-boot image on AEMIF NAND device using standard nand u-boot commands. Also added script to automate this process.
This series is logical continue of
"[U-boot] [Patch v3 0/3] keystone: nand: add additional nand ecclayout" series (http://comments.gmane.org/gmane.comp.boot-loaders.u-boot/189378).
For more informations see:
http://www.ti.com/lit/ug/spruhj3/spruhj3.pdf
Based on u-boot-ti.git master
v2..v1:
k2hk_evm: add script to automate NAND flash process
- include NAND boot under the section "Supported boot modes:" in README
Ivan Khoronzhuk (3):
mtd: nand: davinci: add opportunity to write keystone U-boot image
keystone: add support for NAND gpheader image
k2hk_evm: add script to automate NAND flash process
Makefile | 6 ++ board/ti/k2hk_evm/README | 28 +++++- drivers/mtd/nand/davinci_nand.c | 196 ++++++++++++++++++++++++++++++++++++++++ include/configs/k2hk_evm.h | 8 +- 4 files changed, 235 insertions(+), 3 deletions(-)
Signature · 1 line
1.8.3.2
PATCH v2 1/3 mtd: nand: davinci: add opportunity to write keystone U-boot image
The Keystone SoCs use the same NAND driver as Davinci. This patch adds opportunity to write Keystone U-boot image to NAND device using appropriate RBL ECC layout. This is needed only if RBL boots U-boot from NAND device and that's supposed that raw u-boot partition is used only for writing image.
The main problem is that default Davinci ECC layout is different from Keystone RBL layout. To read U-boot image the RBL needs that image was written using RBL ECC layout.
The BBT table is written using default Davinci layout and has to be updated using one. The BBT can be updated only while erasing chip or by forced bad block assigning, so erase function has to use native ecc layout in order to be able to write BBT correctly. So if we're writing to NAND U-boot address we use RBL layout for others we use default ECC layout.
Also remove definition for CONFIG_CMD_NAND_ECCLAYOUT as there is no reasons to use ECC layout commands. It was added by mistake.
--- drivers/mtd/nand/davinci_nand.c | 196 ++++++++++++++++++++++++++++++++++++++++ include/configs/k2hk_evm.h | 4 +- 2 files changed, 199 insertions(+), 1 deletion(-)
drivers/mtd/nand/davinci_nand.c +196 -0
@@ -305,6 +305,189 @@ static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = {#endif }; +#if definedCONFIG_KEYSTONE_RBL_NAND +#if defined(CONFIG_SYS_NAND_PAGE_2K ) +static struct nand_ecclayout nand_keystone_rbl_4bit_layout_oobfirst = { + .eccbytes =40 , + .eccpos = { +6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 , +22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 , +38 ,39 ,40 ,41 ,42 ,43 ,44 ,45 ,46 ,47 , +54 ,55 ,56 ,57 ,58 ,59 ,60 ,61 ,62 ,63 , + }, + .oobfree = { + {.offset =2 , .length =4 , }, + {.offset =16 , .length =6 , }, + {.offset =32 , .length =6 , }, + {.offset =48 , .length =6 , }, + }, +#elif defined(CONFIG_SYS_NAND_PAGE_4K) + .eccbytes =80 , + .eccpos = { +6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 , +22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 , +38 ,39 ,40 ,41 ,42 ,43 ,44 ,45 ,46 ,47 , +54 ,55 ,56 ,57 ,58 ,59 ,60 ,61 ,62 ,63 , +70 ,71 ,72 ,73 ,74 ,75 ,76 ,77 ,78 ,79 , +86 ,87 ,88 ,89 ,90 ,91 ,92 ,93 ,94 ,95 , +102 ,103 ,104 ,105 ,106 ,107 ,108 ,109 ,110 ,111 , +118 ,119 ,120 ,121 ,122 ,123 ,124 ,125 ,126 ,127 , + }, + .oobfree = { + {.offset =2 , .length =4 , }, + {.offset =16 , .length =6 , }, + {.offset =32 , .length =6 , }, + {.offset =48 , .length =6 , }, + {.offset =64 , .length =6 , }, + {.offset =80 , .length =6 , }, + {.offset =96 , .length =6 , }, + {.offset =112 , .length =6 , }, + }, +#endif +}; + +#ifdef CONFIG_SYS_NAND_PAGE_2K +#define CONFIG_KEYSTONE_NAND_MAX_RBL_PAGE CONFIG_KEYSTONE_NAND_MAX_RBL_SIZE >> 11 +#elif defined(CONFIG_SYS_NAND_PAGE_4K ) +#define CONFIG_KEYSTONE_NAND_MAX_RBL_PAGE CONFIG_KEYSTONE_NAND_MAX_RBL_SIZE >> 12 +#endif + +/** +* nand_davinci_write_page - write one page +* @mtd: MTD device structure +* @chip: NAND chip descriptor +* @buf: the data to write +* @oob_required: must write chip->oob_poi to OOB +* @page: page number to write +* @cached: cached programming +* @raw: use _raw version of write_page +*/ +static int nand_davinci_write_page (struct mtd_info *mtd,struct nand_chip *chip, +const uint8_t *buf,int oob_required, +int page,int cached,int raw) +{ +int status; +int ret =0 ; +struct nand_ecclayout *saved_ecc_layout; + +/* save current ECC layout and assign Keystone RBL ECC layout */ +if (page <CONFIG_KEYSTONE_NAND_MAX_RBL_PAGE ) { + saved_ecc_layout = chip->ecc.layout; + chip->ecc.layout = &nand_keystone_rbl_4bit_layout_oobfirst; + mtd->oobavail = chip->ecc.layout->oobavail; + } + + chip->cmdfunc (mtd,NAND_CMD_SEQIN ,0x00 , page); + +if (unlikely (raw)) + status = chip->ecc.write_page_raw (mtd, chip, buf, oob_required); +else + status = chip->ecc.write_page (mtd, chip, buf, oob_required); + +if (status <0 ) { + ret = status; + goto err; + } + + chip->cmdfunc (mtd,NAND_CMD_PAGEPROG ,-1 ,-1 ); + status = chip->waitfunc (mtd, chip); + +/* +* See if operation failed and additional status checks are +* available. +*/ +if ((status &NAND_STATUS_FAIL ) && (chip->errstat)) + status = chip->errstat (mtd, chip,FL_WRITING , status, page); + +if (status &NAND_STATUS_FAIL ) { + ret = -EIO ; + goto err; + } + +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE +/* Send command to read back the data */ + chip->cmdfunc (mtd,NAND_CMD_READ0 ,0 , page); + +if (chip->verify_buf (mtd, buf, mtd->writesize)) { + ret = -EIO ; + goto err; + } + +/* Make sure the next page prog is preceded by a status read */ + chip->cmdfunc (mtd,NAND_CMD_STATUS ,-1 ,-1 ); +#endif +err: +/* restore ECC layout */ +if (page <CONFIG_KEYSTONE_NAND_MAX_RBL_PAGE ) { + chip->ecc.layout = saved_ecc_layout; + mtd->oobavail = saved_ecc_layout->oobavail; + } + +return ret; +} + +/** +* nand_davinci_read_page_hwecc - hardware ECC based page read function +* @mtd: mtd info structure +* @chip: nand chip info structure +* @buf: buffer to store read data +* @oob_required: caller requires OOB data read to chip->oob_poi +* @page: page number to read +* +* Not for syndrome calculating ECC controllers which need a special oob layout. +*/ +static int nand_davinci_read_page_hwecc (struct mtd_info *mtd,struct nand_chip *chip, +uint8_t *buf,int oob_required,int page) +{ +int i, eccsize = chip->ecc.size; +int eccbytes = chip->ecc.bytes; +int eccsteps = chip->ecc.steps; +uint32_t *eccpos; +uint8_t *p = buf; +uint8_t *ecc_code = chip->buffers->ecccode; +uint8_t *ecc_calc = chip->buffers->ecccalc; +struct nand_ecclayout *saved_ecc_layout = chip->ecc.layout; + +/* save current ECC layout and assign Keystone RBL ECC layout */ +if (page <CONFIG_KEYSTONE_NAND_MAX_RBL_PAGE ) { + chip->ecc.layout = &nand_keystone_rbl_4bit_layout_oobfirst; + mtd->oobavail = chip->ecc.layout->oobavail; + } + + eccpos = chip->ecc.layout->eccpos; + +/* Read the OOB area first */ + chip->cmdfunc (mtd,NAND_CMD_READOOB ,0 , page); + chip->read_buf (mtd, chip->oob_poi, mtd->oobsize); + chip->cmdfunc (mtd,NAND_CMD_READ0 ,0 , page); + +for (i =0 ; i < chip->ecc.total; i++) + ecc_code[i] = chip->oob_poi[eccpos[i]]; + +for (i =0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { +int stat; + + chip->ecc.hwctl (mtd,NAND_ECC_READ ); + chip->read_buf (mtd, p, eccsize); + chip->ecc.calculate (mtd, p, &ecc_calc[i]); + + stat = chip->ecc.correct (mtd, p, &ecc_code[i],NULL ); +if (stat <0 ) + mtd->ecc_stats.failed++; +else + mtd->ecc_stats.corrected += stat; + } + +/* restore ECC layout */ +if (page <CONFIG_KEYSTONE_NAND_MAX_RBL_PAGE ) { + chip->ecc.layout = saved_ecc_layout; + mtd->oobavail = saved_ecc_layout->oobavail; + } + +return 0 ; +} +#endif /* CONFIG_KEYSTONE_RBL_NAND */ +static void nand_davinci_4bit_enable_hwecc (struct mtd_info *mtd,int mode) {u32 val;
@@ -604,6 +787,19 @@ static void nand_flash_init(void)void davinci_nand_init (struct nand_chip *nand) { +#if definedCONFIG_KEYSTONE_RBL_NAND +int i; +struct nand_ecclayout *layout; + + layout = &nand_keystone_rbl_4bit_layout_oobfirst; + layout->oobavail =0 ; +for (i =0 ; layout->oobfree[i].length && + i <ARRAY_SIZE (layout->oobfree); i++) + layout->oobavail += layout->oobfree[i].length; + + nand->write_page = nand_davinci_write_page; + nand->ecc.read_page = nand_davinci_read_page_hwecc; +#endif nand->chip_delay =0 ;#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT nand->bbt_options |=NAND_BBT_USE_FLASH ;
include/configs/k2hk_evm.h +3 -1
@@ -135,7 +135,8 @@/* NAND Configuration */ #define CONFIG_NAND_DAVINCI -#define CONFIG_CMD_NAND_ECCLAYOUT +#define CONFIG_KEYSTONE_RBL_NAND +#define CONFIG_KEYSTONE_NAND_MAX_RBL_SIZE CONFIG_ENV_OFFSET#define CONFIG_SYS_NAND_CS 2#define CONFIG_SYS_NAND_USE_FLASH_BBT #define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
@@ -155,6 +156,7 @@#define CONFIG_MTD_DEVICE #define CONFIG_RBTREE #define CONFIG_LZO +#define MTDIDS_DEFAULT "nand0=davinci_nand.0"#define MTDPARTS_DEFAULT "mtdparts=davinci_nand.0:" \ "1024k(bootloader)ro,512k(params)ro," \ "-(ubifs)"
Signature · 1 line
1.8.3.2
PATCH v2 1/3 mtd: nand: davinci: add opportunity to write keystone U-boot image
Quoted 17 lines · Ivan
The Keystone SoCs use the same NAND driver as Davinci. This patch adds opportunity to write Keystone U-boot image to NAND device using appropriate RBL ECC layout. This is needed only if RBL boots U-boot from NAND device and that's supposed that raw u-boot partition is used only for writing image.
The main problem is that default Davinci ECC layout is different from Keystone RBL layout. To read U-boot image the RBL needs that image was written using RBL ECC layout.
The BBT table is written using default Davinci layout and has to be updated using one. The BBT can be updated only while erasing chip or by forced bad block assigning, so erase function has to use native ecc layout in order to be able to write BBT correctly. So if we're writing to NAND U-boot address we use RBL layout for others we use default ECC layout.
Quoted 4 lines
Also remove definition for
CONFIG_CMD_NAND_ECCLAYOUTas there is no reasons to use ECC layout commands. It was added by mistake.Signed-off-by Ivan Khoronzhuk <[email protected]>
Applied to u-boot-ti/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140725/ead5419c/attachment.pgp>
PATCH v2 2/3 keystone: add support for NAND gpheader image
In reply to Ivan KhoronzhukAdd support for NAND gpheader image. TI Keystone2 ROM bootloader expects 8 bytes of trailing zeroes in the nand u-boot image. So add zeros at the end of the nand gph image.
--- Makefile | 6 ++++++ 1 file changed, 6 insertions(+)
Makefile +6 -0
@@ -937,6 +937,12 @@ OBJCOPYFLAGS_u-boot-spi.gph = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) u-boot-spi.gph: spl/u-boot-spl.gph u-boot.img FORCE $(call if_changed,pad_cat) +MKIMAGEFLAGS_u-boot-nand.gph = -A $(ARCH) -T gpimage -C none \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -n U-Boot +u-boot-nand.gph: u-boot.bin FORCE + $(call if_changed,mkimage) + @dd if=/dev/zero bs=8 count=1 2>/dev/null >> $@ + ifneq ($(CONFIG_SUNXI),) OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \ --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff
Signature · 1 line
1.8.3.2
PATCH v2 2/3 keystone: add support for NAND gpheader image
Quoted 6 lines · Ivan
Add support for NAND gpheader image. TI Keystone2 ROM bootloader expects 8 bytes of trailing zeroes in the nand u-boot image. So add zeros at the end of the nand gph image.
Acked-by Murali Karicheri <[email protected]>Signed-off-by Ivan Khoronzhuk <[email protected]>
Applied to u-boot-ti/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140725/97872ffa/attachment.pgp>
PATCH v2 3/3 k2hk_evm: add script to automate NAND flash process
In reply to Ivan KhoronzhukAdd script to automate NAND flash process. As for now the board has two burn scripts - burn to boot from SPI NOR flash and burn to boot from AEMIF NAND flash, rename burn_uboot script to burn_uboot_spi. Also update README to contain NAND burn U-boot process description.
--- board/ti/k2hk_evm/README | 28 +++++++++++++++++++++++++++- include/configs/k2hk_evm.h | 4 +++- 2 files changed, 30 insertions(+), 2 deletions(-)
board/ti/k2hk_evm/README +27 -1
@@ -38,11 +38,13 @@ board configuration file: include/configs/k2hk_evm.h Supported boot modes: - SPI NOR boot + - AEMIF NAND boot Supported image formats:- - u-boot.bin: for loading and running u-boot.bin through Texas instruments code composure studio (CCS) - u-boot-spi.gph: gpimage for programming SPI NOR flash for SPI NOR boot + - u-boot-nand.gph: gpimage for programming AEMIF NAND flash for NAND boot Build instructions: ===================
@@ -55,6 +57,10 @@ To build u-boot-spi.gph >make k2hk_evm_config >make u-boot-spi.gph +To build u-boot-nand.gph + >make k2hk_evm_config + >make u-boot-nand.gph + Load and Run U-Boot on K2HK EVM using CCS =========================================
@@ -115,8 +121,28 @@ instructions:- 5. At the U-Boot console type following to setup u-boot environment variables. setenv addr_uboot 0x87000000 setenv filesize <size in hex of u-boot-spi.gph rounded to hex 0x10000> - run burn_uboot + run burn_uboot_spi Once u-boot prompt is available, Power OFF the EVM. Set the SW1 dip switch to "SPI Little Endian Boot mode" as per instruction at http://processors.wiki.ti.com/index.php/EVMK2H_Hardware_Setup. 6. Power ON the EVM. The EVM now boots with u-boot image on the NOR flash. + +AEMIF NAND Flash programming instructions +====================================== +U-Boot image can be flashed to first 1024KB of the NAND flash using following +instructions:- + +1. Start CCS and run U-boot as described above. +2. Suspend Target. Select Run -> Suspend from top level menu + CortexA15_1 (Free Running)" +3. Load u-boot-nand.gph binary from build folder on to DDR address 0x87000000 + through CCS as described in step 2 of "Load and Run U-Boot on K2HK EVM + using CCS", but using address 0x87000000. +4. Free Run the target as desribed earlier (step 4) to get u-boot prompt +5. At the U-Boot console type following to setup u-boot environment variables. + setenv filesize <size in hex of u-boot-nand.gph rounded to hex 0x10000> + run burn_uboot_nand + Once u-boot prompt is available, Power OFF the EVM. Set the SW1 dip switch + to "ARM NAND Boot mode" as per instruction at + http://processors.wiki.ti.com/index.php/EVMK2H_Hardware_Setup. +6. Power ON the EVM. The EVM now boots with u-boot image on the NAND flash.
include/configs/k2hk_evm.h +3 -1
@@ -221,8 +221,10 @@"get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0" \"get_uboot_net=dhcp ${addr_uboot} ${tftp_root}/${name_uboot}\0" \ -"burn_uboot=sf probe; sf erase 0 0x100000; " \ +"burn_uboot_spi=sf probe; sf erase 0 0x100000; " \"sf write ${addr_uboot} 0 ${filesize}\0" \ +"burn_uboot_nand=nand erase 0 0x100000; " \ +"nand write ${addr_uboot} 0 ${filesize}\0" \"args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0" \"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \"root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0" \
Signature · 1 line
1.8.3.2
PATCH v2 3/3 k2hk_evm: add script to automate NAND flash process
Quoted 76 lines · Ivan Khoronzhuk
Add script to automate NAND flash process. As for now the board has two burn scripts - burn to boot from SPI NOR flash and burn to boot from AEMIF NAND flash, rename
burn_ubootscript toburn_uboot_spi. Also update README to contain NAND burn U-boot process description.Signed-off-by Ivan Khoronzhuk<[email protected]>--- board/ti/k2hk_evm/README | 28 +++++++++++++++++++++++++++- include/configs/k2hk_evm.h | 4 +++- 2 files changed, 30 insertions(+), 2 deletions(-)board/ti/k2hk_evm/README +27
-1@@ -38,11 +38,13 @@ board configuration file: include/configs/k2hk_evm.h Supported boot modes: - SPI NOR boot + - AEMIF NAND boot Supported image formats:- - u-boot.bin: for loading and running u-boot.bin through Texas instruments code composure studio (CCS) - u-boot-spi.gph: gpimage for programming SPI NOR flash for SPI NOR boot + - u-boot-nand.gph: gpimage for programming AEMIF NAND flash for NAND boot Build instructions: ===================@@ -55,6 +57,10 @@ To build u-boot-spi.gph >make k2hk_evm_config >make u-boot-spi.gph +To build u-boot-nand.gph +>make k2hk_evm_config +>make u-boot-nand.gph + Load and Run U-Boot on K2HK EVM using CCS =========================================@@ -115,8 +121,28 @@ instructions:- 5. At the U-Boot console type following to setup u-boot environment variables. setenv addr_uboot 0x87000000 setenv filesize<size in hex of u-boot-spi.gph rounded to hex 0x10000> - run burn_uboot + run burn_uboot_spi Once u-boot prompt is available, Power OFF the EVM. Set the SW1 dip switch to "SPI Little Endian Boot mode" as per instruction at http://processors.wiki.ti.com/index.php/EVMK2H_Hardware_Setup. 6. Power ON the EVM. The EVM now boots with u-boot image on the NOR flash. + +AEMIF NAND Flash programming instructions +====================================== +U-Boot image can be flashed to first 1024KB of the NAND flash using following +instructions:- + +1. Start CCS and run U-boot as described above. +2. Suspend Target. Select Run -> Suspend from top level menu + CortexA15_1 (Free Running)" +3. Load u-boot-nand.gph binary from build folder on to DDR address 0x87000000 + through CCS as described in step 2 of "Load and Run U-Boot on K2HK EVM + using CCS", but using address 0x87000000. +4. Free Run the target as desribed earlier (step 4) to get u-boot prompt +5. At the U-Boot console type following to setup u-boot environment variables. + setenv filesize<size in hex of u-boot-nand.gph rounded to hex 0x10000> + run burn_uboot_nand + Once u-boot prompt is available, Power OFF the EVM. Set the SW1 dip switch + to "ARM NAND Boot mode" as per instruction at + http://processors.wiki.ti.com/index.php/EVMK2H_Hardware_Setup. +6. Power ON the EVM. The EVM now boots with u-boot image on the NAND flash.include/configs/k2hk_evm.h +0
-0@@ -221,8 +221,10 @@"get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \
include/configs/k2hk_evm.h line 230
Quoted 10 lines
include/configs/k2hk_evm.h +3
-1"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0" \"get_uboot_net=dhcp ${addr_uboot} ${tftp_root}/${name_uboot}\0" \ -"burn_uboot=sf probe; sf erase 0 0x100000; " \ +"burn_uboot_spi=sf probe; sf erase 0 0x100000; " \"sf write ${addr_uboot} 0 ${filesize}\0" \ +"burn_uboot_nand=nand erase 0 0x100000; " \ +"nand write ${addr_uboot} 0 ${filesize}\0" \"args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0" \"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \"root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0" \
PATCH v2 3/3 k2hk_evm: add script to automate NAND flash process
In reply to Ivan KhoronzhukQuoted 7 lines · Ivan
Add script to automate NAND flash process. As for now the board has two burn scripts - burn to boot from SPI NOR flash and burn to boot from AEMIF NAND flash, rename
burn_ubootscript toburn_uboot_spi. Also update README to contain NAND burn U-boot process description.Signed-off-by Ivan Khoronzhuk <[email protected]>Acked-by Murali Karicheri <[email protected]>
Applied to u-boot-ti/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140725/2d39dd54/attachment.pgp>