From patchwork Wed Jun 1 11:23:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 628607 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 3rKSfg4Z6Dz9t5c for ; Wed, 1 Jun 2016 21:23:55 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D4300A74FF; Wed, 1 Jun 2016 13:23:52 +0200 (CEST) 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 4i4_3BBIMMXf; Wed, 1 Jun 2016 13:23:52 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 986A3A750A; Wed, 1 Jun 2016 13:23:47 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id F3A0DA74D0 for ; Wed, 1 Jun 2016 13:23:41 +0200 (CEST) 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 y4ev5r-Xqvsb for ; Wed, 1 Jun 2016 13:23:41 +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 mail.free-electrons.com (down.free-electrons.com [37.187.137.238]) by theia.denx.de (Postfix) with ESMTP id BB55CA74A8 for ; Wed, 1 Jun 2016 13:23:38 +0200 (CEST) Received: by mail.free-electrons.com (Postfix, from userid 110) id A1D613F4; Wed, 1 Jun 2016 13:23:37 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from bbrezillon.home (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 4DD52417; Wed, 1 Jun 2016 13:23:27 +0200 (CEST) From: Boris Brezillon To: Piotr Zierhoffer , Hans de Goede , Scott Wood Date: Wed, 1 Jun 2016 13:23:18 +0200 Message-Id: <1464780204-17737-2-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1464780204-17737-1-git-send-email-boris.brezillon@free-electrons.com> References: <1464780204-17737-1-git-send-email-boris.brezillon@free-electrons.com> Cc: Tom Rini , u-boot@lists.denx.de, linux-sunxi@googlegroups.com Subject: [U-Boot] [PATCH v2 1/7] spl: nand: sunxi: remove support for so-called 'syndrome' mode X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The sunxi SPL NAND controller driver supports use 'BootROM'-like configs, that is, configs where the ECC bytes and real data are interleaved in the page instead of putting ECC bytes in the OOB area. Doing that has several drawbacks: - since you're interleaving data and ECC bytes you can't use the whole page otherwise you might override the bad block marker with non-FF bytes. - to solve the bad block marker problem, the ROM code supports partially using the page, but this introduces a huge penalty both in term of read speed and NAND memory usage. While this is fine for rather small binaries(like the SPL one which is at maximum 24KB large), it becomes non-negligible for the bootloader image (several hundred of KB). - auto-detection of the page size is not reliable (this is in my opinion the biggest problem). If you get the page size wrong, you'll end up reading data at a different offset than what was specified by the caller and the reading may succeed (if valid data were written at this address). For all those reasons I think it's wiser to completely remove support for 'syndrome' configs. If we ever need to support it again, then I'd recommend specifying all the config parameters through Kconfig options. Signed-off-by: Boris Brezillon Acked-by: Hans de Goede --- drivers/mtd/nand/sunxi_nand_spl.c | 56 ++++++++++----------------------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index b0e07aa..1739da2 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -119,9 +119,6 @@ const uint16_t random_seed[128] = { 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db, }; -/* random seed used for syndrome calls */ -const uint16_t random_seed_syndrome = 0x4a80; - #define MAX_RETRIES 10 static int check_value_inner(int offset, int expected_bits, @@ -183,7 +180,7 @@ void nand_init(void) } static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, - int addr_cycles, uint32_t real_addr, dma_addr_t dst, int syndrome) + int addr_cycles, uint32_t real_addr, dma_addr_t dst) { uint32_t val; int i, ecc_off = 0; @@ -209,17 +206,11 @@ static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, page = real_addr / page_size; column = real_addr % page_size; - if (syndrome) - column += (column / ecc_page_size) * ecc_off; - /* clear ecc status */ writel(0, SUNXI_NFC_BASE + NFC_ECC_ST); /* Choose correct seed */ - if (syndrome) - rand_seed = random_seed_syndrome; - else - rand_seed = random_seed[page % 128]; + rand_seed = random_seed[page % 128]; writel((rand_seed << 16) | NFC_ECC_RANDOM_EN | NFC_ECC_EN | NFC_ECC_PIPELINE | (ecc_mode << 12), @@ -228,9 +219,8 @@ static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, val = readl(SUNXI_NFC_BASE + NFC_CTL); writel(val | NFC_CTL_RAM_METHOD, SUNXI_NFC_BASE + NFC_CTL); - if (!syndrome) - writel(page_size + (column / ecc_page_size) * ecc_off, - SUNXI_NFC_BASE + NFC_SPARE_AREA); + writel(page_size + (column / ecc_page_size) * ecc_off, + SUNXI_NFC_BASE + NFC_SPARE_AREA); flush_dcache_range(dst, ALIGN(dst + ecc_page_size, ARCH_DMA_MINALIGN)); @@ -266,7 +256,7 @@ static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_TRANS | NFC_PAGE_CMD | NFC_WAIT_FLAG | ((addr_cycles - 1) << NFC_ADDR_NUM_OFFSET) | - NFC_SEND_ADR | NFC_DATA_SWAP_METHOD | (syndrome ? NFC_SEQ : 0), + NFC_SEND_ADR | NFC_DATA_SWAP_METHOD, SUNXI_NFC_BASE + NFC_CMD); if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_DMA_INT_FLAG, @@ -292,7 +282,7 @@ static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, } static int nand_read_ecc(int page_size, int ecc_strength, int ecc_page_size, - int addr_cycles, uint32_t offs, uint32_t size, void *dest, int syndrome) + int addr_cycles, uint32_t offs, uint32_t size, void *dest) { void *end = dest + size; @@ -301,16 +291,14 @@ static int nand_read_ecc(int page_size, int ecc_strength, int ecc_page_size, for ( ;dest < end; dest += ecc_page_size, offs += ecc_page_size) { if (nand_read_page(page_size, ecc_strength, ecc_page_size, - addr_cycles, offs, (dma_addr_t)dest, - syndrome)) + addr_cycles, offs, (dma_addr_t)dest)) return -1; } return 0; } -static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest, - int syndrome) +static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest) { const struct { int page_size; @@ -337,7 +325,7 @@ static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest, nand_configs[i].ecc_strength, nand_configs[i].ecc_page_size, nand_configs[i].addr_cycles, - offs, size, dest, syndrome) == 0) { + offs, size, dest) == 0) { debug("success\n"); nand_config = i; return 0; @@ -351,48 +339,32 @@ static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest, nand_configs[nand_config].ecc_strength, nand_configs[nand_config].ecc_page_size, nand_configs[nand_config].addr_cycles, - offs, size, dest, syndrome); + offs, size, dest); } int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) { -#if CONFIG_SYS_NAND_U_BOOT_OFFS == CONFIG_SPL_PAD_TO - /* - * u-boot-dtb.bin appended to SPL, use syndrome (like the BROM does) - * and try different erase block sizes to find the backup. - */ - const uint32_t boot_offsets[] = { - 0 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, - 1 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, - 2 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, - 4 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, - }; - const int syndrome = 1; -#else /* - * u-boot-dtb.bin on its own partition, do not use syndrome, u-boot - * partition sits after 2 eraseblocks (spl, spl-backup), look for - * backup u-boot 1 erase block further. + * u-boot partition sits after 2 eraseblocks (spl, spl-backup), look + * for backup u-boot 1 erase block further. */ const uint32_t eraseblock_size = CONFIG_SYS_NAND_U_BOOT_OFFS / 2; const uint32_t boot_offsets[] = { CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_OFFS + eraseblock_size, }; - const int syndrome = 0; -#endif int i; if (offs == CONFIG_SYS_NAND_U_BOOT_OFFS) { for (i = 0; i < ARRAY_SIZE(boot_offsets); i++) { if (nand_read_buffer(boot_offsets[i], size, - dest, syndrome) == 0) + dest) == 0) return 0; } return -1; } - return nand_read_buffer(offs, size, dest, syndrome); + return nand_read_buffer(offs, size, dest); } void nand_deselect(void)