1 /* 2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <arch_helpers.h> 9 #include <assert.h> 10 #include <debug.h> 11 #include <delay_timer.h> 12 #include <denver.h> 13 #include <mmio.h> 14 #include <mce_private.h> 15 #include <platform.h> 16 #include <sys/errno.h> 17 #include <t18x_ari.h> 18 19 /******************************************************************************* 20 * Register offsets for ARI request/results 21 ******************************************************************************/ 22 #define ARI_REQUEST 0x0 23 #define ARI_REQUEST_EVENT_MASK 0x4 24 #define ARI_STATUS 0x8 25 #define ARI_REQUEST_DATA_LO 0xC 26 #define ARI_REQUEST_DATA_HI 0x10 27 #define ARI_RESPONSE_DATA_LO 0x14 28 #define ARI_RESPONSE_DATA_HI 0x18 29 30 /* Status values for the current request */ 31 #define ARI_REQ_PENDING 1U 32 #define ARI_REQ_ONGOING 3U 33 #define ARI_REQUEST_VALID_BIT (1U << 8) 34 #define ARI_EVT_MASK_STANDBYWFI_BIT (1U << 7) 35 36 /* default timeout (ms) to wait for ARI completion */ 37 #define ARI_MAX_RETRY_COUNT 2000 38 39 /******************************************************************************* 40 * ARI helper functions 41 ******************************************************************************/ 42 static inline uint32_t ari_read_32(uint32_t ari_base, uint32_t reg) 43 { 44 return mmio_read_32(ari_base + reg); 45 } 46 47 static inline void ari_write_32(uint32_t ari_base, uint32_t val, uint32_t reg) 48 { 49 mmio_write_32(ari_base + reg, val); 50 } 51 52 static inline uint32_t ari_get_request_low(uint32_t ari_base) 53 { 54 return ari_read_32(ari_base, ARI_REQUEST_DATA_LO); 55 } 56 57 static inline uint32_t ari_get_request_high(uint32_t ari_base) 58 { 59 return ari_read_32(ari_base, ARI_REQUEST_DATA_HI); 60 } 61 62 static inline uint32_t ari_get_response_low(uint32_t ari_base) 63 { 64 return ari_read_32(ari_base, ARI_RESPONSE_DATA_LO); 65 } 66 67 static inline uint32_t ari_get_response_high(uint32_t ari_base) 68 { 69 return ari_read_32(ari_base, ARI_RESPONSE_DATA_HI); 70 } 71 72 static inline void ari_clobber_response(uint32_t ari_base) 73 { 74 ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_LO); 75 ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_HI); 76 } 77 78 static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req, 79 uint32_t lo, uint32_t hi) 80 { 81 uint32_t retries = ARI_MAX_RETRY_COUNT; 82 uint32_t status; 83 84 /* program the request, event_mask, hi and lo registers */ 85 ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO); 86 ari_write_32(ari_base, hi, ARI_REQUEST_DATA_HI); 87 ari_write_32(ari_base, evt_mask, ARI_REQUEST_EVENT_MASK); 88 ari_write_32(ari_base, req | ARI_REQUEST_VALID_BIT, ARI_REQUEST); 89 90 /* 91 * For commands that have an event trigger, we should bypass 92 * ARI_STATUS polling, since MCE is waiting for SW to trigger 93 * the event. 94 */ 95 if (evt_mask) 96 return 0; 97 98 /* For shutdown/reboot commands, we dont have to check for timeouts */ 99 if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) && 100 ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) || 101 (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) { 102 return 0; 103 } 104 105 /* 106 * Wait for the command response for not more than the timeout 107 */ 108 while (retries != 0U) { 109 110 /* read the command status */ 111 status = ari_read_32(ari_base, ARI_STATUS); 112 if ((status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) == 0U) 113 break; 114 115 /* delay 1 ms */ 116 mdelay(1); 117 118 /* decrement the retry count */ 119 retries--; 120 } 121 122 /* assert if the command timed out */ 123 if (retries == 0U) { 124 ERROR("ARI request timed out: req %d on CPU %d\n", 125 req, plat_my_core_pos()); 126 assert(retries != 0U); 127 } 128 129 return 0; 130 } 131 132 int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time) 133 { 134 /* check for allowed power state */ 135 if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && 136 state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { 137 ERROR("%s: unknown cstate (%d)\n", __func__, state); 138 return EINVAL; 139 } 140 141 /* clean the previous response state */ 142 ari_clobber_response(ari_base); 143 144 /* Enter the cstate, to be woken up after wake_time (TSC ticks) */ 145 return ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT, 146 TEGRA_ARI_ENTER_CSTATE, state, wake_time); 147 } 148 149 int ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, 150 uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, 151 uint8_t update_wake_mask) 152 { 153 uint32_t val = 0; 154 155 /* clean the previous response state */ 156 ari_clobber_response(ari_base); 157 158 /* update CLUSTER_CSTATE? */ 159 if (cluster) 160 val |= (cluster & CLUSTER_CSTATE_MASK) | 161 CLUSTER_CSTATE_UPDATE_BIT; 162 163 /* update CCPLEX_CSTATE? */ 164 if (ccplex) 165 val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT | 166 CCPLEX_CSTATE_UPDATE_BIT; 167 168 /* update SYSTEM_CSTATE? */ 169 if (system) 170 val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) | 171 ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) | 172 SYSTEM_CSTATE_UPDATE_BIT); 173 174 /* update wake mask value? */ 175 if (update_wake_mask) 176 val |= CSTATE_WAKE_MASK_UPDATE_BIT; 177 178 /* set the updated cstate info */ 179 return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CSTATE_INFO, val, 180 wake_mask); 181 } 182 183 int ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time) 184 { 185 /* sanity check crossover type */ 186 if ((type == TEGRA_ARI_CROSSOVER_C1_C6) || 187 (type > TEGRA_ARI_CROSSOVER_CCP3_SC1)) 188 return EINVAL; 189 190 /* clean the previous response state */ 191 ari_clobber_response(ari_base); 192 193 /* update crossover threshold time */ 194 return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CROSSOVER, 195 type, time); 196 } 197 198 uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state) 199 { 200 int ret; 201 202 /* sanity check crossover type */ 203 if (state == 0) 204 return EINVAL; 205 206 /* clean the previous response state */ 207 ari_clobber_response(ari_base); 208 209 ret = ari_request_wait(ari_base, 0, TEGRA_ARI_CSTATE_STATS, state, 0); 210 if (ret != 0) 211 return EINVAL; 212 213 return (uint64_t)ari_get_response_low(ari_base); 214 } 215 216 int ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats) 217 { 218 /* clean the previous response state */ 219 ari_clobber_response(ari_base); 220 221 /* write the cstate stats */ 222 return ari_request_wait(ari_base, 0, TEGRA_ARI_WRITE_CSTATE_STATS, state, 223 stats); 224 } 225 226 uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data) 227 { 228 uint64_t resp; 229 int ret; 230 231 /* clean the previous response state */ 232 ari_clobber_response(ari_base); 233 234 /* ARI_REQUEST_DATA_HI is reserved for commands other than 'ECHO' */ 235 if (cmd != TEGRA_ARI_MISC_ECHO) 236 data = 0; 237 238 ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MISC, cmd, data); 239 if (ret) 240 return (uint64_t)ret; 241 242 /* get the command response */ 243 resp = ari_get_response_low(ari_base); 244 resp |= ((uint64_t)ari_get_response_high(ari_base) << 32); 245 246 return resp; 247 } 248 249 int ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) 250 { 251 int ret; 252 253 /* clean the previous response state */ 254 ari_clobber_response(ari_base); 255 256 ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7, 257 wake_time); 258 if (ret) { 259 ERROR("%s: failed (%d)\n", __func__, ret); 260 return 0; 261 } 262 263 /* 1 = CCx allowed, 0 = CCx not allowed */ 264 return (ari_get_response_low(ari_base) & 0x1); 265 } 266 267 int ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) 268 { 269 int ret; 270 271 /* check for allowed power state */ 272 if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && 273 state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { 274 ERROR("%s: unknown cstate (%d)\n", __func__, state); 275 return EINVAL; 276 } 277 278 /* clean the previous response state */ 279 ari_clobber_response(ari_base); 280 281 ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_SC7_ALLOWED, state, 282 wake_time); 283 if (ret) { 284 ERROR("%s: failed (%d)\n", __func__, ret); 285 return 0; 286 } 287 288 /* 1 = SC7 allowed, 0 = SC7 not allowed */ 289 return !!ari_get_response_low(ari_base); 290 } 291 292 int ari_online_core(uint32_t ari_base, uint32_t core) 293 { 294 int cpu = read_mpidr() & MPIDR_CPU_MASK; 295 int cluster = (read_mpidr() & MPIDR_CLUSTER_MASK) >> 296 MPIDR_AFFINITY_BITS; 297 int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; 298 299 /* construct the current CPU # */ 300 cpu |= (cluster << 2); 301 302 /* sanity check target core id */ 303 if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) { 304 ERROR("%s: unsupported core id (%d)\n", __func__, core); 305 return EINVAL; 306 } 307 308 /* 309 * The Denver cluster has 2 CPUs only - 0, 1. 310 */ 311 if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) { 312 ERROR("%s: unknown core id (%d)\n", __func__, core); 313 return EINVAL; 314 } 315 316 /* clean the previous response state */ 317 ari_clobber_response(ari_base); 318 319 return ari_request_wait(ari_base, 0, TEGRA_ARI_ONLINE_CORE, core, 0); 320 } 321 322 int ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable) 323 { 324 int val; 325 326 /* clean the previous response state */ 327 ari_clobber_response(ari_base); 328 329 /* 330 * If the enable bit is cleared, Auto-CC3 will be disabled by setting 331 * the SW visible voltage/frequency request registers for all non 332 * floorswept cores valid independent of StandbyWFI and disabling 333 * the IDLE voltage/frequency request register. If set, Auto-CC3 334 * will be enabled by setting the ARM SW visible voltage/frequency 335 * request registers for all non floorswept cores to be enabled by 336 * StandbyWFI or the equivalent signal, and always keeping the IDLE 337 * voltage/frequency request register enabled. 338 */ 339 val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\ 340 ((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\ 341 (enable ? MCE_AUTO_CC3_ENABLE_BIT : 0)); 342 343 return ari_request_wait(ari_base, 0, TEGRA_ARI_CC3_CTRL, val, 0); 344 } 345 346 int ari_reset_vector_update(uint32_t ari_base) 347 { 348 /* clean the previous response state */ 349 ari_clobber_response(ari_base); 350 351 /* 352 * Need to program the CPU reset vector one time during cold boot 353 * and SC7 exit 354 */ 355 ari_request_wait(ari_base, 0, TEGRA_ARI_COPY_MISCREG_AA64_RST, 0, 0); 356 357 return 0; 358 } 359 360 int ari_roc_flush_cache_trbits(uint32_t ari_base) 361 { 362 /* clean the previous response state */ 363 ari_clobber_response(ari_base); 364 365 return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS, 366 0, 0); 367 } 368 369 int ari_roc_flush_cache(uint32_t ari_base) 370 { 371 /* clean the previous response state */ 372 ari_clobber_response(ari_base); 373 374 return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY, 375 0, 0); 376 } 377 378 int ari_roc_clean_cache(uint32_t ari_base) 379 { 380 /* clean the previous response state */ 381 ari_clobber_response(ari_base); 382 383 return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY, 384 0, 0); 385 } 386 387 uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data) 388 { 389 mca_arg_t mca_arg; 390 int ret; 391 392 /* Set data (write) */ 393 mca_arg.data = data ? *data : 0ull; 394 395 /* Set command */ 396 ari_write_32(ari_base, cmd.input.low, ARI_RESPONSE_DATA_LO); 397 ari_write_32(ari_base, cmd.input.high, ARI_RESPONSE_DATA_HI); 398 399 ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MCA, mca_arg.arg.low, 400 mca_arg.arg.high); 401 if (!ret) { 402 mca_arg.arg.low = ari_get_response_low(ari_base); 403 mca_arg.arg.high = ari_get_response_high(ari_base); 404 if (!mca_arg.err.finish) 405 return (uint64_t)mca_arg.err.error; 406 407 if (data) { 408 mca_arg.arg.low = ari_get_request_low(ari_base); 409 mca_arg.arg.high = ari_get_request_high(ari_base); 410 *data = mca_arg.data; 411 } 412 } 413 414 return 0; 415 } 416 417 int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx) 418 { 419 /* sanity check GSC ID */ 420 if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX) 421 return EINVAL; 422 423 /* clean the previous response state */ 424 ari_clobber_response(ari_base); 425 426 /* 427 * The MCE code will read the GSC carveout value, corrseponding to 428 * the ID, from the MC registers and update the internal GSC registers 429 * of the CCPLEX. 430 */ 431 ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0); 432 433 return 0; 434 } 435 436 void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx) 437 { 438 /* clean the previous response state */ 439 ari_clobber_response(ari_base); 440 441 /* 442 * The MCE will shutdown or restart the entire system 443 */ 444 (void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, state_idx, 0); 445 } 446 447 int ari_read_write_uncore_perfmon(uint32_t ari_base, 448 uncore_perfmon_req_t req, uint64_t *data) 449 { 450 int ret; 451 uint32_t val; 452 453 /* clean the previous response state */ 454 ari_clobber_response(ari_base); 455 456 /* sanity check input parameters */ 457 if (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_READ && !data) { 458 ERROR("invalid parameters\n"); 459 return EINVAL; 460 } 461 462 /* 463 * For "write" commands get the value that has to be written 464 * to the uncore perfmon registers 465 */ 466 val = (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_WRITE) ? 467 *data : 0; 468 469 ret = ari_request_wait(ari_base, 0, TEGRA_ARI_PERFMON, val, req.data); 470 if (ret) 471 return ret; 472 473 /* read the command status value */ 474 req.perfmon_status.val = ari_get_response_high(ari_base) & 475 UNCORE_PERFMON_RESP_STATUS_MASK; 476 477 /* 478 * For "read" commands get the data from the uncore 479 * perfmon registers 480 */ 481 if ((req.perfmon_status.val == 0) && (req.perfmon_command.cmd == 482 UNCORE_PERFMON_CMD_READ)) 483 *data = ari_get_response_low(ari_base); 484 485 return (int)req.perfmon_status.val; 486 } 487 488 void ari_misc_ccplex(uint32_t ari_base, uint32_t index, uint32_t value) 489 { 490 /* 491 * This invokes the ARI_MISC_CCPLEX commands. This can be 492 * used to enable/disable coresight clock gating. 493 */ 494 495 if ((index > TEGRA_ARI_MISC_CCPLEX_EDBGREQ) || 496 ((index == TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL) && 497 (value > 1))) { 498 ERROR("%s: invalid parameters \n", __func__); 499 return; 500 } 501 502 /* clean the previous response state */ 503 ari_clobber_response(ari_base); 504 (void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, index, value); 505 } 506