arm: atmel: sama5d3: add spi and nand spl boot support
Subsystems (4)
v2 cover arm: atmel: sama5d3: add spi and nand spl boot support
This patch enable spi and nand spl boot support on sama5d3xek
Changes in v2:
- Address the comments from Scott Wood
Bo Shen (3):
arm: atmel: sama5d3: add spi spl boot support
mtd: nand: atmel: prepare for nand spl boot support
arm: atmel: sama5d3: add nand spl boot support
arch/arm/cpu/at91-common/spl.c | 4 + arch/arm/include/asm/arch-at91/spl.h | 4 + board/atmel/sama5d3xek/sama5d3xek.c | 4 + drivers/mtd/nand/atmel_nand.c | 208 +++++++++++++++++++++++++++++++++++ include/configs/sama5d3xek.h | 23 ++++ include/nand.h | 6 + 6 files changed, 249 insertions(+)
Signature · 1 line
1.8.5.2
PATCH v2 1/3 arm: atmel: sama5d3: add spi spl boot support
Add SPI SPL boot support for sama5d3xek board.
---
Changes in v2:
- NONE
arch/arm/cpu/at91-common/spl.c | 2 ++ arch/arm/include/asm/arch-at91/spl.h | 2 ++ board/atmel/sama5d3xek/sama5d3xek.c | 2 ++ include/configs/sama5d3xek.h | 11 +++++++++++ 4 files changed, 17 insertions(+)
arch/arm/cpu/at91-common/spl.c +2 -0
@@ -52,6 +52,8 @@ u32 spl_boot_device(void) {#ifdef CONFIG_SYS_USE_MMC return BOOT_DEVICE_MMC1 ; +#elif CONFIG_SYS_USE_SERIALFLASH +return BOOT_DEVICE_SPI ;#endif return BOOT_DEVICE_NONE ; }
arch/arm/include/asm/arch-at91/spl.h +2 -0
@@ -14,6 +14,8 @@ enum {BOOT_DEVICE_MMC1 ,BOOT_DEVICE_MMC2 ,BOOT_DEVICE_MMC2_2 , +#elif CONFIG_SYS_USE_SERIALFLASH + BOOT_DEVICE_SPI, #endif };
board/atmel/sama5d3xek/sama5d3xek.c +2 -0
@@ -307,6 +307,8 @@ void spl_board_init(void) {#ifdef CONFIG_SYS_USE_MMC sama5d3xek_mci_hw_init (); +#elif CONFIG_SYS_USE_SERIALFLASH +at91_spi0_hw_init (1 <<0 );#endif }
include/configs/sama5d3xek.h +11 -0
@@ -258,6 +258,8 @@#define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_BOARD_INIT +#define CONFIG_SYS_MONITOR_LEN (512 << 10) +#ifdef CONFIG_SYS_USE_MMC #define CONFIG_SPL_LDSCRIPT arch/arm/cpu/at91-common/u-boot-spl.lds#define CONFIG_SPL_MMC_SUPPORT
@@ -267,6 +269,15 @@#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img"#define CONFIG_SPL_FAT_SUPPORT #define CONFIG_SPL_LIBDISK_SUPPORT + +#elif CONFIG_SYS_USE_SERIALFLASH +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SPL_SPI_BUS 0 +#define CONFIG_SPL_SPI_CS 0 +#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x8400 +#endif #endif
Signature · 1 line
1.8.5.2
PATCH v2 1/3 arm: atmel: sama5d3: add spi spl boot support
Dear Bo Shen,
Quoted 8 lines · Bo Shen
Add SPI SPL boot support for sama5d3xek board.
Signed-off-by Bo Shen <[email protected]>---
Changes in v2:
- NONE
Quoted 5 lines
arch/arm/cpu/at91-common/spl.c | 2 ++ arch/arm/include/asm/arch-at91/spl.h | 2 ++ board/atmel/sama5d3xek/sama5d3xek.c | 2 ++ include/configs/sama5d3xek.h | 11 +++++++++++ 4 files changed, 17 insertions(+)
applied to u-boot-atmel/master, thanks!
Best regards,
Andreas Bie?mann
PATCH v2 2/3 mtd: nand: atmel: prepare for nand spl boot support
In reply to Bo ShenPrepare for nand spl boot support. It supports nand software ECC and hardware PMECC.
This patch is take <drivers/mtd/nand/nand_spl_simple.c> as reference.
---
Changes in v2:
- Address the comments from Scott Wood
drivers/mtd/nand/atmel_nand.c | 208 ++++++++++++++++++++++++++++++++++++++++++ include/nand.h | 6 ++ 2 files changed, 214 insertions(+)
drivers/mtd/nand/atmel_nand.c +208 -0
@@ -31,6 +31,10 @@ #ifdef CONFIG_ATMEL_NAND_HW_PMECC +#ifdef CONFIG_SPL_BUILD +#undef CONFIG_SYS_NAND_ONFI_DETECTION +#endif + struct atmel_nand_host { struct pmecc_regs __iomem *pmecc; struct pmecc_errloc_regs __iomem *pmerrloc;
@@ -1169,6 +1173,209 @@ static int at91_nand_ready(struct mtd_info *mtd) }#endif +#ifdef CONFIG_SPL_BUILD +/* The following code is for SPL */ +static nand_info_t mtd; +static struct nand_chip nand_chip; + +static int nand_command (int block,int page,uint32_t offs,u8 cmd) +{ +struct nand_chip *this = mtd.priv; +int page_addr = page + block *CONFIG_SYS_NAND_PAGE_COUNT ; +void (*hwctrl)(struct mtd_info *mtd,int cmd, +unsigned int ctrl) = this->cmd_ctrl; + +while (this->dev_ready (&mtd)) + ; + +if (cmd ==NAND_CMD_READOOB ) { + offs +=CONFIG_SYS_NAND_PAGE_SIZE ; + cmd =NAND_CMD_READ0 ; + } + +hwctrl (&mtd, cmd,NAND_CTRL_CLE |NAND_CTRL_CHANGE ); + +if (this->options &NAND_BUSWIDTH_16 ) + offs >>=1 ; + +hwctrl (&mtd, offs &0xff ,NAND_CTRL_ALE |NAND_CTRL_CHANGE ); +hwctrl (&mtd, (offs >>8 ) &0xff ,NAND_CTRL_ALE ); +hwctrl (&mtd, (page_addr &0xff ),NAND_CTRL_ALE ); +hwctrl (&mtd, ((page_addr >>8 ) &0xff ),NAND_CTRL_ALE ); +#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE +hwctrl (&mtd, (page_addr >>16 ) &0x0f ,NAND_CTRL_ALE ); +#endif +hwctrl (&mtd,NAND_CMD_NONE ,NAND_NCE |NAND_CTRL_CHANGE ); + +hwctrl (&mtd,NAND_CMD_READSTART ,NAND_CTRL_CLE |NAND_CTRL_CHANGE ); +hwctrl (&mtd,NAND_CMD_NONE ,NAND_NCE |NAND_CTRL_CHANGE ); + +while (this->dev_ready (&mtd)) + ; + +return 0 ; +} + +static int nand_is_bad_block (int block) +{ +struct nand_chip *this = mtd.priv; + +nand_command (block,0 ,CONFIG_SYS_NAND_BAD_BLOCK_POS ,NAND_CMD_READOOB ); + +if (this->options &NAND_BUSWIDTH_16 ) { +if (readw (this->IO_ADDR_R) !=0xffff ) +return 1 ; + }else { +if (readb (this->IO_ADDR_R) !=0xff ) +return 1 ; + } + +return 0 ; +} + +#ifdef CONFIG_SPL_NAND_ECC +static int nand_ecc_pos[] =CONFIG_SYS_NAND_ECCPOS ; +#define ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \ + CONFIG_SYS_NAND_ECCSIZE) +#define ECCTOTAL (ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES) + +static int nand_read_page (int block,int page,void *dst) +{ +struct nand_chip *this = mtd.priv; +u_char ecc_calc[ECCTOTAL ]; +u_char ecc_code[ECCTOTAL ]; +u_char oob_data[CONFIG_SYS_NAND_OOBSIZE ]; +int eccsize =CONFIG_SYS_NAND_ECCSIZE ; +int eccbytes =CONFIG_SYS_NAND_ECCBYTES ; +int eccsteps =ECCSTEPS ; +int i; +uint8_t *p = dst; +nand_command (block, page,0 ,NAND_CMD_READ0 ); + +for (i =0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { +if (this->ecc.mode !=NAND_ECC_SOFT ) + this->ecc.hwctl (&mtd,NAND_ECC_READ ); + this->read_buf (&mtd, p, eccsize); + this->ecc.calculate (&mtd, p, &ecc_calc[i]); + } + this->read_buf (&mtd, oob_data,CONFIG_SYS_NAND_OOBSIZE ); + +for (i =0 ; i <ECCTOTAL ; i++) + ecc_code[i] = oob_data[nand_ecc_pos[i]]; + + eccsteps =ECCSTEPS ; + p = dst; + +for (i =0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) + this->ecc.correct (&mtd, p, &ecc_code[i], &ecc_calc[i]); + +return 0 ; +} +#else +static int nand_read_page (int block,int page,void *dst) +{ +struct nand_chip *this = mtd.priv; + +nand_command (block, page,0 ,NAND_CMD_READ0 ); +atmel_nand_pmecc_read_page (&mtd, this, dst,0 , page); + +return 0 ; +} +#endif /* CONFIG_SPL_NAND_ECC */ + +int nand_spl_load_image (uint32_t offs,unsigned int size,void *dst) +{ +unsigned int block, lastblock; +unsigned int page; + + block = offs /CONFIG_SYS_NAND_BLOCK_SIZE ; + lastblock = (offs + size -1 ) /CONFIG_SYS_NAND_BLOCK_SIZE ; + page = (offs %CONFIG_SYS_NAND_BLOCK_SIZE ) /CONFIG_SYS_NAND_PAGE_SIZE ; + +while (block <= lastblock) { +if (!nand_is_bad_block (block)) { +while (page <CONFIG_SYS_NAND_PAGE_COUNT ) { +nand_read_page (block, page, dst); + dst +=CONFIG_SYS_NAND_PAGE_SIZE ; + page++; + } + + page =0 ; + }else { + lastblock++; + } + + block++; + } + +return 0 ; +} + +int at91_nand_wait_ready (struct mtd_info *mtd) +{ +struct nand_chip *this = mtd->priv; + +udelay (this->chip_delay); + +return 0 ; +} + +int board_nand_init (struct nand_chip *nand) +{ +int ret =0 ; + + nand->ecc.mode =NAND_ECC_SOFT ; +#ifdef CONFIG_SYS_NAND_DBW_16 + nand->options =NAND_BUSWIDTH_16 ; + nand->read_buf = nand_read_buf16; +#else + nand->read_buf = nand_read_buf; +#endif + nand->cmd_ctrl = at91_nand_hwcontrol; +#ifdef CONFIG_SYS_NAND_READY_PIN + nand->dev_ready = at91_nand_ready; +#else + nand->dev_ready = at91_nand_wait_ready; +#endif + nand->chip_delay =20 ; + +#ifdef CONFIG_ATMEL_NAND_HWECC +#ifdef CONFIG_ATMEL_NAND_HW_PMECC + ret =atmel_pmecc_nand_init_params (nand, &mtd); +#endif +#endif + +return ret; +} + +void nand_init (void ) +{ + mtd.writesize =CONFIG_SYS_NAND_PAGE_SIZE ; + mtd.oobsize =CONFIG_SYS_NAND_OOBSIZE ; + mtd.priv = &nand_chip; + nand_chip.IO_ADDR_R = (void __iomem *)CONFIG_SYS_NAND_BASE ; + nand_chip.IO_ADDR_W = (void __iomem *)CONFIG_SYS_NAND_BASE ; +board_nand_init (&nand_chip); + +#ifdef CONFIG_SPL_NAND_ECC +if (nand_chip.ecc.mode ==NAND_ECC_SOFT ) { + nand_chip.ecc.calculate = nand_calculate_ecc; + nand_chip.ecc.correct = nand_correct_data; + } +#endif + +if (nand_chip.select_chip) + nand_chip.select_chip (&mtd,0 ); +} + +void nand_deselect (void ) +{ +if (nand_chip.select_chip) + nand_chip.select_chip (&mtd,-1 ); +} + +#else +#ifndef CONFIG_SYS_NAND_BASE_LIST #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }#endif
@@ -1227,3 +1434,4 @@ void board_nand_init(void)dev_err (host->dev,"atmel_nand: Fail to initialize #%d chip" , i); } +#endif /* CONFIG_SPL_BUILD */
include/nand.h +6 -0
@@ -21,10 +21,16 @@* at the same time, so do it here. When all drivers are * converted, this will go away. */ +#ifdef CONFIG_SPL_BUILD +#if defined(CONFIG_NAND_FSL_ELBC ) || defined(CONFIG_NAND_FSL_IFC ) +#define CONFIG_SYS_NAND_SELF_INIT +#endif +#else #if defined(CONFIG_NAND_FSL_ELBC ) || defined(CONFIG_NAND_ATMEL )\ || defined(CONFIG_NAND_FSL_IFC )#define CONFIG_SYS_NAND_SELF_INIT #endif +#endif extern void nand_init (void );
Signature · 1 line
1.8.5.2
PATCH v2 2/3 mtd: nand: atmel: prepare for nand spl boot support
Dear Bo Shen,
Quoted 6 lines · Bo Shen
Prepare for nand spl boot support. It supports nand software ECC and hardware PMECC.
This patch is take <drivers/mtd/nand/nand_spl_simple.c> as reference.Signed-off-by Bo Shen <[email protected]>
Quoted 7 lines
---
Changes in v2:
- Address the comments from Scott Wood
drivers/mtd/nand/atmel_nand.c| 208 ++++++++++++++++++++++++++++++++++++++++++include/nand.h| 6 ++2 files changed, 214 insertions(+)
applied to u-boot-atmel/master, thanks!
Best regards,
Andreas Bie?mann
PATCH v2 3/3 arm: atmel: sama5d3: add nand spl boot support
In reply to Bo ShenAdd NAND SPL boot support with hardware PMECC.
---
Changes in v2:
- NONE
arch/arm/cpu/at91-common/spl.c | 2 ++ arch/arm/include/asm/arch-at91/spl.h | 2 ++ board/atmel/sama5d3xek/sama5d3xek.c | 2 ++ include/configs/sama5d3xek.h | 12 ++++++++++++ 4 files changed, 18 insertions(+)
arch/arm/cpu/at91-common/spl.c +2 -0
@@ -52,6 +52,8 @@ u32 spl_boot_device(void) {#ifdef CONFIG_SYS_USE_MMC return BOOT_DEVICE_MMC1 ; +#elif CONFIG_SYS_USE_NANDFLASH +return BOOT_DEVICE_NAND ;#elif CONFIG_SYS_USE_SERIALFLASH return BOOT_DEVICE_SPI ;#endif
arch/arm/include/asm/arch-at91/spl.h +2 -0
@@ -14,6 +14,8 @@ enum {BOOT_DEVICE_MMC1 ,BOOT_DEVICE_MMC2 ,BOOT_DEVICE_MMC2_2 , +#elif CONFIG_SYS_USE_NANDFLASH +BOOT_DEVICE_NAND , #elif CONFIG_SYS_USE_SERIALFLASH BOOT_DEVICE_SPI, #endif
board/atmel/sama5d3xek/sama5d3xek.c +2 -0
@@ -307,6 +307,8 @@ void spl_board_init(void) {#ifdef CONFIG_SYS_USE_MMC sama5d3xek_mci_hw_init (); +#elif CONFIG_SYS_USE_NANDFLASH +sama5d3xek_nand_hw_init ();#elif CONFIG_SYS_USE_SERIALFLASH at91_spi0_hw_init (1 <<0 );#endif
include/configs/sama5d3xek.h +12 -0
@@ -270,6 +270,18 @@#define CONFIG_SPL_FAT_SUPPORT #define CONFIG_SPL_LIBDISK_SUPPORT +#elif CONFIG_SYS_USE_NANDFLASH +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_NAND_DRIVERS +#define CONFIG_SPL_NAND_BASE +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x40000 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE +#define CONFIG_SYS_NAND_PAGE_SIZE 0x800 +#define CONFIG_SYS_NAND_PAGE_COUNT 64 +#define CONFIG_SYS_NAND_OOBSIZE 64 +#define CONFIG_SYS_NAND_BLOCK_SIZE 0x20000 +#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0x0 +#elif CONFIG_SYS_USE_SERIALFLASH #define CONFIG_SPL_SPI_SUPPORT #define CONFIG_SPL_SPI_FLASH_SUPPORT
Signature · 1 line
1.8.5.2
PATCH v2 3/3 arm: atmel: sama5d3: add nand spl boot support
Dear Bo Shen,
Quoted 8 lines · Bo Shen
Add NAND SPL boot support with hardware PMECC.
Signed-off-by Bo Shen <[email protected]>---
Changes in v2:
- NONE
Quoted 5 lines
arch/arm/cpu/at91-common/spl.c | 2 ++ arch/arm/include/asm/arch-at91/spl.h | 2 ++ board/atmel/sama5d3xek/sama5d3xek.c | 2 ++ include/configs/sama5d3xek.h | 12 ++++++++++++ 4 files changed, 18 insertions(+)
applied to u-boot-atmel/master, thanks!
Best regards,
Andreas Bie?mann