From patchwork Sun Nov 3 15:49:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1188572 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="cZLd+1ZJ"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 475gPm21gbz9sP3 for ; Mon, 4 Nov 2019 02:50:52 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id F17EFC22049; Sun, 3 Nov 2019 15:50:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 39343C21FBC; Sun, 3 Nov 2019 15:50:27 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 4FA00C21FBF; Sun, 3 Nov 2019 15:50:24 +0000 (UTC) Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by lists.denx.de (Postfix) with ESMTPS id 80ED3C21C29 for ; Sun, 3 Nov 2019 15:50:24 +0000 (UTC) Received: by mail-wr1-f66.google.com with SMTP id w18so14340269wrt.3 for ; Sun, 03 Nov 2019 07:50:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+tI3PeCShF7j1TYZcGvo3brwccwgSavGy6xlxfVSQC4=; b=cZLd+1ZJXGyYmJbPNVgHQWsGh5aP9PZU4hNlb0si32RYtsrOOAbmOBzoljcJ9lNz6V Pk5qSylIty+3fsp4jxOdAZoo+0H8nZ1DfladZxDjywunEaXXgvWUS7HY3mqBbKeBQNIv WiZNafTk6DRNPDKKvbN9KeVbTfPn33KTiNmuAOW0vR4MQWse6f5pW3p3gweMS1IhjPDZ WvtLgfubkYQjiAp5xHh78Jao44bBfBbyButMBuWWWEaQE+3D2CvyX7lMS2xG+LiOMurL LnS/qhI5G4tANKFgI8aKciu70xstBdK0w2vHX+bm15Z58AkXYEW3EuRsuZ8SPUZB67t4 ztiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+tI3PeCShF7j1TYZcGvo3brwccwgSavGy6xlxfVSQC4=; b=nsz3HZkLxFOQDU18V8Mk/F84qbaCSEJytNhRtSyBUUMaQMaPxNe2x+AuTA1/qUF5pZ AzM2W9t3bNpYg7LPqYpM5JuTVnaLrJit0rrT864wY6OdSed/7+w5b3PpbPFQUnrCJFS+ 9T67bWCMtwHFCNLMypHMdyII6FoSRj++fCPYBxBqXPmRpm+4qJGETlSXoCWTfx9xsuKj 7zRWapWrktxoyOpe/0Pt/6aWVkJ0tQ/4HFa+npiDDMgg6ROyw8SH0+MHUn5pvGZM2Cfs uAR4fkthvgBsd5Kv5oyNc9yPj9YH/pE14Q0OogsaNh5ER105wotWU3NDo8gOF5CuEwqt wg5g== X-Gm-Message-State: APjAAAXTEm+Wd6SCvN1/nKtmdzheCWrzEuAjDvrLyV/IVihq8EcV7CBL StmSL+j1C1EeatMmocf+LmzI5Us7ZC0= X-Google-Smtp-Source: APXvYqxszLc1Yc4U7fBQ5Gy12lLDN80FLlgURbSgkInvGPe5uX3VZqtzrBisXJH8+sVt9naaenO3Bg== X-Received: by 2002:adf:e5cc:: with SMTP id a12mr20219694wrn.258.1572796223771; Sun, 03 Nov 2019 07:50:23 -0800 (PST) Received: from localhost (46-126-71-123.dynamic.hispeed.ch. [46.126.71.123]) by smtp.gmail.com with ESMTPSA id d202sm13672543wmd.47.2019.11.03.07.50.22 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 03 Nov 2019 07:50:23 -0800 (PST) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Sun, 3 Nov 2019 16:49:42 +0100 Message-Id: <20191103154946.24969-2-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191103154946.24969-1-igor.opaniuk@gmail.com> References: <20191103154946.24969-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v3 1/5] imx: gpmi: add defines for hw randominizer X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Igor Opaniuk Extend GPMI Integrated ECC Control Register Description, include additional defines for enabling randomizer function and providing proper randomizer type. For additional details check i.MX7 APR, section 9.6.6.3 GPMI Integrated ECC Control Register Description (GPMI_ECCCTRLn) Signed-off-by: Igor Opaniuk Tested-by: Max Krummenacher Reviewed-by: Oleksandr Suvorov --- arch/arm/include/asm/mach-imx/regs-gpmi.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/include/asm/mach-imx/regs-gpmi.h b/arch/arm/include/asm/mach-imx/regs-gpmi.h index 80cb731724..33daa53c45 100644 --- a/arch/arm/include/asm/mach-imx/regs-gpmi.h +++ b/arch/arm/include/asm/mach-imx/regs-gpmi.h @@ -70,6 +70,11 @@ struct mxs_gpmi_regs { #define GPMI_ECCCTRL_ECC_CMD_OFFSET 13 #define GPMI_ECCCTRL_ECC_CMD_DECODE (0x0 << 13) #define GPMI_ECCCTRL_ECC_CMD_ENCODE (0x1 << 13) +#define GPMI_ECCCTRL_RANDOMIZER_ENABLE (1 << 11) +#define GPMI_ECCCTRL_RANDOMIZER_TYPE0 0 +#define GPMI_ECCCTRL_RANDOMIZER_TYPE1 (1 << 9) +#define GPMI_ECCCTRL_RANDOMIZER_TYPE2 (2 << 9) + #define GPMI_ECCCTRL_ENABLE_ECC (1 << 12) #define GPMI_ECCCTRL_BUFFER_MASK_MASK 0x1ff #define GPMI_ECCCTRL_BUFFER_MASK_OFFSET 0 From patchwork Sun Nov 3 15:49:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1188574 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="eVtCCp9W"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 475gRF24CNz9sP3 for ; Mon, 4 Nov 2019 02:52:09 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 03EEAC21E73; Sun, 3 Nov 2019 15:51:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 40B16C21E73; Sun, 3 Nov 2019 15:50:45 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 9B363C2202F; Sun, 3 Nov 2019 15:50:28 +0000 (UTC) Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by lists.denx.de (Postfix) with ESMTPS id 2D998C22005 for ; Sun, 3 Nov 2019 15:50:26 +0000 (UTC) Received: by mail-wr1-f68.google.com with SMTP id w18so14340324wrt.3 for ; Sun, 03 Nov 2019 07:50:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DyDKgT+wXFx82VM7lGkkCrgKvts7w3dMEdkXiezwKpc=; b=eVtCCp9WbxpIS2OpRSvSIFASbbThD7vtkTpexiDfgCDlHayF6F55mLzEgpq5NbOH8z LB5QsJEHaV1l7eicnJtS7O2DogvHupJqBTXGxb4lUMYg2vqe7f7xXcJ8K8mMtkcthSvz V5x/t6sKoIXM+Mu+gHr9XPNABFxAKDC4Uirp9N7NM97Plq82omUcJRpxRdEYcZ92WlcW VlmIugQw9Yaw4NfgeHDdED3A411riL7SPbr3CkcA3VSGwlW7m8OxR4KHazYTQcxhaAzD 2LW2rJYyA0ZjcCSZTdg1zbvLK6+vh/Z//KiHz5gEpkRYyEBwrCIZvQ/z+cE23bpMTs7S mX3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DyDKgT+wXFx82VM7lGkkCrgKvts7w3dMEdkXiezwKpc=; b=U0p8ie9z7ZEgRM9d4Q/y3lDMw2m/X7Cn7mRkpR+m4SxJdyCZ0I8Th78+HKLBylg/N5 W1XbJQBB2irKo83B0LobiWkAGplITCaFQPMnF8uAd48R5WBvScJLv/nMj6mGoFMwvXem HodRyRYaNSVT70bsau07Fj3ykxMHJowmn0hd1wRLiuxa2V37BfQ+afjlrRxDbXRD5pdz 7C3fIV1y724MhyPQVxGGbEX2M9W1BXoTFLILKZcTVVm5wt9aFhDz8JENT4kwAcGdzCdM UBEIh+fOjiWncj1w3BQ1g20JLS2OfJJYgryW+Kq9rUm1srjGqOthspuOYtGBKQfzC0vU ClOw== X-Gm-Message-State: APjAAAUOqMtmvDetg8sd/CXMOZz4e7dx8TxAjGJtcnuyx4F0/RvTs2zN ZXF1GlMWZrS+Gzwx8n4Zb83dnTlClUw= X-Google-Smtp-Source: APXvYqxud+DtpBhwrtHXprnyesF9BJnLp7ONV15da0czAJHw3PSc7uXstWVqEtPkaEO6tfvt4xUOlA== X-Received: by 2002:a5d:4c83:: with SMTP id z3mr19812621wrs.92.1572796225345; Sun, 03 Nov 2019 07:50:25 -0800 (PST) Received: from localhost (46-126-71-123.dynamic.hispeed.ch. [46.126.71.123]) by smtp.gmail.com with ESMTPSA id d20sm20917012wra.4.2019.11.03.07.50.24 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 03 Nov 2019 07:50:24 -0800 (PST) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Sun, 3 Nov 2019 16:49:43 +0100 Message-Id: <20191103154946.24969-3-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191103154946.24969-1-igor.opaniuk@gmail.com> References: <20191103154946.24969-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , Marcel Ziswiler , Sergey Kubushyn , Max Krummenacher Subject: [U-Boot] [PATCH v3 2/5] nand: mxs_nand: add API for switching different BCH layouts X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Igor Opaniuk On i.MX7 in a sake of reducing the disturbances caused by a neighboring cells in the FCB page in the NAND chip, a randomizer is enabled when reading the FCB page by ROM bootloader. Add API for setting BCH to specific layout (and restoring it back) used by ROM bootloader to be able to burn it in a proper way to NAND using nandbcb command. Signed-off-by: Igor Opaniuk Signed-off-by: Anti Sullin Tested-by: Max Krummenacher Reviewed-by: Oleksandr Suvorov --- drivers/mtd/nand/raw/mxs_nand.c | 116 ++++++++++++++++++++++++++++++++ include/mxs_nand.h | 22 ++++++ 2 files changed, 138 insertions(+) diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index a41b9620d0..ad7b644886 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -740,6 +740,19 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; + if (is_mx7() && nand_info->en_randomizer) { + d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | + GPMI_ECCCTRL_RANDOMIZER_TYPE2; + /* + * Write NAND page number needed to be randomized + * to GPMI_ECCCOUNT register. + * + * The value is between 0-255. For additional details + * check 9.6.6.4 of i.MX7D Applications Processor reference + */ + d->cmd.pio_words[3] |= (page % 255) << 16; + } + mxs_dma_desc_append(channel, d); /* Flush caches */ @@ -1003,6 +1016,10 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) uint32_t tmp; int ret; + nand_info->en_randomizer = 0; + nand_info->oobsize = mtd->oobsize; + nand_info->writesize = mtd->writesize; + ret = mxs_nand_set_geometry(mtd, geo); if (ret) return ret; @@ -1020,6 +1037,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout0); + nand_info->bch_flash0layout0 = tmp; tmp = (mtd->writesize + mtd->oobsize) << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; @@ -1028,6 +1046,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout1); + nand_info->bch_flash0layout1 = tmp; /* Set *all* chip selects to use layout 0 */ writel(0, &bch_regs->hw_bch_layoutselect); @@ -1303,3 +1322,100 @@ err: free(nand_info); } #endif + +/* + * Read NAND layout for FCB block generation. + */ +void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l) +{ + struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + u32 tmp; + + tmp = readl(&bch_regs->hw_bch_flash0layout0); + l->nblocks = (tmp & BCH_FLASHLAYOUT0_NBLOCKS_MASK) >> + BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; + l->meta_size = (tmp & BCH_FLASHLAYOUT0_META_SIZE_MASK) >> + BCH_FLASHLAYOUT0_META_SIZE_OFFSET; + + tmp = readl(&bch_regs->hw_bch_flash0layout1); + l->data0_size = 4 * ((tmp & BCH_FLASHLAYOUT0_DATA0_SIZE_MASK) >> + BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET); + l->ecc0 = (tmp & BCH_FLASHLAYOUT0_ECC0_MASK) >> + BCH_FLASHLAYOUT0_ECC0_OFFSET; + l->datan_size = 4 * ((tmp & BCH_FLASHLAYOUT1_DATAN_SIZE_MASK) >> + BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET); + l->eccn = (tmp & BCH_FLASHLAYOUT1_ECCN_MASK) >> + BCH_FLASHLAYOUT1_ECCN_OFFSET; +} + +/* + * Set BCH to specific layout used by ROM bootloader to read FCB. + */ +void mxs_nand_mode_fcb(struct mtd_info *mtd) +{ + u32 tmp; + struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + struct nand_chip *nand = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + + nand_info->en_randomizer = 1; + + mtd->writesize = 1024; + mtd->oobsize = 1862 - 1024; + + /* 8 ecc_chunks_*/ + tmp = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; + /* 32 bytes for metadata */ + tmp |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; + /* using ECC62 level to be performed */ + tmp |= 0x1F << BCH_FLASHLAYOUT0_ECC0_OFFSET; + /* 0x20 * 4 bytes of the data0 block */ + tmp |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET; + tmp |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; + writel(tmp, &bch_regs->hw_bch_flash0layout0); + + /* 1024 for data + 838 for OOB */ + tmp = 1862 << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; + /* using ECC62 level to be performed */ + tmp |= 0x1F << BCH_FLASHLAYOUT1_ECCN_OFFSET; + /* 0x20 * 4 bytes of the data0 block */ + tmp |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET; + tmp |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; + writel(tmp, &bch_regs->hw_bch_flash0layout1); +} + +/* + * Restore BCH to normal settings. + */ +void mxs_nand_mode_normal(struct mtd_info *mtd) +{ + struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + struct nand_chip *nand = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + + nand_info->en_randomizer = 0; + + mtd->writesize = nand_info->writesize; + mtd->oobsize = nand_info->oobsize; + + writel(nand_info->bch_flash0layout0, &bch_regs->hw_bch_flash0layout0); + writel(nand_info->bch_flash0layout1, &bch_regs->hw_bch_flash0layout1); +} + +uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + struct bch_geometry *geo = &nand_info->bch_geometry; + + return geo->block_mark_byte_offset; +} + +uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + struct bch_geometry *geo = &nand_info->bch_geometry; + + return geo->block_mark_bit_offset; +} diff --git a/include/mxs_nand.h b/include/mxs_nand.h index 4bd65cded9..ada20483d0 100644 --- a/include/mxs_nand.h +++ b/include/mxs_nand.h @@ -66,8 +66,30 @@ struct mxs_nand_info { /* DMA descriptors */ struct mxs_dma_desc **desc; uint32_t desc_index; + + /* Hardware BCH interface and randomizer */ + u32 en_randomizer; + u32 writesize; + u32 oobsize; + u32 bch_flash0layout0; + u32 bch_flash0layout1; +}; + +struct mxs_nand_layout { + u32 nblocks; + u32 meta_size; + u32 data0_size; + u32 ecc0; + u32 datan_size; + u32 eccn; }; int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info); int mxs_nand_init_spl(struct nand_chip *nand); int mxs_nand_setup_ecc(struct mtd_info *mtd); + +void mxs_nand_mode_fcb(struct mtd_info *mtd); +void mxs_nand_mode_normal(struct mtd_info *mtd); +u32 mxs_nand_mark_byte_offset(struct mtd_info *mtd); +u32 mxs_nand_mark_bit_offset(struct mtd_info *mtd); +void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l); From patchwork Sun Nov 3 15:49:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1188573 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="UW2f9uZG"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 475gQX3l3pz9sP3 for ; Mon, 4 Nov 2019 02:51:32 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 3CC4AC2204C; Sun, 3 Nov 2019 15:50:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C92BEC22036; Sun, 3 Nov 2019 15:50:42 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id E4CE7C21FF3; Sun, 3 Nov 2019 15:50:29 +0000 (UTC) Received: from mail-wm1-f65.google.com (mail-wm1-f65.google.com [209.85.128.65]) by lists.denx.de (Postfix) with ESMTPS id 423C8C22037 for ; Sun, 3 Nov 2019 15:50:27 +0000 (UTC) Received: by mail-wm1-f65.google.com with SMTP id 11so14112581wmk.0 for ; Sun, 03 Nov 2019 07:50:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=x2DQsaZX6MBxFr+hM1ifJr9PgJE/nEi+sNxstnwChkQ=; b=UW2f9uZGtrrGJ7x1f4ZtKIqu+dh6boWcuZJI97r1Ci3psJM3ujGQhr5IV+y2H5pFcP cvww+tLiNbT2IJ0rhCWW6UkktcHoJAu5WVuG2a3es/RkvX6lEuBvfvvuMlASWSqfsYMj RypltTw2PX8Mxo9VT3fdiORBTm+Tvim9DYM+g2+2Iz8oUV0evkawczxugFEjAUINXBnS IuigQlAih9uBgeq/4r6ncxN5yznf8EBneQwb/6SFJsSBgmm2saSmPuLzZyVnCMANdDhg WgKaIeRW1U21etN5Rr53S1iC9VUFwX75ZhhbwoC3mr6LdhpAuar5TYBl2kE3K3nrIMKW D+9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=x2DQsaZX6MBxFr+hM1ifJr9PgJE/nEi+sNxstnwChkQ=; b=B38f6qtl12K675ykpg9UbZYjEYqmMxnOLLSqEiJOXVBXElfObYjqPDjytVnGNfSjBF iStI8qFd7N6ISXWQdrdyz3ixGfopzt7wbhJg4+utBo/oy22pi6g7GnNxPV7JCKv+8TGM 7ce/RmeZf9Hu4eqWJYV7D/wcJAS0XLnrXS+U5/UWRPf2k2/pRavWgrgHtW7qy46SWMcx EFGskkhJhgu7ahVqsoK5Y2opAh5gftGv7Px0Lh8NmF1BXWUQwCiPd/4DRUwE44/JIbEq VEcnN+o/EizFx4MyEzOvRSjfHVN0L4Dw2gfYw3gSDRuHE8S4jSmzYZtg/l1JZGOQLTrF PmJg== X-Gm-Message-State: APjAAAVmehweCOnvalLk+dmg3zn3tEmsUG40ot/Z647spRIBUeqP8PtH iL3NxnhQis4JtPEdeVYY4EyjdCiIaKQ= X-Google-Smtp-Source: APXvYqwdbYnJDQhB7LkDfTZuZbdPuiytLo3mRtVS1tW4JYnDyT0RBvoffs+hofdaBV/SIattzFGIIQ== X-Received: by 2002:a1c:6486:: with SMTP id y128mr18054018wmb.148.1572796226491; Sun, 03 Nov 2019 07:50:26 -0800 (PST) Received: from localhost (46-126-71-123.dynamic.hispeed.ch. [46.126.71.123]) by smtp.gmail.com with ESMTPSA id p4sm5328908wrx.71.2019.11.03.07.50.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 03 Nov 2019 07:50:26 -0800 (PST) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Sun, 3 Nov 2019 16:49:44 +0100 Message-Id: <20191103154946.24969-4-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191103154946.24969-1-igor.opaniuk@gmail.com> References: <20191103154946.24969-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v3 3/5] imx: nandbcb: add support for i.MX7 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Igor Opaniuk Add support for updating FCB/DBBT on i.MX7: - additional new fields in FCB structure - Leverage hardware BCH/randomizer for writing FCB Signed-off-by: Igor Opaniuk Tested-by: Max Krummenacher Reviewed-by: Oleksandr Suvorov --- arch/arm/include/asm/mach-imx/imx-nandbcb.h | 12 ++ arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/cmd_nandbcb.c | 137 +++++++++++++------- 3 files changed, 104 insertions(+), 47 deletions(-) diff --git a/arch/arm/include/asm/mach-imx/imx-nandbcb.h b/arch/arm/include/asm/mach-imx/imx-nandbcb.h index 033659a038..907e7ed8f9 100644 --- a/arch/arm/include/asm/mach-imx/imx-nandbcb.h +++ b/arch/arm/include/asm/mach-imx/imx-nandbcb.h @@ -106,6 +106,18 @@ struct fcb_block { /* The swap position of main area in spare area */ u32 spare_offset; + + /* Actual for iMX7 only */ + u32 onfi_sync_enable; + u32 onfi_sync_speed; + u32 onfi_sync_nand_data; + u32 reserved2[6]; + u32 disbbm_search; + u32 disbbm_search_limit; + u32 reserved3[15]; + u32 read_retry_enable; + u32 reserved4[1]; + u32 fill_to_1024[183]; }; #endif /* _IMX_NAND_BCB_H_ */ diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 4a2f39b110..3f93fe5174 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -82,7 +82,7 @@ config CMD_NANDBCB bool "i.MX6 NAND Boot Control Block(BCB) command" depends on NAND && CMD_MTDPARTS select BCH if MX6UL || MX6ULL - default y if ARCH_MX6 && NAND_MXS + default y if (ARCH_MX6 && NAND_MXS) || (ARCH_MX7 && NAND_MXS) help Unlike normal 'nand write/erase' commands, this command update Boot Control Block(BCB) for i.MX6 platform NAND IP's. diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index 1a2e017aaf..a3a44bc284 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -131,26 +132,36 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + struct mxs_nand_layout l; + + mxs_nand_get_layout(mtd, &l); fcb->fingerprint = FCB_FINGERPRINT; fcb->version = FCB_VERSION_1; + fcb->pagesize = mtd->writesize; fcb->oob_pagesize = mtd->writesize + mtd->oobsize; fcb->sectors = mtd->erasesize / mtd->writesize; - /* Divide ECC strength by two and save the value into FCB structure. */ - fcb->ecc_level = nand_info->bch_geometry.ecc_strength >> 1; - - fcb->ecc_type = fcb->ecc_level; + fcb->meta_size = l.meta_size; + fcb->nr_blocks = l.nblocks; + fcb->ecc_nr = l.data0_size; + fcb->ecc_level = l.ecc0; + fcb->ecc_size = l.datan_size; + fcb->ecc_type = l.eccn; /* Also hardcoded in kobs-ng */ - fcb->ecc_nr = 0x00000200; - fcb->ecc_size = 0x00000200; - fcb->datasetup = 80; - fcb->datahold = 60; - fcb->addr_setup = 25; - fcb->dsample_time = 6; - fcb->meta_size = 10; + if (is_mx6()) { + fcb->datasetup = 80; + fcb->datahold = 60; + fcb->addr_setup = 25; + fcb->dsample_time = 6; + } else if (is_mx7()) { + fcb->datasetup = 10; + fcb->datahold = 7; + fcb->addr_setup = 15; + fcb->dsample_time = 6; + } /* DBBT search area starts at second page on first block */ fcb->dbbt_start = 1; @@ -162,6 +173,9 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) fcb->nr_blocks = mtd->writesize / fcb->ecc_nr - 1; + fcb->disbbm = 0; + fcb->disbbm_search = 0; + fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4); } @@ -197,6 +211,7 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, size_t fwsize, dummy; int i, ret; + fcb_raw_page = 0; /* erase */ memset(&opts, 0, sizeof(opts)); opts.offset = off; @@ -287,50 +302,79 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, else if (ret > 0) dbbt->dbbtpages = 1; - /* write fcb/dbbt */ - fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); - if (!fcb_raw_page) { - debug("failed to allocate fcb_raw_page\n"); - ret = -ENOMEM; - goto dbbt_data_page_err; - } + /* + * We prepare raw page only for i.MX6, for i.MX7 we + * leverage BCH hw module instead + */ + if (is_mx6()) { + /* write fcb/dbbt */ + fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, + GFP_KERNEL); + if (!fcb_raw_page) { + debug("failed to allocate fcb_raw_page\n"); + ret = -ENOMEM; + goto dbbt_data_page_err; + } #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) - /* 40 bit BCH, for i.MX6UL(L) */ - encode_bch_ecc(fcb_raw_page + 32, fcb, 40); + /* 40 bit BCH, for i.MX6UL(L) */ + encode_bch_ecc(fcb_raw_page + 32, fcb, 40); #else - memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); - encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512); + memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); + encode_hamming_13_8(fcb_raw_page + 12, + fcb_raw_page + 12 + 512, 512); #endif - /* - * Set the first and second byte of OOB data to 0xFF, not 0x00. These - * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since - * the FCB is mostly written to the first page in a block, a scan for - * factory bad blocks will detect these blocks as bad, e.g. when - * function nand_scan_bbt() is executed to build a new bad block table. - */ - memset(fcb_raw_page + mtd->writesize, 0xFF, 2); - + /* + * Set the first and second byte of OOB data to 0xFF, + * not 0x00. These bytes are used as the Manufacturers Bad + * Block Marker (MBBM). Since the FCB is mostly written to + * the first page in a block, a scan for + * factory bad blocks will detect these blocks as bad, e.g. + * when function nand_scan_bbt() is executed to build a new + * bad block table. + */ + memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + } for (i = 0; i < nr_blks_fcb; i++) { if (mtd_block_isbad(mtd, off)) { printf("Block %d is bad, skipped\n", i); continue; } - /* raw write */ - mtd_oob_ops_t ops = { - .datbuf = (u8 *)fcb_raw_page, - .oobbuf = ((u8 *)fcb_raw_page) + mtd->writesize, - .len = mtd->writesize, - .ooblen = mtd->oobsize, - .mode = MTD_OPS_RAW - }; - - ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); - if (ret) - goto fcb_raw_page_err; - debug("NAND fcb write: 0x%x offset, 0x%x bytes written: %s\n", - mtd->erasesize * i, ops.len, ret ? "ERROR" : "OK"); + /* + * User BCH ECC hardware module for i.MX7 + */ + if (is_mx7()) { + u32 off = i * mtd->erasesize; + size_t rwsize = sizeof(*fcb); + + printf("Writing %d bytes to 0x%x: ", rwsize, off); + + /* switch nand BCH to FCB compatible settings */ + mxs_nand_mode_fcb(mtd); + ret = nand_write(mtd, off, &rwsize, + (unsigned char *)fcb); + mxs_nand_mode_normal(mtd); + + printf("%s\n", ret ? "ERROR" : "OK"); + } else if (is_mx6()) { + /* raw write */ + mtd_oob_ops_t ops = { + .datbuf = (u8 *)fcb_raw_page, + .oobbuf = ((u8 *)fcb_raw_page) + + mtd->writesize, + .len = mtd->writesize, + .ooblen = mtd->oobsize, + .mode = MTD_OPS_RAW + }; + + ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); + if (ret) + goto fcb_raw_page_err; + debug("NAND fcb write: 0x%x offset 0x%x written: %s\n", + mtd->erasesize * i, ops.len, ret ? + "ERROR" : "OK"); + } ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, mtd->writesize, &dummy, dbbt_page); @@ -352,7 +396,8 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, } fcb_raw_page_err: - kfree(fcb_raw_page); + if (is_mx6()) + kfree(fcb_raw_page); dbbt_data_page_err: kfree(dbbt_data_page); dbbt_page_err: From patchwork Sun Nov 3 15:49:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1188575 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="hReY7k+v"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 475gS15ChFz9sP3 for ; Mon, 4 Nov 2019 02:52:49 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 6EEB5C22049; Sun, 3 Nov 2019 15:51:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id BEAD3C22037; Sun, 3 Nov 2019 15:50:47 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 60767C22032; Sun, 3 Nov 2019 15:50:30 +0000 (UTC) Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by lists.denx.de (Postfix) with ESMTPS id 70F34C22036 for ; Sun, 3 Nov 2019 15:50:28 +0000 (UTC) Received: by mail-wr1-f68.google.com with SMTP id a11so14308295wra.6 for ; Sun, 03 Nov 2019 07:50:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=qGdatWkVTnBarBIWyBa8LwCNc+1hjt2JLjlR8YXuJs0=; b=hReY7k+vfTp/L+F2raBAO6nxldzx082k5di9oTzYHPQcwK+CQhcVWPrLnARFkNI1jO swul7BKKjEw26lHjAiA1WnAX3yZp3RFbEH4rxaSAF0YPsIuyHU25a//OqQ3p8TxTUrZb EdIjk8yfJSRUVnGTpvN9QMHiWFndHr04wf/GE416qyU0taO7TM21gXMRJcYqSAJdajYu BGcOZ47D1Bm3tOkZW1a/a00PuBlHEHOFcTMj8200Dnz0H4SL9X9AnPLEBDtR266MNAhK Hw+zNqwW9bm7J4i7Xn+x1449oz2LI76KTS9564R6tSZMePAOK16YFd1QWEVXKAGN2ze4 FMng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qGdatWkVTnBarBIWyBa8LwCNc+1hjt2JLjlR8YXuJs0=; b=U+hrfBIod3No6jk6C9yfUgLH4UsgVryufIHQvCKIqxiE3eKsPxg4+PnvQcbcX0CeaQ I1nF6hScbBvJsOX+CvaS6UHi08+6DiLyV2zx4wixAgPE0XZMsvH5tIwA7k3/GxZimLIN pcO0KgYS9D2OzckZh1oSaYV5VykAlpGazafGkXGI9wMRWjbglp6GZ18ISFGZoqYhucWm g6oVZkU1CjyKtSlIVpaxB6LfpdSq81zpEZELhHqhPq9O7knPDlEzQt/6rkK+T4cIegvJ bwg0zwTvmZFGZsfWgjkmGZ2PEo+xA6YRI4ZNSMe1/jkEFH3HFWnwuxXBJCph16EmrcZ9 0jvg== X-Gm-Message-State: APjAAAVuvSwjlWbqprZQvU1p1LYUD6gEZp/8BYc2/m5hUfRMUutVGv0Q m0szUgMSw9T7CP7HpTHa4o1oMRo4yyI= X-Google-Smtp-Source: APXvYqwQ22WWkPDxbaKvbTkavvW9QSUcNwbKxrIPlaYpoxQ1Yy282raDwGu108qKEbcyU2EleOGekA== X-Received: by 2002:a5d:448f:: with SMTP id j15mr18621535wrq.70.1572796227637; Sun, 03 Nov 2019 07:50:27 -0800 (PST) Received: from localhost (46-126-71-123.dynamic.hispeed.ch. [46.126.71.123]) by smtp.gmail.com with ESMTPSA id 189sm18406143wmc.7.2019.11.03.07.50.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 03 Nov 2019 07:50:27 -0800 (PST) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Sun, 3 Nov 2019 16:49:45 +0100 Message-Id: <20191103154946.24969-5-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191103154946.24969-1-igor.opaniuk@gmail.com> References: <20191103154946.24969-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v3 4/5] imx: nandbcb: refactor update function X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Igor Opaniuk Move code for writing FCB/DBBT pages to a separate function Signed-off-by: Igor Opaniuk Tested-by: Max Krummenacher Reviewed-by: Oleksandr Suvorov --- arch/arm/mach-imx/cmd_nandbcb.c | 231 ++++++++++++++++++-------------- 1 file changed, 127 insertions(+), 104 deletions(-) diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index a3a44bc284..6e7e982ee5 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -128,7 +128,8 @@ static u32 calc_chksum(void *buf, size_t size) return ~chksum; } -static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) +static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, + u32 fw1_start, u32 fw2_start, u32 fw_pages) { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); @@ -176,6 +177,11 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) fcb->disbbm = 0; fcb->disbbm_search = 0; + fcb->fw1_start = fw1_start; /* Firmware image starts on this sector */ + fcb->fw2_start = fw2_start; /* Secondary FW Image starting Sector */ + fcb->fw1_pages = fw_pages; /* Number of sectors in firmware image */ + fcb->fw2_pages = fw_pages; /* Number of sector in secondary FW image */ + fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4); } @@ -199,6 +205,114 @@ static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks) return n_bad_blocks; } +static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, + struct dbbt_block *dbbt, void *dbbt_data_page, + loff_t off) +{ + void *fcb_raw_page = 0; + int i, ret; + size_t dummy; + + /* + * We prepare raw page only for i.MX6, for i.MX7 we + * leverage BCH hw module instead + */ + if (is_mx6()) { + /* write fcb/dbbt */ + fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, + GFP_KERNEL); + if (!fcb_raw_page) { + debug("failed to allocate fcb_raw_page\n"); + ret = -ENOMEM; + return ret; + } + +#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) + /* 40 bit BCH, for i.MX6UL(L) */ + encode_bch_ecc(fcb_raw_page + 32, fcb, 40); +#else + memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); + encode_hamming_13_8(fcb_raw_page + 12, + fcb_raw_page + 12 + 512, 512); +#endif + /* + * Set the first and second byte of OOB data to 0xFF, + * not 0x00. These bytes are used as the Manufacturers Bad + * Block Marker (MBBM). Since the FCB is mostly written to + * the first page in a block, a scan for + * factory bad blocks will detect these blocks as bad, e.g. + * when function nand_scan_bbt() is executed to build a new + * bad block table. + */ + memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + } + for (i = 0; i < 2; i++) { + if (mtd_block_isbad(mtd, off)) { + printf("Block %d is bad, skipped\n", i); + continue; + } + + /* + * User BCH ECC hardware module for i.MX7 + */ + if (is_mx7()) { + u32 off = i * mtd->erasesize; + size_t rwsize = sizeof(*fcb); + + printf("Writing %d bytes to 0x%x: ", rwsize, off); + + /* switch nand BCH to FCB compatible settings */ + mxs_nand_mode_fcb(mtd); + ret = nand_write(mtd, off, &rwsize, + (unsigned char *)fcb); + mxs_nand_mode_normal(mtd); + + printf("%s\n", ret ? "ERROR" : "OK"); + } else if (is_mx6()) { + /* raw write */ + mtd_oob_ops_t ops = { + .datbuf = (u8 *)fcb_raw_page, + .oobbuf = ((u8 *)fcb_raw_page) + + mtd->writesize, + .len = mtd->writesize, + .ooblen = mtd->oobsize, + .mode = MTD_OPS_RAW + }; + + ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); + if (ret) + goto fcb_raw_page_err; + debug("NAND fcb write: 0x%x offset 0x%x written: %s\n", + mtd->erasesize * i, ops.len, ret ? + "ERROR" : "OK"); + } + + ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, + mtd->writesize, &dummy, (void *)dbbt); + if (ret) + goto fcb_raw_page_err; + debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n", + mtd->erasesize * i + mtd->writesize, dummy, + ret ? "ERROR" : "OK"); + + /* dbbtpages == 0 if no bad blocks */ + if (dbbt->dbbtpages > 0) { + loff_t to = (mtd->erasesize * i + mtd->writesize * 5); + + ret = mtd_write(mtd, to, mtd->writesize, &dummy, + dbbt_data_page); + if (ret) + goto fcb_raw_page_err; + } + } + +fcb_raw_page_err: + if (is_mx6()) + kfree(fcb_raw_page); + + return ret; +} + static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, size_t maxsize, const u_char *buf) { @@ -206,12 +320,12 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, struct fcb_block *fcb; struct dbbt_block *dbbt; loff_t fw1_off; - void *fwbuf, *fcb_raw_page, *dbbt_page, *dbbt_data_page; + void *fwbuf, *dbbt_page, *dbbt_data_page; + u32 fw1_start, fw1_pages; int nr_blks, nr_blks_fcb, fw1_blk; - size_t fwsize, dummy; - int i, ret; + size_t fwsize; + int ret; - fcb_raw_page = 0; /* erase */ memset(&opts, 0, sizeof(opts)); opts.offset = off; @@ -273,9 +387,9 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, goto fwbuf_err; } - fcb->fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; - fcb->fw1_pages = size / mtd->writesize + 1; - fill_fcb(fcb, mtd); + fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; + fw1_pages = size / mtd->writesize + 1; + fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages); /* fill dbbt */ dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); @@ -302,102 +416,11 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, else if (ret > 0) dbbt->dbbtpages = 1; - /* - * We prepare raw page only for i.MX6, for i.MX7 we - * leverage BCH hw module instead - */ - if (is_mx6()) { - /* write fcb/dbbt */ - fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, - GFP_KERNEL); - if (!fcb_raw_page) { - debug("failed to allocate fcb_raw_page\n"); - ret = -ENOMEM; - goto dbbt_data_page_err; - } - -#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) - /* 40 bit BCH, for i.MX6UL(L) */ - encode_bch_ecc(fcb_raw_page + 32, fcb, 40); -#else - memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); - encode_hamming_13_8(fcb_raw_page + 12, - fcb_raw_page + 12 + 512, 512); -#endif - /* - * Set the first and second byte of OOB data to 0xFF, - * not 0x00. These bytes are used as the Manufacturers Bad - * Block Marker (MBBM). Since the FCB is mostly written to - * the first page in a block, a scan for - * factory bad blocks will detect these blocks as bad, e.g. - * when function nand_scan_bbt() is executed to build a new - * bad block table. - */ - memset(fcb_raw_page + mtd->writesize, 0xFF, 2); - } - for (i = 0; i < nr_blks_fcb; i++) { - if (mtd_block_isbad(mtd, off)) { - printf("Block %d is bad, skipped\n", i); - continue; - } - - /* - * User BCH ECC hardware module for i.MX7 - */ - if (is_mx7()) { - u32 off = i * mtd->erasesize; - size_t rwsize = sizeof(*fcb); - - printf("Writing %d bytes to 0x%x: ", rwsize, off); - - /* switch nand BCH to FCB compatible settings */ - mxs_nand_mode_fcb(mtd); - ret = nand_write(mtd, off, &rwsize, - (unsigned char *)fcb); - mxs_nand_mode_normal(mtd); - - printf("%s\n", ret ? "ERROR" : "OK"); - } else if (is_mx6()) { - /* raw write */ - mtd_oob_ops_t ops = { - .datbuf = (u8 *)fcb_raw_page, - .oobbuf = ((u8 *)fcb_raw_page) + - mtd->writesize, - .len = mtd->writesize, - .ooblen = mtd->oobsize, - .mode = MTD_OPS_RAW - }; - - ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); - if (ret) - goto fcb_raw_page_err; - debug("NAND fcb write: 0x%x offset 0x%x written: %s\n", - mtd->erasesize * i, ops.len, ret ? - "ERROR" : "OK"); - } - - ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, - mtd->writesize, &dummy, dbbt_page); - if (ret) - goto fcb_raw_page_err; - debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n", - mtd->erasesize * i + mtd->writesize, dummy, - ret ? "ERROR" : "OK"); - - /* dbbtpages == 0 if no bad blocks */ - if (dbbt->dbbtpages > 0) { - loff_t to = (mtd->erasesize * i + mtd->writesize * 5); - - ret = mtd_write(mtd, to, mtd->writesize, &dummy, - dbbt_data_page); - if (ret) - goto fcb_raw_page_err; - } - } + /* write fcb and dbbt to nand */ + ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, off); + if (ret < 0) + printf("failed to write FCB/DBBT\n"); -fcb_raw_page_err: - if (is_mx6()) - kfree(fcb_raw_page); dbbt_data_page_err: kfree(dbbt_data_page); dbbt_page_err: @@ -424,7 +447,7 @@ static int do_nandbcb_update(int argc, char * const argv[]) dev = nand_curr_device; if (dev < 0) { - printf("failed to get nand_curr_device, run nand device"); + printf("failed to get nand_curr_device, run nand device\n"); return CMD_RET_FAILURE; } From patchwork Sun Nov 3 15:49:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1188576 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="E4ugr9M/"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 475gSc6KHwz9sP3 for ; Mon, 4 Nov 2019 02:53:20 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 76D7EC22039; Sun, 3 Nov 2019 15:51:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 69CBFC2203E; Sun, 3 Nov 2019 15:51:11 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 21259C22050; Sun, 3 Nov 2019 15:50:31 +0000 (UTC) Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by lists.denx.de (Postfix) with ESMTPS id BB459C21FEA for ; Sun, 3 Nov 2019 15:50:29 +0000 (UTC) Received: by mail-wm1-f67.google.com with SMTP id c17so6727705wmk.2 for ; Sun, 03 Nov 2019 07:50:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Qon8rBpm74R+ZMk6lm7ipGvg8Y+ESRyHzGQ/0CVOKzY=; b=E4ugr9M/frHEuWwm07ml1QS+/tB4ZdUAuOrLtaZQF2Zq1iXqkbcOv7QQE3tev5x8bm Qe4BK3Sc9H5URwS+hyq9hUQtTZKZ9BFzgz9acI3vW3baFVsor9p0SPDgrEO/ri2g4XyA bMlGUtGAN9mAq4WRJW/oBgmqlMM2mgqIICr3t8AF4d6AnTKGCYO/80kCnQdqkk9Iwl/a /Gralll80IsAWx614J+w7fKtondFCXSQbS6p7xnMwTeGyIBdfbkgusjzEjRVuNuE+Cv6 Vi2I4yrjYp/xMrwhmouS8ydNvbRo+K/FZhdIMKCMKGjARDSpAe266ucyQcT0IlC+mxxP 5vTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Qon8rBpm74R+ZMk6lm7ipGvg8Y+ESRyHzGQ/0CVOKzY=; b=eYOmzAJcNHSPtjECsNeLBPVrgS0qbGqwORzn7fK/VYzpsCOWBhpuIjX4OZ1q7Qyfu4 0+byfHP0inmYQpGvbF96ONALIXRxiamnJbk7idApZdElONIOT4lSp2N1X5gbefgeqcmD Fx3aYchqvz12x+XHwhP1XFE6pkX+PTC+aUHcERho4tigMpJ5PbnU/l+85g+LrTv40nIV HJLnQsHvnel+3IKUJBcpO9nyIbUSLRw+9J0AZeRVgLzpLsqxzEe68thH0n5btyg9qGIr ALplcb+/7pNC/e7uH9SD30ly3TX5p5V8+iNfF8I7Il8PYFv5N+/+uvuHXErkl4Z6TcRH WZ0w== X-Gm-Message-State: APjAAAXErUY+Ym8XwqQSU1UfCIsCsk9tNmn7U1nm0K5h5jmX2c709Nbe m8zQLrhuh7yw/bMoRIRW6T4lkgIje+Q= X-Google-Smtp-Source: APXvYqy8Qhpnis1KS5U9qVqy/w96TtVNsGtZt3wCIYF3OjZR1Dwb+CgA2lh2JLlc/Pg4Ts1x32rQjA== X-Received: by 2002:a1c:4489:: with SMTP id r131mr18374629wma.132.1572796229067; Sun, 03 Nov 2019 07:50:29 -0800 (PST) Received: from localhost (46-126-71-123.dynamic.hispeed.ch. [46.126.71.123]) by smtp.gmail.com with ESMTPSA id a16sm21356170wmd.11.2019.11.03.07.50.28 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 03 Nov 2019 07:50:28 -0800 (PST) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Sun, 3 Nov 2019 16:49:46 +0100 Message-Id: <20191103154946.24969-6-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191103154946.24969-1-igor.opaniuk@gmail.com> References: <20191103154946.24969-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v3 5/5] imx: nandbcb: add support for writing BCB only X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" From: Igor Opaniuk Add subcommand for add writing BCB only, where we provide appropriate offsets for firmware1 and firmware2 and size. Example of usage: > nandbcb bcbonly 0x00180000 0x00080000 0x00200000 Writing 1024 bytes to 0x0: randomizing OK Writing 1024 bytes to 0x20000: randomizing OK Signed-off-by: Igor Opaniuk Tested-by: Max Krummenacher Reviewed-by: Oleksandr Suvorov --- arch/arm/mach-imx/cmd_nandbcb.c | 92 ++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index 6e7e982ee5..09c4356529 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -433,6 +433,88 @@ err: return ret; } +static int do_nandbcb_bcbonly(int argc, char * const argv[]) +{ + struct fcb_block *fcb; + struct dbbt_block *dbbt; + u32 fw_len, fw1_off, fw2_off; + struct mtd_info *mtd; + void *dbbt_page, *dbbt_data_page; + int dev, ret; + + dev = nand_curr_device; + if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) || + (!get_nand_dev_by_index(dev))) { + puts("No devices available\n"); + return CMD_RET_FAILURE; + } + + mtd = get_nand_dev_by_index(dev); + + if (argc < 3) + return CMD_RET_FAILURE; + + fw_len = simple_strtoul(argv[1], NULL, 16); + fw1_off = simple_strtoul(argv[2], NULL, 16); + + if (argc > 3) + fw2_off = simple_strtoul(argv[3], NULL, 16); + else + fw2_off = fw1_off; + + /* fill fcb */ + fcb = kzalloc(sizeof(*fcb), GFP_KERNEL); + if (!fcb) { + debug("failed to allocate fcb\n"); + ret = -ENOMEM; + return CMD_RET_FAILURE; + } + + fill_fcb(fcb, mtd, fw1_off / mtd->writesize, + fw2_off / mtd->writesize, fw_len / mtd->writesize); + + /* fill dbbt */ + dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_page) { + debug("failed to allocate dbbt_page\n"); + ret = -ENOMEM; + goto fcb_err; + } + + dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_data_page) { + debug("failed to allocate dbbt_data_page\n"); + ret = -ENOMEM; + goto dbbt_page_err; + } + + dbbt = dbbt_page; + dbbt->checksum = 0; + dbbt->fingerprint = DBBT_FINGERPRINT2; + dbbt->version = DBBT_VERSION_1; + ret = dbbt_fill_data(mtd, dbbt_data_page, 0); + if (ret < 0) + goto dbbt_data_page_err; + else if (ret > 0) + dbbt->dbbtpages = 1; + + /* write fcb and dbbt to nand */ + ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, 0); +dbbt_data_page_err: + kfree(dbbt_data_page); +dbbt_page_err: + kfree(dbbt_page); +fcb_err: + kfree(fcb); + + if (ret < 0) { + printf("failed to write FCB/DBBT\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + static int do_nandbcb_update(int argc, char * const argv[]) { struct mtd_info *mtd; @@ -489,6 +571,11 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc, goto done; } + if (strcmp(cmd, "bcbonly") == 0) { + ret = do_nandbcb_bcbonly(argc, argv); + goto done; + } + done: if (ret != -1) return ret; @@ -499,7 +586,10 @@ usage: #ifdef CONFIG_SYS_LONGHELP static char nandbcb_help_text[] = "update addr off|partition len - update 'len' bytes starting at\n" - " 'off|part' to memory address 'addr', skipping bad blocks"; + " 'off|part' to memory address 'addr', skipping bad blocks\n" + "bcbonly fw-size fw1-off [fw2-off] - write only BCB (FCB and DBBT)\n" + " where `fw-size` is fw sizes in bytes, `fw1-off` and\n" + " and `fw2-off` - firmware offsets "; #endif U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb,