1 /* 2 * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <inttypes.h> 9 #include <stdbool.h> 10 #include <stdint.h> 11 12 #include <platform_def.h> 13 14 #include <arch_helpers.h> 15 #include <common/bl_common.h> 16 #include <common/debug.h> 17 #include <context.h> 18 #include <drivers/arm/cci.h> 19 #include <drivers/console.h> 20 #include <lib/el3_runtime/context_mgmt.h> 21 #include <lib/mmio.h> 22 #include <lib/xlat_tables/xlat_tables_v2.h> 23 #include <plat/common/platform.h> 24 25 #include <imx8qx_pads.h> 26 #include <imx8_iomux.h> 27 #include <imx8_lpuart.h> 28 #include <plat_imx8.h> 29 #include <sci/sci.h> 30 #include <sec_rsrc.h> 31 32 static const unsigned long BL31_COHERENT_RAM_START = BL_COHERENT_RAM_BASE; 33 static const unsigned long BL31_COHERENT_RAM_END = BL_COHERENT_RAM_END; 34 static const unsigned long BL31_RO_START = BL_CODE_BASE; 35 static const unsigned long BL31_RO_END = BL_CODE_END; 36 static const unsigned long BL31_RW_END = BL_END; 37 38 IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START); 39 40 static entry_point_info_t bl32_image_ep_info; 41 static entry_point_info_t bl33_image_ep_info; 42 43 /* Default configuration for i.MX8QM/QXP MEK */ 44 #if defined(IMX_USE_UART0) 45 #define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \ 46 (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 47 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 48 (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ 49 (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) 50 #define IMX_RES_UART SC_R_UART_0 51 #define IMX_PAD_UART_RX SC_P_UART0_RX 52 #define IMX_PAD_UART_TX SC_P_UART0_TX 53 54 #elif defined(IMX_USE_UART1) 55 #define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \ 56 (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 57 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 58 (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ 59 (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) 60 #define IMX_RES_UART SC_R_UART_1 61 #define IMX_PAD_UART_RX SC_P_UART1_RX 62 #define IMX_PAD_UART_TX SC_P_UART1_TX 63 64 /* 65 * On Toradex Colibri i.MX8QXP UART3 on the FLEXCAN2. 66 * Use custom pad control for this 67 */ 68 #elif defined(IMX_USE_UART3) 69 /* 70 * FLEXCAN2_RX/TX pads are muxed to ADMA_UART3_RX/TX, 71 * For ref: 72 * 000b - ADMA_FLEXCAN2_RX 73 * 001b - ADMA_SAI3_RXD 74 * 010b - ADMA_UART3_RX 75 * 011b - ADMA_SAI1_RXFS 76 * 100b - LSIO_GPIO1_IO19 77 */ 78 #define UART_PAD_CTRL (PADRING_IFMUX_EN_MASK | PADRING_GP_EN_MASK | \ 79 (SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ 80 (2U << PADRING_IFMUX_SHIFT) | \ 81 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ 82 (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ 83 (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) 84 #define IMX_RES_UART SC_R_UART_3 85 #define IMX_PAD_UART_RX SC_P_FLEXCAN2_RX 86 #define IMX_PAD_UART_TX SC_P_FLEXCAN2_TX 87 #else 88 #error "Provide proper UART configuration in IMX_DEBUG_UART" 89 #endif 90 91 static const mmap_region_t imx_mmap[] = { 92 MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW), 93 {0} 94 }; 95 96 static uint32_t get_spsr_for_bl33_entry(void) 97 { 98 unsigned long el_status; 99 unsigned long mode; 100 uint32_t spsr; 101 102 /* figure out what mode we enter the non-secure world */ 103 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; 104 el_status &= ID_AA64PFR0_ELX_MASK; 105 106 mode = (el_status) ? MODE_EL2 : MODE_EL1; 107 108 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 109 return spsr; 110 } 111 112 #if DEBUG_CONSOLE_A35 113 static void lpuart32_serial_setbrg(unsigned int base, int baudrate) 114 { 115 unsigned int sbr, osr, baud_diff, tmp_osr, tmp_sbr; 116 unsigned int diff1, diff2, tmp, rate; 117 118 if (baudrate == 0) 119 panic(); 120 121 sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); 122 123 baud_diff = baudrate; 124 osr = 0; 125 sbr = 0; 126 for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) { 127 tmp_sbr = (rate / (baudrate * tmp_osr)); 128 if (tmp_sbr == 0) 129 tmp_sbr = 1; 130 131 /* calculate difference in actual baud w/ current values */ 132 diff1 = rate / (tmp_osr * tmp_sbr) - baudrate; 133 diff2 = rate / (tmp_osr * (tmp_sbr + 1)); 134 135 /* select best values between sbr and sbr+1 */ 136 if (diff1 > (baudrate - diff2)) { 137 diff1 = baudrate - diff2; 138 tmp_sbr++; 139 } 140 141 if (diff1 <= baud_diff) { 142 baud_diff = diff1; 143 osr = tmp_osr; 144 sbr = tmp_sbr; 145 } 146 } 147 148 tmp = mmio_read_32(IMX_BOOT_UART_BASE + BAUD); 149 150 if ((osr > 3) && (osr < 8)) 151 tmp |= LPUART_BAUD_BOTHEDGE_MASK; 152 153 tmp &= ~LPUART_BAUD_OSR_MASK; 154 tmp |= LPUART_BAUD_OSR(osr - 1); 155 tmp &= ~LPUART_BAUD_SBR_MASK; 156 tmp |= LPUART_BAUD_SBR(sbr); 157 158 /* explicitly disable 10 bit mode & set 1 stop bit */ 159 tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK); 160 161 mmio_write_32(IMX_BOOT_UART_BASE + BAUD, tmp); 162 } 163 164 static int lpuart32_serial_init(unsigned int base) 165 { 166 unsigned int tmp; 167 168 /* disable TX & RX before enabling clocks */ 169 tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL); 170 tmp &= ~(CTRL_TE | CTRL_RE); 171 mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp); 172 173 mmio_write_32(IMX_BOOT_UART_BASE + MODIR, 0); 174 mmio_write_32(IMX_BOOT_UART_BASE + FIFO, ~(FIFO_TXFE | FIFO_RXFE)); 175 176 mmio_write_32(IMX_BOOT_UART_BASE + MATCH, 0); 177 178 /* provide data bits, parity, stop bit, etc */ 179 lpuart32_serial_setbrg(base, IMX_BOOT_UART_BAUDRATE); 180 181 /* eight data bits no parity bit */ 182 tmp = mmio_read_32(IMX_BOOT_UART_BASE + CTRL); 183 tmp &= ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK); 184 mmio_write_32(IMX_BOOT_UART_BASE + CTRL, tmp); 185 186 mmio_write_32(IMX_BOOT_UART_BASE + CTRL, CTRL_RE | CTRL_TE); 187 188 mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55); 189 mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x55); 190 mmio_write_32(IMX_BOOT_UART_BASE + DATA, 0x0A); 191 192 return 0; 193 } 194 #endif 195 196 void imx8_partition_resources(void) 197 { 198 sc_rm_pt_t secure_part, os_part; 199 sc_rm_mr_t mr, mr_record = 64; 200 sc_faddr_t start, end; 201 sc_err_t err; 202 bool owned; 203 int i; 204 205 err = sc_rm_get_partition(ipc_handle, &secure_part); 206 if (err) 207 ERROR("sc_rm_get_partition failed: %u\n", err); 208 209 err = sc_rm_partition_alloc(ipc_handle, &os_part, false, false, 210 false, false, false); 211 if (err) 212 ERROR("sc_rm_partition_alloc failed: %u\n", err); 213 214 err = sc_rm_set_parent(ipc_handle, os_part, secure_part); 215 if (err) 216 ERROR("sc_rm_set_parent: %u\n", err); 217 218 /* set secure resources to NOT-movable */ 219 for (i = 0; i < (ARRAY_SIZE(secure_rsrcs)); i++) { 220 err = sc_rm_set_resource_movable(ipc_handle, 221 secure_rsrcs[i], secure_rsrcs[i], false); 222 if (err) 223 ERROR("sc_rm_set_resource_movable: rsrc %u, ret %u\n", 224 secure_rsrcs[i], err); 225 } 226 227 /* move all movable resources and pins to non-secure partition */ 228 err = sc_rm_move_all(ipc_handle, secure_part, os_part, true, true); 229 if (err) 230 ERROR("sc_rm_move_all: %u\n", err); 231 232 /* iterate through peripherals to give NS OS part access */ 233 for (i = 0; i < ARRAY_SIZE(ns_access_allowed); i++) { 234 err = sc_rm_set_peripheral_permissions(ipc_handle, 235 ns_access_allowed[i], os_part, SC_RM_PERM_FULL); 236 if (err) 237 ERROR("sc_rm_set_peripheral_permissions: rsrc %u, \ 238 ret %u\n", ns_access_allowed[i], err); 239 } 240 241 /* 242 * sc_rm_set_peripheral_permissions 243 * sc_rm_set_memreg_permissions 244 * sc_rm_set_pin_movable 245 */ 246 for (mr = 0; mr < 64; mr++) { 247 owned = sc_rm_is_memreg_owned(ipc_handle, mr); 248 if (owned) { 249 err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end); 250 if (err) 251 ERROR("Memreg get info failed, %u\n", mr); 252 253 NOTICE("Memreg %u 0x%" PRIx64 " -- 0x%" PRIx64 "\n", mr, start, end); 254 if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) { 255 mr_record = mr; /* Record the mr for ATF running */ 256 } else { 257 err = sc_rm_assign_memreg(ipc_handle, os_part, mr); 258 if (err) 259 ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 ", \ 260 err %d\n", start, end, err); 261 } 262 } 263 } 264 265 if (mr_record != 64) { 266 err = sc_rm_get_memreg_info(ipc_handle, mr_record, &start, &end); 267 if (err) 268 ERROR("Memreg get info failed, %u\n", mr_record); 269 if ((BL31_LIMIT - 1) < end) { 270 err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end); 271 if (err) 272 ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 273 (sc_faddr_t)BL31_LIMIT, end); 274 err = sc_rm_assign_memreg(ipc_handle, os_part, mr); 275 if (err) 276 ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 277 (sc_faddr_t)BL31_LIMIT, end); 278 } 279 280 if (start < (BL31_BASE - 1)) { 281 err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1); 282 if (err) 283 ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 284 start, (sc_faddr_t)BL31_BASE - 1); 285 err = sc_rm_assign_memreg(ipc_handle, os_part, mr); 286 if (err) 287 ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", 288 start, (sc_faddr_t)BL31_BASE - 1); 289 } 290 } 291 292 if (err) 293 NOTICE("Partitioning Failed\n"); 294 else 295 NOTICE("Non-secure Partitioning Succeeded\n"); 296 } 297 298 void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 299 u_register_t arg2, u_register_t arg3) 300 { 301 #if DEBUG_CONSOLE 302 static console_t console; 303 #endif 304 if (sc_ipc_open(&ipc_handle, SC_IPC_BASE) != SC_ERR_NONE) 305 panic(); 306 307 #if DEBUG_CONSOLE_A35 308 sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART, 309 SC_PM_PW_MODE_ON); 310 sc_pm_clock_rate_t rate = 80000000; 311 sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); 312 sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false); 313 314 /* Configure UART pads */ 315 sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL); 316 sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL); 317 lpuart32_serial_init(IMX_BOOT_UART_BASE); 318 #endif 319 320 #if DEBUG_CONSOLE 321 console_lpuart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, 322 IMX_CONSOLE_BAUDRATE, &console); 323 #endif 324 /* Turn on MU1 for non-secure OS/Hypervisor */ 325 sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON); 326 327 /* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */ 328 sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON); 329 sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0); 330 mmio_write_32(IMX_GPT0_LPCG_BASE, mmio_read_32(IMX_GPT0_LPCG_BASE) | (1 << 25)); 331 332 /* 333 * create new partition for non-secure OS/Hypervisor 334 * uses global structs defined in sec_rsrc.h 335 */ 336 imx8_partition_resources(); 337 338 bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET; 339 bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); 340 SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 341 } 342 343 void bl31_plat_arch_setup(void) 344 { 345 unsigned long ro_start = BL31_RO_START; 346 unsigned long ro_size = BL31_RO_END - BL31_RO_START; 347 unsigned long rw_start = BL31_RW_START; 348 unsigned long rw_size = BL31_RW_END - BL31_RW_START; 349 #if USE_COHERENT_MEM 350 unsigned long coh_start = BL31_COHERENT_RAM_START; 351 unsigned long coh_size = BL31_COHERENT_RAM_END - BL31_COHERENT_RAM_START; 352 #endif 353 354 mmap_add_region(ro_start, ro_start, ro_size, 355 MT_RO | MT_MEMORY | MT_SECURE); 356 mmap_add_region(rw_start, rw_start, rw_size, 357 MT_RW | MT_MEMORY | MT_SECURE); 358 mmap_add(imx_mmap); 359 360 #if USE_COHERENT_MEM 361 mmap_add_region(coh_start, coh_start, coh_size, 362 MT_DEVICE | MT_RW | MT_SECURE); 363 #endif 364 365 init_xlat_tables(); 366 enable_mmu_el3(0); 367 } 368 369 void bl31_platform_setup(void) 370 { 371 plat_gic_driver_init(); 372 plat_gic_init(); 373 } 374 375 entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type) 376 { 377 if (type == NON_SECURE) 378 return &bl33_image_ep_info; 379 if (type == SECURE) 380 return &bl32_image_ep_info; 381 382 return NULL; 383 } 384 385 unsigned int plat_get_syscnt_freq2(void) 386 { 387 return COUNTER_FREQUENCY; 388 } 389