
Hi Parthiban,
Thanks a lot for working on this.
Please see comments below.
Firmware Configuration Block(FCB) for imx6ul(l) needs to be BCH encoded. This patch depends on [1].
Signed-off-by: Parthiban Nallathambi pn@denx.de
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..34176ee6e4 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);
}
free(ecc_buf);
free(tmp_buf);
free_bch(bch);
I have used kfree() instead of free() in entire nand bcb code So, I think for consistency reason it should be kfree here.
Could you please resend this patch with above mentioned changes. Other than this,
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
Acked-by: Shyam Saini shyam.saini@amarulasolutions.com