xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c (revision 2bda92025bbc72f35b4a1bee76cfb1a2b002e5e6)
1 /*
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>
18 #include <platform_def.h>
19 #include <stdbool.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <t194_nvg.h>
23 #include <tegra_def.h>
24 #include <tegra_platform.h>
25 
26 /* Handler to check if MCE firmware is supported */
27 static 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 
38 /*******************************************************************************
39  * Common handler for all MCE commands
40  ******************************************************************************/
41 int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
42 			uint64_t arg2)
43 {
44 	uint64_t ret64 = 0, arg3, arg4, arg5;
45 	int32_t ret = 0;
46 	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:
54 		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 
59 		break;
60 
61 	case MCE_CMD_UPDATE_CSTATE_INFO:
62 		/*
63 		 * get the parameters required for the update cstate info
64 		 * command
65 		 */
66 		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));
69 
70 		/* 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);
79 
80 		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));
83 
84 		break;
85 
86 	case MCE_CMD_UPDATE_CROSSOVER_TIME:
87 		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 		}
92 
93 		break;
94 
95 	case MCE_CMD_READ_CSTATE_STATS:
96 		ret64 = nvg_get_cstate_stat_query_value();
97 
98 		/* update context to return cstate stats value */
99 		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64));
100 		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64));
101 
102 		break;
103 
104 	case MCE_CMD_WRITE_CSTATE_STATS:
105 		ret = nvg_set_cstate_stat_query_value(arg0);
106 
107 		break;
108 
109 	case MCE_CMD_IS_SC7_ALLOWED:
110 		ret = nvg_is_sc7_allowed();
111 		if (ret < 0) {
112 			ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
113 			break;
114 		}
115 
116 		/* update context to return SC7 status value */
117 		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));
119 
120 		break;
121 
122 	case MCE_CMD_ONLINE_CORE:
123 		ret = nvg_online_core((uint32_t)arg0);
124 		if (ret < 0) {
125 			ERROR("%s: online_core failed(%d)\n", __func__, ret);
126 		}
127 
128 		break;
129 
130 	case MCE_CMD_CC3_CTRL:
131 		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 		}
135 
136 		break;
137 
138 	case MCE_CMD_READ_VERSIONS:
139 		/* get the MCE firmware version */
140 		ret64 = nvg_get_version();
141 
142 		/*
143 		 * version = minor(63:32) | major(31:0). Update context
144 		 * to return major and minor version number.
145 		 */
146 		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));
148 
149 		break;
150 
151 	case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
152 		ret = nvg_roc_clean_cache_trbits();
153 		if (ret < 0) {
154 			ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
155 				ret);
156 		}
157 
158 		break;
159 
160 	case MCE_CMD_ROC_FLUSH_CACHE:
161 		ret = nvg_roc_flush_cache();
162 		if (ret < 0) {
163 			ERROR("%s: flush cache failed(%d)\n", __func__, ret);
164 		}
165 
166 		break;
167 
168 	case MCE_CMD_ROC_CLEAN_CACHE:
169 		ret = nvg_roc_clean_cache();
170 		if (ret < 0) {
171 			ERROR("%s: clean cache failed(%d)\n", __func__, ret);
172 		}
173 
174 		break;
175 
176 	default:
177 		ERROR("unknown MCE command (%llu)\n", cmd);
178 		ret = EINVAL;
179 		break;
180 	}
181 
182 	return ret;
183 }
184 
185 /*******************************************************************************
186  * Handler to update carveout values for Video Memory Carveout region
187  ******************************************************************************/
188 int32_t mce_update_gsc_videomem(void)
189 {
190 	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;
202 }
203 
204 /*******************************************************************************
205  * Handler to update carveout values for TZDRAM aperture
206  ******************************************************************************/
207 int32_t mce_update_gsc_tzdram(void)
208 {
209 	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;
221 }
222 
223 /*******************************************************************************
224  * Handler to update carveout values for TZ SysRAM aperture
225  ******************************************************************************/
226 int32_t mce_update_gsc_tzram(void)
227 {
228 	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;
240 }
241 
242 /*******************************************************************************
243  * Handler to issue the UPDATE_CSTATE_INFO request
244  ******************************************************************************/
245 void mce_update_cstate_info(const mce_cstate_info_t *cstate)
246 {
247 	/* issue the UPDATE_CSTATE_INFO request */
248 	nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
249 		cstate->wake_mask, cstate->update_wake_mask);
250 }
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  ******************************************************************************/
256 void 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 	 */
264 	if (mce_firmware_not_supported()) {
265 		return;
266 	}
267 
268 	/*
269 	 * Read the MCE firmware version and extract the major and minor
270 	 * version fields
271 	 */
272 	version = nvg_get_version();
273 	minor = (uint32_t)version;
274 	major = (uint32_t)(version >> 32);
275 
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 	 */
283 	if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
284 		ERROR("MCE major version mismatch\n");
285 		panic();
286 	}
287 
288 	if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
289 		ERROR("MCE minor version mismatch\n");
290 		panic();
291 	}
292 }
293