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: