1 /* 2 * Copyright 2019 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <stdlib.h> 9 #include <stdint.h> 10 #include <services/std_svc.h> 11 #include <string.h> 12 #include <platform_def.h> 13 #include <common/debug.h> 14 #include <common/runtime_svc.h> 15 #include <imx_sip_svc.h> 16 #include <lib/el3_runtime/context_mgmt.h> 17 #include <lib/mmio.h> 18 #include <sci/sci.h> 19 20 #if defined(PLAT_imx8mn) || defined(PLAT_imx8mp) 21 /* 22 * Defined in 23 * table 11. ROM event log buffer address location 24 * AN12853 "i.MX ROMs Log Events" 25 */ 26 #define ROM_LOG_BUFFER_ADDR 0x9E0 27 #endif 28 29 #if defined(PLAT_imx8qm) || defined(PLAT_imx8qx) 30 31 #ifdef PLAT_imx8qm 32 static const int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = { 33 SC_R_A53, SC_R_A72, 34 }; 35 #endif 36 37 static int imx_srtc_set_time(uint32_t year_mon, 38 unsigned long day_hour, 39 unsigned long min_sec) 40 { 41 return sc_timer_set_rtc_time(ipc_handle, 42 year_mon >> 16, year_mon & 0xffff, 43 day_hour >> 16, day_hour & 0xffff, 44 min_sec >> 16, min_sec & 0xffff); 45 } 46 47 int imx_srtc_handler(uint32_t smc_fid, 48 void *handle, 49 u_register_t x1, 50 u_register_t x2, 51 u_register_t x3, 52 u_register_t x4) 53 { 54 int ret; 55 56 switch (x1) { 57 case IMX_SIP_SRTC_SET_TIME: 58 ret = imx_srtc_set_time(x2, x3, x4); 59 break; 60 default: 61 ret = SMC_UNK; 62 } 63 64 SMC_RET1(handle, ret); 65 } 66 67 static void imx_cpufreq_set_target(uint32_t cluster_id, unsigned long freq) 68 { 69 sc_pm_clock_rate_t rate = (sc_pm_clock_rate_t)freq; 70 71 #ifdef PLAT_imx8qm 72 sc_pm_set_clock_rate(ipc_handle, ap_cluster_index[cluster_id], SC_PM_CLK_CPU, &rate); 73 #endif 74 #ifdef PLAT_imx8qx 75 sc_pm_set_clock_rate(ipc_handle, SC_R_A35, SC_PM_CLK_CPU, &rate); 76 #endif 77 } 78 79 int imx_cpufreq_handler(uint32_t smc_fid, 80 u_register_t x1, 81 u_register_t x2, 82 u_register_t x3) 83 { 84 switch (x1) { 85 case IMX_SIP_SET_CPUFREQ: 86 imx_cpufreq_set_target(x2, x3); 87 break; 88 default: 89 return SMC_UNK; 90 } 91 92 return 0; 93 } 94 95 static bool wakeup_src_irqsteer; 96 97 bool imx_is_wakeup_src_irqsteer(void) 98 { 99 return wakeup_src_irqsteer; 100 } 101 102 int imx_wakeup_src_handler(uint32_t smc_fid, 103 u_register_t x1, 104 u_register_t x2, 105 u_register_t x3) 106 { 107 switch (x1) { 108 case IMX_SIP_WAKEUP_SRC_IRQSTEER: 109 wakeup_src_irqsteer = true; 110 break; 111 case IMX_SIP_WAKEUP_SRC_SCU: 112 wakeup_src_irqsteer = false; 113 break; 114 default: 115 return SMC_UNK; 116 } 117 118 return SMC_OK; 119 } 120 121 int imx_otp_handler(uint32_t smc_fid, 122 void *handle, 123 u_register_t x1, 124 u_register_t x2) 125 { 126 int ret; 127 uint32_t fuse; 128 129 switch (smc_fid) { 130 case IMX_SIP_OTP_READ: 131 ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse); 132 SMC_RET2(handle, ret, fuse); 133 break; 134 case IMX_SIP_OTP_WRITE: 135 ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2); 136 SMC_RET1(handle, ret); 137 break; 138 default: 139 ret = SMC_UNK; 140 SMC_RET1(handle, ret); 141 break; 142 } 143 144 return ret; 145 } 146 147 int imx_misc_set_temp_handler(uint32_t smc_fid, 148 u_register_t x1, 149 u_register_t x2, 150 u_register_t x3, 151 u_register_t x4) 152 { 153 return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4); 154 } 155 156 #endif /* defined(PLAT_imx8qm) || defined(PLAT_imx8qx) */ 157 158 #if defined(PLAT_imx8mm) || defined(PLAT_imx8mq) 159 int imx_src_handler(uint32_t smc_fid, 160 u_register_t x1, 161 u_register_t x2, 162 u_register_t x3, 163 void *handle) 164 { 165 uint32_t val; 166 167 switch (x1) { 168 case IMX_SIP_SRC_SET_SECONDARY_BOOT: 169 if (x2 != 0U) { 170 mmio_setbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET, 171 SRC_GPR10_PERSIST_SECONDARY_BOOT); 172 } else { 173 mmio_clrbits_32(IMX_SRC_BASE + SRC_GPR10_OFFSET, 174 SRC_GPR10_PERSIST_SECONDARY_BOOT); 175 } 176 break; 177 case IMX_SIP_SRC_IS_SECONDARY_BOOT: 178 val = mmio_read_32(IMX_SRC_BASE + SRC_GPR10_OFFSET); 179 return !!(val & SRC_GPR10_PERSIST_SECONDARY_BOOT); 180 default: 181 return SMC_UNK; 182 183 }; 184 185 return 0; 186 } 187 #endif /* defined(PLAT_imx8mm) || defined(PLAT_imx8mq) */ 188 189 #if defined(PLAT_imx8mn) || defined(PLAT_imx8mp) 190 static bool is_secondary_boot(void) 191 { 192 uint32_t *rom_log_addr = (uint32_t *)ROM_LOG_BUFFER_ADDR; 193 bool is_secondary = false; 194 uint32_t *rom_log; 195 uint8_t event_id; 196 197 /* If the ROM event log pointer is not valid. */ 198 if (*rom_log_addr < 0x900000 || *rom_log_addr >= 0xB00000 || 199 *rom_log_addr & 0x3) { 200 return false; 201 } 202 203 /* Parse the ROM event ID version 2 log */ 204 rom_log = (uint32_t *)(uintptr_t)(*rom_log_addr); 205 for (size_t i = 0; i < 128; i++) { 206 event_id = rom_log[i] >> 24; 207 switch (event_id) { 208 case 0x00: /* End of list */ 209 return is_secondary; 210 /* Log entries with 1 parameter, skip 1 */ 211 case 0x80: /* Perform the device initialization */ 212 case 0x81: /* The boot device initialization completes */ 213 case 0x82: /* Execute boot device driver pre-config */ 214 case 0x8F: /* The boot device initialization fails */ 215 case 0x90: /* Start to read data from boot device */ 216 case 0x91: /* Reading data from boot device completes */ 217 case 0x9F: /* Reading data from boot device fails */ 218 i += 1; 219 continue; 220 /* Log entries with 2 parameters, skip 2 */ 221 case 0xA0: /* Image authentication result */ 222 case 0xC0: /* Jump to the boot image soon */ 223 i += 2; 224 continue; 225 /* Booted the primary boot image */ 226 case 0x50: 227 is_secondary = false; 228 continue; 229 /* Booted the secondary boot image */ 230 case 0x51: 231 is_secondary = true; 232 continue; 233 } 234 } 235 236 return is_secondary; 237 } 238 239 int imx_src_handler(uint32_t smc_fid, 240 u_register_t x1, 241 u_register_t x2, 242 u_register_t x3, 243 void *handle) 244 { 245 switch (x1) { 246 case IMX_SIP_SRC_SET_SECONDARY_BOOT: 247 /* we do support that on these SoCs */ 248 break; 249 case IMX_SIP_SRC_IS_SECONDARY_BOOT: 250 return is_secondary_boot(); 251 default: 252 return SMC_UNK; 253 }; 254 255 return 0; 256 } 257 #endif /* defined(PLAT_imx8mn) || defined(PLAT_imx8mp) */ 258 259 static uint64_t imx_get_commit_hash(u_register_t x2, 260 u_register_t x3, 261 u_register_t x4) 262 { 263 /* Parse the version_string */ 264 char *parse = (char *)version_string; 265 uint64_t hash = 0; 266 267 do { 268 parse = strchr(parse, '-'); 269 if (parse) { 270 parse += 1; 271 if (*(parse) == 'g') { 272 /* Default is 7 hexadecimal digits */ 273 memcpy((void *)&hash, (void *)(parse + 1), 7); 274 break; 275 } 276 } 277 278 } while (parse != NULL); 279 280 return hash; 281 } 282 283 uint64_t imx_buildinfo_handler(uint32_t smc_fid, 284 u_register_t x1, 285 u_register_t x2, 286 u_register_t x3, 287 u_register_t x4) 288 { 289 uint64_t ret; 290 291 switch (x1) { 292 case IMX_SIP_BUILDINFO_GET_COMMITHASH: 293 ret = imx_get_commit_hash(x2, x3, x4); 294 break; 295 default: 296 return SMC_UNK; 297 } 298 299 return ret; 300 } 301 302 int imx_kernel_entry_handler(uint32_t smc_fid, 303 u_register_t x1, 304 u_register_t x2, 305 u_register_t x3, 306 u_register_t x4) 307 { 308 static entry_point_info_t bl33_image_ep_info; 309 entry_point_info_t *next_image_info; 310 unsigned int mode; 311 312 if (x1 < (PLAT_NS_IMAGE_OFFSET & 0xF0000000)) 313 return SMC_UNK; 314 315 mode = MODE32_svc; 316 317 next_image_info = &bl33_image_ep_info; 318 319 next_image_info->pc = x1; 320 321 next_image_info->spsr = SPSR_MODE32(mode, SPSR_T_ARM, SPSR_E_LITTLE, 322 (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT)); 323 324 next_image_info->args.arg0 = 0; 325 next_image_info->args.arg1 = 0; 326 next_image_info->args.arg2 = x3; 327 328 SET_SECURITY_STATE(next_image_info->h.attr, NON_SECURE); 329 330 cm_init_my_context(next_image_info); 331 cm_prepare_el3_exit(NON_SECURE); 332 333 return 0; 334 } 335 336 #if defined(PLAT_imx8ulp) 337 int imx_hifi_xrdc(uint32_t smc_fid) 338 { 339 mmio_setbits_32(IMX_SIM2_BASE + 0x8, BIT_32(19) | BIT_32(17) | BIT_32(18)); 340 mmio_clrbits_32(IMX_SIM2_BASE + 0x8, BIT_32(16)); 341 342 extern int xrdc_apply_hifi_config(void); 343 xrdc_apply_hifi_config(); 344 345 return 0; 346 } 347 #endif 348