blob: 0a6515e1ce1a4f48bb15b053cca8258e9682bcb0 [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>
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070019#include <string.h>
20#include <errno.h>
Steven Kao2cdb6782017-01-05 17:04:40 +080021#include <t194_nvg.h>
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070022#include <tegra_def.h>
23#include <tegra_platform.h>
24
25/*******************************************************************************
26 * Common handler for all MCE commands
27 ******************************************************************************/
Anthony Zhou5e890b32017-04-28 13:52:58 +080028int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070029 uint64_t arg2)
30{
31 uint64_t ret64 = 0, arg3, arg4, arg5;
Steven Kao2cdb6782017-01-05 17:04:40 +080032 int32_t ret = 0;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070033 cpu_context_t *ctx = cm_get_context(NON_SECURE);
34 gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
35
36 assert(ctx);
37 assert(gp_regs);
38
39 switch (cmd) {
40 case MCE_CMD_ENTER_CSTATE:
Steven Kao2cdb6782017-01-05 17:04:40 +080041 ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1);
42 if (ret < 0) {
43 ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
44 }
45
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070046 break;
47
48 case MCE_CMD_UPDATE_CSTATE_INFO:
49 /*
50 * get the parameters required for the update cstate info
51 * command
52 */
Steven Kao2cdb6782017-01-05 17:04:40 +080053 arg3 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4));
54 arg4 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5));
55 arg5 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070056
Steven Kao2cdb6782017-01-05 17:04:40 +080057 /* arg0 cluster
58 * arg1 ccplex
59 * arg2 system
60 * arg3 sys_state_force => T19x not support
61 * arg4 wake_mask
62 * arg5 update_wake_mask
63 */
64 nvg_update_cstate_info((uint32_t)arg0, (uint32_t)arg1,
65 (uint32_t)arg2, (uint32_t)arg4, (uint8_t)arg5);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070066
Steven Kao2cdb6782017-01-05 17:04:40 +080067 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4), (arg3));
68 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5), (arg4));
69 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6), (arg5));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070070
71 break;
72
73 case MCE_CMD_UPDATE_CROSSOVER_TIME:
Steven Kao2cdb6782017-01-05 17:04:40 +080074 ret = nvg_update_crossover_time((uint32_t)arg0, (uint32_t)arg1);
75 if (ret < 0) {
76 ERROR("%s: update_crossover_time failed(%d)\n",
77 __func__, ret);
78 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070079
80 break;
81
82 case MCE_CMD_READ_CSTATE_STATS:
Steven Kao2cdb6782017-01-05 17:04:40 +080083 ret64 = nvg_get_cstate_stat_query_value();
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070084
85 /* update context to return cstate stats value */
Steven Kao2cdb6782017-01-05 17:04:40 +080086 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64));
87 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070088
89 break;
90
91 case MCE_CMD_WRITE_CSTATE_STATS:
Steven Kao2cdb6782017-01-05 17:04:40 +080092 ret = nvg_set_cstate_stat_query_value(arg0);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070093
94 break;
95
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070096 case MCE_CMD_IS_SC7_ALLOWED:
Steven Kao2cdb6782017-01-05 17:04:40 +080097 ret = nvg_is_sc7_allowed();
98 if (ret < 0) {
99 ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
100 break;
101 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700102
103 /* update context to return SC7 status value */
Steven Kao2cdb6782017-01-05 17:04:40 +0800104 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), ((uint64_t)ret));
105 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X3), ((uint64_t)ret));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700106
107 break;
108
109 case MCE_CMD_ONLINE_CORE:
Steven Kao2cdb6782017-01-05 17:04:40 +0800110 ret = nvg_online_core((uint32_t)arg0);
111 if (ret < 0) {
112 ERROR("%s: online_core failed(%d)\n", __func__, ret);
113 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700114
115 break;
116
117 case MCE_CMD_CC3_CTRL:
Steven Kao2cdb6782017-01-05 17:04:40 +0800118 ret = nvg_cc3_ctrl((uint32_t)arg0, (uint8_t)arg2);
119 if (ret < 0) {
120 ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
121 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700122
123 break;
124
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700125 case MCE_CMD_READ_VERSIONS:
126 /* get the MCE firmware version */
Steven Kao2cdb6782017-01-05 17:04:40 +0800127 ret64 = nvg_get_version();
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700128
129 /*
130 * version = minor(63:32) | major(31:0). Update context
131 * to return major and minor version number.
132 */
Steven Kao2cdb6782017-01-05 17:04:40 +0800133 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64 & (uint64_t)0xFFFF));
134 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64 >> 32));
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700135
136 break;
137
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700138 case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
Steven Kao2cdb6782017-01-05 17:04:40 +0800139 ret = nvg_roc_clean_cache_trbits();
140 if (ret < 0) {
141 ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
142 ret);
143 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700144
145 break;
146
147 case MCE_CMD_ROC_FLUSH_CACHE:
Steven Kao2cdb6782017-01-05 17:04:40 +0800148 ret = nvg_roc_flush_cache();
149 if (ret < 0) {
150 ERROR("%s: flush cache failed(%d)\n", __func__, ret);
151 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700152
153 break;
154
155 case MCE_CMD_ROC_CLEAN_CACHE:
Steven Kao2cdb6782017-01-05 17:04:40 +0800156 ret = nvg_roc_clean_cache();
157 if (ret < 0) {
158 ERROR("%s: clean cache failed(%d)\n", __func__, ret);
159 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700160
161 break;
162
163 default:
Anthony Zhou5e890b32017-04-28 13:52:58 +0800164 ERROR("unknown MCE command (%llu)\n", cmd);
Steven Kao2cdb6782017-01-05 17:04:40 +0800165 ret = EINVAL;
166 break;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700167 }
168
169 return ret;
170}
171
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700172/*******************************************************************************
173 * Handler to update carveout values for Video Memory Carveout region
174 ******************************************************************************/
Steven Kao2cdb6782017-01-05 17:04:40 +0800175int32_t mce_update_gsc_videomem(void)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700176{
Steven Kao2cdb6782017-01-05 17:04:40 +0800177 return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_VPR_IDX);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700178}
179
180/*******************************************************************************
181 * Handler to update carveout values for TZDRAM aperture
182 ******************************************************************************/
Steven Kao2cdb6782017-01-05 17:04:40 +0800183int32_t mce_update_gsc_tzdram(void)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700184{
Steven Kao2cdb6782017-01-05 17:04:40 +0800185 return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZ_DRAM_IDX);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700186}
187
188/*******************************************************************************
189 * Handler to update carveout values for TZ SysRAM aperture
190 ******************************************************************************/
Steven Kao2cdb6782017-01-05 17:04:40 +0800191int32_t mce_update_gsc_tzram(void)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700192{
Steven Kao2cdb6782017-01-05 17:04:40 +0800193 return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZRAM);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700194}
195
196/*******************************************************************************
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700197 * Handler to issue the UPDATE_CSTATE_INFO request
198 ******************************************************************************/
Anthony Zhou5e890b32017-04-28 13:52:58 +0800199void mce_update_cstate_info(const mce_cstate_info_t *cstate)
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700200{
201 /* issue the UPDATE_CSTATE_INFO request */
Steven Kao2cdb6782017-01-05 17:04:40 +0800202 nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
203 cstate->wake_mask, cstate->update_wake_mask);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700204}
205
206/*******************************************************************************
207 * Handler to read the MCE firmware version and check if it is compatible
208 * with interface header the BL3-1 was compiled against
209 ******************************************************************************/
210void mce_verify_firmware_version(void)
211{
212 uint64_t version;
213 uint32_t major, minor;
214
215 /*
216 * MCE firmware is not running on simulation platforms.
217 */
Steven Kao2cdb6782017-01-05 17:04:40 +0800218 if ((tegra_platform_is_linsim() == 1U) ||
Rohit Khannaf2cb2d92017-03-03 11:33:32 -0800219 (tegra_platform_is_virt_dev_kit() == 1U) ||
220 (tegra_platform_is_qt() == 1U)) {
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700221 return;
Steven Kao2cdb6782017-01-05 17:04:40 +0800222 }
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700223
224 /*
225 * Read the MCE firmware version and extract the major and minor
226 * version fields
227 */
Steven Kao2cdb6782017-01-05 17:04:40 +0800228 version = nvg_get_version();
229 minor = (uint32_t)version;
230 major = (uint32_t)(version >> 32);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700231
232 INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
233 0, 0);
234
235 /*
236 * Verify that the MCE firmware version and the interface header
237 * match
238 */
Steven Kao2cdb6782017-01-05 17:04:40 +0800239 if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700240 ERROR("MCE major version mismatch\n");
241 panic();
242 }
243
Steven Kao2cdb6782017-01-05 17:04:40 +0800244 if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700245 ERROR("MCE minor version mismatch\n");
246 panic();
247 }
248}