summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/mx7ulp/Kconfig6
-rw-r--r--arch/arm/cpu/armv7/mx7ulp/Makefile1
-rw-r--r--arch/arm/cpu/armv7/mx7ulp/piggy_m4.S2
-rw-r--r--arch/arm/cpu/armv7/mx7ulp/soc.c43
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;
}