From patchwork Wed Aug 14 06:16:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pekon gupta X-Patchwork-Id: 266966 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id DB5E82C0085 for ; Wed, 14 Aug 2013 16:17:46 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2A9B84A11E; Wed, 14 Aug 2013 08:17:43 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id foduNBpd9tNy; Wed, 14 Aug 2013 08:17:42 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BB9B74A0FE; Wed, 14 Aug 2013 08:17:30 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 97BE04A0C7 for ; Wed, 14 Aug 2013 08:17:18 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5qZLY9YNDsEp for ; Wed, 14 Aug 2013 08:17:12 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) by theia.denx.de (Postfix) with ESMTPS id 0D8FD4A0F3 for ; Wed, 14 Aug 2013 08:17:05 +0200 (CEST) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id r7E6H1F4002728; Wed, 14 Aug 2013 01:17:01 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r7E6H1F0024828; Wed, 14 Aug 2013 01:17:01 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.2.342.3; Wed, 14 Aug 2013 01:17:01 -0500 Received: from psplinux064.india.ti.com (psplinux064.india.ti.com [172.24.162.112]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id r7E6Gv74009818; Wed, 14 Aug 2013 01:16:59 -0500 From: Pekon Gupta To: , Date: Wed, 14 Aug 2013 11:46:52 +0530 Message-ID: <1376461015-29007-2-git-send-email-pekon@ti.com> X-Mailer: git-send-email 1.8.1 In-Reply-To: <1376461015-29007-1-git-send-email-pekon@ti.com> References: <1376461015-29007-1-git-send-email-pekon@ti.com> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 1/4] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de BCH8_ECC scheme implemented in omap_gpmc.c driver has following two favours +-----------------------------------+-----------------+-----------------+ |ECC Scheme | ECC Calculation | Error Detection | +-----------------------------------+-----------------+-----------------+ |OMAP_ECC_BCH8_CODE_HW |GPMC |ELM H/W engine | |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW |GPMC |S/W BCH library | +-----------------------------------+-----------------+-----------------+ Current implementation enables of BCH8_CODE_HW only for AM33xx SoC family. (using CONFIG_AM33XX). However, other SoC families (like TI81xx) also have ELM hardware module, and can support ECC error detection using ELM. This patch - replaces CONFIG_AM33xx define with CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW so that all device families having required h/w capability can use ELM for error detection in ECC_BCHx schemes. - replaces CONFIG_NAND_OMAP_BCH8 with CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW && CONFIG_BCH and separates out code for above mentioned BCH8_ECC implementations so that driver can be build independently using anyone of them. CONFIG_BCH is used to enable software BCH library in lib/bch.c Signed-off-by: Pekon Gupta --- doc/README.nand | 20 +++++++ drivers/mtd/nand/omap_gpmc.c | 128 ++++++++++++++++++++++++------------------- include/configs/am335x_evm.h | 1 + include/configs/ti814x_evm.h | 2 +- include/configs/tricorder.h | 2 +- 5 files changed, 96 insertions(+), 57 deletions(-) diff --git a/doc/README.nand b/doc/README.nand index 913e9b5..b84fce7 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -169,6 +169,26 @@ Configuration Options: Please convert your driver even if you don't need the extra flexibility, so that one day we can eliminate the old mechanism. + CONFIG_BCH + Enables software based BCH ECC algorithm present in lib/bch.c + This is used by SoC platforms which do not have in-build hardware + engine to calculate and correct BCH ECC. + + +Platform specific configs + CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW + Enables 8-bit BCH ECC scheme on NAND with following attributes + - ECC calculation done by GPMC hardware engine + - ECC error detection done by ELM hardware engine + - ECC layout compatible with ROM code + + CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW + - ECC calculation done by GPMC hardware engine + - ECC error detection done using /lib/bch.c software library + - ECC layout is comapatible to SW ECC scheme + * requires CONFIG_BCH for enabling lib/bch.c + + NOTE: ===== diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index ec1787f..d9a4a5e 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -15,9 +15,7 @@ #include #include #include -#ifdef CONFIG_AM33XX #include -#endif static uint8_t cs; static __maybe_unused struct nand_ecclayout hw_nand_oob = @@ -274,7 +272,7 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode) { uint32_t val; uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1; -#ifdef CONFIG_AM33XX +#if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW) uint32_t unused_length = 0; #endif uint32_t wr_mode = BCH_WRAPMODE_6; @@ -283,7 +281,7 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode) /* Clear the ecc result registers, select ecc reg as 1 */ writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control); -#ifdef CONFIG_AM33XX +#if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW) wr_mode = BCH_WRAPMODE_1; switch (bch->nibbles) { @@ -375,10 +373,11 @@ static void __maybe_unused omap_ecc_disable(struct mtd_info *mtd) writel((readl(&gpmc_cfg->ecc_config) & ~0x1), &gpmc_cfg->ecc_config); } + /* - * BCH8 support (needs ELM and thus AM33xx-only) + * BCH support using ELM module */ -#ifdef CONFIG_AM33XX +#if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW) /* * omap_read_bch8_result - Read BCH result for BCH8 level * @@ -631,12 +630,13 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip, } return 0; } -#endif /* CONFIG_AM33XX */ +#endif /* CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW */ /* * OMAP3 BCH8 support (with BCH library) */ -#ifdef CONFIG_NAND_OMAP_BCH8 +#if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) && \ + defined(CONFIG_BCH) /* * omap_calculate_ecc_bch - Read BCH ECC result * @@ -752,7 +752,7 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd) chip_priv->control = NULL; } } -#endif /* CONFIG_NAND_OMAP_BCH8 */ +#endif /* CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW && CONFIG_BCH */ #ifndef CONFIG_SPL_BUILD /* @@ -803,25 +803,43 @@ void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength) nand->ecc.calculate = omap_calculate_ecc; omap_hwecc_init(nand); printf("1-bit hamming HW ECC selected\n"); - } -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8) - else if (eccstrength == 8) { - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.layout = &hw_bch8_nand_oob; - nand->ecc.size = 512; -#ifdef CONFIG_AM33XX - nand->ecc.bytes = 14; - nand->ecc.read_page = omap_read_page_bch; + } else if (eccstrength == 8) { +#if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW) + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = &hw_bch8_nand_oob; + nand->ecc.size = 512; + nand->ecc.bytes = 14; + nand->ecc.read_page = omap_read_page_bch; + nand->ecc.hwctl = omap_enable_ecc_bch; + nand->ecc.correct = omap_correct_data_bch; + nand->ecc.calculate = omap_calculate_ecc_bch; + /* ELM is used for ECC error detection */ + elm_init(); + nand->priv = &bch_priv; + omap_hwecc_init_bch(nand, NAND_ECC_READ); + printf("using OMAP_ECC_BCH8_CODE_HW\n"); +#elif defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) && \ + defined(CONFIG_BCH) + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = &hw_bch8_nand_oob; + nand->ecc.size = 512; + nand->ecc.bytes = 13; + nand->ecc.hwctl = omap_enable_ecc_bch; + nand->ecc.correct = omap_correct_data_bch; + nand->ecc.calculate = omap_calculate_ecc_bch; + /* BCH SW library is used for error detection */ + bch_priv.control = init_bch(13, 8, 0x201b); + if (!bch_priv.control) { + puts("Could not init_bch()\n"); + return -ENODEV; + } + nand->priv = &bch_priv; + omap_hwecc_init_bch(nand, NAND_ECC_READ); + printf("using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n"); #else - nand->ecc.bytes = 13; + printf("selected ECC not supported or not enabled\n"); #endif - nand->ecc.hwctl = omap_enable_ecc_bch; - nand->ecc.correct = omap_correct_data_bch; - nand->ecc.calculate = omap_calculate_ecc_bch; - omap_hwecc_init_bch(nand, NAND_ECC_READ); - printf("8-bit BCH HW ECC selected\n"); } -#endif } else { nand->ecc.mode = NAND_ECC_SOFT; /* Use mtd default settings */ @@ -894,44 +912,45 @@ int board_nand_init(struct nand_chip *nand) nand->chip_delay = 100; -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8) -#ifdef CONFIG_AM33XX - /* AM33xx uses the ELM */ - /* required in case of BCH */ +#if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW) + printf("NAND: using OMAP_ECC_BCH8_CODE_HW\n"); + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = &hw_bch8_nand_oob; + nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; + nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.strength = 8; + nand->ecc.hwctl = omap_enable_ecc_bch; + nand->ecc.correct = omap_correct_data_bch; + nand->ecc.calculate = omap_calculate_ecc_bch; + nand->ecc.read_page = omap_read_page_bch; + /* ELM is used for ECC error detection */ elm_init(); -#else - /* - * Whereas other OMAP based SoC do not have the ELM, they use the BCH - * SW library. - */ - bch_priv.control = init_bch(13, 8, 0x201b /* hw polynominal */); + nand->priv = &bch_priv; + omap_hwecc_init_bch(nand, NAND_ECC_READ); +#elif defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) && \ + defined(CONFIG_BCH) + printf("NAND: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n"); + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = &hw_bch8_nand_oob; + nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; + nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; + nand->ecc.strength = 8; + nand->ecc.hwctl = omap_enable_ecc_bch; + nand->ecc.correct = omap_correct_data_bch; + nand->ecc.calculate = omap_calculate_ecc_bch; + /* BCH SW library is used for error detection */ + bch_priv.control = init_bch(13, 8, 0x201b /* hw polynominal */); if (!bch_priv.control) { puts("Could not init_bch()\n"); return -ENODEV; } -#endif - /* BCH info that will be correct for SPL or overridden otherwise. */ nand->priv = &bch_priv; -#endif - - /* Default ECC mode */ -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8) - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.layout = &hw_bch8_nand_oob; - nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; - nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; - nand->ecc.strength = 8; - nand->ecc.hwctl = omap_enable_ecc_bch; - nand->ecc.correct = omap_correct_data_bch; - nand->ecc.calculate = omap_calculate_ecc_bch; -#ifdef CONFIG_AM33XX - nand->ecc.read_page = omap_read_page_bch; -#endif omap_hwecc_init_bch(nand, NAND_ECC_READ); -#else -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC) +#elif !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC) + printf("NAND: using OMAP_ECC_HAM1_CODE_SW\n"); nand->ecc.mode = NAND_ECC_SOFT; #else + printf("NAND: using OMAP_ECC_HAM1_CODE_HW\n"); nand->ecc.mode = NAND_ECC_HW; nand->ecc.layout = &hw_nand_oob; nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; @@ -942,7 +961,6 @@ int board_nand_init(struct nand_chip *nand) nand->ecc.strength = 1; omap_hwecc_init(nand); #endif -#endif #ifdef CONFIG_SPL_BUILD if (nand->options & NAND_BUSWIDTH_16) diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index c5a6d4b..8f3bd54 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -493,6 +493,7 @@ #define CONFIG_NAND /* NAND support */ #ifdef CONFIG_NAND +#define CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW #define CONFIG_CMD_NAND #define CONFIG_CMD_MTDPARTS #define MTDIDS_DEFAULT "nand0=omap2-nand.0" diff --git a/include/configs/ti814x_evm.h b/include/configs/ti814x_evm.h index b6fafc7..546cc07 100644 --- a/include/configs/ti814x_evm.h +++ b/include/configs/ti814x_evm.h @@ -286,7 +286,7 @@ #define CONFIG_NAND /* NAND support */ #ifdef CONFIG_NAND -#define CONFIG_MTD_NAND_OMAP_BCH +#define CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW #define CONFIG_CMD_NAND #define CONFIG_CMD_MTDPARTS #define MTDIDS_DEFAULT "nand0=omap2-nand.0" diff --git a/include/configs/tricorder.h b/include/configs/tricorder.h index 4e2cb65..dc4f6dc 100644 --- a/include/configs/tricorder.h +++ b/include/configs/tricorder.h @@ -109,7 +109,7 @@ #define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND */ /* devices */ -#define CONFIG_NAND_OMAP_BCH8 +#define CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW #define CONFIG_BCH /* commands to include */