blob: 355a5474e3c45e3e3c32b54655b8dba39110db91 [file] [log] [blame]
Varun Wadekarecd6a5a2018-04-09 17:48:58 -07001/*
2 * Copyright (c) 2019, NVIDIA CORPORATION. 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 <common/bl_common.h>
11#include <context.h>
12#include <lib/el3_runtime/context_mgmt.h>
13#include <common/debug.h>
14#include <denver.h>
15#include <mce.h>
16#include <mce_private.h>
17#include <mmio.h>
Steven Kao2cdb6782017-01-05 17:04:40 +080018#include <platform_def.h>
Steven Kao6f373a22017-09-29 18:09:17 +080019#include <stdbool.h>
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070020#include <string.h>
21#include <errno.h>
Steven Kao2cdb6782017-01-05 17:04:40 +080022#include <t194_nvg.h>
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070023#include <tegra_def.h>
24#include <tegra_platform.h>
25
Steven Kao6f373a22017-09-29 18:09:17 +080026/* Handler to check if MCE firmware is supported */
27static bool mce_firmware_not_supported(void)
28{
29 bool status;
30
31 /* these platforms do not load MCE firmware */
32 status = tegra_platform_is_linsim() || tegra_platform_is_qt() ||
33 tegra_platform_is_virt_dev_kit();
34
35 return status;
36}
37
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070038/*******************************************************************************
39 * Common handler for all MCE commands
40 ******************************************************************************/
Anthony Zhou5e890b32017-04-28 13:52:58 +080041int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070042 uint64_t arg2)
43{
44 uint64_t ret64 = 0, arg3, arg4, arg5;
Steven Kao2cdb6782017-01-05 17:04:40 +080045 int32_t ret = 0;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070046 cpu_context_t *ctx = cm_get_context(NON_SECURE);
47 gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
48
49 assert(ctx);
50 assert(gp_regs);
51
52 switch (cmd) {
53 case MCE_CMD_ENTER_CSTATE:
Steven Kao2cdb6782017-01-05 17:04:40 +080054 ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1);
55 if (ret < 0) {
56 ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
57 }
58
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070059 break;
60
61 case MCE_CMD_UPDATE_CSTATE_INFO:
62 /*
63 * get the parameters required for the update cstate info
64 * command
65 */
Steven Kao2cdb6782017-01-05 17:04:40 +080066 arg3 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4));
67 arg4 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5));
68 arg5 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070069
Steven Kao2cdb6782017-01-05 17:04:40 +080070 /* arg0 cluster
71 * arg1 ccplex
72 * arg2 system
73 * arg3 sys_state_force => T19x not support
74 * arg4 wake_mask
75 * arg5 update_wake_mask
76 */
77 nvg_update_cstate_info((uint32_t)arg0, (uint32_t)arg1,
78 (uint32_t)arg2, (uint32_t)arg4, (uint8_t)arg5);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070079
Steven Kao2cdb6782017-01-05 17:04:40 +080080 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4), (arg3));
81 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5), (arg4));
82 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6), (arg5));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070083
84 break;
85
86 case MCE_CMD_UPDATE_CROSSOVER_TIME:
Steven Kao2cdb6782017-01-05 17:04:40 +080087 ret = nvg_update_crossover_time((uint32_t)arg0, (uint32_t)arg1);
88 if (ret < 0) {
89 ERROR("%s: update_crossover_time failed(%d)\n",
90 __func__, ret);
91 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070092
93 break;
94
95 case MCE_CMD_READ_CSTATE_STATS:
Steven Kao2cdb6782017-01-05 17:04:40 +080096 ret64 = nvg_get_cstate_stat_query_value();
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070097
98 /* update context to return cstate stats value */
Steven Kao2cdb6782017-01-05 17:04:40 +080099 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64));
100 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700101
102 break;
103
104 case MCE_CMD_WRITE_CSTATE_STATS:
Steven Kao2cdb6782017-01-05 17:04:40 +0800105 ret = nvg_set_cstate_stat_query_value(arg0);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700106
107 break;
108
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700109 case MCE_CMD_IS_SC7_ALLOWED:
Steven Kao2cdb6782017-01-05 17:04:40 +0800110 ret = nvg_is_sc7_allowed();
111 if (ret < 0) {
112 ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
113 break;
114 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700115
116 /* update context to return SC7 status value */
Steven Kao2cdb6782017-01-05 17:04:40 +0800117 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), ((uint64_t)ret));
118 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X3), ((uint64_t)ret));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700119
120 break;
121
122 case MCE_CMD_ONLINE_CORE:
Steven Kao2cdb6782017-01-05 17:04:40 +0800123 ret = nvg_online_core((uint32_t)arg0);
124 if (ret < 0) {
125 ERROR("%s: online_core failed(%d)\n", __func__, ret);
126 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700127
128 break;
129
130 case MCE_CMD_CC3_CTRL:
Steven Kao2cdb6782017-01-05 17:04:40 +0800131 ret = nvg_cc3_ctrl((uint32_t)arg0, (uint8_t)arg2);
132 if (ret < 0) {
133 ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
134 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700135
136 break;
137
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700138 case MCE_CMD_READ_VERSIONS:
139 /* get the MCE firmware version */
Steven Kao2cdb6782017-01-05 17:04:40 +0800140 ret64 = nvg_get_version();
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700141
142 /*
143 * version = minor(63:32) | major(31:0). Update context
144 * to return major and minor version number.
145 */
Steven Kao2cdb6782017-01-05 17:04:40 +0800146 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64 & (uint64_t)0xFFFF));
147 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64 >> 32));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700148
149 break;
150
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700151 case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
Steven Kao2cdb6782017-01-05 17:04:40 +0800152 ret = nvg_roc_clean_cache_trbits();
153 if (ret < 0) {
154 ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
155 ret);
156 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700157
158 break;
159
160 case MCE_CMD_ROC_FLUSH_CACHE:
Steven Kao2cdb6782017-01-05 17:04:40 +0800161 ret = nvg_roc_flush_cache();
162 if (ret < 0) {
163 ERROR("%s: flush cache failed(%d)\n", __func__, ret);
164 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700165
166 break;
167
168 case MCE_CMD_ROC_CLEAN_CACHE:
Steven Kao2cdb6782017-01-05 17:04:40 +0800169 ret = nvg_roc_clean_cache();
170 if (ret < 0) {
171 ERROR("%s: clean cache failed(%d)\n", __func__, ret);
172 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700173
174 break;
175
176 default:
Anthony Zhou5e890b32017-04-28 13:52:58 +0800177 ERROR("unknown MCE command (%llu)\n", cmd);
Steven Kao2cdb6782017-01-05 17:04:40 +0800178 ret = EINVAL;
179 break;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700180 }
181
182 return ret;
183}
184
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700185/*******************************************************************************
186 * Handler to update carveout values for Video Memory Carveout region
187 ******************************************************************************/
Steven Kao2cdb6782017-01-05 17:04:40 +0800188int32_t mce_update_gsc_videomem(void)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700189{
Steven Kao6f373a22017-09-29 18:09:17 +0800190 int32_t ret;
191
192 /*
193 * MCE firmware is not running on simulation platforms.
194 */
195 if (mce_firmware_not_supported()) {
196 ret = -EINVAL;
197 } else {
198 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR);
199 }
200
201 return ret;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700202}
203
204/*******************************************************************************
205 * Handler to update carveout values for TZDRAM aperture
206 ******************************************************************************/
Steven Kao2cdb6782017-01-05 17:04:40 +0800207int32_t mce_update_gsc_tzdram(void)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700208{
Steven Kao6f373a22017-09-29 18:09:17 +0800209 int32_t ret;
210
211 /*
212 * MCE firmware is not running on simulation platforms.
213 */
214 if (mce_firmware_not_supported()) {
215 ret = -EINVAL;
216 } else {
217 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM);
218 }
219
220 return ret;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700221}
222
223/*******************************************************************************
224 * Handler to update carveout values for TZ SysRAM aperture
225 ******************************************************************************/
Steven Kao2cdb6782017-01-05 17:04:40 +0800226int32_t mce_update_gsc_tzram(void)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700227{
Steven Kao6f373a22017-09-29 18:09:17 +0800228 int32_t ret;
229
230 /*
231 * MCE firmware is not running on simulation platforms.
232 */
233 if (mce_firmware_not_supported()) {
234 ret = -EINVAL;
235 } else {
236 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM);
237 }
238
239 return ret;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700240}
241
242/*******************************************************************************
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700243 * Handler to issue the UPDATE_CSTATE_INFO request
244 ******************************************************************************/
Anthony Zhou5e890b32017-04-28 13:52:58 +0800245void mce_update_cstate_info(const mce_cstate_info_t *cstate)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700246{
247 /* issue the UPDATE_CSTATE_INFO request */
Steven Kao2cdb6782017-01-05 17:04:40 +0800248 nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
249 cstate->wake_mask, cstate->update_wake_mask);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700250}
251
252/*******************************************************************************
253 * Handler to read the MCE firmware version and check if it is compatible
254 * with interface header the BL3-1 was compiled against
255 ******************************************************************************/
256void mce_verify_firmware_version(void)
257{
258 uint64_t version;
259 uint32_t major, minor;
260
261 /*
262 * MCE firmware is not running on simulation platforms.
263 */
Steven Kao6f373a22017-09-29 18:09:17 +0800264 if (mce_firmware_not_supported()) {
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700265 return;
Steven Kao2cdb6782017-01-05 17:04:40 +0800266 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700267
268 /*
269 * Read the MCE firmware version and extract the major and minor
270 * version fields
271 */
Steven Kao2cdb6782017-01-05 17:04:40 +0800272 version = nvg_get_version();
273 minor = (uint32_t)version;
274 major = (uint32_t)(version >> 32);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700275
276 INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
277 0, 0);
278
279 /*
280 * Verify that the MCE firmware version and the interface header
281 * match
282 */
Steven Kao2cdb6782017-01-05 17:04:40 +0800283 if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700284 ERROR("MCE major version mismatch\n");
285 panic();
286 }
287
Steven Kao2cdb6782017-01-05 17:04:40 +0800288 if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700289 ERROR("MCE minor version mismatch\n");
290 panic();
291 }
292}