From patchwork Mon Oct 21 13:38:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1180606 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="QOqosr/L"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46xd7z1yJyz9sSF for ; Tue, 22 Oct 2019 00:41:02 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 815DEC21E2C; Mon, 21 Oct 2019 13:39:50 +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 4D69BC21E4F; Mon, 21 Oct 2019 13:39:26 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 13F38C21E4E; Mon, 21 Oct 2019 13:39:06 +0000 (UTC) Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by lists.denx.de (Postfix) with ESMTPS id 1AA4FC21D74 for ; Mon, 21 Oct 2019 13:39:05 +0000 (UTC) Received: by mail-wr1-f65.google.com with SMTP id c6so1832794wrm.6 for ; Mon, 21 Oct 2019 06:39:05 -0700 (PDT) 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=AlPysylv1Ntcqlsn/8gVSaRGrzqtU53/rrl/6S53WKY=; b=QOqosr/L1b1E/+ZnB5p5JzsGH6/vlE5l8ZDfE67D4E3o2JxIVgmSPLm4GiOX8iZXtr n2YEOsLHkamSOti/BbGhkZ0fq/wuPKG8W3qUUbm0IqizxNLvGgvY71AytTQMcFUvEQLC G2uN5Sd0Z0VrPRJ7btsPoTLoSdyVDEpDkv5ESF+hN8ysf6n2oZFDNTDmTL/B/jK/P+rw pcGDbEkszMmtmwgoKQJj0khqqUeqSRE1XfFSVati4SiuEwwKG2EELjg1loqkrQopm7Pz 8SWtYv0Y4yat9mBdvm3pVXorwKyC7Hwezdsz02vH/eiVeVOXtpzFHMXe2EWfY8JE4/hd +VYw== 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=AlPysylv1Ntcqlsn/8gVSaRGrzqtU53/rrl/6S53WKY=; b=gKqYuzyIUfGT8OsDvmbVKzxRFBiF8bJDr6C6wbbIf3tST7He1kMrXqg5BfB0xKCq0k IMw6qZV4OPl2iyEZTeZOkdQjUgvmJJ+CuCBTJTgBZBDY7hsVMH9phc+8IQnS801+3ngr gKhxPo5cvmmURnS+VI44+TvIJg6Vd/Pu2EKORyTViIW3Pqjv2keWSk9sjyry5JumZ9D6 uZMpDVwdJ/CAQPfe/RLCXeOaG5JWlySQ33cO8nB+TUWJbEUGNYjiYlFcnDWb5H7o9Mfv w0Z2TAvTFQz0OJn18xwUUOnutIXIGOjook7fCU5S67V8KwCsxOz+5DMGUVZiXBVMDIkz KeCg== X-Gm-Message-State: APjAAAWjpb85gGtiTECP9JfO5L2SNAggLsXGtXmFdj2wFyYwudSrwMZQ 6KfgazblhFVLGqOvsdSlFAS+naE+F1k= X-Google-Smtp-Source: APXvYqzTu54Xm+vabNJyA5CAN0ZBFcVC4Lw5lW7k4SRv/Pk+CKkNOlmSdV6xscizGckMq3UgOzo/6Q== X-Received: by 2002:a5d:54d1:: with SMTP id x17mr18599062wrv.297.1571665144402; Mon, 21 Oct 2019 06:39:04 -0700 (PDT) Received: from localhost ([194.105.145.90]) by smtp.gmail.com with ESMTPSA id h3sm1480331wrt.88.2019.10.21.06.39.03 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Oct 2019 06:39:03 -0700 (PDT) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Mon, 21 Oct 2019 16:38:55 +0300 Message-Id: <20191021133859.23824-2-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191021133859.23824-1-igor.opaniuk@gmail.com> References: <20191021133859.23824-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v2 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 Reviewed-by: Oleksandr Suvorov Tested-by: Max Krummenacher --- 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 Mon Oct 21 13:38:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1180598 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="PGK0jmuF"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46xd7j4LGKz9sRX for ; Tue, 22 Oct 2019 00:40:49 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 33619C21DAF; Mon, 21 Oct 2019 13:39:35 +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 DD329C21E34; Mon, 21 Oct 2019 13:39:22 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 74684C21E0B; Mon, 21 Oct 2019 13:39:08 +0000 (UTC) Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by lists.denx.de (Postfix) with ESMTPS id 528E3C21DED for ; Mon, 21 Oct 2019 13:39:06 +0000 (UTC) Received: by mail-wr1-f65.google.com with SMTP id c6so1832889wrm.6 for ; Mon, 21 Oct 2019 06:39:06 -0700 (PDT) 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=K+moRdUsl/sL14DjUM6iwSzjMjSIN5iIW5/DnKmlN9U=; b=PGK0jmuFgW+RZBBuxUv5IJOAVkCSPfqttcB3KFXCatQrj0684EL4JT8ivZgvMCbGtk bqfJYjLs//i0pY1zAN2X8rkQz+y95OGSYC9dlcoaIUERHUmRl3DSn7JR+00smulkPATP Oo2Rk1jU4i5eBQ+zL7PBgekg2T8swBExViq1aH05HGUcGgQHiGdLqM7oAZrGliUFRCnM 91PPLXhIdubcxPUU5V5HU2RM/jckmfL/DKgxdOAbiHtLc1VUfdVcQSFk9B++4YWoOe1T dV6Jq/el/dnAIlHmpL6YsUOOX2ecxMP1nx8Y2swheidrYUf38sRE7UAYg4mud/p9ogUb VueQ== 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=K+moRdUsl/sL14DjUM6iwSzjMjSIN5iIW5/DnKmlN9U=; b=QRY8o9y5/uirEjnYYkY55f5x3DIrqPU+J3CaanQFl0CI04nM1P8fVK7hIfjNxh8obQ SonR5jAqGD++7ON0jQkVSk7SPSgJ/9k+0lBCCEeMBc6aYwQQtSWIzVEGKxE/srtnku2p HlOyhlRyEem0nKPL1NBB/P094Sj2vY6dkYQmFmup6ib8NUIWpahp7PmkufOVSaa3N4xH x9hp7sLdUGjhCabanlSzQK93WwUs3eBQlt6FjSeP+FKIXE92n+qjEvsGd/aD/NnUPwUm DCQgxbO2sDmMcU0Ih074JroWg8Kabw8DrdNmoGvWsAmjTE5SytoOyQCzFFp5wA02uBnx 6EhQ== X-Gm-Message-State: APjAAAUuCMmH0Q3xyAgE6qZs4dka9EYVVa6+Fx8leAvTMZ9Wm2nGX1h/ 2DrF79bRtApRBDDP1YRzdC045Pkgp7I= X-Google-Smtp-Source: APXvYqwln3XEUE7HOFsZPuRhKMICU3eWtkZ93TQ7ulVshMEMKVM/Wu6iD7qtpGLQvwCX26zlhy2M9g== X-Received: by 2002:adf:dd4d:: with SMTP id u13mr5718373wrm.104.1571665145634; Mon, 21 Oct 2019 06:39:05 -0700 (PDT) Received: from localhost ([194.105.145.90]) by smtp.gmail.com with ESMTPSA id f6sm13963323wrm.61.2019.10.21.06.39.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Oct 2019 06:39:05 -0700 (PDT) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Mon, 21 Oct 2019 16:38:56 +0300 Message-Id: <20191021133859.23824-3-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191021133859.23824-1-igor.opaniuk@gmail.com> References: <20191021133859.23824-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , Marcel Ziswiler , Sergey Kubushyn , Max Krummenacher Subject: [U-Boot] [PATCH v2 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 Reviewed-by: Oleksandr Suvorov Tested-by: Max Krummenacher --- 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 Mon Oct 21 13:38:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1180595 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="Ps0szLbO"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46xd6P39LSz9sPj for ; Tue, 22 Oct 2019 00:39:41 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 1D755C21DFD; Mon, 21 Oct 2019 13:39:18 +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 62DB1C21E1A; Mon, 21 Oct 2019 13:39:15 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 5C336C21DB6; Mon, 21 Oct 2019 13:39:10 +0000 (UTC) Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by lists.denx.de (Postfix) with ESMTPS id 12604C21DFD for ; Mon, 21 Oct 2019 13:39:08 +0000 (UTC) Received: by mail-wr1-f67.google.com with SMTP id w18so13502151wrt.3 for ; Mon, 21 Oct 2019 06:39:08 -0700 (PDT) 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=vAeJhxnirSL/sD3np2QKP+61LfphfrwLuXvcLHfYrTg=; b=Ps0szLbO6rp1ygJKvk6J2OgVpxfhTe0tV1QFQhf1Za1cwADk8vKXwevnidzaW/FPx8 A86uw1r4+ah8cTPVkFzyb7W9fFRDGN4Lf/jGtVf2uxuIbEV7HADB9xrg7J63YPIaSHwO zEJGfokA/qtbjCbI/7iuP2+xYHMb/S94neDdwN5pJ+iGoxLPreffweturlvFSLdRA24y y2vP78BA8a/qrqeaz8Ds4GZCB6YrP/q6n9/+RdvuljTFVgBkHBzLme1xVKipH404ZIF6 WhywoWyhxPhL+DEuOUnb3Ys7xNR7KmINsGG/VKznXgg48H11SQ2q4klmnYlH0Nx7QyF2 Ux8w== 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=vAeJhxnirSL/sD3np2QKP+61LfphfrwLuXvcLHfYrTg=; b=D6PRg3sR3D4J+Rjd9CZ0elyhejAb/wbzyYRdv3SsVqhP9auW7Z5q6GkCW/HHU2fZlj axJxj+95SLCB/4YqqsjppvQJIc2JuZ9MDvAP48tN0j2ZvUe4Q7AHx4l1hK0AdQnkbQA0 rJRXr868Humbkd6030Wg69+0VpH4Ajivn0BbkHPR3nvQ6xpDsAPuj7Qla6epAWZsVOe3 yOJ181q8RnzqrEdMNPcpJ349lH2eX+xPntpUVML182LzK7Zg0mYIT2exZVckCE7fN2qS alrDkFWcs3tg2a+zZF5DRA4eTjeKcBzg9ywNrqInmxWLVxYzCqnwa41cxEfHWywA+82t i+GQ== X-Gm-Message-State: APjAAAXxzc3q++xreWuq8Ywp9CE1eYUd5oED07gPd1mA+Fdbjxd6XWuh I/doOs7nRVQOhI+3+8IFLxdBiz+5N3k= X-Google-Smtp-Source: APXvYqxOTx2hnfl7sxX4l1yk4EQL4/m5XLLPhZ74fVwyGRg7cIzjXjK40aWs9bPvCzB6lYFfjWaC/g== X-Received: by 2002:adf:b1c6:: with SMTP id r6mr8365727wra.48.1571665147261; Mon, 21 Oct 2019 06:39:07 -0700 (PDT) Received: from localhost ([194.105.145.90]) by smtp.gmail.com with ESMTPSA id a189sm1935969wma.2.2019.10.21.06.39.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Oct 2019 06:39:06 -0700 (PDT) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Mon, 21 Oct 2019 16:38:57 +0300 Message-Id: <20191021133859.23824-4-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191021133859.23824-1-igor.opaniuk@gmail.com> References: <20191021133859.23824-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v2 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 Reviewed-by: Oleksandr Suvorov Tested-by: Max Krummenacher --- arch/arm/include/asm/mach-imx/imx-nandbcb.h | 12 ++ arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/cmd_nandbcb.c | 129 +++++++++++++------- 3 files changed, 100 insertions(+), 43 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 b0b9d2c070..c22e8f51b4 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -81,7 +81,7 @@ config CMD_HDMIDETECT config CMD_NANDBCB bool "i.MX6 NAND Boot Control Block(BCB) command" depends on NAND && CMD_MTDPARTS - 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 7811c61d22..aae2cc82f3 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -67,26 +68,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; @@ -98,6 +109,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); } @@ -133,6 +147,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; @@ -223,45 +238,74 @@ 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; - } - - memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); - encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512); /* - * 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. + * We prepare raw page only for i.MX6, for i.MX7 we + * leverage BCH hw module instead */ - memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + 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; + } + memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); + encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + + 12 + 512, 512); + /* + * 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); @@ -283,7 +327,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 Mon Oct 21 13:38:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1180608 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="IM/nWjgM"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46xd801Dhnz9sSH for ; Tue, 22 Oct 2019 00:41:03 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 9679AC21E73; Mon, 21 Oct 2019 13:40:06 +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 D8DE8C21E02; Mon, 21 Oct 2019 13:40:03 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id B421DC21E0B; Mon, 21 Oct 2019 13:39:11 +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 6347BC21DE8 for ; Mon, 21 Oct 2019 13:39:09 +0000 (UTC) Received: by mail-wr1-f66.google.com with SMTP id s1so5289048wro.0 for ; Mon, 21 Oct 2019 06:39:09 -0700 (PDT) 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=PTqyDJ2fAMRKNdM+XjTR4d40eg+22QW6dhqucKvQImY=; b=IM/nWjgMJZP8+2BlIGgjgbrdn6sK1tJ4EPGnFFcV/fdiEUYkUSaBP8nyW7dca8w3Cj czZiu3nZRRyaNlfYKC7eAhgRpatDWbinJAptyPY//wP8DRF38LGF46jEqLReRQuwSkmM qViB/2gmqM7jE7fc8fZWA08IdV8WCPcHJ9OHK4DD7Vlbk/CnJzuRxOiCFXV58XR+XA1A L6j9HA7OSjjeVNGbRNRXiILoDTdWADEdT/hkg8z6GyYH2IhYEBwNDqF9ughMr5iv70SK 9d2FFE5Bo46aDY4zh9jH4sT9+tb/W6eBcaajKBRFzfWrIhs6Fy524hS8E2jy2UsPFxua aLFg== 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=PTqyDJ2fAMRKNdM+XjTR4d40eg+22QW6dhqucKvQImY=; b=ucOTT33R3NerGQf+BJ0fFc2ynB9QWhx6HCjhSQnMqGqMDJoCUri0SAU2M27QVJk8ck h0a1zB4t7nRbKMzsWM06A0V46P+WgCCvonKGM712OSABogWB5nRimBGMK2Wlv9LIqwrM gxAUFG0frS01d8CrpiZJKG55k5YFaXqUk8lXto6kYt9TE3XQTttonpAZjugWPIWTtzYd zfFP4naZebazDDzM+bNKb6I0SetvLyrV49FxdIkyjIS9u/m1RBaer0ZA9HziDYDeGOrA tMuQjuJnY7GQzVTDZJ8/ESLf9Z3HdewqQjwAvR+g+aXF+tR/8V+A9ZP6U0wOC1B9eIq3 YDEw== X-Gm-Message-State: APjAAAVBqRzBZQZSXs/ULIT5bsy7mFejZU2e6IBh7Mb7nzmfrNAWuOeC 0GEK2aRnLld+C0IbTRnmU57eOvw6f18= X-Google-Smtp-Source: APXvYqy7e1RLU7U7wvGR54g0pbXnCkKZCibQlfeHm/xz61+nOHh1H9rPX4NLoYHOByPeZFvApGs64w== X-Received: by 2002:adf:9c81:: with SMTP id d1mr19101794wre.238.1571665148616; Mon, 21 Oct 2019 06:39:08 -0700 (PDT) Received: from localhost ([194.105.145.90]) by smtp.gmail.com with ESMTPSA id 65sm7192616wrs.9.2019.10.21.06.39.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Oct 2019 06:39:08 -0700 (PDT) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Mon, 21 Oct 2019 16:38:58 +0300 Message-Id: <20191021133859.23824-5-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191021133859.23824-1-igor.opaniuk@gmail.com> References: <20191021133859.23824-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v2 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 Reviewed-by: Oleksandr Suvorov Tested-by: Max Krummenacher --- arch/arm/mach-imx/cmd_nandbcb.c | 221 ++++++++++++++++++-------------- 1 file changed, 122 insertions(+), 99 deletions(-) diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index aae2cc82f3..fbe780ccda 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -64,7 +64,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); @@ -112,6 +113,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); } @@ -135,6 +141,109 @@ 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; + } + + memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); + encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + + 12 + 512, 512); + /* + * 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) { @@ -142,12 +251,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; @@ -209,9 +318,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); @@ -238,97 +347,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; - } - - memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); - encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + - 12 + 512, 512); - /* - * 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: @@ -355,7 +378,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 Mon Oct 21 13:38:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Opaniuk X-Patchwork-Id: 1180611 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="FIsOOcwO"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46xd8h2swBz9sR3 for ; Tue, 22 Oct 2019 00:41:39 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 709F6C21E6A; Mon, 21 Oct 2019 13:40:24 +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 8952EC21DB3; Mon, 21 Oct 2019 13:40:07 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id A5A27C21DED; Mon, 21 Oct 2019 13:39:13 +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 C1324C21DB6 for ; Mon, 21 Oct 2019 13:39:10 +0000 (UTC) Received: by mail-wr1-f68.google.com with SMTP id c6so1833213wrm.6 for ; Mon, 21 Oct 2019 06:39:10 -0700 (PDT) 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=CWdoml6p3iXKOo9G7jmsB5JLSIoUiOfe/pPcqFc3skc=; b=FIsOOcwO7zjD3bN+tTyGPdAPyYOuLex6ScYNWmbkDB7agJaD6V57tghnr+SMX51GwW exVjTIXLGrjREf30kPVf85kiZD8Pv5CgefJOQ18340QjykQ+GJGv1WznilA/22LwlsM5 EPIBvni3jcDoUqC2y8ImwZS4DJWiiSmoju5h3dGSnep7PtumO/X12o36kxGkpLJolE3b fB39UEOMRZrS+Tf5Lc7wjs6Hdt4jliJnqOckB3AyJTSa8wgIc2cLcSVLdAkXCsHEuofq qF2Mlq1wjorE0WAMW+rIYnizSDw+OE3F0af8kbOZ3y5X7itqg3oZy5H6aXA4KD/k+aDu v0bA== 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=CWdoml6p3iXKOo9G7jmsB5JLSIoUiOfe/pPcqFc3skc=; b=NCpnMTUShwwhqsIBZZV8J0Ve47xbmwAJEHVd/oO7wuBz+FBbRdH7ewYe+icZmtbg5A a9F2AIKPskORTVA56H+9Pm9nV03vcclI498UFIaskhGjm4Z3mzna6Y4Bl6v5zNNvNc4a SGkswxOnJhjL/YjQst0e/6yMLCQbinHhyYzVu3sNaWfbSNRJYY4XU7oP3VBA+QQddjbS BHr9Mkq982D5o8O9qArRcCN78qvaaz57r4j5d464palbV2mBe0+Cxi6w5Mq/ZhcyP2Ze aImaUCGpT2yu4yhaLWFOIFoWofP9IJ66kv/0SOEU8ziTpUCoIqWi+46zhEdLh0NZe8kT kF+Q== X-Gm-Message-State: APjAAAVWlEYFRsV1lInBcH6f4+4vDMuTfEfX8v+njBci2qSgRXnVaX4U t4sVtC5D3sa2w86G6jhqBoYsvJ389pk= X-Google-Smtp-Source: APXvYqx5DEHJCLmTxZgby1o+FdaD0m4vEqShlVedCk8T9vK11y1RvF1Qc+Y8nippZe7UJEkJx5h8bg== X-Received: by 2002:adf:f101:: with SMTP id r1mr2246110wro.320.1571665150065; Mon, 21 Oct 2019 06:39:10 -0700 (PDT) Received: from localhost ([194.105.145.90]) by smtp.gmail.com with ESMTPSA id k3sm1846092wro.77.2019.10.21.06.39.09 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Oct 2019 06:39:09 -0700 (PDT) From: Igor Opaniuk To: u-boot@lists.denx.de Date: Mon, 21 Oct 2019 16:38:59 +0300 Message-Id: <20191021133859.23824-6-igor.opaniuk@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191021133859.23824-1-igor.opaniuk@gmail.com> References: <20191021133859.23824-1-igor.opaniuk@gmail.com> Cc: Anti Sullin , Igor Opaniuk , "NXP i.MX U-Boot Team" , Marcel Ziswiler , Max Krummenacher Subject: [U-Boot] [PATCH v2 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 Reviewed-by: Oleksandr Suvorov Tested-by: Max Krummenacher --- 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 fbe780ccda..d11e16cf83 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -364,6 +364,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; @@ -420,6 +502,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; @@ -430,7 +517,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,