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; }