diff options
author | Allen Xu <b45815@freescale.com> | 2014-12-16 20:30:08 -0600 |
---|---|---|
committer | Peng Fan <Peng.Fan@freescale.com> | 2015-04-29 14:46:01 +0800 |
commit | 77ca54d246cf90af88afe4eb93e63823b1de1e4a (patch) | |
tree | 921000930157c140529a8ea2930a85ca50be37d9 | |
parent | 823e4975ecf30c59d949fafae47d8a37dd82f36c (diff) | |
download | u-boot-imx-77ca54d246cf90af88afe4eb93e63823b1de1e4a.zip u-boot-imx-77ca54d246cf90af88afe4eb93e63823b1de1e4a.tar.gz u-boot-imx-77ca54d246cf90af88afe4eb93e63823b1de1e4a.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>
(cherry picked from commit 9045626dbc7798cc340f64699bc9bd35c537498a)
Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Conflicts:
include/linux/mtd/nand.h
-rw-r--r-- | arch/arm/include/asm/imx-common/regs-bch.h | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/mxs_nand.c | 22 |
2 files changed, 17 insertions, 9 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 4790013..5a7ef6b 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) @@ -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 */ |