summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAlice Guo <alice.guo@nxp.com>2020-05-05 22:04:00 +0800
committerStefano Babic <sbabic@denx.de>2020-05-10 20:55:20 +0200
commit66dbd9c9ede2a1b109b008b7063e9901d2cea07f (patch)
treee78fc82f81cc5034b464d54a12f890b195aaf6a2 /arch
parentc6ed3508bda58ab4a750eb11956f7779cc27e84d (diff)
nandbcb: support i.MX8M
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-imx/Kconfig2
-rw-r--r--arch/arm/mach-imx/cmd_nandbcb.c88
2 files changed, 68 insertions, 22 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 396f7c9288..bed8cc7e88 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -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.
diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c
index 103c3d6a08..682f5064e6 100644
--- a/arch/arm/mach-imx/cmd_nandbcb.c
+++ b/arch/arm/mach-imx/cmd_nandbcb.c
@@ -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 */