feat(imx8ulp): add i.MX8ULP basic support
Add the basic support for i.MX8ULP.
The i.MX 8ULP family of processors features NXP’s advanced
implementation of the dual Arm Cortex-A35 cores alongside
an Arm Cortex-M33. This combined architecture enables the
device to run a rich operating system (such as Linux) on
the Cortex-A35 core and an RTOS (such as FreeRTOS) on the
Cortex-M33 core. It also includes a Cadence Tensilica Fusion
DSP for low-power audio and a HiFi4 DSP for advanced audio
and machine learning applications.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Jacky Bai <ping.bai@nxp.com>
Change-Id: I12df622b95960bcdf7da52e4c66470a700690e36
diff --git a/plat/imx/imx8ulp/imx8ulp_bl31_setup.c b/plat/imx/imx8ulp/imx8ulp_bl31_setup.c
new file mode 100644
index 0000000..c257263
--- /dev/null
+++ b/plat/imx/imx8ulp/imx8ulp_bl31_setup.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2021-2024 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <drivers/console.h>
+#include <drivers/generic_delay_timer.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+
+#include <imx8_lpuart.h>
+#include <imx_plat_common.h>
+#include <plat_imx8.h>
+#include <upower_api.h>
+
+#define MAP_BL31_TOTAL \
+ MAP_REGION_FLAT(BL31_BASE, BL31_LIMIT - BL31_BASE, MT_MEMORY | MT_RW | MT_SECURE)
+#define MAP_BL31_RO \
+ MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_MEMORY | MT_RO | MT_SECURE)
+
+#define MAP_COHERENT_MEM \
+ MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, (BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE), \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+static const mmap_region_t imx_mmap[] = {
+ DEVICE0_MAP, DEVICE1_MAP, ELE_MAP,
+ SEC_SIM_MAP, SRAM0_MAP,
+ {0}
+};
+
+extern uint32_t upower_init(void);
+extern void imx8ulp_init_scmi_server(void);
+
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ static console_t console;
+
+
+ /* enable the GPIO D,E,F non-secure access by default */
+ mmio_write_32(IMX_PCC4_BASE + 0x78, 0xc0000000);
+ mmio_write_32(IMX_PCC4_BASE + 0x7c, 0xc0000000);
+ mmio_write_32(IMX_PCC5_BASE + 0x114, 0xc0000000);
+
+ mmio_write_32(IMX_GPIOE_BASE + 0x10, 0xffffffff);
+ mmio_write_32(IMX_GPIOE_BASE + 0x14, 0x3);
+ mmio_write_32(IMX_GPIOE_BASE + 0x18, 0xffffffff);
+ mmio_write_32(IMX_GPIOE_BASE + 0x1c, 0x3);
+
+ mmio_write_32(IMX_GPIOF_BASE + 0x10, 0xffffffff);
+ mmio_write_32(IMX_GPIOF_BASE + 0x14, 0x3);
+ mmio_write_32(IMX_GPIOF_BASE + 0x18, 0xffffffff);
+ mmio_write_32(IMX_GPIOF_BASE + 0x1c, 0x3);
+
+ mmio_write_32(IMX_GPIOD_BASE + 0x10, 0xffffffff);
+ mmio_write_32(IMX_GPIOD_BASE + 0x14, 0x3);
+ mmio_write_32(IMX_GPIOD_BASE + 0x18, 0xffffffff);
+ mmio_write_32(IMX_GPIOD_BASE + 0x1c, 0x3);
+
+ console_lpuart_register(IMX_LPUART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+ IMX_CONSOLE_BAUDRATE, &console);
+
+ /* This console is only used for boot stage */
+ console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
+
+ bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
+ bl33_image_ep_info.spsr = plat_get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+}
+
+void bl31_plat_arch_setup(void)
+{
+ const mmap_region_t bl_regions[] = {
+ MAP_BL31_TOTAL,
+ MAP_BL31_RO,
+#if USE_COHERENT_MEM
+ MAP_COHERENT_MEM,
+#endif
+ {0},
+ };
+
+ setup_page_tables(bl_regions, imx_mmap);
+ enable_mmu_el3(0);
+
+ /* TODO: Hack, refine this piece, scmi channel free */
+ mmio_write_32(SRAM0_BASE + 0x4, 1);
+}
+
+void bl31_platform_setup(void)
+{
+ /* select the arch timer source */
+ mmio_setbits_32(IMX_SIM1_BASE + 0x30, 0x8000000);
+
+ generic_delay_timer_init();
+
+ plat_gic_driver_init();
+ plat_gic_init();
+
+ imx8ulp_init_scmi_server();
+ upower_init();
+}
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
+{
+ if (type == NON_SECURE) {
+ return &bl33_image_ep_info;
+ } else {
+ return &bl32_image_ep_info;
+ }
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return COUNTER_FREQUENCY;
+}
+
+void bl31_plat_runtime_setup(void)
+{
+}