nandbcb: support i.MX8M
authorAlice Guo <alice.guo@nxp.com>
Tue, 5 May 2020 14:04:00 +0000 (22:04 +0800)
committerStefano Babic <sbabic@denx.de>
Sun, 10 May 2020 18:55:20 +0000 (20:55 +0200)
Tested on i.MX8MM EVK, imx8mm evk uses BCH
encoding and randomizer
modify macro and print size_t with %zx
use CONFIG_IMX8M because it should apply to imx8mq/mm/mn

Signed-off-by: Alice Guo <alice.guo@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/cmd_nandbcb.c

index 396f7c92887b7844b94c0e710457e53c5e746831..bed8cc7e886d6ecc701c212dec004a6612f197ef 100644 (file)
@@ -89,7 +89,7 @@ config CMD_NANDBCB
        bool "i.MX6 NAND Boot Control Block(BCB) command"
        depends on MTD_RAW_NAND && CMD_MTDPARTS
        select BCH if MX6UL || MX6ULL
-       default y if (ARCH_MX6 && NAND_MXS) || (ARCH_MX7 && NAND_MXS)
+       default y if ((ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M) && NAND_MXS)
        help
          Unlike normal 'nand write/erase' commands, this command update
          Boot Control Block(BCB) for i.MX6 platform NAND IP's.
index 103c3d6a0871264bdacba21e96dac439e9dd978f..682f5064e6db6355d9695860751267e7896dc244 100644 (file)
@@ -30,6 +30,8 @@
 
 #define BF_VAL(v, bf)          (((v) & bf##_MASK) >> bf##_OFFSET)
 #define GETBIT(v, n)           (((v) >> (n)) & 0x1)
+#define IMX8MQ_SPL_SZ 0x3e000
+#define IMX8MQ_HDMI_FW_SZ 0x19c00
 
 #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL)
 static uint8_t reverse_bit(uint8_t b)
@@ -157,7 +159,7 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd,
        fcb->bchtype = l.gf_len;
 
        /* Also hardcoded in kobs-ng */
-       if (is_mx6()) {
+       if (is_mx6() || is_imx8m()) {
                fcb->datasetup = 80;
                fcb->datahold = 60;
                fcb->addr_setup = 25;
@@ -260,11 +262,11 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb,
                /*
                 * User BCH ECC hardware module for i.MX7
                 */
-               if (is_mx7()) {
+               if (is_mx7() || is_imx8m()) {
                        u32 off = i * mtd->erasesize;
                        size_t rwsize = sizeof(*fcb);
 
-                       printf("Writing %d bytes to 0x%x: ", rwsize, off);
+                       printf("Writing %zd bytes to 0x%x: ", rwsize, off);
 
                        /* switch nand BCH to FCB compatible settings */
                        mxs_nand_mode_fcb(mtd);
@@ -287,7 +289,7 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb,
                        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",
+                       debug("NAND fcb write: 0x%x offset 0x%zx written: %s\n",
                              mtd->erasesize * i, ops.len, ret ?
                              "ERROR" : "OK");
                }
@@ -296,7 +298,7 @@ static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb,
                                mtd->writesize, &dummy, (void *)dbbt);
                if (ret)
                        goto fcb_raw_page_err;
-               debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n",
+               debug("NAND dbbt write: 0x%x offset, 0x%zx bytes written: %s\n",
                      mtd->erasesize * i + mtd->writesize, dummy,
                      ret ? "ERROR" : "OK");
 
@@ -330,6 +332,9 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
        int nr_blks, nr_blks_fcb, fw1_blk;
        size_t fwsize;
        int ret;
+       size_t extra_fwsize;
+       void *extra_fwbuf;
+       loff_t extra_fw1_off;
 
        /* erase */
        memset(&opts, 0, sizeof(opts));
@@ -366,23 +371,62 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
        fw1_blk = nr_blks_fcb;
 
        /* write fw */
-       fwsize = ALIGN(size + FLASH_OFFSET_STANDARD + mtd->writesize,
-                      mtd->writesize);
-       fwbuf = kzalloc(fwsize, GFP_KERNEL);
-       if (!fwbuf) {
-               debug("failed to allocate fwbuf\n");
-               ret = -ENOMEM;
-               goto err;
-       }
+       fwbuf = NULL;
+       if (is_mx6() || is_mx7()) {
+               fwsize = ALIGN(size + FLASH_OFFSET_STANDARD + mtd->writesize,
+                              mtd->writesize);
+               fwbuf = kzalloc(fwsize, GFP_KERNEL);
+               if (!fwbuf) {
+                       debug("failed to allocate fwbuf\n");
+                       ret = -ENOMEM;
+                       goto err;
+               }
 
-       memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, size);
-       fw1_off = fw1_blk * mtd->erasesize;
-       ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize,
-                                 (u_char *)fwbuf, WITH_WR_VERIFY);
-       printf("NAND fw write: 0x%llx offset, 0x%x bytes written: %s\n",
-              fw1_off, fwsize, ret ? "ERROR" : "OK");
-       if (ret)
-               goto fwbuf_err;
+               memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, size);
+               fw1_off = fw1_blk * mtd->erasesize;
+               ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize,
+                                         (u_char *)fwbuf, WITH_WR_VERIFY);
+               printf("NAND fw write: 0x%llx offset, 0x%zx bytes written: %s\n",
+                      fw1_off, fwsize, ret ? "ERROR" : "OK");
+               if (ret)
+                       goto fwbuf_err;
+       } else if (is_imx8m()) {
+               fwsize = ALIGN(IMX8MQ_SPL_SZ + FLASH_OFFSET_STANDARD + mtd->writesize, mtd->writesize);
+               fwbuf = kzalloc(fwsize, GFP_KERNEL);
+               if (!fwbuf) {
+                       printf("failed to allocate fwbuf\n");
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               memcpy(fwbuf + FLASH_OFFSET_STANDARD, buf, IMX8MQ_SPL_SZ);
+               fw1_off = fw1_blk * mtd->erasesize;
+               ret = nand_write_skip_bad(mtd, fw1_off, &fwsize, NULL, maxsize,
+                                         (u_char *)fwbuf, WITH_WR_VERIFY);
+               printf("NAND fw write: 0x%llx offset, 0x%zx bytes written: %s\n",
+                      fw1_off, fwsize, ret ? "ERROR" : "OK");
+               if (ret)
+                       goto fwbuf_err;
+
+               extra_fwsize = ALIGN(IMX8MQ_SPL_SZ + mtd->writesize, mtd->writesize);
+               extra_fwbuf = kzalloc(extra_fwsize, GFP_KERNEL);
+               extra_fw1_off = fw1_off + mtd->erasesize * ((IMX8MQ_SPL_SZ + mtd->erasesize - 1) / mtd->erasesize);
+               if (!extra_fwbuf) {
+                       printf("failed to allocate fwbuf\n");
+                       ret = -ENOMEM;
+                       goto fwbuf_err;
+               }
+
+               memcpy(extra_fwbuf, buf + IMX8MQ_HDMI_FW_SZ, IMX8MQ_SPL_SZ);
+               ret = nand_write_skip_bad(mtd, extra_fw1_off, &extra_fwsize, NULL, maxsize,
+                                         (u_char *)extra_fwbuf, WITH_WR_VERIFY);
+               printf("NAND extra_fw write: 0x%llx offset, 0x%zx bytes written: %s\n",
+                      extra_fw1_off, extra_fwsize, ret ? "ERROR" : "OK");
+               if (ret) {
+                       kfree(extra_fwbuf);
+                       goto fwbuf_err;
+               }
+       }
 
        /* fill fcb */
        fcb = kzalloc(sizeof(*fcb), GFP_KERNEL);
@@ -394,6 +438,8 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
 
        fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize;
        fw1_pages = size / mtd->writesize + 1;
+       if (is_imx8m())
+               fw1_pages = (IMX8MQ_SPL_SZ + (mtd->writesize - 1)) / mtd->writesize;
        fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages);
 
        /* fill dbbt */