HI Stefano, On Sun, Nov 3, 2019 at 2:55 PM Stefano Babic <sba...@denx.de> wrote: > > Hi Igor, > > On 21/10/19 15:38, Igor Opaniuk wrote: > > From: Igor Opaniuk <igor.opan...@toradex.com> > > > > 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 <igor.opan...@toradex.com> > > --- > > > > Patch conflicts with the one for i.MX6UL, that I have currently applied > (you see it on -next branch). Could you please rebase on it and resend ? > Thanks ! Done, please check v3 here [1] Thanks
[1] https://patchwork.ozlabs.org/project/uboot/list/?series=140330 > > Regards, > Stefano > > > 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 <jffs2/jffs2.h> > > #include <linux/mtd/mtd.h> > > > > +#include <asm/arch/sys_proto.h> > > #include <asm/mach-imx/imx-nandbcb.h> > > #include <asm/mach-imx/imximage.cfg> > > #include <mxs_nand.h> > > @@ -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: > > > > > -- > ===================================================================== > DENX Software Engineering GmbH, Managing Director: Wolfgang Denk > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de > ===================================================================== -- Best regards - Freundliche GrĂ¼sse - Meilleures salutations Igor Opaniuk mailto: igor.opan...@gmail.com skype: igor.opanyuk +380 (93) 836 40 67 http://ua.linkedin.com/in/iopaniuk _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot