summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen Xu <b45815@freescale.com>2014-12-16 20:30:08 -0600
committerAllen Xu <b45815@freescale.com>2014-12-16 22:36:20 -0600
commit9045626dbc7798cc340f64699bc9bd35c537498a (patch)
treebe2e411a897b8232c2c2e3b84f66b709f1d7c7ed
parentbbf8af8909842d6e9f6c2175eade998faf58a0d6 (diff)
downloadu-boot-imx-9045626dbc7798cc340f64699bc9bd35c537498a.zip
u-boot-imx-9045626dbc7798cc340f64699bc9bd35c537498a.tar.gz
u-boot-imx-9045626dbc7798cc340f64699bc9bd35c537498a.tar.bz2
MLK-10035-2: supports NAND chips with oob size up to 744 byte
Update the u-boot code to support NAND chips with oob size up to 744 byte. For the NAND flash MT29F32G08CBADA, which consists of 2 planes x 1064 blocks per plane. Obviously the block number is not power-of-2. But all MTD driver assumes the page per block and block per plane must be a power of 2 number. So the last 40 blocks in each plane must be truncated. Signed-off-by: Allen Xu <b45815@freescale.com>
-rw-r--r--arch/arm/include/asm/imx-common/regs-bch.h4
-rw-r--r--drivers/mtd/nand/mxs_nand.c24
-rw-r--r--include/linux/mtd/nand.h2
3 files changed, 19 insertions, 11 deletions
diff --git a/arch/arm/include/asm/imx-common/regs-bch.h b/arch/arm/include/asm/imx-common/regs-bch.h
index a33d341..1a60b15 100644
--- a/arch/arm/include/asm/imx-common/regs-bch.h
+++ b/arch/arm/include/asm/imx-common/regs-bch.h
@@ -5,7 +5,7 @@
* on behalf of DENX Software Engineering GmbH
*
* Based on code from LTIB:
- * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2014 Freescale Semiconductor, Inc. All Rights Reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -148,6 +148,7 @@ struct mxs_bch_regs {
#define BCH_FLASHLAYOUT0_ECC0_ECC30 (0xf << 12)
#define BCH_FLASHLAYOUT0_ECC0_ECC32 (0x10 << 12)
#define BCH_FLASHLAYOUT0_GF13_0_GF14_1 (1 << 10)
+#define BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET 10
#define BCH_FLASHLAYOUT0_DATA0_SIZE_MASK 0xfff
#define BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET 0
@@ -178,6 +179,7 @@ struct mxs_bch_regs {
#define BCH_FLASHLAYOUT1_ECCN_ECC30 (0xf << 12)
#define BCH_FLASHLAYOUT1_ECCN_ECC32 (0x10 << 12)
#define BCH_FLASHLAYOUT1_GF13_0_GF14_1 (1 << 10)
+#define BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET 10
#define BCH_FLASHLAYOUT1_DATAN_SIZE_MASK 0xfff
#define BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET 0
diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index 9479e11..8ef9b07 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -41,6 +41,9 @@
#define MXS_NAND_BCH_TIMEOUT 10000
+int chunk_data_chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
+int galois_field = 13;
+
struct mxs_nand_info {
int cur_chip;
@@ -130,12 +133,12 @@ static void mxs_nand_return_dma_descs(struct mxs_nand_info *info)
static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size)
{
- return page_data_size / MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
+ return page_data_size / chunk_data_chunk_size;
}
static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
{
- return ecc_strength * 13;
+ return ecc_strength * galois_field;
}
static uint32_t mxs_nand_aux_status_offset(void)
@@ -149,7 +152,7 @@ static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
int ecc_strength;
ecc_strength = ((page_oob_size - MXS_NAND_METADATA_SIZE) * 8)
- / (13 * mxs_nand_ecc_chunk_cnt(page_data_size));
+ /(galois_field * mxs_nand_ecc_chunk_cnt(page_data_size));
/* We need the minor even number. */
ecc_strength -= ecc_strength & 1;
@@ -166,7 +169,7 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
uint32_t block_mark_chunk_bit_offset;
uint32_t block_mark_bit_offset;
- chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
+ chunk_data_size_in_bits = chunk_data_chunk_size * 8;
chunk_ecc_size_in_bits = mxs_nand_ecc_size_in_bits(ecc_strength);
chunk_total_size_in_bits =
@@ -966,9 +969,8 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
uint32_t tmp;
if (mtd->oobsize > MXS_NAND_CHUNK_DATA_CHUNK_SIZE) {
- printf("we do not support the NAND whose OOB size is"
- "larger then 512 bytes!\n");
- return -EINVAL;
+ chunk_data_chunk_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 2;
+ galois_field = 14;
}
/* Configure BCH and set NFC geometry */
@@ -980,16 +982,20 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
<< BCH_FLASHLAYOUT0_ECC0_OFFSET;
- tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE
+ tmp |= chunk_data_chunk_size
>> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
+ tmp |= (14 == galois_field ? 1 : 0)
+ << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
writel(tmp, &bch_regs->hw_bch_flash0layout0);
tmp = (mtd->writesize + mtd->oobsize)
<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
<< BCH_FLASHLAYOUT1_ECCN_OFFSET;
- tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE
+ tmp |= chunk_data_chunk_size
>> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
+ tmp |= (14 == galois_field ? 1 : 0)
+ << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
writel(tmp, &bch_regs->hw_bch_flash0layout1);
/* Set *all* chip selects to use layout 0 */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 0546565..2636a98 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -46,7 +46,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);
* is supported now. If you add a chip with bigger oobsize/page
* adjust this accordingly.
*/
-#define NAND_MAX_OOBSIZE 640
+#define NAND_MAX_OOBSIZE 744
#define NAND_MAX_PAGESIZE 8192
/*