> Subject: [PATCH v2 1/2] i.MX6: nand: extend nandbcb command for > imx6UL(L) > > Firmware Configuration Block(FCB) for imx6ul(l) needs to be BCH encoded. > This patch depends on [1]. > > [1]: > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatch > work.ozlabs.org%2Fproject%2Fuboot%2Flist%2F%3Fseries%3D113810& > data=02%7C01%7Cpeng.fan%40nxp.com%7Cd3b7409c0d254724d28508d727 > e5c283%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637021740 > 084139651&sdata=SxaieXR9bG3ChctaPrpYBI6yqXOD6blKSu6tjP0qccE%3 > D&reserved=0 > > Signed-off-by: Parthiban Nallathambi <[email protected]> > Acked-by: Shyam Saini <[email protected]>
Acked-by: Peng Fan <[email protected]> > --- > > Notes: > Changes in v2: > - use kfree instead of free > > arch/arm/mach-imx/Kconfig | 1 + > arch/arm/mach-imx/cmd_nandbcb.c | 72 > ++++++++++++++++++++++++++++++++- > 2 files changed, 71 insertions(+), 2 deletions(-) > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index > aeb5493488..175bed601e 100644 > --- a/arch/arm/mach-imx/Kconfig > +++ b/arch/arm/mach-imx/Kconfig > @@ -74,6 +74,7 @@ config CMD_HDMIDETECT > 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 > help > Unlike normal 'nand write/erase' commands, this command update > diff --git a/arch/arm/mach-imx/cmd_nandbcb.c > b/arch/arm/mach-imx/cmd_nandbcb.c index 065b814b2e..e11df401e4 > 100644 > --- a/arch/arm/mach-imx/cmd_nandbcb.c > +++ b/arch/arm/mach-imx/cmd_nandbcb.c > @@ -14,8 +14,10 @@ > > #include <asm/io.h> > #include <jffs2/jffs2.h> > +#include <linux/bch.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> > @@ -25,6 +27,66 @@ > #define BF_VAL(v, bf) (((v) & bf##_MASK) >> bf##_OFFSET) > #define GETBIT(v, n) (((v) >> (n)) & 0x1) > > +static uint8_t reverse_bit(uint8_t b) > +{ > + b = (b & 0xf0) >> 4 | (b & 0x0f) << 4; > + b = (b & 0xcc) >> 2 | (b & 0x33) << 2; > + b = (b & 0xaa) >> 1 | (b & 0x55) << 1; > + > + return b; > +} > + > +static void encode_bch_ecc(void *buf, struct fcb_block *fcb, int > +eccbits) { > + int i, j, m = 13; > + int blocksize = 128; > + int numblocks = 8; > + int ecc_buf_size = (m * eccbits + 7) / 8; > + struct bch_control *bch = init_bch(m, eccbits, 0); > + u8 *ecc_buf = kzalloc(ecc_buf_size, GFP_KERNEL); > + u8 *tmp_buf = kzalloc(blocksize * numblocks, GFP_KERNEL); > + u8 *psrc, *pdst; > + > + /* > + * The blocks here are bit aligned. If eccbits is a multiple of 8, > + * we just can copy bytes. Otherwiese we must move the blocks to > + * the next free bit position. > + */ > + WARN_ON(eccbits % 8); > + > + memcpy(tmp_buf, fcb, sizeof(*fcb)); > + > + for (i = 0; i < numblocks; i++) { > + memset(ecc_buf, 0, ecc_buf_size); > + psrc = tmp_buf + i * blocksize; > + pdst = buf + i * (blocksize + ecc_buf_size); > + > + /* copy data byte aligned to destination buf */ > + memcpy(pdst, psrc, blocksize); > + > + /* > + * imx-kobs use a modified encode_bch which reverse the > + * bit order of the data before calculating bch. > + * Do this in the buffer and use the bch lib here. > + */ > + for (j = 0; j < blocksize; j++) > + psrc[j] = reverse_bit(psrc[j]); > + > + encode_bch(bch, psrc, blocksize, ecc_buf); > + > + /* reverse ecc bit */ > + for (j = 0; j < ecc_buf_size; j++) > + ecc_buf[j] = reverse_bit(ecc_buf[j]); > + > + /* Here eccbuf is byte aligned and we can just copy it */ > + memcpy(pdst + blocksize, ecc_buf, ecc_buf_size); > + } > + > + kfree(ecc_buf); > + kfree(tmp_buf); > + free_bch(bch); > +} > + > static u8 calculate_parity_13_8(u8 d) > { > u8 p = 0; > @@ -231,8 +293,14 @@ static int nandbcb_update(struct mtd_info *mtd, > loff_t off, size_t size, > 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); > + if (is_mx6ul() || is_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); > + } > /* > * 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 > -- > 2.21.0 _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

