blob: e948e9903dacfc9f05bf65fb24b0d500cf21d715 [file] [log] [blame]
Varun Wadekara0352ab2017-03-14 14:24:35 -07001/*
Antonio Nino Diaz4b32e622018-08-16 16:52:57 +01002 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
Varun Wadekara0352ab2017-03-14 14:24:35 -07003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekara0352ab2017-03-14 14:24:35 -07005 */
6
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00007#include <assert.h>
8#include <errno.h>
9#include <string.h>
10
Varun Wadekara0352ab2017-03-14 14:24:35 -070011#include <arch.h>
12#include <arch_helpers.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013#include <common/bl_common.h>
14#include <common/debug.h>
Varun Wadekara0352ab2017-03-14 14:24:35 -070015#include <context.h>
Varun Wadekara0352ab2017-03-14 14:24:35 -070016#include <denver.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017#include <lib/el3_runtime/context_mgmt.h>
18#include <lib/mmio.h>
19
Varun Wadekara0352ab2017-03-14 14:24:35 -070020#include <mce.h>
Varun Wadekarb5568282016-12-13 18:04:35 -080021#include <mce_private.h>
Varun Wadekara0352ab2017-03-14 14:24:35 -070022#include <t18x_ari.h>
23#include <tegra_def.h>
Varun Wadekarefa66d42016-07-18 17:42:02 -070024#include <tegra_platform.h>
Varun Wadekara0352ab2017-03-14 14:24:35 -070025
26/* NVG functions handlers */
27static arch_mce_ops_t nvg_mce_ops = {
28 .enter_cstate = nvg_enter_cstate,
29 .update_cstate_info = nvg_update_cstate_info,
30 .update_crossover_time = nvg_update_crossover_time,
31 .read_cstate_stats = nvg_read_cstate_stats,
32 .write_cstate_stats = nvg_write_cstate_stats,
33 .call_enum_misc = ari_enumeration_misc,
34 .is_ccx_allowed = nvg_is_ccx_allowed,
35 .is_sc7_allowed = nvg_is_sc7_allowed,
36 .online_core = nvg_online_core,
37 .cc3_ctrl = nvg_cc3_ctrl,
38 .update_reset_vector = ari_reset_vector_update,
39 .roc_flush_cache = ari_roc_flush_cache,
40 .roc_flush_cache_trbits = ari_roc_flush_cache_trbits,
41 .roc_clean_cache = ari_roc_clean_cache,
42 .read_write_mca = ari_read_write_mca,
43 .update_ccplex_gsc = ari_update_ccplex_gsc,
Varun Wadekar4ff3e8d2016-04-29 10:40:02 -070044 .enter_ccplex_state = ari_enter_ccplex_state,
Krishna Sitaramanb429d562016-07-19 16:36:13 -070045 .read_write_uncore_perfmon = ari_read_write_uncore_perfmon,
46 .misc_ccplex = ari_misc_ccplex
Varun Wadekara0352ab2017-03-14 14:24:35 -070047};
48
49/* ARI functions handlers */
50static arch_mce_ops_t ari_mce_ops = {
51 .enter_cstate = ari_enter_cstate,
52 .update_cstate_info = ari_update_cstate_info,
53 .update_crossover_time = ari_update_crossover_time,
54 .read_cstate_stats = ari_read_cstate_stats,
55 .write_cstate_stats = ari_write_cstate_stats,
56 .call_enum_misc = ari_enumeration_misc,
57 .is_ccx_allowed = ari_is_ccx_allowed,
58 .is_sc7_allowed = ari_is_sc7_allowed,
59 .online_core = ari_online_core,
60 .cc3_ctrl = ari_cc3_ctrl,
61 .update_reset_vector = ari_reset_vector_update,
62 .roc_flush_cache = ari_roc_flush_cache,
63 .roc_flush_cache_trbits = ari_roc_flush_cache_trbits,
64 .roc_clean_cache = ari_roc_clean_cache,
65 .read_write_mca = ari_read_write_mca,
66 .update_ccplex_gsc = ari_update_ccplex_gsc,
Varun Wadekar4ff3e8d2016-04-29 10:40:02 -070067 .enter_ccplex_state = ari_enter_ccplex_state,
Krishna Sitaramanb429d562016-07-19 16:36:13 -070068 .read_write_uncore_perfmon = ari_read_write_uncore_perfmon,
69 .misc_ccplex = ari_misc_ccplex
Varun Wadekara0352ab2017-03-14 14:24:35 -070070};
71
Anthony Zhou1ab31402017-03-06 16:06:45 +080072typedef struct {
Varun Wadekara0352ab2017-03-14 14:24:35 -070073 uint32_t ari_base;
74 arch_mce_ops_t *ops;
75} mce_config_t;
76
77/* Table to hold the per-CPU ARI base address and function handlers */
78static mce_config_t mce_cfg_table[MCE_ARI_APERTURES_MAX] = {
79 {
80 /* A57 Core 0 */
81 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_0_OFFSET,
82 .ops = &ari_mce_ops,
83 },
84 {
85 /* A57 Core 1 */
86 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_1_OFFSET,
87 .ops = &ari_mce_ops,
88 },
89 {
90 /* A57 Core 2 */
91 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_2_OFFSET,
92 .ops = &ari_mce_ops,
93 },
94 {
95 /* A57 Core 3 */
96 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_3_OFFSET,
97 .ops = &ari_mce_ops,
98 },
99 {
100 /* D15 Core 0 */
101 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_4_OFFSET,
102 .ops = &nvg_mce_ops,
103 },
104 {
105 /* D15 Core 1 */
106 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_5_OFFSET,
107 .ops = &nvg_mce_ops,
108 }
109};
110
111static uint32_t mce_get_curr_cpu_ari_base(void)
112{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800113 uint64_t mpidr = read_mpidr();
Anthony Zhou3b804502017-06-26 20:33:34 +0800114 uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
115 uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
Varun Wadekara0352ab2017-03-14 14:24:35 -0700116
117 /*
118 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
119 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU
120 * numbers start from 0. In order to get the proper arch_mce_ops_t
121 * struct, we have to convert the Denver CPU ids to the corresponding
122 * indices in the mce_ops_table array.
123 */
Anthony Zhou1ab31402017-03-06 16:06:45 +0800124 if (impl == DENVER_IMPL) {
125 cpuid |= 0x4U;
126 }
Varun Wadekara0352ab2017-03-14 14:24:35 -0700127
128 return mce_cfg_table[cpuid].ari_base;
129}
130
131static arch_mce_ops_t *mce_get_curr_cpu_ops(void)
132{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800133 uint64_t mpidr = read_mpidr();
Anthony Zhou3b804502017-06-26 20:33:34 +0800134 uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
135 uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) &
136 MIDR_IMPL_MASK;
Varun Wadekara0352ab2017-03-14 14:24:35 -0700137
138 /*
139 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
140 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU
141 * numbers start from 0. In order to get the proper arch_mce_ops_t
142 * struct, we have to convert the Denver CPU ids to the corresponding
143 * indices in the mce_ops_table array.
144 */
Anthony Zhou1ab31402017-03-06 16:06:45 +0800145 if (impl == DENVER_IMPL) {
146 cpuid |= 0x4U;
147 }
Varun Wadekara0352ab2017-03-14 14:24:35 -0700148
149 return mce_cfg_table[cpuid].ops;
150}
151
152/*******************************************************************************
153 * Common handler for all MCE commands
154 ******************************************************************************/
Anthony Zhou1ab31402017-03-06 16:06:45 +0800155int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
Varun Wadekara0352ab2017-03-14 14:24:35 -0700156 uint64_t arg2)
157{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800158 const arch_mce_ops_t *ops;
159 gp_regs_t *gp_regs = get_gpregs_ctx(cm_get_context(NON_SECURE));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700160 uint32_t cpu_ari_base;
161 uint64_t ret64 = 0, arg3, arg4, arg5;
Anthony Zhou1ab31402017-03-06 16:06:45 +0800162 int32_t ret = 0;
Varun Wadekara0352ab2017-03-14 14:24:35 -0700163
Anthony Zhou1ab31402017-03-06 16:06:45 +0800164 assert(gp_regs != NULL);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700165
166 /* get a pointer to the CPU's arch_mce_ops_t struct */
167 ops = mce_get_curr_cpu_ops();
168
169 /* get the CPU's ARI base address */
170 cpu_ari_base = mce_get_curr_cpu_ari_base();
171
172 switch (cmd) {
173 case MCE_CMD_ENTER_CSTATE:
174 ret = ops->enter_cstate(cpu_ari_base, arg0, arg1);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700175
176 break;
177
178 case MCE_CMD_UPDATE_CSTATE_INFO:
179 /*
180 * get the parameters required for the update cstate info
181 * command
182 */
Anthony Zhou3b804502017-06-26 20:33:34 +0800183 arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
184 arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
185 arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700186
187 ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0,
188 (uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3,
189 (uint32_t)arg4, (uint8_t)arg5);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700190
Anthony Zhou3b804502017-06-26 20:33:34 +0800191 write_ctx_reg(gp_regs, CTX_GPREG_X4, (0ULL));
192 write_ctx_reg(gp_regs, CTX_GPREG_X5, (0ULL));
193 write_ctx_reg(gp_regs, CTX_GPREG_X6, (0ULL));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700194
195 break;
196
197 case MCE_CMD_UPDATE_CROSSOVER_TIME:
198 ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700199
200 break;
201
202 case MCE_CMD_READ_CSTATE_STATS:
203 ret64 = ops->read_cstate_stats(cpu_ari_base, arg0);
204
205 /* update context to return cstate stats value */
Anthony Zhou3b804502017-06-26 20:33:34 +0800206 write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
207 write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700208
209 break;
210
211 case MCE_CMD_WRITE_CSTATE_STATS:
212 ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700213
214 break;
215
216 case MCE_CMD_IS_CCX_ALLOWED:
217 ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700218
219 /* update context to return CCx status value */
Anthony Zhou3b804502017-06-26 20:33:34 +0800220 write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700221
222 break;
223
224 case MCE_CMD_IS_SC7_ALLOWED:
225 ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700226
227 /* update context to return SC7 status value */
Anthony Zhou3b804502017-06-26 20:33:34 +0800228 write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
229 write_ctx_reg(gp_regs, CTX_GPREG_X3, (uint64_t)(ret));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700230
231 break;
232
233 case MCE_CMD_ONLINE_CORE:
234 ret = ops->online_core(cpu_ari_base, arg0);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700235
236 break;
237
238 case MCE_CMD_CC3_CTRL:
239 ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700240
241 break;
242
243 case MCE_CMD_ECHO_DATA:
244 ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO,
245 arg0);
246
247 /* update context to return if echo'd data matched source */
Anthony Zhou3b804502017-06-26 20:33:34 +0800248 write_ctx_reg(gp_regs, CTX_GPREG_X1, ((ret64 == arg0) ?
249 1ULL : 0ULL));
250 write_ctx_reg(gp_regs, CTX_GPREG_X2, ((ret64 == arg0) ?
251 1ULL : 0ULL));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700252
253 break;
254
255 case MCE_CMD_READ_VERSIONS:
256 ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION,
257 arg0);
258
259 /*
260 * version = minor(63:32) | major(31:0). Update context
261 * to return major and minor version number.
262 */
Anthony Zhou3b804502017-06-26 20:33:34 +0800263 write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
264 write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64 >> 32ULL));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700265
266 break;
267
268 case MCE_CMD_ENUM_FEATURES:
Krishna Sitaramanfc2ec162016-07-27 16:26:45 -0700269 ret64 = ops->call_enum_misc(cpu_ari_base,
Varun Wadekara0352ab2017-03-14 14:24:35 -0700270 TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);
271
272 /* update context to return features value */
Anthony Zhou3b804502017-06-26 20:33:34 +0800273 write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700274
Varun Wadekara0352ab2017-03-14 14:24:35 -0700275 break;
276
277 case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
278 ret = ops->roc_flush_cache_trbits(cpu_ari_base);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700279
280 break;
281
282 case MCE_CMD_ROC_FLUSH_CACHE:
283 ret = ops->roc_flush_cache(cpu_ari_base);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700284
285 break;
286
287 case MCE_CMD_ROC_CLEAN_CACHE:
288 ret = ops->roc_clean_cache(cpu_ari_base);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700289
290 break;
291
292 case MCE_CMD_ENUM_READ_MCA:
Anthony Zhou1ab31402017-03-06 16:06:45 +0800293 ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700294
295 /* update context to return MCA data/error */
Anthony Zhou3b804502017-06-26 20:33:34 +0800296 write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
297 write_ctx_reg(gp_regs, CTX_GPREG_X2, (arg1));
298 write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700299
300 break;
301
302 case MCE_CMD_ENUM_WRITE_MCA:
Anthony Zhou1ab31402017-03-06 16:06:45 +0800303 ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
Varun Wadekara0352ab2017-03-14 14:24:35 -0700304
305 /* update context to return MCA error */
Anthony Zhou3b804502017-06-26 20:33:34 +0800306 write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
307 write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
Varun Wadekara0352ab2017-03-14 14:24:35 -0700308
309 break;
310
Varun Wadekarad2824f2016-03-28 13:44:35 -0700311#if ENABLE_CHIP_VERIFICATION_HARNESS
312 case MCE_CMD_ENABLE_LATIC:
313 /*
314 * This call is not for production use. The constant value,
315 * 0xFFFF0000, is specific to allowing for enabling LATIC on
316 * pre-production parts for the chip verification harness.
317 *
318 * Enabling LATIC allows S/W to read the MINI ISPs in the
319 * CCPLEX. The ISMs are used for various measurements relevant
320 * to particular locations in the Silicon. They are small
321 * counters which can be polled to determine how fast a
322 * particular location in the Silicon is.
323 */
324 ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(),
325 0xFFFF0000);
326
327 break;
328#endif
Varun Wadekar4ff3e8d2016-04-29 10:40:02 -0700329
330 case MCE_CMD_UNCORE_PERFMON_REQ:
Anthony Zhou1ab31402017-03-06 16:06:45 +0800331 ret = ops->read_write_uncore_perfmon(cpu_ari_base, arg0, &arg1);
Varun Wadekar4ff3e8d2016-04-29 10:40:02 -0700332
333 /* update context to return data */
Anthony Zhou3b804502017-06-26 20:33:34 +0800334 write_ctx_reg(gp_regs, CTX_GPREG_X1, (arg1));
Varun Wadekar4ff3e8d2016-04-29 10:40:02 -0700335 break;
336
Krishna Sitaramanb429d562016-07-19 16:36:13 -0700337 case MCE_CMD_MISC_CCPLEX:
338 ops->misc_ccplex(cpu_ari_base, arg0, arg1);
339
340 break;
341
Varun Wadekara0352ab2017-03-14 14:24:35 -0700342 default:
Masahiro Yamadae93a0f42018-02-02 15:09:36 +0900343 ERROR("unknown MCE command (%llu)\n", cmd);
Anthony Zhou1ab31402017-03-06 16:06:45 +0800344 ret = EINVAL;
345 break;
Varun Wadekara0352ab2017-03-14 14:24:35 -0700346 }
347
348 return ret;
349}
350
351/*******************************************************************************
352 * Handler to update the reset vector for CPUs
353 ******************************************************************************/
Anthony Zhou1ab31402017-03-06 16:06:45 +0800354int32_t mce_update_reset_vector(void)
Varun Wadekara0352ab2017-03-14 14:24:35 -0700355{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800356 const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
Varun Wadekara0352ab2017-03-14 14:24:35 -0700357
Krishna Sitaramand007f762016-09-02 16:53:04 -0700358 ops->update_reset_vector(mce_get_curr_cpu_ari_base());
Varun Wadekara0352ab2017-03-14 14:24:35 -0700359
360 return 0;
361}
362
Anthony Zhou1ab31402017-03-06 16:06:45 +0800363static int32_t mce_update_ccplex_gsc(tegra_ari_gsc_index_t gsc_idx)
Varun Wadekara0352ab2017-03-14 14:24:35 -0700364{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800365 const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
Varun Wadekara0352ab2017-03-14 14:24:35 -0700366
367 ops->update_ccplex_gsc(mce_get_curr_cpu_ari_base(), gsc_idx);
368
369 return 0;
370}
371
372/*******************************************************************************
373 * Handler to update carveout values for Video Memory Carveout region
374 ******************************************************************************/
Anthony Zhou1ab31402017-03-06 16:06:45 +0800375int32_t mce_update_gsc_videomem(void)
Varun Wadekara0352ab2017-03-14 14:24:35 -0700376{
377 return mce_update_ccplex_gsc(TEGRA_ARI_GSC_VPR_IDX);
378}
379
380/*******************************************************************************
381 * Handler to update carveout values for TZDRAM aperture
382 ******************************************************************************/
Anthony Zhou1ab31402017-03-06 16:06:45 +0800383int32_t mce_update_gsc_tzdram(void)
Varun Wadekara0352ab2017-03-14 14:24:35 -0700384{
385 return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZ_DRAM_IDX);
386}
387
388/*******************************************************************************
389 * Handler to update carveout values for TZ SysRAM aperture
390 ******************************************************************************/
Anthony Zhou1ab31402017-03-06 16:06:45 +0800391int32_t mce_update_gsc_tzram(void)
Varun Wadekara0352ab2017-03-14 14:24:35 -0700392{
393 return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZRAM);
394}
395
396/*******************************************************************************
397 * Handler to shutdown/reset the entire system
398 ******************************************************************************/
399__dead2 void mce_enter_ccplex_state(uint32_t state_idx)
400{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800401 const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
Varun Wadekara0352ab2017-03-14 14:24:35 -0700402
403 /* sanity check state value */
Anthony Zhou1ab31402017-03-06 16:06:45 +0800404 if ((state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) &&
405 (state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT)) {
Varun Wadekara0352ab2017-03-14 14:24:35 -0700406 panic();
Anthony Zhou1ab31402017-03-06 16:06:45 +0800407 }
Varun Wadekara0352ab2017-03-14 14:24:35 -0700408
409 ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(), state_idx);
410
411 /* wait till the CCPLEX powers down */
Anthony Zhou1ab31402017-03-06 16:06:45 +0800412 for (;;) {
Varun Wadekara0352ab2017-03-14 14:24:35 -0700413 ;
Anthony Zhou1ab31402017-03-06 16:06:45 +0800414 }
Varun Wadekara0352ab2017-03-14 14:24:35 -0700415
Varun Wadekara0352ab2017-03-14 14:24:35 -0700416}
Varun Wadekar47ddd002016-03-28 16:00:02 -0700417
418/*******************************************************************************
Varun Wadekarc47504f2017-03-23 17:32:20 -0700419 * Handler to issue the UPDATE_CSTATE_INFO request
420 ******************************************************************************/
Anthony Zhou1ab31402017-03-06 16:06:45 +0800421void mce_update_cstate_info(const mce_cstate_info_t *cstate)
Varun Wadekarc47504f2017-03-23 17:32:20 -0700422{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800423 const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
Varun Wadekarc47504f2017-03-23 17:32:20 -0700424
425 /* issue the UPDATE_CSTATE_INFO request */
426 ops->update_cstate_info(mce_get_curr_cpu_ari_base(), cstate->cluster,
427 cstate->ccplex, cstate->system, cstate->system_state_force,
428 cstate->wake_mask, cstate->update_wake_mask);
429}
430
431/*******************************************************************************
Varun Wadekar47ddd002016-03-28 16:00:02 -0700432 * Handler to read the MCE firmware version and check if it is compatible
433 * with interface header the BL3-1 was compiled against
434 ******************************************************************************/
435void mce_verify_firmware_version(void)
436{
Anthony Zhou1ab31402017-03-06 16:06:45 +0800437 const arch_mce_ops_t *ops;
Varun Wadekar47ddd002016-03-28 16:00:02 -0700438 uint32_t cpu_ari_base;
439 uint64_t version;
Varun Wadekarefa66d42016-07-18 17:42:02 -0700440 uint32_t major, minor;
441
442 /*
Varun Wadekarb5568282016-12-13 18:04:35 -0800443 * MCE firmware is not supported on simulation platforms.
Varun Wadekarefa66d42016-07-18 17:42:02 -0700444 */
Anthony Zhou1ab31402017-03-06 16:06:45 +0800445 if (tegra_platform_is_emulation()) {
Varun Wadekar47ddd002016-03-28 16:00:02 -0700446
Anthony Zhou1ab31402017-03-06 16:06:45 +0800447 INFO("MCE firmware is not supported\n");
Varun Wadekar47ddd002016-03-28 16:00:02 -0700448
Anthony Zhou1ab31402017-03-06 16:06:45 +0800449 } else {
450 /* get a pointer to the CPU's arch_mce_ops_t struct */
451 ops = mce_get_curr_cpu_ops();
Varun Wadekar47ddd002016-03-28 16:00:02 -0700452
Anthony Zhou1ab31402017-03-06 16:06:45 +0800453 /* get the CPU's ARI base address */
454 cpu_ari_base = mce_get_curr_cpu_ari_base();
Varun Wadekar47ddd002016-03-28 16:00:02 -0700455
Anthony Zhou1ab31402017-03-06 16:06:45 +0800456 /*
457 * Read the MCE firmware version and extract the major and minor
458 * version fields
459 */
460 version = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, 0);
461 major = (uint32_t)version;
462 minor = (uint32_t)(version >> 32);
Varun Wadekar47ddd002016-03-28 16:00:02 -0700463
Anthony Zhou1ab31402017-03-06 16:06:45 +0800464 INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
465 TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR);
Varun Wadekar47ddd002016-03-28 16:00:02 -0700466
Anthony Zhou1ab31402017-03-06 16:06:45 +0800467 /*
468 * Verify that the MCE firmware version and the interface header
469 * match
470 */
471 if (major != TEGRA_ARI_VERSION_MAJOR) {
472 ERROR("ARI major version mismatch\n");
473 panic();
474 }
475
476 if (minor < TEGRA_ARI_VERSION_MINOR) {
477 ERROR("ARI minor version mismatch\n");
478 panic();
479 }
Varun Wadekar47ddd002016-03-28 16:00:02 -0700480 }
481}