diff --git a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c index 9b5760753..235b9889a 100644 --- a/drivers/nxp/clk/s32cc/s32cc_clk_drv.c +++ b/drivers/nxp/clk/s32cc/s32cc_clk_drv.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -1464,7 +1465,39 @@ static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id) return 0; } -void s32cc_clk_register_drv(void) +static int s32cc_clk_mmap_regs(const struct s32cc_clk_drv *drv) +{ + const uintptr_t base_addrs[11] = { + drv->fxosc_base, + drv->armpll_base, + drv->periphpll_base, + drv->armdfs_base, + drv->cgm0_base, + drv->cgm1_base, + drv->cgm5_base, + drv->ddrpll_base, + drv->mc_me, + drv->mc_rgm, + drv->rdc, + }; + size_t i; + int ret; + + for (i = 0U; i < ARRAY_SIZE(base_addrs); i++) { + ret = mmap_add_dynamic_region(base_addrs[i], base_addrs[i], + PAGE_SIZE, + MT_DEVICE | MT_RW | MT_SECURE); + if (ret != 0) { + ERROR("Failed to map clock module 0x%" PRIuPTR "\n", + base_addrs[i]); + return ret; + } + } + + return 0; +} + +int s32cc_clk_register_drv(bool mmap_regs) { static const struct clk_ops s32cc_clk_ops = { .enable = s32cc_clk_enable, @@ -1475,7 +1508,19 @@ void s32cc_clk_register_drv(void) .get_parent = s32cc_clk_get_parent, .set_parent = s32cc_clk_set_parent, }; + const struct s32cc_clk_drv *drv; clk_register(&s32cc_clk_ops); + + drv = get_drv(); + if (drv == NULL) { + return -EINVAL; + } + + if (mmap_regs) { + return s32cc_clk_mmap_regs(drv); + } + + return 0; } diff --git a/drivers/nxp/clk/s32cc/s32cc_early_clks.c b/drivers/nxp/clk/s32cc/s32cc_early_clks.c index 02b9df93c..f001568f4 100644 --- a/drivers/nxp/clk/s32cc/s32cc_early_clks.c +++ b/drivers/nxp/clk/s32cc/s32cc_early_clks.c @@ -180,11 +180,14 @@ static int enable_ddr_clk(void) return ret; } -int s32cc_init_early_clks(void) +int s32cc_init_core_clocks(void) { int ret; - s32cc_clk_register_drv(); + ret = s32cc_clk_register_drv(false); + if (ret != 0) { + return ret; + } ret = setup_fxosc(); if (ret != 0) { @@ -206,6 +209,18 @@ int s32cc_init_early_clks(void) return ret; } + return ret; +} + +int s32cc_init_early_clks(void) +{ + int ret; + + ret = s32cc_clk_register_drv(true); + if (ret != 0) { + return ret; + } + ret = setup_periph_pll(); if (ret != 0) { return ret; diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h index d879f5bed..632b82fc1 100644 --- a/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h +++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-drv.h @@ -6,6 +6,7 @@ #ifndef S32CC_CLK_DRV_H #define S32CC_CLK_DRV_H +int s32cc_init_core_clocks(void); int s32cc_init_early_clks(void); #endif diff --git a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h index e6adeccd7..c6e90f056 100644 --- a/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h +++ b/include/drivers/nxp/clk/s32cc/s32cc-clk-utils.h @@ -5,6 +5,7 @@ #ifndef S32CC_CLK_UTILS_H #define S32CC_CLK_UTILS_H +#include #include struct s32cc_clk *s32cc_get_clk_from_table(const struct s32cc_clk_array *const *clk_arr, @@ -18,6 +19,6 @@ int s32cc_get_id_from_table(const struct s32cc_clk_array *const *clk_arr, struct s32cc_clk *s32cc_get_arch_clk(unsigned long id); int s32cc_get_clk_id(const struct s32cc_clk *clk, unsigned long *id); -void s32cc_clk_register_drv(void); +int s32cc_clk_register_drv(bool mmap_regs); #endif /* S32CC_CLK_UTILS_H */ diff --git a/plat/nxp/s32/s32g274ardb2/include/platform_def.h b/plat/nxp/s32/s32g274ardb2/include/platform_def.h index 1a4c495aa..cb166581d 100644 --- a/plat/nxp/s32/s32g274ardb2/include/platform_def.h +++ b/plat/nxp/s32/s32g274ardb2/include/platform_def.h @@ -48,7 +48,7 @@ /* We'll be doing a 1:1 mapping anyway */ #define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 36) -#define MAX_MMAP_REGIONS U(8) +#define MAX_MMAP_REGIONS U(18) #define MAX_XLAT_TABLES U(32) /* Console settings */ diff --git a/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h b/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h new file mode 100644 index 000000000..0f0c8041c --- /dev/null +++ b/plat/nxp/s32/s32g274ardb2/include/s32cc-bl-common.h @@ -0,0 +1,12 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef S32CC_BL_COMMON_H +#define S32CC_BL_COMMON_H + +int s32cc_bl_mmu_setup(void); + +#endif /* S32CC_BL_COMMON_H */ diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c index 4645f01ed..0929f9d84 100644 --- a/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c +++ b/plat/nxp/s32/s32g274ardb2/plat_bl2_el3_setup.c @@ -4,15 +4,21 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include #include +#include #include #include #include + #include +#include #include +#define SIUL20_BASE UL(0x4009C000) #define SIUL2_PC09_MSCR UL(0x4009C2E4) #define SIUL2_PC10_MSCR UL(0x4009C2E8) #define SIUL2_PC10_LIN0_IMCR UL(0x4009CA40) @@ -38,6 +44,20 @@ void plat_flush_next_bl_params(void) void bl2_platform_setup(void) { + int ret; + + ret = mmap_add_dynamic_region(S32G_FIP_BASE, S32G_FIP_BASE, + S32G_FIP_SIZE, + MT_MEMORY | MT_RW | MT_SECURE); + if (ret != 0) { + panic(); + } +} + +static int s32g_mmap_siul2(void) +{ + return mmap_add_dynamic_region(SIUL20_BASE, SIUL20_BASE, PAGE_SIZE, + MT_DEVICE | MT_RW | MT_SECURE); } static void linflex_config_pinctrl(void) @@ -55,14 +75,6 @@ void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1, { int ret; - ret = s32cc_init_early_clks(); - if (ret != 0) { - panic(); - } - - linflex_config_pinctrl(); - console_s32g2_register(); - /* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which * we have manually set during early BL2 boot. */ @@ -71,6 +83,29 @@ void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1, ncore_init(); ncore_caiu_online(A53_CLUSTER0_CAIU); + ret = s32cc_init_core_clocks(); + if (ret != 0) { + panic(); + } + + ret = s32cc_bl_mmu_setup(); + if (ret != 0) { + panic(); + } + + ret = s32cc_init_early_clks(); + if (ret != 0) { + panic(); + } + + ret = s32g_mmap_siul2(); + if (ret != 0) { + panic(); + } + + linflex_config_pinctrl(); + console_s32g2_register(); + plat_s32g2_io_setup(); } @@ -78,3 +113,26 @@ void bl2_el3_plat_arch_setup(void) { } +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + const struct bl_mem_params_node *desc = get_bl_mem_params_node(image_id); + const struct image_info *img_info; + size_t size; + + if (desc == NULL) { + return -EINVAL; + } + + img_info = &desc->image_info; + + if ((img_info == NULL) || (img_info->image_max_size == 0U)) { + return -EINVAL; + } + + size = page_align(img_info->image_max_size, UP); + + return mmap_add_dynamic_region(img_info->image_base, + img_info->image_base, + size, + MT_MEMORY | MT_RW | MT_SECURE); +} diff --git a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c index 03bf35cc1..22c66b00e 100644 --- a/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c +++ b/plat/nxp/s32/s32g274ardb2/plat_bl31_setup.c @@ -4,10 +4,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include +#include #include #include +#include + static entry_point_info_t bl33_image_ep_info; static unsigned int s32g2_mpidr_to_core_pos(unsigned long mpidr); @@ -25,8 +29,6 @@ static uint32_t get_spsr_for_bl33_entry(void) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - console_s32g2_register(); - SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0); bl33_image_ep_info.pc = BL33_BASE; bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); @@ -35,6 +37,14 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, void bl31_plat_arch_setup(void) { + int ret; + + ret = s32cc_bl_mmu_setup(); + if (ret != 0) { + panic(); + } + + console_s32g2_register(); } struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) @@ -42,6 +52,31 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) return &bl33_image_ep_info; } +static int mmap_gic(const gicv3_driver_data_t *gic_data) +{ + size_t gicr_size; + int ret; + + ret = mmap_add_dynamic_region(gic_data->gicd_base, + gic_data->gicd_base, + PAGE_SIZE_64KB, + MT_DEVICE | MT_RW | MT_SECURE); + if (ret != 0) { + return ret; + } + + gicr_size = gicv3_redist_size(0x0U); + ret = mmap_add_dynamic_region(gic_data->gicr_base, + gic_data->gicr_base, + gicr_size * gic_data->rdistif_num, + MT_DEVICE | MT_RW | MT_SECURE); + if (ret != 0) { + return ret; + } + + return 0; +} + void bl31_platform_setup(void) { static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; @@ -52,8 +87,13 @@ void bl31_platform_setup(void) .rdistif_base_addrs = rdistif_base_addrs, .mpidr_to_core_pos = s32g2_mpidr_to_core_pos, }; - unsigned int pos = plat_my_core_pos(); + int ret; + + ret = mmap_gic(&plat_gic_data); + if (ret != 0) { + panic(); + } gicv3_driver_init(&plat_gic_data); gicv3_distif_init(); diff --git a/plat/nxp/s32/s32g274ardb2/plat_console.c b/plat/nxp/s32/s32g274ardb2/plat_console.c index 542fa7bef..e65e43953 100644 --- a/plat/nxp/s32/s32g274ardb2/plat_console.c +++ b/plat/nxp/s32/s32g274ardb2/plat_console.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -17,6 +18,12 @@ void console_s32g2_register(void) }; int ret; + ret = mmap_add_dynamic_region(UART_BASE, UART_BASE, PAGE_SIZE, + MT_DEVICE | MT_RW | MT_SECURE); + if (ret != 0) { + panic(); + } + ret = console_linflex_register(UART_BASE, UART_CLOCK_HZ, UART_BAUDRATE, &s32g2_console); if (ret == 0) { diff --git a/plat/nxp/s32/s32g274ardb2/platform.mk b/plat/nxp/s32/s32g274ardb2/platform.mk index 7d6e960a1..4ec7cd04f 100644 --- a/plat/nxp/s32/s32g274ardb2/platform.mk +++ b/plat/nxp/s32/s32g274ardb2/platform.mk @@ -38,6 +38,9 @@ ERRATA_A53_1530924 := 1 ERRATA_SPECULATIVE_AT := 1 ERRATA_S32_051700 := 1 +PLAT_XLAT_TABLES_DYNAMIC := 1 +$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) + # Selecting Drivers for SoC $(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM)) $(eval $(call SET_NXP_MAKE_FLAG,CLK_NEEDED,BL_COMM)) @@ -47,6 +50,8 @@ include ${PLAT_DRIVERS_PATH}/drivers.mk BL_COMMON_SOURCES += \ ${PLAT_S32G274ARDB2}/plat_console.c \ ${PLAT_S32G274ARDB2}/plat_helpers.S \ + ${PLAT_S32G274ARDB2}/s32cc_bl_common.c \ + ${XLAT_TABLES_LIB_SRCS} \ BL2_SOURCES += \ ${BL_COMMON_SOURCES} \ diff --git a/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c b/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c new file mode 100644 index 000000000..466443849 --- /dev/null +++ b/plat/nxp/s32/s32g274ardb2/s32cc_bl_common.c @@ -0,0 +1,40 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include + +#include + +int s32cc_bl_mmu_setup(void) +{ + const unsigned long code_start = BL_CODE_BASE; + const unsigned long rw_start = BL_CODE_END; + unsigned long code_size; + unsigned long rw_size; + + if (code_start > BL_CODE_END) { + return -EINVAL; + } + + if (rw_start > BL_END) { + return -EINVAL; + } + + code_size = BL_CODE_END - code_start; + rw_size = BL_END - rw_start; + + mmap_add_region(code_start, code_start, code_size, + MT_RO | MT_MEMORY | MT_SECURE); + mmap_add_region(rw_start, rw_start, rw_size, + MT_RW | MT_MEMORY | MT_SECURE); + + init_xlat_tables(); + enable_mmu_el3(0); + + return 0; +}