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