[U-Boot] [PATCH v3 1/5] at91: atmel_nand: extract HWECC initialization code into one function: atmel_hw_nand_init_param().
Andreas Bießmann
andreas.devel at googlemail.com
Sat Sep 1 16:19:53 CEST 2012
Dear Josh Wu,
On 23.08.2012 12:05, Josh Wu wrote:
> This patch
> 1. extract the hwecc initialization code into one function. It is a preparation for adding atmel PMECC support.
> 2. enable CONFIG_SYS_NAND_SELF_INIT. Which make us can configurate the ecc parameters between nand_scan_ident() and nand_scan_tail().
>
> Signed-off-by: Josh Wu <josh.wu at atmel.com>
> ---
applied to u-boot-atmel/master with two minor changes (read on).
> Changes since v2:
> adapt to CONFIG_SYS_NAND_SELF_INIT.
>
> drivers/mtd/nand/atmel_nand.c | 145 ++++++++++++++++++++++++-----------------
> include/nand.h | 2 +-
> 2 files changed, 88 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index de66382..21dc4f5 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -232,6 +232,60 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,
> static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
> {
> }
> +
> +int atmel_hwecc_nand_init_param(struct nand_chip *nand, struct mtd_info *mtd)
> +{
> + nand->ecc.mode = NAND_ECC_HW;
> + nand->ecc.calculate = atmel_nand_calculate;
> + nand->ecc.correct = atmel_nand_correct;
> + nand->ecc.hwctl = atmel_nand_hwctl;
> + nand->ecc.read_page = atmel_nand_read_page;
> + nand->ecc.bytes = 4;
> +
> + if (nand->ecc.mode == NAND_ECC_HW) {
> + /* ECC is calculated for the whole page (1 step) */
> + nand->ecc.size = mtd->writesize;
> +
> + /* set ECC page size and oob layout */
> + switch (mtd->writesize) {
> + case 512:
> + nand->ecc.layout = &atmel_oobinfo_small;
> + ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR,
> + ATMEL_ECC_PAGESIZE_528);
> + break;
> + case 1024:
> + nand->ecc.layout = &atmel_oobinfo_large;
> + ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR,
> + ATMEL_ECC_PAGESIZE_1056);
> + break;
> + case 2048:
> + nand->ecc.layout = &atmel_oobinfo_large;
> + ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR,
> + ATMEL_ECC_PAGESIZE_2112);
> + break;
> + case 4096:
> + nand->ecc.layout = &atmel_oobinfo_large;
> + ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR,
> + ATMEL_ECC_PAGESIZE_4224);
> + break;
> + default:
> + /* page size not handled by HW ECC */
> + /* switching back to soft ECC */
> + nand->ecc.mode = NAND_ECC_SOFT;
> + nand->ecc.calculate = NULL;
> + nand->ecc.correct = NULL;
> + nand->ecc.hwctl = NULL;
> + nand->ecc.read_page = NULL;
> + nand->ecc.postpad = 0;
> + nand->ecc.prepad = 0;
> + nand->ecc.bytes = 0;
> + break;
> + }
> + }
> +
> + return 0;
> +}
> +
> #endif
>
> static void at91_nand_hwcontrol(struct mtd_info *mtd,
> @@ -267,12 +321,20 @@ static int at91_nand_ready(struct mtd_info *mtd)
> }
> #endif
>
> -int board_nand_init(struct nand_chip *nand)
> -{
> -#ifdef CONFIG_ATMEL_NAND_HWECC
> - static int chip_nr = 0;
> - struct mtd_info *mtd;
> +#ifndef CONFIG_SYS_NAND_BASE_LIST
> +#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
> #endif
> +static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
> +static ulong base_addr[CONFIG_SYS_MAX_NAND_DEVICE] = CONFIG_SYS_NAND_BASE_LIST;
> +
> +int atmel_nand_chip_init(int devnum, ulong base_addr)
> +{
> + int ret;
> + struct mtd_info *mtd = &nand_info[devnum];
> + struct nand_chip *nand = &nand_chip[devnum];
> +
> + mtd->priv = nand;
> + nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;
>
> nand->ecc.mode = NAND_ECC_SOFT;
> #ifdef CONFIG_SYS_NAND_DBW_16
> @@ -284,62 +346,29 @@ int board_nand_init(struct nand_chip *nand)
> #endif
> nand->chip_delay = 20;
>
> -#ifdef CONFIG_ATMEL_NAND_HWECC
> - nand->ecc.mode = NAND_ECC_HW;
> - nand->ecc.calculate = atmel_nand_calculate;
> - nand->ecc.correct = atmel_nand_correct;
> - nand->ecc.hwctl = atmel_nand_hwctl;
> - nand->ecc.read_page = atmel_nand_read_page;
> - nand->ecc.bytes = 4;
> -#endif
> + ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
> + if (ret)
> + return ret;
>
> #ifdef CONFIG_ATMEL_NAND_HWECC
> - mtd = &nand_info[chip_nr++];
> - mtd->priv = nand;
> + ret = atmel_hwecc_nand_init_param(nand, mtd);
> +#endif
> + if (ret)
> + return ret;
put this return value check into the ifdef, run time tested on
at91sam9260ek with HWECC enabled in board config.
>
> - /* Detect NAND chips */
> - if (nand_scan_ident(mtd, 1, NULL)) {
> - printk(KERN_WARNING "NAND Flash not found !\n");
> - return -ENXIO;
> - }
> + ret = nand_scan_tail(mtd);
> + if (!ret)
> + nand_register(devnum);
>
> - if (nand->ecc.mode == NAND_ECC_HW) {
> - /* ECC is calculated for the whole page (1 step) */
> - nand->ecc.size = mtd->writesize;
> -
> - /* set ECC page size and oob layout */
> - switch (mtd->writesize) {
> - case 512:
> - nand->ecc.layout = &atmel_oobinfo_small;
> - ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_528);
> - break;
> - case 1024:
> - nand->ecc.layout = &atmel_oobinfo_large;
> - ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_1056);
> - break;
> - case 2048:
> - nand->ecc.layout = &atmel_oobinfo_large;
> - ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_2112);
> - break;
> - case 4096:
> - nand->ecc.layout = &atmel_oobinfo_large;
> - ecc_writel(CONFIG_SYS_NAND_ECC_BASE, MR, ATMEL_ECC_PAGESIZE_4224);
> - break;
> - default:
> - /* page size not handled by HW ECC */
> - /* switching back to soft ECC */
> - nand->ecc.mode = NAND_ECC_SOFT;
> - nand->ecc.calculate = NULL;
> - nand->ecc.correct = NULL;
> - nand->ecc.hwctl = NULL;
> - nand->ecc.read_page = NULL;
> - nand->ecc.postpad = 0;
> - nand->ecc.prepad = 0;
> - nand->ecc.bytes = 0;
> - break;
> - }
> - }
> -#endif
> + return ret;
> +}
>
> - return 0;
> +void board_nand_init(void)
> +{
> + int i;
> + for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
> + if (atmel_nand_chip_init(i, base_addr[i]))
> + printk(KERN_ERR "atmel_nand: Fail to initialize #%d chip",
> + i);
> }
> +
removed this empty newline at EOF.
> diff --git a/include/nand.h b/include/nand.h
> index a48b1b8..c554c55 100644
> --- a/include/nand.h
> +++ b/include/nand.h
> @@ -31,7 +31,7 @@
> * at the same time, so do it here. When all drivers are
> * converted, this will go away.
> */
> -#if defined(CONFIG_NAND_FSL_ELBC)
> +#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_ATMEL)
> #define CONFIG_SYS_NAND_SELF_INIT
> #endif
>
>
Best regards
Andreas Bießmann
More information about the U-Boot
mailing list