2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
8 #include <arch_helpers.h>
11 #include <delay_timer.h>
14 #include <mce_private.h>
19 /*******************************************************************************
20 * Register offsets for ARI request/results
21 ******************************************************************************/
22 #define ARI_REQUEST 0x0U
23 #define ARI_REQUEST_EVENT_MASK 0x4U
24 #define ARI_STATUS 0x8U
25 #define ARI_REQUEST_DATA_LO 0xCU
26 #define ARI_REQUEST_DATA_HI 0x10U
27 #define ARI_RESPONSE_DATA_LO 0x14U
28 #define ARI_RESPONSE_DATA_HI 0x18U
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)
36 /* default timeout (ms) to wait for ARI completion */
37 #define ARI_MAX_RETRY_COUNT 2000
39 /*******************************************************************************
40 * ARI helper functions
41 ******************************************************************************/
42 static inline uint32_t ari_read_32(uint32_t ari_base
, uint32_t reg
)
44 return mmio_read_32((uint64_t)ari_base
+ (uint64_t)reg
);
47 static inline void ari_write_32(uint32_t ari_base
, uint32_t val
, uint32_t reg
)
49 mmio_write_32((uint64_t)ari_base
+ (uint64_t)reg
, val
);
52 static inline uint32_t ari_get_request_low(uint32_t ari_base
)
54 return ari_read_32(ari_base
, ARI_REQUEST_DATA_LO
);
57 static inline uint32_t ari_get_request_high(uint32_t ari_base
)
59 return ari_read_32(ari_base
, ARI_REQUEST_DATA_HI
);
62 static inline uint32_t ari_get_response_low(uint32_t ari_base
)
64 return ari_read_32(ari_base
, ARI_RESPONSE_DATA_LO
);
67 static inline uint32_t ari_get_response_high(uint32_t ari_base
)
69 return ari_read_32(ari_base
, ARI_RESPONSE_DATA_HI
);
72 static inline void ari_clobber_response(uint32_t ari_base
)
74 ari_write_32(ari_base
, 0, ARI_RESPONSE_DATA_LO
);
75 ari_write_32(ari_base
, 0, ARI_RESPONSE_DATA_HI
);
78 static int32_t ari_request_wait(uint32_t ari_base
, uint32_t evt_mask
, uint32_t req
,
79 uint32_t lo
, uint32_t hi
)
81 uint32_t retries
= ARI_MAX_RETRY_COUNT
;
85 /* program the request, event_mask, hi and lo registers */
86 ari_write_32(ari_base
, lo
, ARI_REQUEST_DATA_LO
);
87 ari_write_32(ari_base
, hi
, ARI_REQUEST_DATA_HI
);
88 ari_write_32(ari_base
, evt_mask
, ARI_REQUEST_EVENT_MASK
);
89 ari_write_32(ari_base
, req
| ARI_REQUEST_VALID_BIT
, ARI_REQUEST
);
92 * For commands that have an event trigger, we should bypass
93 * ARI_STATUS polling, since MCE is waiting for SW to trigger
99 /* For shutdown/reboot commands, we dont have to check for timeouts */
100 if ((req
== (uint32_t)TEGRA_ARI_MISC_CCPLEX
) &&
101 ((lo
== (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF
) ||
102 (lo
== (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT
))) {
106 * Wait for the command response for not more than the timeout
108 while (retries
!= 0U) {
110 /* read the command status */
111 status
= ari_read_32(ari_base
, ARI_STATUS
);
112 if ((status
& (ARI_REQ_ONGOING
| ARI_REQ_PENDING
)) == 0U) {
119 /* decrement the retry count */
123 /* assert if the command timed out */
125 ERROR("ARI request timed out: req %d on CPU %d\n",
126 req
, plat_my_core_pos());
127 assert(retries
!= 0U);
135 int32_t ari_enter_cstate(uint32_t ari_base
, uint32_t state
, uint32_t wake_time
)
139 /* check for allowed power state */
140 if ((state
!= TEGRA_ARI_CORE_C0
) &&
141 (state
!= TEGRA_ARI_CORE_C1
) &&
142 (state
!= TEGRA_ARI_CORE_C6
) &&
143 (state
!= TEGRA_ARI_CORE_C7
)) {
144 ERROR("%s: unknown cstate (%d)\n", __func__
, state
);
147 /* clean the previous response state */
148 ari_clobber_response(ari_base
);
150 /* Enter the cstate, to be woken up after wake_time (TSC ticks) */
151 ret
= ari_request_wait(ari_base
, ARI_EVT_MASK_STANDBYWFI_BIT
,
152 TEGRA_ARI_ENTER_CSTATE
, state
, wake_time
);
158 int32_t ari_update_cstate_info(uint32_t ari_base
, uint32_t cluster
, uint32_t ccplex
,
159 uint32_t system
, uint8_t sys_state_force
, uint32_t wake_mask
,
160 uint8_t update_wake_mask
)
164 /* clean the previous response state */
165 ari_clobber_response(ari_base
);
167 /* update CLUSTER_CSTATE? */
169 val
|= (cluster
& (uint32_t)CLUSTER_CSTATE_MASK
) |
170 (uint32_t)CLUSTER_CSTATE_UPDATE_BIT
;
173 /* update CCPLEX_CSTATE? */
175 val
|= ((ccplex
& (uint32_t)CCPLEX_CSTATE_MASK
) << (uint32_t)CCPLEX_CSTATE_SHIFT
) |
176 (uint32_t)CCPLEX_CSTATE_UPDATE_BIT
;
179 /* update SYSTEM_CSTATE? */
181 val
|= ((system
& (uint32_t)SYSTEM_CSTATE_MASK
) << (uint32_t)SYSTEM_CSTATE_SHIFT
) |
182 (((uint32_t)sys_state_force
<< SYSTEM_CSTATE_FORCE_UPDATE_SHIFT
) |
183 (uint32_t)SYSTEM_CSTATE_UPDATE_BIT
);
186 /* update wake mask value? */
187 if (update_wake_mask
!= 0U) {
188 val
|= (uint32_t)CSTATE_WAKE_MASK_UPDATE_BIT
;
191 /* set the updated cstate info */
192 return ari_request_wait(ari_base
, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO
, val
,
196 int32_t ari_update_crossover_time(uint32_t ari_base
, uint32_t type
, uint32_t time
)
200 /* sanity check crossover type */
201 if ((type
== TEGRA_ARI_CROSSOVER_C1_C6
) ||
202 (type
> TEGRA_ARI_CROSSOVER_CCP3_SC1
)) {
205 /* clean the previous response state */
206 ari_clobber_response(ari_base
);
208 /* update crossover threshold time */
209 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_UPDATE_CROSSOVER
,
216 uint64_t ari_read_cstate_stats(uint32_t ari_base
, uint32_t state
)
221 /* sanity check crossover type */
225 /* clean the previous response state */
226 ari_clobber_response(ari_base
);
228 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_CSTATE_STATS
, state
, 0U);
232 result
= (uint64_t)ari_get_response_low(ari_base
);
238 int32_t ari_write_cstate_stats(uint32_t ari_base
, uint32_t state
, uint32_t stats
)
240 /* clean the previous response state */
241 ari_clobber_response(ari_base
);
243 /* write the cstate stats */
244 return ari_request_wait(ari_base
, 0U, TEGRA_ARI_WRITE_CSTATE_STATS
, state
,
248 uint64_t ari_enumeration_misc(uint32_t ari_base
, uint32_t cmd
, uint32_t data
)
252 uint32_t local_data
= data
;
254 /* clean the previous response state */
255 ari_clobber_response(ari_base
);
257 /* ARI_REQUEST_DATA_HI is reserved for commands other than 'ECHO' */
258 if (cmd
!= TEGRA_ARI_MISC_ECHO
) {
262 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_MISC
, cmd
, local_data
);
264 resp
= (uint64_t)ret
;
266 /* get the command response */
267 resp
= ari_get_response_low(ari_base
);
268 resp
|= ((uint64_t)ari_get_response_high(ari_base
) << 32);
274 int32_t ari_is_ccx_allowed(uint32_t ari_base
, uint32_t state
, uint32_t wake_time
)
279 /* clean the previous response state */
280 ari_clobber_response(ari_base
);
282 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_IS_CCX_ALLOWED
, state
& 0x7U
,
285 ERROR("%s: failed (%d)\n", __func__
, ret
);
288 result
= ari_get_response_low(ari_base
) & 0x1U
;
291 /* 1 = CCx allowed, 0 = CCx not allowed */
292 return (int32_t)result
;
295 int32_t ari_is_sc7_allowed(uint32_t ari_base
, uint32_t state
, uint32_t wake_time
)
299 /* check for allowed power state */
300 if ((state
!= TEGRA_ARI_CORE_C0
) &&
301 (state
!= TEGRA_ARI_CORE_C1
) &&
302 (state
!= TEGRA_ARI_CORE_C6
) &&
303 (state
!= TEGRA_ARI_CORE_C7
)) {
304 ERROR("%s: unknown cstate (%d)\n", __func__
, state
);
307 /* clean the previous response state */
308 ari_clobber_response(ari_base
);
310 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_IS_SC7_ALLOWED
, state
,
313 ERROR("%s: failed (%d)\n", __func__
, ret
);
316 /* 1 = SC7 allowed, 0 = SC7 not allowed */
317 result
= (ari_get_response_low(ari_base
) != 0U) ? 1 : 0;
324 int32_t ari_online_core(uint32_t ari_base
, uint32_t core
)
326 uint64_t cpu
= read_mpidr() & (uint64_t)(MPIDR_CPU_MASK
);
327 uint64_t cluster
= (read_mpidr() & (uint64_t)(MPIDR_CLUSTER_MASK
)) >>
328 (uint64_t)(MPIDR_AFFINITY_BITS
);
329 uint64_t impl
= (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT
) & (uint64_t)MIDR_IMPL_MASK
;
332 /* construct the current CPU # */
333 cpu
|= (cluster
<< 2);
335 /* sanity check target core id */
336 if ((core
>= MCE_CORE_ID_MAX
) || (cpu
== (uint64_t)core
)) {
337 ERROR("%s: unsupported core id (%d)\n", __func__
, core
);
341 * The Denver cluster has 2 CPUs only - 0, 1.
343 if ((impl
== (uint32_t)DENVER_IMPL
) &&
344 ((core
== 2U) || (core
== 3U))) {
345 ERROR("%s: unknown core id (%d)\n", __func__
, core
);
348 /* clean the previous response state */
349 ari_clobber_response(ari_base
);
350 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_ONLINE_CORE
, core
, 0U);
357 int32_t ari_cc3_ctrl(uint32_t ari_base
, uint32_t freq
, uint32_t volt
, uint8_t enable
)
361 /* clean the previous response state */
362 ari_clobber_response(ari_base
);
365 * If the enable bit is cleared, Auto-CC3 will be disabled by setting
366 * the SW visible voltage/frequency request registers for all non
367 * floorswept cores valid independent of StandbyWFI and disabling
368 * the IDLE voltage/frequency request register. If set, Auto-CC3
369 * will be enabled by setting the ARM SW visible voltage/frequency
370 * request registers for all non floorswept cores to be enabled by
371 * StandbyWFI or the equivalent signal, and always keeping the IDLE
372 * voltage/frequency request register enabled.
374 val
= (((freq
& MCE_AUTO_CC3_FREQ_MASK
) << MCE_AUTO_CC3_FREQ_SHIFT
) |\
375 ((volt
& MCE_AUTO_CC3_VTG_MASK
) << MCE_AUTO_CC3_VTG_SHIFT
) |\
376 ((enable
!= 0U) ? MCE_AUTO_CC3_ENABLE_BIT
: 0U));
378 return ari_request_wait(ari_base
, 0U, TEGRA_ARI_CC3_CTRL
, val
, 0U);
381 int32_t ari_reset_vector_update(uint32_t ari_base
)
383 /* clean the previous response state */
384 ari_clobber_response(ari_base
);
387 * Need to program the CPU reset vector one time during cold boot
390 (void)ari_request_wait(ari_base
, 0U, TEGRA_ARI_COPY_MISCREG_AA64_RST
, 0U, 0U);
395 int32_t ari_roc_flush_cache_trbits(uint32_t ari_base
)
397 /* clean the previous response state */
398 ari_clobber_response(ari_base
);
400 return ari_request_wait(ari_base
, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS
,
404 int32_t ari_roc_flush_cache(uint32_t ari_base
)
406 /* clean the previous response state */
407 ari_clobber_response(ari_base
);
409 return ari_request_wait(ari_base
, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY
,
413 int32_t ari_roc_clean_cache(uint32_t ari_base
)
415 /* clean the previous response state */
416 ari_clobber_response(ari_base
);
418 return ari_request_wait(ari_base
, 0U, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY
,
422 uint64_t ari_read_write_mca(uint32_t ari_base
, uint64_t cmd
, uint64_t *data
)
424 uint64_t mca_arg_data
, result
= 0;
425 uint32_t resp_lo
, resp_hi
;
426 uint32_t mca_arg_err
, mca_arg_finish
;
429 /* Set data (write) */
430 mca_arg_data
= (data
!= NULL
) ? *data
: 0ULL;
433 ari_write_32(ari_base
, (uint32_t)cmd
, ARI_RESPONSE_DATA_LO
);
434 ari_write_32(ari_base
, (uint32_t)(cmd
>> 32U), ARI_RESPONSE_DATA_HI
);
436 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_MCA
,
437 (uint32_t)mca_arg_data
,
438 (uint32_t)(mca_arg_data
>> 32U));
440 resp_lo
= ari_get_response_low(ari_base
);
441 resp_hi
= ari_get_response_high(ari_base
);
443 mca_arg_err
= resp_lo
& MCA_ARG_ERROR_MASK
;
444 mca_arg_finish
= (resp_hi
>> MCA_ARG_FINISH_SHIFT
) &
447 if (mca_arg_finish
== 0U) {
448 result
= (uint64_t)mca_arg_err
;
451 resp_lo
= ari_get_request_low(ari_base
);
452 resp_hi
= ari_get_request_high(ari_base
);
453 *data
= ((uint64_t)resp_hi
<< 32U) |
462 int32_t ari_update_ccplex_gsc(uint32_t ari_base
, uint32_t gsc_idx
)
465 /* sanity check GSC ID */
466 if (gsc_idx
> (uint32_t)TEGRA_ARI_GSC_VPR_IDX
) {
469 /* clean the previous response state */
470 ari_clobber_response(ari_base
);
473 * The MCE code will read the GSC carveout value, corrseponding to
474 * the ID, from the MC registers and update the internal GSC registers
477 (void)ari_request_wait(ari_base
, 0U, TEGRA_ARI_UPDATE_CCPLEX_GSC
, gsc_idx
, 0U);
483 void ari_enter_ccplex_state(uint32_t ari_base
, uint32_t state_idx
)
485 /* clean the previous response state */
486 ari_clobber_response(ari_base
);
489 * The MCE will shutdown or restart the entire system
491 (void)ari_request_wait(ari_base
, 0U, TEGRA_ARI_MISC_CCPLEX
, state_idx
, 0U);
494 int32_t ari_read_write_uncore_perfmon(uint32_t ari_base
, uint64_t req
,
499 uint8_t req_cmd
, req_status
;
501 req_cmd
= (uint8_t)(req
>> UNCORE_PERFMON_CMD_SHIFT
);
503 /* clean the previous response state */
504 ari_clobber_response(ari_base
);
506 /* sanity check input parameters */
507 if ((req_cmd
== UNCORE_PERFMON_CMD_READ
) && (data
== NULL
)) {
508 ERROR("invalid parameters\n");
512 * For "write" commands get the value that has to be written
513 * to the uncore perfmon registers
515 val
= (req_cmd
== UNCORE_PERFMON_CMD_WRITE
) ?
516 (uint32_t)*data
: 0U;
518 ret
= ari_request_wait(ari_base
, 0U, TEGRA_ARI_PERFMON
, val
,
523 /* read the command status value */
524 req_status
= (uint8_t)ari_get_response_high(ari_base
) &
525 UNCORE_PERFMON_RESP_STATUS_MASK
;
528 * For "read" commands get the data from the uncore
531 req_status
>>= UNCORE_PERFMON_RESP_STATUS_SHIFT
;
532 if ((req_status
== 0U) && (req_cmd
== UNCORE_PERFMON_CMD_READ
)) {
533 *data
= ari_get_response_low(ari_base
);
535 result
= (int32_t)req_status
;
542 void ari_misc_ccplex(uint32_t ari_base
, uint32_t index
, uint32_t value
)
545 * This invokes the ARI_MISC_CCPLEX commands. This can be
546 * used to enable/disable coresight clock gating.
549 if ((index
> TEGRA_ARI_MISC_CCPLEX_EDBGREQ
) ||
550 ((index
== TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL
) &&
552 ERROR("%s: invalid parameters \n", __func__
);
554 /* clean the previous response state */
555 ari_clobber_response(ari_base
);
556 (void)ari_request_wait(ari_base
, 0U, TEGRA_ARI_MISC_CCPLEX
, index
, value
);