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 <mich...@amarulasolutions.com>
---
Changes V1->V2:
        - adjust commit message
        - drop and extra blank line
---
 arch/arm/mach-imx/cmd_nandbcb.c | 40 +++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c
index 09622c13c9..bd14b8583a 100644
--- a/arch/arm/mach-imx/cmd_nandbcb.c
+++ b/arch/arm/mach-imx/cmd_nandbcb.c
@@ -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;
-- 
2.25.1

Reply via email to