diff options
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/piggy_m4.S | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/soc.c | 43 |
4 files changed, 52 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/mx7ulp/Kconfig b/arch/arm/cpu/armv7/mx7ulp/Kconfig index 1bdc85a..a1db6c4 100644 --- a/arch/arm/cpu/armv7/mx7ulp/Kconfig +++ b/arch/arm/cpu/armv7/mx7ulp/Kconfig @@ -3,6 +3,12 @@ if ARCH_MX7ULP config SYS_SOC default "mx7ulp" +config IMX_M4_BIND + bool "Bind ULP M4 image to final u-boot" + help + Select this to bind a ULP M4 image to final u-boot image + User needs put the M4 image ulp_m4.bin under u-boot directory + choice prompt "MX7ULP board select" optional diff --git a/arch/arm/cpu/armv7/mx7ulp/Makefile b/arch/arm/cpu/armv7/mx7ulp/Makefile index 0248ea8..2a55b97 100644 --- a/arch/arm/cpu/armv7/mx7ulp/Makefile +++ b/arch/arm/cpu/armv7/mx7ulp/Makefile @@ -6,3 +6,4 @@ # obj-y := soc.o clock.o iomux.o pcc.o scg.o +obj-$(CONFIG_IMX_M4_BIND) += piggy_m4.o diff --git a/arch/arm/cpu/armv7/mx7ulp/piggy_m4.S b/arch/arm/cpu/armv7/mx7ulp/piggy_m4.S new file mode 100644 index 0000000..b33e842 --- /dev/null +++ b/arch/arm/cpu/armv7/mx7ulp/piggy_m4.S @@ -0,0 +1,2 @@ + .section .firmware_image,#alloc + .incbin "ulp_m4.bin" diff --git a/arch/arm/cpu/armv7/mx7ulp/soc.c b/arch/arm/cpu/armv7/mx7ulp/soc.c index 4fd4c3a..d0f4897 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> #include <asm/imx-common/hab.h> @@ -49,8 +50,46 @@ enum bt_mode get_boot_mode(void) return LOW_POWER_BOOT; } +#ifdef CONFIG_IMX_M4_BIND +char __firmware_image_start[0] __attribute__((section(".__firmware_image_start"))); +char __firmware_image_end[0] __attribute__((section(".__firmware_image_end"))); + +int mcore_early_load_and_boot(void) +{ + u32 *src_addr = (u32 *)&__firmware_image_start; + u32 *dest_addr = (u32 *)TCML_BASE; /*TCML*/ + u32 image_size = SZ_128K + SZ_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; } @@ -149,6 +188,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; } |