diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/soc.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/mx7ulp/soc.c b/arch/arm/cpu/armv7/mx7ulp/soc.c index 5caa8dd..bffd212 100644 --- a/arch/arm/cpu/armv7/mx7ulp/soc.c +++ b/arch/arm/cpu/armv7/mx7ulp/soc.c @@ -6,6 +6,7 @@ #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/imx-regs.h> +#include <asm/sections.h> #include <asm/arch/sys_proto.h> static char *get_reset_cause(char *); @@ -41,8 +42,43 @@ enum bt_mode get_boot_mode(void) return LOW_POWER_BOOT; } +#ifdef CONFIG_IMX_M4_BIND +int mcore_early_load_and_boot(void) +{ + u32 *src_addr = (u32 *)&_end; + u32 *dest_addr = (u32 *)TCML_BASE; /*TCML*/ + u32 image_size = SIZE_128K + SIZE_64K; /* 192 KB*/ + u32 pc = 0, tag = 0; + + memcpy(dest_addr, src_addr, image_size); + + /* Set GP register to tell the M4 rom the image entry */ + /* We assume the M4 image has IVT head and padding which + * should be same as the one programmed into QSPI flash + */ + tag = *(dest_addr + 1024); + if (tag != 0x402000d1) + return -1; + + pc = *(dest_addr + 1025); + + writel(pc, SIM0_RBASE + 0x70); /*GP7*/ + + return 0; +} +#endif + int arch_cpu_init(void) { +#ifdef CONFIG_IMX_M4_BIND + int ret; + if (get_boot_mode() == SINGLE_BOOT) { + ret = mcore_early_load_and_boot(); + if (ret) + puts("Invalid M4 image, boot failed\n"); + } +#endif + return 0; } @@ -203,6 +239,10 @@ int print_cpuinfo(void) case SINGLE_BOOT: default: printf("Single boot\n"); +#ifdef CONFIG_IMX_M4_BIND + if (readl(SIM0_RBASE + 0x70)) + printf("M4 start at 0x%x\n", readl(SIM0_RBASE + 0x70)); +#endif break; } |