cmd_nandbcb: Support secondary boot address of imx8mn
authorMichael Trimarchi <michael@amarulasolutions.com>
Fri, 7 Jan 2022 17:27:17 +0000 (18:27 +0100)
committerStefano Babic <sbabic@denx.de>
Sat, 5 Feb 2022 12:38:39 +0000 (13:38 +0100)
Add support of secondary boot address for imx8mn. The secondary
boot address is hardcoded in the fuse. The value is calculated
from there according to the following description:

The fuse IMG_CNTN_SET1_OFFSET (0x490[22:19]) is defined as follows:
- Secondary boot is disabled if fuse value is bigger than 10, n = fuse
  value bigger than 10.
- n == 0: Offset = 4MB
- n == 2: Offset = 1MB
- Others & n <= 10 : Offset = 1MB*2^n
- For FlexSPI boot, the valid values are: 0, 1, 2, 3, 4, 5, 6, and 7.

Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
arch/arm/mach-imx/cmd_nandbcb.c

index 646da01..f119e9f 100644 (file)
@@ -132,6 +132,7 @@ static struct platform_config imx8q_plat_config = {
 
 /* boot search related variables and definitions */
 static int g_boot_search_count = 4;
+static int g_boot_secondary_offset;
 static int g_boot_search_stride;
 static int g_pages_per_stride;
 
@@ -275,9 +276,9 @@ static int nandbcb_set_boot_config(int argc, char * const argv[],
        boot_stream2_address = ((maxsize - boot_stream1_address) / 2 +
                               boot_stream1_address);
 
-       if (boot_cfg->secondary_boot_stream_off_in_MB)
+       if (g_boot_secondary_offset)
                boot_stream2_address =
-                       (loff_t)boot_cfg->secondary_boot_stream_off_in_MB * 1024 * 1024;
+                       (loff_t)g_boot_secondary_offset * 1024 * 1024;
 
        max_boot_stream_size = boot_stream2_address - boot_stream1_address;
 
@@ -1269,6 +1270,36 @@ static bool check_fingerprint(void *data, int fingerprint)
        return (*(int *)(data + off) == fingerprint);
 }
 
+static int fuse_secondary_boot(u32 bank, u32 word, u32 mask, u32 off)
+{
+       int err;
+       u32 val;
+       int ret;
+
+       err = fuse_read(bank, word, &val);
+       if (err)
+               return 0;
+
+       val = (val & mask) >> off;
+
+       if (val > 10)
+               return 0;
+
+       switch (val) {
+       case 0:
+               ret = 4;
+               break;
+       case 1:
+               ret = 1;
+               break;
+       default:
+               ret = 2 << val;
+               break;
+       }
+
+       return ret;
+};
+
 static int fuse_to_search_count(u32 bank, u32 word, u32 mask, u32 off)
 {
        int err;
@@ -1506,6 +1537,11 @@ static int do_nandbcb(struct cmd_tbl *cmdtp, int flag, int argc,
                       g_boot_search_count);
        }
 
+       if (plat_config.misc_flags & FIRMWARE_SECONDARY_FIXED_ADDR) {
+               if (is_imx8mn())
+                       g_boot_secondary_offset = fuse_secondary_boot(2, 1, 0xff0000, 16);
+       }
+
        cmd = argv[1];
        --argc;
        ++argv;