xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c (revision 1520b5d6888c470692c73fa1bb6fcf09aa96869b)
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 <string.h>
20 #include <errno.h>
21 #include <t194_nvg.h>
22 #include <tegra_def.h>
23 #include <tegra_platform.h>
24 
25 /*******************************************************************************
26  * Common handler for all MCE commands
27  ******************************************************************************/
28 int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
29 			uint64_t arg2)
30 {
31 	uint64_t ret64 = 0, arg3, arg4, arg5;
32 	int32_t ret = 0;
33 	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:
41 		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 
46 		break;
47 
48 	case MCE_CMD_UPDATE_CSTATE_INFO:
49 		/*
50 		 * get the parameters required for the update cstate info
51 		 * command
52 		 */
53 		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));
56 
57 		/* 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);
66 
67 		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));
70 
71 		break;
72 
73 	case MCE_CMD_UPDATE_CROSSOVER_TIME:
74 		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 		}
79 
80 		break;
81 
82 	case MCE_CMD_READ_CSTATE_STATS:
83 		ret64 = nvg_get_cstate_stat_query_value();
84 
85 		/* update context to return cstate stats value */
86 		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64));
87 		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64));
88 
89 		break;
90 
91 	case MCE_CMD_WRITE_CSTATE_STATS:
92 		ret = nvg_set_cstate_stat_query_value(arg0);
93 
94 		break;
95 
96 	case MCE_CMD_IS_SC7_ALLOWED:
97 		ret = nvg_is_sc7_allowed();
98 		if (ret < 0) {
99 			ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
100 			break;
101 		}
102 
103 		/* update context to return SC7 status value */
104 		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));
106 
107 		break;
108 
109 	case MCE_CMD_ONLINE_CORE:
110 		ret = nvg_online_core((uint32_t)arg0);
111 		if (ret < 0) {
112 			ERROR("%s: online_core failed(%d)\n", __func__, ret);
113 		}
114 
115 		break;
116 
117 	case MCE_CMD_CC3_CTRL:
118 		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 		}
122 
123 		break;
124 
125 	case MCE_CMD_READ_VERSIONS:
126 		/* get the MCE firmware version */
127 		ret64 = nvg_get_version();
128 
129 		/*
130 		 * version = minor(63:32) | major(31:0). Update context
131 		 * to return major and minor version number.
132 		 */
133 		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));
135 
136 		break;
137 
138 	case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
139 		ret = nvg_roc_clean_cache_trbits();
140 		if (ret < 0) {
141 			ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
142 				ret);
143 		}
144 
145 		break;
146 
147 	case MCE_CMD_ROC_FLUSH_CACHE:
148 		ret = nvg_roc_flush_cache();
149 		if (ret < 0) {
150 			ERROR("%s: flush cache failed(%d)\n", __func__, ret);
151 		}
152 
153 		break;
154 
155 	case MCE_CMD_ROC_CLEAN_CACHE:
156 		ret = nvg_roc_clean_cache();
157 		if (ret < 0) {
158 			ERROR("%s: clean cache failed(%d)\n", __func__, ret);
159 		}
160 
161 		break;
162 
163 	default:
164 		ERROR("unknown MCE command (%llu)\n", cmd);
165 		ret = EINVAL;
166 		break;
167 	}
168 
169 	return ret;
170 }
171 
172 /*******************************************************************************
173  * Handler to update carveout values for Video Memory Carveout region
174  ******************************************************************************/
175 int32_t mce_update_gsc_videomem(void)
176 {
177 	return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_VPR_IDX);
178 }
179 
180 /*******************************************************************************
181  * Handler to update carveout values for TZDRAM aperture
182  ******************************************************************************/
183 int32_t mce_update_gsc_tzdram(void)
184 {
185 	return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZ_DRAM_IDX);
186 }
187 
188 /*******************************************************************************
189  * Handler to update carveout values for TZ SysRAM aperture
190  ******************************************************************************/
191 int32_t mce_update_gsc_tzram(void)
192 {
193 	return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZRAM);
194 }
195 
196 /*******************************************************************************
197  * Handler to issue the UPDATE_CSTATE_INFO request
198  ******************************************************************************/
199 void mce_update_cstate_info(const mce_cstate_info_t *cstate)
200 {
201 	/* issue the UPDATE_CSTATE_INFO request */
202 	nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
203 		cstate->wake_mask, cstate->update_wake_mask);
204 }
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  ******************************************************************************/
210 void 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 	 */
218 	if ((tegra_platform_is_linsim() == 1U) ||
219 		(tegra_platform_is_virt_dev_kit() == 1U) ||
220 		(tegra_platform_is_qt() == 1U)) {
221 		return;
222 	}
223 
224 	/*
225 	 * Read the MCE firmware version and extract the major and minor
226 	 * version fields
227 	 */
228 	version = nvg_get_version();
229 	minor = (uint32_t)version;
230 	major = (uint32_t)(version >> 32);
231 
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 	 */
239 	if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
240 		ERROR("MCE major version mismatch\n");
241 		panic();
242 	}
243 
244 	if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
245 		ERROR("MCE minor version mismatch\n");
246 		panic();
247 	}
248 }
249