[U-Boot] [PATCH v2 1/2] i.MX6: nand: extend nandbcb command for imx6UL(L)

Peng Fan peng.fan at nxp.com
Mon Aug 26 08:24:00 UTC 2019


> 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 <pn at denx.de>
> Acked-by: Shyam Saini <shyam.saini at amarulasolutions.com>

Acked-by: Peng Fan <peng.fan at nxp.com>

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



More information about the U-Boot mailing list