summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorIgor Opaniuk <igor.opaniuk@toradex.com>2019-11-03 16:49:46 +0100
committerStefano Babic <sbabic@denx.de>2019-11-03 21:49:49 +0100
commitae8a53ece0ff3b1ed686c3e0af14e59973d25db8 (patch)
treed5778783194105f4be4a2c3b114095619bb1dade /arch/arm/mach-imx
parent1b899a80415060600b8150b9e29d3428cfec3513 (diff)
imx: nandbcb: add support for writing BCB only
Add subcommand for add writing BCB only, where we provide appropriate offsets for firmware1 and firmware2 and size. Example of usage: > nandbcb bcbonly 0x00180000 0x00080000 0x00200000 Writing 1024 bytes to 0x0: randomizing OK Writing 1024 bytes to 0x20000: randomizing OK Signed-off-by: Igor Opaniuk <igor.opaniuk@toradex.com> Tested-by: Max Krummenacher <max.krummenacher@toradex.com> Reviewed-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/cmd_nandbcb.c92
1 files changed, 91 insertions, 1 deletions
diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c
index 6e7e982ee5..09c4356529 100644
--- a/arch/arm/mach-imx/cmd_nandbcb.c
+++ b/arch/arm/mach-imx/cmd_nandbcb.c
@@ -433,6 +433,88 @@ err:
return ret;
}
+static int do_nandbcb_bcbonly(int argc, char * const argv[])
+{
+ struct fcb_block *fcb;
+ struct dbbt_block *dbbt;
+ u32 fw_len, fw1_off, fw2_off;
+ struct mtd_info *mtd;
+ void *dbbt_page, *dbbt_data_page;
+ int dev, ret;
+
+ dev = nand_curr_device;
+ if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) ||
+ (!get_nand_dev_by_index(dev))) {
+ puts("No devices available\n");
+ return CMD_RET_FAILURE;
+ }
+
+ mtd = get_nand_dev_by_index(dev);
+
+ if (argc < 3)
+ return CMD_RET_FAILURE;
+
+ fw_len = simple_strtoul(argv[1], NULL, 16);
+ fw1_off = simple_strtoul(argv[2], NULL, 16);
+
+ if (argc > 3)
+ fw2_off = simple_strtoul(argv[3], NULL, 16);
+ else
+ fw2_off = fw1_off;
+
+ /* fill fcb */
+ fcb = kzalloc(sizeof(*fcb), GFP_KERNEL);
+ if (!fcb) {
+ debug("failed to allocate fcb\n");
+ ret = -ENOMEM;
+ return CMD_RET_FAILURE;
+ }
+
+ fill_fcb(fcb, mtd, fw1_off / mtd->writesize,
+ fw2_off / mtd->writesize, fw_len / mtd->writesize);
+
+ /* fill dbbt */
+ dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL);
+ if (!dbbt_page) {
+ debug("failed to allocate dbbt_page\n");
+ ret = -ENOMEM;
+ goto fcb_err;
+ }
+
+ dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL);
+ if (!dbbt_data_page) {
+ debug("failed to allocate dbbt_data_page\n");
+ ret = -ENOMEM;
+ goto dbbt_page_err;
+ }
+
+ dbbt = dbbt_page;
+ dbbt->checksum = 0;
+ dbbt->fingerprint = DBBT_FINGERPRINT2;
+ dbbt->version = DBBT_VERSION_1;
+ ret = dbbt_fill_data(mtd, dbbt_data_page, 0);
+ if (ret < 0)
+ goto dbbt_data_page_err;
+ else if (ret > 0)
+ dbbt->dbbtpages = 1;
+
+ /* write fcb and dbbt to nand */
+ ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, 0);
+dbbt_data_page_err:
+ kfree(dbbt_data_page);
+dbbt_page_err:
+ kfree(dbbt_page);
+fcb_err:
+ kfree(fcb);
+
+ if (ret < 0) {
+ printf("failed to write FCB/DBBT\n");
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
static int do_nandbcb_update(int argc, char * const argv[])
{
struct mtd_info *mtd;
@@ -489,6 +571,11 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc,
goto done;
}
+ if (strcmp(cmd, "bcbonly") == 0) {
+ ret = do_nandbcb_bcbonly(argc, argv);
+ goto done;
+ }
+
done:
if (ret != -1)
return ret;
@@ -499,7 +586,10 @@ usage:
#ifdef CONFIG_SYS_LONGHELP
static char nandbcb_help_text[] =
"update addr off|partition len - update 'len' bytes starting at\n"
- " 'off|part' to memory address 'addr', skipping bad blocks";
+ " 'off|part' to memory address 'addr', skipping bad blocks\n"
+ "bcbonly fw-size fw1-off [fw2-off] - write only BCB (FCB and DBBT)\n"
+ " where `fw-size` is fw sizes in bytes, `fw1-off` and\n"
+ " and `fw2-off` - firmware offsets ";
#endif
U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb,