diff options
author | Peng Fan <peng.fan@nxp.com> | 2022-04-21 11:18:31 +0800 |
---|---|---|
committer | Ye Li <ye.li@nxp.com> | 2022-07-06 22:36:02 +0800 |
commit | 4420de9c78fc3e74bd8540cb16627f7c3c99d20a (patch) | |
tree | 91a8f3e4c3605203d3fbbee7349937f496dab8bf /arch/arm | |
parent | b54050b30a197ada1e96923ce8d4f7f509491bac (diff) |
LFU-330-38 imx9: Support booting m33 from Acore
Add bootaux command to support on-demand booting M33 from u-boot.
It kicks M33 via ATF by "bootaux 0x201e0000 0"
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-imx/imx9/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx9/imx_bootaux.c | 138 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx9/soc.c | 8 |
3 files changed, 150 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/imx9/Makefile b/arch/arm/mach-imx/imx9/Makefile index 41a22500c9..6d038a60c6 100644 --- a/arch/arm/mach-imx/imx9/Makefile +++ b/arch/arm/mach-imx/imx9/Makefile @@ -5,3 +5,7 @@ obj-y += lowlevel_init.o obj-y += soc.o clock.o clock_root.o trdc.o obj-$(CONFIG_AHAB_BOOT) += ahab.o + +#ifndef CONFIG_SPL_BUILD +obj-y += imx_bootaux.o +#endif diff --git a/arch/arm/mach-imx/imx9/imx_bootaux.c b/arch/arm/mach-imx/imx9/imx_bootaux.c new file mode 100644 index 0000000000..721e77193e --- /dev/null +++ b/arch/arm/mach-imx/imx9/imx_bootaux.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 NXP + */ + +#include <common.h> +#include <log.h> +#include <asm/io.h> +#include <asm/mach-imx/sys_proto.h> +#include <command.h> +#include <elf.h> +#include <imx_sip.h> +#include <linux/arm-smccc.h> +#include <linux/compiler.h> +#include <cpu_func.h> + +int arch_auxiliary_core_check_up(u32 core_id) +{ + struct arm_smccc_res res; + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STARTED, 0, 0, + 0, 0, 0, 0, &res); + + return res.a0; +} + +int arch_auxiliary_core_down(u32 core_id) +{ + struct arm_smccc_res res; + + printf("## Stopping auxiliary core\n"); + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_STOP, 0, 0, + 0, 0, 0, 0, &res); + + return 0; +} + +int arch_auxiliary_core_up(u32 core_id, ulong addr) +{ + struct arm_smccc_res res; + u32 stack, pc; + + if (!addr) + return -EINVAL; + + stack = *(u32 *)addr; + pc = *(u32 *)(addr + 4); + + printf("## Starting auxiliary core stack = 0x%08X, pc = 0x%08X...\n", stack, pc); + + arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_MCU_START, 0, 0, + 0, 0, 0, 0, &res); + + return 0; +} + +/* + * To i.MX6SX and i.MX7D, the image supported by bootaux needs + * the reset vector at the head for the image, with SP and PC + * as the first two words. + * + * Per the cortex-M reference manual, the reset vector of M4/M7 needs + * to exist at 0x0 (TCMUL/IDTCM). The PC and SP are the first two addresses + * of that vector. So to boot M4/M7, the A core must build the M4/M7's reset + * vector with getting the PC and SP from image and filling them to + * TCMUL/IDTCM. When M4/M7 is kicked, it will load the PC and SP by itself. + * The TCMUL/IDTCM is mapped to (MCU_BOOTROM_BASE_ADDR) at A core side for + * accessing the M4/M7 TCMUL/IDTCM. + */ +static int do_bootaux(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + ulong addr; + int ret, up; + u32 core = 0; + u32 stop = 0; + + if (argc < 2) + return CMD_RET_USAGE; + + if (argc > 2) + core = simple_strtoul(argv[2], NULL, 10); + + if (argc > 3) + stop = simple_strtoul(argv[3], NULL, 10); + + up = arch_auxiliary_core_check_up(core); + if (up) { + printf("## Auxiliary core is already up\n"); + return CMD_RET_SUCCESS; + } + + addr = simple_strtoul(argv[1], NULL, 16); + + if (!addr) + return CMD_RET_FAILURE; + + ret = arch_auxiliary_core_up(core, addr); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static int do_stopaux(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret, up; + + up = arch_auxiliary_core_check_up(0); + if (!up) { + printf("## Auxiliary core is already down\n"); + return CMD_RET_SUCCESS; + } + + ret = arch_auxiliary_core_down(0); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + stopaux, CONFIG_SYS_MAXARGS, 1, do_stopaux, + "Start auxiliary core", + "<address> [<core>]\n" + " - start auxiliary core [<core>] (default 0),\n" + " at address <address>\n" +); + +U_BOOT_CMD( + bootaux, CONFIG_SYS_MAXARGS, 1, do_bootaux, + "Start auxiliary core", + "<address> [<core>]\n" + " - start auxiliary core [<core>] (default 0),\n" + " at address <address>\n" +); diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index 96d71eacec..76611c5b0f 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -212,6 +212,14 @@ static struct mm_region imx93_mem_map[] = { .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE }, { + /* TCM */ + .virt = 0x201c0000UL, + .phys = 0x201c0000UL, + .size = 0x80000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { /* OCRAM */ .virt = 0x20480000UL, .phys = 0x20480000UL, |