From patchwork Fri Dec 19 04:39:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 422757 X-Patchwork-Delegate: scottwood@freescale.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 01BEE140082 for ; Fri, 19 Dec 2014 15:39:57 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 720004B61D; Fri, 19 Dec 2014 05:39:51 +0100 (CET) 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 4hVCUeeCI14W; Fri, 19 Dec 2014 05:39:51 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 01C794B628; Fri, 19 Dec 2014 05:39:49 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D7FC14B606 for ; Fri, 19 Dec 2014 05:39:40 +0100 (CET) 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 HLs9zNvPn1Cg for ; Fri, 19 Dec 2014 05:39:40 +0100 (CET) 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 na01-by2-obe.outbound.protection.outlook.com (mail-by2on0106.outbound.protection.outlook.com [207.46.100.106]) by theia.denx.de (Postfix) with ESMTPS id E5F1A4B605 for ; Fri, 19 Dec 2014 05:39:35 +0100 (CET) Received: from BN3PR0301CA0084.namprd03.prod.outlook.com (25.160.152.180) by BN1PR0301MB0724.namprd03.prod.outlook.com (25.160.78.143) with Microsoft SMTP Server (TLS) id 15.1.49.12; Fri, 19 Dec 2014 04:39:32 +0000 Received: from BL2FFO11FD036.protection.gbl (2a01:111:f400:7c09::104) by BN3PR0301CA0084.outlook.office365.com (2a01:111:e400:401e::52) with Microsoft SMTP Server (TLS) id 15.1.36.23 via Frontend Transport; Fri, 19 Dec 2014 04:39:32 +0000 Received: from tx30smr01.am.freescale.net (192.88.168.50) by BL2FFO11FD036.mail.protection.outlook.com (10.173.161.132) with Microsoft SMTP Server (TLS) id 15.1.26.17 via Frontend Transport; Fri, 19 Dec 2014 04:39:31 +0000 Received: from linux-jyl1.ap.freescale.net (b51431-11.ap.freescale.net [10.193.102.234]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id sBJ4dFq0002234; Thu, 18 Dec 2014 21:39:29 -0700 From: Peng Fan To: Date: Fri, 19 Dec 2014 12:39:13 +0800 Message-ID: <1418963953-1623-2-git-send-email-Peng.Fan@freescale.com> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1418963953-1623-1-git-send-email-Peng.Fan@freescale.com> References: <1418963953-1623-1-git-send-email-Peng.Fan@freescale.com> X-EOPAttributedMessage: 0 Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=Peng.Fan@freescale.com; X-Forefront-Antispam-Report: CIP:192.88.168.50; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(339900001)(189002)(199003)(50226001)(229853001)(99396003)(575784001)(4396001)(107046002)(2371004)(2351001)(120916001)(92566001)(85426001)(84676001)(89996001)(47776003)(20776003)(64706001)(87936001)(19580405001)(19580395003)(46102003)(97736003)(36756003)(86362001)(6806004)(50466002)(77156002)(62966003)(21056001)(110136001)(68736005)(77096005)(48376002)(2950100001)(105606002)(50986999)(76176999)(104016003)(31966008)(106466001); DIR:OUT; SFP:1102; SCL:1; SRVR:BN1PR0301MB0724; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; MLV:sfv; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Antispam: UriScan:; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;SRVR:BN1PR0301MB0724; X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004); SRVR:BN1PR0301MB0724; X-Forefront-PRVS: 0430FA5CB7 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:; SRVR:BN1PR0301MB0724; X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Dec 2014 04:39:31.8010 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.168.50] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN1PR0301MB0724 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 2/2] mtd:mxs:nand support oobsize bigger than 512 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 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 If ecc chunk data size is 512 and oobsize is bigger than 512, there is a chance that block_mark_bit_offset conflicts with bch ecc area. The following graph is modified from kernel gpmi-nand.c driver with each data block 512 bytes. We can see that Block Mark conflicts with ecc area from bch view. We can enlarge the ecc chunk size to avoid this problem to those oobsize which is larger than 512. | P | |<----------------------------------------------------------------->| | | | (Block Mark) | | P' | | | | |<--------------------------------------------------->| D | | O'| | |<--------->| |<->| V V V V V +---+--------------+-+--------------+-+--------------+-+----------+-+---+ | M | data |E| data |E| data |E| data |E| | +---+--------------+-+--------------+-+--------------+-+----------+-+---+ ^ ^ | O | |<---------------->| P : the page size for BCH module. E : The ECC strength. G : the length of Galois Field. N : The chunk count of per page. M : the metasize of per page. C : the ecc chunk size, aka the "data" above. P': the nand chip's page size. O : the nand chip's oob size. O': the free oob. Signed-off-by: Peng Fan Reviewed-by: Marek Vasut --- arch/arm/include/asm/imx-common/regs-bch.h | 2 ++ drivers/mtd/nand/mxs_nand.c | 33 ++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 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..5c47783 100644 --- a/arch/arm/include/asm/imx-common/regs-bch.h +++ b/arch/arm/include/asm/imx-common/regs-bch.h @@ -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 a45fcf9..0db9eb3 100644 --- a/drivers/mtd/nand/mxs_nand.c +++ b/drivers/mtd/nand/mxs_nand.c @@ -29,6 +29,7 @@ #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 +#define MXS_NAND_MAX_CHUNK_DATA_CHUNK_SIZE 1024 #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512 #if defined(CONFIG_MX6) #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2 @@ -68,6 +69,8 @@ struct mxs_nand_info { }; struct nand_ecclayout fake_ecc_layout; +static int chunk_data_size = MXS_NAND_CHUNK_DATA_CHUNK_SIZE; +static int gf_len = 13; /* * Cache management functions @@ -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_size; } static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength) { - return ecc_strength * 13; + return ecc_strength * gf_len; } 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)); + / (gf_len * mxs_nand_ecc_chunk_cnt(page_data_size)); return round_down(ecc_strength, 2); } @@ -164,7 +167,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_size * 8; chunk_ecc_size_in_bits = mxs_nand_ecc_size_in_bits(ecc_strength); chunk_total_size_in_bits = @@ -963,6 +966,20 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd) struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; uint32_t tmp; + if (mtd->oobsize > MXS_NAND_MAX_CHUNK_DATA_CHUNK_SIZE) { + printf("We do not support the NAND device whose oob size is larger then %d bytes!\n", MXS_NAND_MAX_CHUNK_DATA_CHUNK_SIZE); + return -EINVAL; + } + + /* + * If oobsize bigger than 512, galois filed should be 14, ecc chunk + * data size should be 1024 but not 512. + */ + if (mtd->oobsize > MXS_NAND_CHUNK_DATA_CHUNK_SIZE) { + gf_len = 14; + chunk_data_size = MXS_NAND_MAX_CHUNK_DATA_CHUNK_SIZE; + } + /* Configure BCH and set NFC geometry */ mxs_reset_block(&bch_regs->hw_bch_ctrl_reg); @@ -972,16 +989,16 @@ 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 - >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= chunk_data_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= (14 == gf_len ? 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 - >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= chunk_data_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT; + tmp |= (14 == gf_len ? 1 : 0) << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout1); /* Set *all* chip selects to use layout 0 */