1 /*
2 * Copyright 2024-2025 NXP
3 * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include <errno.h>
9
10 #include <common/debug.h>
11 #include <common/desc_image_load.h>
12 #include <drivers/generic_delay_timer.h>
13 #include <imx_usdhc.h>
14 #include <lib/mmio.h>
15 #include <lib/utils.h>
16 #include <lib/xlat_tables/xlat_tables_v2.h>
17 #include <plat/common/platform.h>
18 #include <plat_console.h>
19 #include <s32cc-clk-drv.h>
20
21 #include <plat_io_storage.h>
22 #include <s32cc-bl-common.h>
23 #include <s32cc-ncore.h>
24
25 #define SIUL20_BASE UL(0x4009C000)
26 #define SIUL2_PC09_MSCR UL(0x4009C2E4)
27 #define SIUL2_PC10_MSCR UL(0x4009C2E8)
28 #define SIUL2_PC10_LIN0_IMCR UL(0x4009CA40)
29
30 #define LIN0_TX_MSCR_CFG U(0x00214001)
31 #define LIN0_RX_MSCR_CFG U(0x00094000)
32 #define LIN0_RX_IMCR_CFG U(0x00000002)
33
plat_get_bl_image_load_info(void)34 struct bl_load_info *plat_get_bl_image_load_info(void)
35 {
36 return get_bl_load_info_from_mem_params_desc();
37 }
38
plat_get_next_bl_params(void)39 struct bl_params *plat_get_next_bl_params(void)
40 {
41 return get_next_bl_params_from_mem_params_desc();
42 }
43
plat_flush_next_bl_params(void)44 void plat_flush_next_bl_params(void)
45 {
46 flush_bl_params_desc();
47 }
48
bl2_platform_setup(void)49 void bl2_platform_setup(void)
50 {
51 int ret;
52
53 ret = mmap_add_dynamic_region(S32G_FIP_BASE, S32G_FIP_BASE,
54 S32G_FIP_SIZE,
55 MT_MEMORY | MT_RW | MT_SECURE);
56 if (ret != 0) {
57 panic();
58 }
59 }
60
s32g_mmap_siul2(void)61 static int s32g_mmap_siul2(void)
62 {
63 return mmap_add_dynamic_region(SIUL20_BASE, SIUL20_BASE, PAGE_SIZE,
64 MT_DEVICE | MT_RW | MT_SECURE);
65 }
66
linflex_config_pinctrl(void)67 static void linflex_config_pinctrl(void)
68 {
69 /* set PC09 - MSCR[41] - for UART0 TXD */
70 mmio_write_32(SIUL2_PC09_MSCR, LIN0_TX_MSCR_CFG);
71 /* set PC10 - MSCR[42] - for UART0 RXD */
72 mmio_write_32(SIUL2_PC10_MSCR, LIN0_RX_MSCR_CFG);
73 /* set PC10 - MSCR[512]/IMCR[0] - for UART0 RXD */
74 mmio_write_32(SIUL2_PC10_LIN0_IMCR, LIN0_RX_IMCR_CFG);
75 }
76
init_s32g_usdhc(void)77 static void init_s32g_usdhc(void)
78 {
79 static struct mmc_device_info sd_device_info = {
80 .mmc_dev_type = MMC_IS_SD_HC,
81 .ocr_voltage = OCR_3_2_3_3 | OCR_3_3_3_4,
82 };
83 imx_usdhc_params_t params;
84
85 zeromem(¶ms, sizeof(imx_usdhc_params_t));
86
87 params.reg_base = S32G_USDHC_BASE;
88 params.clk_rate = 25000000;
89 params.bus_width = MMC_BUS_WIDTH_4;
90 params.flags = MMC_FLAG_SD_CMD6;
91
92 imx_usdhc_init(¶ms, &sd_device_info);
93 }
94
plat_s32_mmc_setup(void)95 static void plat_s32_mmc_setup(void)
96 {
97 init_s32g_usdhc();
98 }
99
bl2_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)100 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
101 u_register_t arg2, u_register_t arg3)
102 {
103 int ret;
104
105 /* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
106 * we have manually set during early BL2 boot.
107 */
108 ncore_disable_caiu_isolation(A53_CLUSTER0_CAIU);
109
110 ncore_init();
111 ncore_caiu_online(A53_CLUSTER0_CAIU);
112
113 ret = s32cc_init_core_clocks();
114 if (ret != 0) {
115 panic();
116 }
117
118 ret = s32cc_bl_mmu_setup();
119 if (ret != 0) {
120 panic();
121 }
122
123 ret = s32cc_init_early_clks();
124 if (ret != 0) {
125 panic();
126 }
127
128 ret = s32g_mmap_siul2();
129 if (ret != 0) {
130 panic();
131 }
132
133 generic_delay_timer_init();
134
135 /* Configure the generic timer frequency to ensure proper operation
136 * of the architectural timer in BL2.
137 */
138 write_cntfrq_el0(plat_get_syscnt_freq2());
139
140 linflex_config_pinctrl();
141 console_s32g2_register();
142
143 plat_s32_mmc_setup();
144
145 plat_s32g2_io_setup();
146 }
147
bl2_plat_arch_setup(void)148 void bl2_plat_arch_setup(void)
149 {
150 }
151
bl2_plat_handle_pre_image_load(unsigned int image_id)152 int bl2_plat_handle_pre_image_load(unsigned int image_id)
153 {
154 const struct bl_mem_params_node *desc = get_bl_mem_params_node(image_id);
155 const struct image_info *img_info;
156 size_t size;
157
158 if (desc == NULL) {
159 return -EINVAL;
160 }
161
162 img_info = &desc->image_info;
163
164 if ((img_info == NULL) || (img_info->image_max_size == 0U)) {
165 return -EINVAL;
166 }
167
168 size = page_align(img_info->image_max_size, UP);
169
170 return mmap_add_dynamic_region(img_info->image_base,
171 img_info->image_base,
172 size,
173 MT_MEMORY | MT_RW | MT_SECURE);
174 }
175