[PATCHv5 00/14] Add a subcommand 'release' to cmd/cpu.c

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
This patch set is to add a subcommand 'release' to the 'cpu' command in cmd/cpu.c, making the command is able to release a core to run baremetal and RTOS applications.
Fixed some problems of the imx8_cpu.c and added i.MX 8M series SoCs support.
Added ARM A53 core clock registration in clock driver of i.MX 8M Mini, Nano and Plus SoCs.
And enabled the 'cpu' command and imx CPU driver for i.MX 8M series EVK boards and i.MX 93 EVK board.
Hou Zhiqiang (14): clk: imx8m: register ARM A53 core clock cpu: add release_core callback cpu: sandbox: implement release_core callback test: cpu: add test for release CPU core. cpu: imx: fix the CPU frequency in cpu_imx_get_info() cpu: imx: fix the CPU type field width cpu: imx: removed the tail '\n' of the CPU description cpu: imx: Add i.MX 8M series SoCs cpu: imx: implement release_core callback cmd: cpu: add release subcommand doc: cmd: add documentation for cpu command MAINTAINERS: add entry for cpu command configs: imx8m: enable the 'cpu' command configs: imx93: enable the 'cpu' command
--- V5: - Added cmd/cpu to doc/usage/index.rst to fix doc build failure. - Made the i.MX8M core clock CLK_IS_CRITICAL. V4: - Moved the depended patch into this thread. - Removed the tail '\n' of the CPU description for imx CPU driver. - Refined the documentation of 'cpu' command. V3: - Added documentation for 'cpu' command. - Fixed the getting cpu frequency issue in i.MX CPU driver. V2: - Implemented release_core() in sandbox and added test for the new API. - Increased the CPU type mask in i.MX CPU driver. - Added i.MX 8M series SoCs in i.MX CPU driver
MAINTAINERS | 7 +++ cmd/cpu.c | 44 ++++++++++++- configs/imx8mm_evk_defconfig | 3 + configs/imx8mn_evk_defconfig | 3 + configs/imx8mp_evk_defconfig | 3 + configs/imx93_11x11_evk_defconfig | 1 + doc/usage/cmd/cpu.rst | 101 ++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + drivers/clk/imx/clk-imx8mm.c | 8 +++ drivers/clk/imx/clk-imx8mn.c | 8 +++ drivers/clk/imx/clk-imx8mp.c | 8 +++ drivers/cpu/cpu-uclass.c | 10 +++ drivers/cpu/cpu_sandbox.c | 6 ++ drivers/cpu/imx8_cpu.c | 38 +++++++++-- include/cpu.h | 15 +++++ test/dm/cpu.c | 2 + 16 files changed, 251 insertions(+), 7 deletions(-) create mode 100644 doc/usage/cmd/cpu.rst

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Register ARM A53 core clock for i.MX 8M Mini, Nano and Plus, preparing for enabling the 'cpu' command, which depends on this to print CPU core frequency.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com --- V5: - Made the i.MX8M core clock CLK_IS_CRITICAL.
drivers/clk/imx/clk-imx8mm.c | 8 ++++++++ drivers/clk/imx/clk-imx8mn.c | 8 ++++++++ drivers/clk/imx/clk-imx8mp.c | 8 ++++++++ 3 files changed, 24 insertions(+)
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index e538f047b3..a91c6767fa 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -21,6 +21,8 @@ static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_se static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+static const char * const imx8mm_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", }; + static const char * const imx8mm_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; @@ -417,6 +419,12 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); #endif
+ clk_dm(IMX8MM_CLK_ARM, + imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1, + imx8mm_arm_core_sels, + ARRAY_SIZE(imx8mm_arm_core_sels), + CLK_IS_CRITICAL)); + return 0; }
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 8911e342f1..125215e84f 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -23,6 +23,8 @@ static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_se static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+static const char * const imx8mn_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", }; + static const char * const imx8mn_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; @@ -403,6 +405,12 @@ static int imx8mn_clk_probe(struct udevice *dev) imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); #endif
+ clk_dm(IMX8MN_CLK_ARM, + imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1, + imx8mn_arm_core_sels, + ARRAY_SIZE(imx8mn_arm_core_sels), + CLK_IS_CRITICAL)); + return 0; }
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 6b18483c81..34d91cd688 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -21,6 +21,8 @@ static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_se static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+static const char * const imx8mp_arm_core_sels[] = {"arm_a53_src", "arm_pll_out", }; + static const char * const imx8mp_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; @@ -354,6 +356,12 @@ static int imx8mp_clk_probe(struct udevice *dev)
clk_dm(IMX8MP_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
+ clk_dm(IMX8MP_CLK_ARM, + imx_clk_mux2_flags("arm_core", base + 0x9880, 24, 1, + imx8mp_arm_core_sels, + ARRAY_SIZE(imx8mp_arm_core_sels), + CLK_IS_CRITICAL)); + return 0; }

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Add a new callback release_core to the cpu_ops, which is used to release a CPU core to run baremetal or RTOS application on a SoC with multiple CPU cores.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Reviewed-by: Simon Glass sjg@chromium.org --- V5: - No change.
drivers/cpu/cpu-uclass.c | 10 ++++++++++ include/cpu.h | 15 +++++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c index 16f8f2e521..2c8e46c05e 100644 --- a/drivers/cpu/cpu-uclass.c +++ b/drivers/cpu/cpu-uclass.c @@ -104,6 +104,16 @@ int cpu_get_vendor(const struct udevice *dev, char *buf, int size) return ops->get_vendor(dev, buf, size); }
+int cpu_release_core(const struct udevice *dev, phys_addr_t addr) +{ + struct cpu_ops *ops = cpu_get_ops(dev); + + if (!ops->release_core) + return -ENOSYS; + + return ops->release_core(dev, addr); +} + U_BOOT_DRIVER(cpu_bus) = { .name = "cpu_bus", .id = UCLASS_SIMPLE_BUS, diff --git a/include/cpu.h b/include/cpu.h index 2077ff3063..0018910d61 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -102,6 +102,15 @@ struct cpu_ops { * if not. */ int (*is_current)(struct udevice *dev); + + /** + * release_core() - Relase a CPU core to the given address to run application + * + * @dev: Device to check (UCLASS_CPU) + * @addr: Address to relese the CPU core + * @return 0 if OK, -ve on error + */ + int (*release_core)(const struct udevice *dev, phys_addr_t addr); };
#define cpu_get_ops(dev) ((struct cpu_ops *)(dev)->driver->ops) @@ -164,4 +173,10 @@ int cpu_is_current(struct udevice *cpu); */ struct udevice *cpu_get_current_dev(void);
+/** + * cpu_release_core() - Relase a CPU core to the given address to run application + * + * @return 0 if OK, -ve on error + */ +int cpu_release_core(const struct udevice *dev, phys_addr_t addr); #endif

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Add empty release CPU core function for testing.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Reviewed-by: Simon Glass sjg@chromium.org --- V5: - No change.
drivers/cpu/cpu_sandbox.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/cpu/cpu_sandbox.c b/drivers/cpu/cpu_sandbox.c index e65e1bdc51..b152795783 100644 --- a/drivers/cpu/cpu_sandbox.c +++ b/drivers/cpu/cpu_sandbox.c @@ -44,6 +44,11 @@ void cpu_sandbox_set_current(const char *name) cpu_current = name; }
+static int cpu_sandbox_release_core(const struct udevice *dev, phys_addr_t addr) +{ + return 0; +} + static int cpu_sandbox_is_current(struct udevice *dev) { if (!strcmp(dev->name, cpu_current)) @@ -58,6 +63,7 @@ static const struct cpu_ops cpu_sandbox_ops = { .get_count = cpu_sandbox_get_count, .get_vendor = cpu_sandbox_get_vendor, .is_current = cpu_sandbox_is_current, + .release_core = cpu_sandbox_release_core, };
static int cpu_sandbox_bind(struct udevice *dev)

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Add test for API cpu_release_core().
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Reviewed-by: Simon Glass sjg@chromium.org --- V5: - No change.
test/dm/cpu.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/test/dm/cpu.c b/test/dm/cpu.c index acba810599..8af25316ce 100644 --- a/test/dm/cpu.c +++ b/test/dm/cpu.c @@ -43,6 +43,8 @@ static int dm_test_cpu(struct unit_test_state *uts) ut_assertok(cpu_get_vendor(dev, text, sizeof(text))); ut_assertok(strcmp(text, "Languid Example Garbage Inc."));
+ ut_assertok(cpu_release_core(dev, 0)); + return 0; }

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
The cpu_freq stores the current CPU frequency in Hz.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Reviewed-by: Michael Trimarchi michael@amarulasolutions.com --- V5: - No change.
drivers/cpu/imx8_cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 4781a56554..601a7071a6 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2019 NXP + * Copyright 2019, 2024 NXP */
#include <cpu.h> @@ -193,7 +193,7 @@ static int cpu_imx_get_info(const struct udevice *dev, struct cpu_info *info) { struct cpu_imx_plat *plat = dev_get_plat(dev);
- info->cpu_freq = plat->freq_mhz * 1000; + info->cpu_freq = plat->freq_mhz * 1000000; info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU); return 0; }

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Increase one more bit to cover all CPU types. Otherwise it shows wrong CPU info on some platforms, such as i.MX8M Plus:
U-Boot 2024.04+g674440bc73e+p0 (Jun 06 2024 - 10:05:34 +0000)
CPU: NXP i.MX8MM Rev1.1 A53 at 4154504685 MHz at 30C
Model: NXP i.MX8MPlus LPDDR4 EVK board
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com --- V5: - No change.
drivers/cpu/imx8_cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 601a7071a6..6a97b7b9ad 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -287,7 +287,7 @@ static int imx_cpu_probe(struct udevice *dev) cpurev = get_cpu_rev(); plat->cpurev = cpurev; plat->rev = get_imx_rev_str(cpurev & 0xFFF); - plat->type = get_imx_type_str((cpurev & 0xFF000) >> 12); + plat->type = get_imx_type_str((cpurev & 0x1FF000) >> 12); plat->freq_mhz = imx_get_cpu_rate(dev) / 1000000; plat->mpidr = dev_read_addr(dev); if (plat->mpidr == FDT_ADDR_T_NONE) {

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Return CPU description string without newline character in the end.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com --- V5: - No change.
drivers/cpu/imx8_cpu.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index 6a97b7b9ad..b633a2c73a 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -184,8 +184,6 @@ static int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size) ret = snprintf(buf, size, " - invalid sensor data"); }
- snprintf(buf + ret, size - ret, "\n"); - return 0; }

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Add i.MX 8M Mini, Nano and Plus SoCs support.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com --- V5: - No change.
drivers/cpu/imx8_cpu.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index b633a2c73a..a35147b72a 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -31,6 +31,12 @@ struct cpu_imx_plat { static const char *get_imx_type_str(u32 imxtype) { switch (imxtype) { + case MXC_CPU_IMX8MM: + return "8MM"; + case MXC_CPU_IMX8MN: + return "8MN"; + case MXC_CPU_IMX8MP: + return "8MP"; case MXC_CPU_IMX8QXP: case MXC_CPU_IMX8QXP_A0: return "8QXP";

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Release the secondary cores through the PSCI request.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com --- V5: - No change.
drivers/cpu/imx8_cpu.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index a35147b72a..60deca963a 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -7,6 +7,7 @@ #include <dm.h> #include <thermal.h> #include <asm/global_data.h> +#include <asm/ptrace.h> #include <asm/system.h> #include <firmware/imx/sci/sci.h> #include <asm/arch/sys_proto.h> @@ -15,6 +16,7 @@ #include <imx_thermal.h> #include <linux/bitops.h> #include <linux/clk-provider.h> +#include <linux/psci.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -240,12 +242,34 @@ static int cpu_imx_is_current(struct udevice *dev) return 0; }
+static int cpu_imx_release_core(const struct udevice *dev, phys_addr_t addr) +{ + struct cpu_imx_plat *plat = dev_get_plat(dev); + struct pt_regs regs; + + regs.regs[0] = PSCI_0_2_FN64_CPU_ON; + regs.regs[1] = plat->mpidr; + regs.regs[2] = addr; + regs.regs[3] = 0; + + smc_call(®s); + if (regs.regs[0]) { + printf("Failed to release CPU core (mpidr: 0x%x)\n", plat->mpidr); + return -1; + } + + printf("Released CPU core (mpidr: 0x%x) to address 0x%llx\n", plat->mpidr, addr); + + return 0; +} + static const struct cpu_ops cpu_imx_ops = { .get_desc = cpu_imx_get_desc, .get_info = cpu_imx_get_info, .get_count = cpu_imx_get_count, .get_vendor = cpu_imx_get_vendor, .is_current = cpu_imx_is_current, + .release_core = cpu_imx_release_core, };
static const struct udevice_id cpu_imx_ids[] = {

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Add a new subcommand 'release' to bring up a core to run baremetal and RTOS applications.
For example on i.MX8M Plus EVK, release the LAST core to run a RTOS application, passing the sequence number of the CPU core to release, here it is 3: u-boot=> cpu list 0: cpu@0 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C 1: cpu@1 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 30C 2: cpu@2 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C 3: cpu@3 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C
u-boot=> load mmc 1:2 c0000000 /hello_world.bin 66008 bytes read in 5 ms (12.6 MiB/s) u-boot=> dcache flush; icache flush u-boot=> cpu release 3 c0000000 Released CPU core (mpidr: 0x3) to address 0xc0000000
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Reviewed-by: Simon Glass sjg@chromium.org --- V5: - No change.
cmd/cpu.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-)
diff --git a/cmd/cpu.c b/cmd/cpu.c index 9e323069b9..2755250756 100644 --- a/cmd/cpu.c +++ b/cmd/cpu.c @@ -3,6 +3,7 @@ * Copyright (c) 2015 Google, Inc * Written by Simon Glass sjg@chromium.org * Copyright (c) 2017 Álvaro Fernández Rojas noltari@gmail.com + * Copyright 2024 NXP */
#include <command.h> @@ -18,6 +19,19 @@ static const char *cpu_feature_name[CPU_FEAT_COUNT] = { "Device ID", };
+static struct udevice *cpu_find_device(unsigned long cpu_id) +{ + struct udevice *dev; + + for (uclass_first_device(UCLASS_CPU, &dev); dev; + uclass_next_device(&dev)) { + if (cpu_id == dev_seq(dev)) + return dev; + } + + return NULL; +} + static int print_cpu_list(bool detail) { struct udevice *dev; @@ -82,10 +96,36 @@ static int do_cpu_detail(struct cmd_tbl *cmdtp, int flag, int argc, return 0; }
+static int do_cpu_release(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct udevice *dev; + unsigned long cpu_id; + unsigned long long boot_addr; + + if (argc != 3) + return CMD_RET_USAGE; + + cpu_id = dectoul(argv[1], NULL); + dev = cpu_find_device(cpu_id); + if (!dev) + return CMD_RET_FAILURE; + + boot_addr = simple_strtoull(argv[2], NULL, 16); + + if (cpu_release_core(dev, boot_addr)) + return CMD_RET_FAILURE; + + return 0; +} + U_BOOT_LONGHELP(cpu, "list - list available CPUs\n" - "cpu detail - show CPU detail"); + "cpu detail - show CPU detail\n" + "cpu release <core ID> <addr> - Release CPU <core ID> at <addr>\n" + " <core ID>: the sequence number in list subcommand outputs");
U_BOOT_CMD_WITH_SUBCMDS(cpu, "display information about CPUs", cpu_help_text, U_BOOT_SUBCMD_MKENT(list, 1, 1, do_cpu_list), - U_BOOT_SUBCMD_MKENT(detail, 1, 0, do_cpu_detail)); + U_BOOT_SUBCMD_MKENT(detail, 1, 0, do_cpu_detail), + U_BOOT_SUBCMD_MKENT(release, 3, 0, do_cpu_release));

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Add documentation for the 'cpu' command, taking NXP i.MX 8M Plus as a example.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Reviewed-by: Simon Glass sjg@chromium.org --- V5: - Added cmd/cpu to doc/usage/index.rst to fix doc build failure.
doc/usage/cmd/cpu.rst | 101 ++++++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 2 files changed, 102 insertions(+) create mode 100644 doc/usage/cmd/cpu.rst
diff --git a/doc/usage/cmd/cpu.rst b/doc/usage/cmd/cpu.rst new file mode 100644 index 0000000000..8b0b7d5a69 --- /dev/null +++ b/doc/usage/cmd/cpu.rst @@ -0,0 +1,101 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. Copyright 2024 NXP + +.. index:: + single: cpu (command) + +cpu command +=========== + +Synopsis +-------- + +:: + + cpu list + cpu detail + cpu release <core ID> <addr> + +Description +----------- + +The *cpu* command prints information about the CPUs, and release a CPU core +to a given address to run applications. + + +cpu list +~~~~~~~~ + +The 'list' subcommand lists and prints brief information of all the CPU cores, +the CPU information is provided by vendors' CPU driver. + +cpu detail +~~~~~~~~~~ + +The 'detail' subcommand prints more details about the CPU cores, including +CPU ID, core frequency and feature list. + +cpu release +~~~~~~~~~~~ + +The 'release' subcommand is used to release a CPU core to run a baremetal or +RTOS applications. +The parameter <core ID> is the sequence number of the CPU core to release. +The parameter <addr> is the address to run of the specified core after release. + + +Examples +-------- + +cpu list +~~~~~~~~ + +This example lists all the CPU cores On i.MX8M Plus EVK: +:: + + u-boot=> cpu list + 0: cpu@0 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C + 1: cpu@1 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 30C + 2: cpu@2 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C + 3: cpu@3 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C + +cpu detail +~~~~~~~~~~ + +This example prints the details of the CPU cores On i.MX8M Plus EVK: +:: + + u-boot=> cpu detail + 0: cpu@0 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C + ID = 0, freq = 1.2 GHz: L1 cache, MMU + 1: cpu@1 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 30C + ID = 0, freq = 1.2 GHz: L1 cache, MMU + 2: cpu@2 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C + ID = 0, freq = 1.2 GHz: L1 cache, MMU + 3: cpu@3 NXP i.MX8MP Rev1.1 A53 at 1200 MHz at 31C + ID = 0, freq = 1.2 GHz: L1 cache, MMU + +cpu release +~~~~~~~~~~~ + +This example shows release the LAST CPU core to run a RTOS application, on +i.MX8M Plus EVK: +:: + + u-boot=> load mmc 1:2 c0000000 /hello_world.bin + 66008 bytes read in 5 ms (12.6 MiB/s) + u-boot=> dcache flush; icache flush + u-boot=> cpu release 3 c0000000 + Released CPU core (mpidr: 0x3) to address 0xc0000000 + + +Configuration +------------- + +The cpu command is available if CONFIG_CMD_CPU=y. + +Return code +----------- + +The return value $? is set to 0 (true) if the command is successful, +1 (false) otherwise. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 49b354e6ff..1f6518b77c 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -50,6 +50,7 @@ Shell commands cmd/coninfo cmd/conitrace cmd/cp + cmd/cpu cmd/cyclic cmd/dm cmd/ebtupdate

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Added the original author Simon and myself.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Reviewed-by: Simon Glass sjg@chromium.org --- V5: - No change.
MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS index c2832345ab..ddcb7128db 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -997,6 +997,13 @@ F: arch/m68k/ F: doc/arch/m68k.rst F: drivers/watchdog/mcf_wdt.c
+CPU +M: Simon Glass sjg@chromium.org +M: Hou Zhiqiang Zhiqiang.Hou@nxp.com +S: Maintained +F: cmd/cpu.c +F: doc/usage/cpu.rst + CYCLIC M: Stefan Roese sr@denx.de S: Maintained

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Enable the 'cpu' command and the depended imx CPU driver to display the CPU info and release CPU core to run baremetal or RTOS applications.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com --- V5: - No change.
configs/imx8mm_evk_defconfig | 3 +++ configs/imx8mn_evk_defconfig | 3 +++ configs/imx8mp_evk_defconfig | 3 +++ 3 files changed, 9 insertions(+)
diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig index ff33d1532a..8b04586f86 100644 --- a/configs/imx8mm_evk_defconfig +++ b/configs/imx8mm_evk_defconfig @@ -118,3 +118,6 @@ CONFIG_SDP_LOADADDR=0x40400000 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_SPL_USB_SDP_SUPPORT=y CONFIG_IMX_WATCHDOG=y +CONFIG_CPU=y +CONFIG_CPU_IMX=y +CONFIG_CMD_CPU=y diff --git a/configs/imx8mn_evk_defconfig b/configs/imx8mn_evk_defconfig index 2402e9e8bf..ee7a5e9088 100644 --- a/configs/imx8mn_evk_defconfig +++ b/configs/imx8mn_evk_defconfig @@ -105,3 +105,6 @@ CONFIG_SYSRESET_PSCI=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_DM_THERMAL=y CONFIG_IMX_WATCHDOG=y +CONFIG_CPU=y +CONFIG_CPU_IMX=y +CONFIG_CMD_CPU=y diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig index f5ba022b07..3176069991 100644 --- a/configs/imx8mp_evk_defconfig +++ b/configs/imx8mp_evk_defconfig @@ -137,3 +137,6 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL" CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_IMX_WATCHDOG=y +CONFIG_CPU=y +CONFIG_CPU_IMX=y +CONFIG_CMD_CPU=y

From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
Enable the 'cpu' command to display the CPU info and release CPU core to run baremetal or RTOS applications.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com --- V5: - No change.
configs/imx93_11x11_evk_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/imx93_11x11_evk_defconfig b/configs/imx93_11x11_evk_defconfig index 2246715d82..93ab0b9aa3 100644 --- a/configs/imx93_11x11_evk_defconfig +++ b/configs/imx93_11x11_evk_defconfig @@ -52,6 +52,7 @@ CONFIG_CMD_ERASEENV=y # CONFIG_CMD_CRC32 is not set CONFIG_CMD_MEMTEST=y CONFIG_CMD_CLK=y +CONFIG_CMD_CPU=y CONFIG_CMD_DFU=y CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y

On Thu, Aug 1, 2024 at 12:39 AM Zhiqiang Hou Zhiqiang.Hou@nxp.com wrote:
From: Hou Zhiqiang Zhiqiang.Hou@nxp.com
This patch set is to add a subcommand 'release' to the 'cpu' command in cmd/cpu.c, making the command is able to release a core to run baremetal and RTOS applications.
Fixed some problems of the imx8_cpu.c and added i.MX 8M series SoCs support.
Added ARM A53 core clock registration in clock driver of i.MX 8M Mini, Nano and Plus SoCs.
And enabled the 'cpu' command and imx CPU driver for i.MX 8M series EVK boards and i.MX 93 EVK board.
Hou Zhiqiang (14): clk: imx8m: register ARM A53 core clock cpu: add release_core callback cpu: sandbox: implement release_core callback test: cpu: add test for release CPU core. cpu: imx: fix the CPU frequency in cpu_imx_get_info() cpu: imx: fix the CPU type field width cpu: imx: removed the tail '\n' of the CPU description cpu: imx: Add i.MX 8M series SoCs cpu: imx: implement release_core callback cmd: cpu: add release subcommand doc: cmd: add documentation for cpu command MAINTAINERS: add entry for cpu command configs: imx8m: enable the 'cpu' command configs: imx93: enable the 'cpu' command
Applied all, thanks.
participants (2)
-
Fabio Estevam
-
Zhiqiang Hou