xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c (revision b10d44995eb652675863c2cc6a7726683613da0d)
1 /*
2  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <arch.h>
32 #include <arch_helpers.h>
33 #include <assert.h>
34 #include <debug.h>
35 #include <delay_timer.h>
36 #include <denver.h>
37 #include <mmio.h>
38 #include <mce_private.h>
39 #include <platform.h>
40 #include <sys/errno.h>
41 #include <t18x_ari.h>
42 
43 /*******************************************************************************
44  * Register offsets for ARI request/results
45  ******************************************************************************/
46 #define ARI_REQUEST			0x0
47 #define ARI_REQUEST_EVENT_MASK		0x4
48 #define ARI_STATUS			0x8
49 #define ARI_REQUEST_DATA_LO		0xC
50 #define ARI_REQUEST_DATA_HI		0x10
51 #define ARI_RESPONSE_DATA_LO		0x14
52 #define ARI_RESPONSE_DATA_HI		0x18
53 
54 /* Status values for the current request */
55 #define ARI_REQ_PENDING			1U
56 #define ARI_REQ_ONGOING			3U
57 #define ARI_REQUEST_VALID_BIT		(1U << 8)
58 #define ARI_EVT_MASK_STANDBYWFI_BIT	(1U << 7)
59 
60 /* default timeout (ms) to wait for ARI completion */
61 #define ARI_MAX_RETRY_COUNT		2000
62 
63 /*******************************************************************************
64  * ARI helper functions
65  ******************************************************************************/
66 static inline uint32_t ari_read_32(uint32_t ari_base, uint32_t reg)
67 {
68 	return mmio_read_32(ari_base + reg);
69 }
70 
71 static inline void ari_write_32(uint32_t ari_base, uint32_t val, uint32_t reg)
72 {
73 	mmio_write_32(ari_base + reg, val);
74 }
75 
76 static inline uint32_t ari_get_request_low(uint32_t ari_base)
77 {
78 	return ari_read_32(ari_base, ARI_REQUEST_DATA_LO);
79 }
80 
81 static inline uint32_t ari_get_request_high(uint32_t ari_base)
82 {
83 	return ari_read_32(ari_base, ARI_REQUEST_DATA_HI);
84 }
85 
86 static inline uint32_t ari_get_response_low(uint32_t ari_base)
87 {
88 	return ari_read_32(ari_base, ARI_RESPONSE_DATA_LO);
89 }
90 
91 static inline uint32_t ari_get_response_high(uint32_t ari_base)
92 {
93 	return ari_read_32(ari_base, ARI_RESPONSE_DATA_HI);
94 }
95 
96 static inline void ari_clobber_response(uint32_t ari_base)
97 {
98 	ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_LO);
99 	ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_HI);
100 }
101 
102 static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
103 		uint32_t lo, uint32_t hi)
104 {
105 	uint32_t retries = ARI_MAX_RETRY_COUNT;
106 	uint32_t status;
107 
108 	/* program the request, event_mask, hi and lo registers */
109 	ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO);
110 	ari_write_32(ari_base, hi, ARI_REQUEST_DATA_HI);
111 	ari_write_32(ari_base, evt_mask, ARI_REQUEST_EVENT_MASK);
112 	ari_write_32(ari_base, req | ARI_REQUEST_VALID_BIT, ARI_REQUEST);
113 
114 	/*
115 	 * For commands that have an event trigger, we should bypass
116 	 * ARI_STATUS polling, since MCE is waiting for SW to trigger
117 	 * the event.
118 	 */
119 	if (evt_mask)
120 		return 0;
121 
122 	/* For shutdown/reboot commands, we dont have to check for timeouts */
123 	if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) &&
124 	    ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
125 	     (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
126 			return 0;
127 	}
128 
129 	/*
130 	 * Wait for the command response for not more than the timeout
131 	 */
132 	while (retries != 0U) {
133 
134 		/* read the command status */
135 		status = ari_read_32(ari_base, ARI_STATUS);
136 		if ((status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) == 0U)
137 			break;
138 
139 		/* delay 1 ms */
140 		mdelay(1);
141 
142 		/* decrement the retry count */
143 		retries--;
144 	}
145 
146 	/* assert if the command timed out */
147 	if (retries == 0U) {
148 		ERROR("ARI request timed out: req %d on CPU %d\n",
149 			req, plat_my_core_pos());
150 		assert(retries != 0U);
151 	}
152 
153 	return 0;
154 }
155 
156 int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
157 {
158 	/* check for allowed power state */
159 	if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 &&
160 	    state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) {
161 		ERROR("%s: unknown cstate (%d)\n", __func__, state);
162 		return EINVAL;
163 	}
164 
165 	/* clean the previous response state */
166 	ari_clobber_response(ari_base);
167 
168 	/* Enter the cstate, to be woken up after wake_time (TSC ticks) */
169 	return ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT,
170 		TEGRA_ARI_ENTER_CSTATE, state, wake_time);
171 }
172 
173 int ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
174 	uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
175 	uint8_t update_wake_mask)
176 {
177 	uint32_t val = 0;
178 
179 	/* clean the previous response state */
180 	ari_clobber_response(ari_base);
181 
182 	/* update CLUSTER_CSTATE? */
183 	if (cluster)
184 		val |= (cluster & CLUSTER_CSTATE_MASK) |
185 			CLUSTER_CSTATE_UPDATE_BIT;
186 
187 	/* update CCPLEX_CSTATE? */
188 	if (ccplex)
189 		val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT |
190 			CCPLEX_CSTATE_UPDATE_BIT;
191 
192 	/* update SYSTEM_CSTATE? */
193 	if (system)
194 		val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
195 		       ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
196 			SYSTEM_CSTATE_UPDATE_BIT);
197 
198 	/* update wake mask value? */
199 	if (update_wake_mask)
200 		val |= CSTATE_WAKE_MASK_UPDATE_BIT;
201 
202 	/* set the updated cstate info */
203 	return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CSTATE_INFO, val,
204 			wake_mask);
205 }
206 
207 int ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time)
208 {
209 	/* sanity check crossover type */
210 	if ((type == TEGRA_ARI_CROSSOVER_C1_C6) ||
211 	    (type > TEGRA_ARI_CROSSOVER_CCP3_SC1))
212 		return EINVAL;
213 
214 	/* clean the previous response state */
215 	ari_clobber_response(ari_base);
216 
217 	/* update crossover threshold time */
218 	return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CROSSOVER,
219 			type, time);
220 }
221 
222 uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state)
223 {
224 	int ret;
225 
226 	/* sanity check crossover type */
227 	if (state == 0)
228 		return EINVAL;
229 
230 	/* clean the previous response state */
231 	ari_clobber_response(ari_base);
232 
233 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_CSTATE_STATS, state, 0);
234 	if (ret != 0)
235 		return EINVAL;
236 
237 	return (uint64_t)ari_get_response_low(ari_base);
238 }
239 
240 int ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats)
241 {
242 	/* clean the previous response state */
243 	ari_clobber_response(ari_base);
244 
245 	/* write the cstate stats */
246 	return ari_request_wait(ari_base, 0, TEGRA_ARI_WRITE_CSTATE_STATS, state,
247 			stats);
248 }
249 
250 uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data)
251 {
252 	uint64_t resp;
253 	int ret;
254 
255 	/* clean the previous response state */
256 	ari_clobber_response(ari_base);
257 
258 	/* ARI_REQUEST_DATA_HI is reserved for commands other than 'ECHO' */
259 	if (cmd != TEGRA_ARI_MISC_ECHO)
260 		data = 0;
261 
262 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MISC, cmd, data);
263 	if (ret)
264 		return (uint64_t)ret;
265 
266 	/* get the command response */
267 	resp = ari_get_response_low(ari_base);
268 	resp |= ((uint64_t)ari_get_response_high(ari_base) << 32);
269 
270 	return resp;
271 }
272 
273 int ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
274 {
275 	int ret;
276 
277 	/* clean the previous response state */
278 	ari_clobber_response(ari_base);
279 
280 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7,
281 			wake_time);
282 	if (ret) {
283 		ERROR("%s: failed (%d)\n", __func__, ret);
284 		return 0;
285 	}
286 
287 	/* 1 = CCx allowed, 0 = CCx not allowed */
288 	return (ari_get_response_low(ari_base) & 0x1);
289 }
290 
291 int ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
292 {
293 	int ret;
294 
295 	/* check for allowed power state */
296 	if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 &&
297 	    state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) {
298 		ERROR("%s: unknown cstate (%d)\n", __func__, state);
299 		return EINVAL;
300 	}
301 
302 	/* clean the previous response state */
303 	ari_clobber_response(ari_base);
304 
305 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_SC7_ALLOWED, state,
306 			wake_time);
307 	if (ret) {
308 		ERROR("%s: failed (%d)\n", __func__, ret);
309 		return 0;
310 	}
311 
312 	/* 1 = SC7 allowed, 0 = SC7 not allowed */
313 	return !!ari_get_response_low(ari_base);
314 }
315 
316 int ari_online_core(uint32_t ari_base, uint32_t core)
317 {
318 	int cpu = read_mpidr() & MPIDR_CPU_MASK;
319 	int cluster = (read_mpidr() & MPIDR_CLUSTER_MASK) >>
320 			MPIDR_AFFINITY_BITS;
321 	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
322 
323 	/* construct the current CPU # */
324 	cpu |= (cluster << 2);
325 
326 	/* sanity check target core id */
327 	if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) {
328 		ERROR("%s: unsupported core id (%d)\n", __func__, core);
329 		return EINVAL;
330 	}
331 
332 	/*
333 	 * The Denver cluster has 2 CPUs only - 0, 1.
334 	 */
335 	if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) {
336 		ERROR("%s: unknown core id (%d)\n", __func__, core);
337 		return EINVAL;
338 	}
339 
340 	/* clean the previous response state */
341 	ari_clobber_response(ari_base);
342 
343 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ONLINE_CORE, core, 0);
344 }
345 
346 int ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable)
347 {
348 	int val;
349 
350 	/* clean the previous response state */
351 	ari_clobber_response(ari_base);
352 
353 	/*
354 	 * If the enable bit is cleared, Auto-CC3 will be disabled by setting
355 	 * the SW visible voltage/frequency request registers for all non
356 	 * floorswept cores valid independent of StandbyWFI and disabling
357 	 * the IDLE voltage/frequency request register. If set, Auto-CC3
358 	 * will be enabled by setting the ARM SW visible voltage/frequency
359 	 * request registers for all non floorswept cores to be enabled by
360 	 * StandbyWFI or the equivalent signal, and always keeping the IDLE
361 	 * voltage/frequency request register enabled.
362 	 */
363 	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\
364 		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
365 		(enable ? MCE_AUTO_CC3_ENABLE_BIT : 0));
366 
367 	return ari_request_wait(ari_base, 0, TEGRA_ARI_CC3_CTRL, val, 0);
368 }
369 
370 int ari_reset_vector_update(uint32_t ari_base)
371 {
372 	/* clean the previous response state */
373 	ari_clobber_response(ari_base);
374 
375 	/*
376 	 * Need to program the CPU reset vector one time during cold boot
377 	 * and SC7 exit
378 	 */
379 	ari_request_wait(ari_base, 0, TEGRA_ARI_COPY_MISCREG_AA64_RST, 0, 0);
380 
381 	return 0;
382 }
383 
384 int ari_roc_flush_cache_trbits(uint32_t ari_base)
385 {
386 	/* clean the previous response state */
387 	ari_clobber_response(ari_base);
388 
389 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS,
390 			0, 0);
391 }
392 
393 int ari_roc_flush_cache(uint32_t ari_base)
394 {
395 	/* clean the previous response state */
396 	ari_clobber_response(ari_base);
397 
398 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY,
399 			0, 0);
400 }
401 
402 int ari_roc_clean_cache(uint32_t ari_base)
403 {
404 	/* clean the previous response state */
405 	ari_clobber_response(ari_base);
406 
407 	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY,
408 			0, 0);
409 }
410 
411 uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data)
412 {
413 	mca_arg_t mca_arg;
414 	int ret;
415 
416 	/* Set data (write) */
417 	mca_arg.data = data ? *data : 0ull;
418 
419 	/* Set command */
420 	ari_write_32(ari_base, cmd.input.low, ARI_RESPONSE_DATA_LO);
421 	ari_write_32(ari_base, cmd.input.high, ARI_RESPONSE_DATA_HI);
422 
423 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MCA, mca_arg.arg.low,
424 			mca_arg.arg.high);
425 	if (!ret) {
426 		mca_arg.arg.low = ari_get_response_low(ari_base);
427 		mca_arg.arg.high = ari_get_response_high(ari_base);
428 		if (!mca_arg.err.finish)
429 			return (uint64_t)mca_arg.err.error;
430 
431 		if (data) {
432 			mca_arg.arg.low = ari_get_request_low(ari_base);
433 			mca_arg.arg.high = ari_get_request_high(ari_base);
434 			*data = mca_arg.data;
435 		}
436 	}
437 
438 	return 0;
439 }
440 
441 int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx)
442 {
443 	/* sanity check GSC ID */
444 	if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX)
445 		return EINVAL;
446 
447 	/* clean the previous response state */
448 	ari_clobber_response(ari_base);
449 
450 	/*
451 	 * The MCE code will read the GSC carveout value, corrseponding to
452 	 * the ID, from the MC registers and update the internal GSC registers
453 	 * of the CCPLEX.
454 	 */
455 	ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0);
456 
457 	return 0;
458 }
459 
460 void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx)
461 {
462 	/* clean the previous response state */
463 	ari_clobber_response(ari_base);
464 
465 	/*
466 	 * The MCE will shutdown or restart the entire system
467 	 */
468 	(void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, state_idx, 0);
469 }
470 
471 int ari_read_write_uncore_perfmon(uint32_t ari_base,
472 		uncore_perfmon_req_t req, uint64_t *data)
473 {
474 	int ret;
475 	uint32_t val;
476 
477 	/* clean the previous response state */
478 	ari_clobber_response(ari_base);
479 
480 	/* sanity check input parameters */
481 	if (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_READ && !data) {
482 		ERROR("invalid parameters\n");
483 		return EINVAL;
484 	}
485 
486 	/*
487 	 * For "write" commands get the value that has to be written
488 	 * to the uncore perfmon registers
489 	 */
490 	val = (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_WRITE) ?
491 		*data : 0;
492 
493 	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_PERFMON, val, req.data);
494 	if (ret)
495 		return ret;
496 
497 	/* read the command status value */
498 	req.perfmon_status.val = ari_get_response_high(ari_base) &
499 				 UNCORE_PERFMON_RESP_STATUS_MASK;
500 
501 	/*
502 	 * For "read" commands get the data from the uncore
503 	 * perfmon registers
504 	 */
505 	if ((req.perfmon_status.val == 0) && (req.perfmon_command.cmd ==
506 	     UNCORE_PERFMON_CMD_READ))
507 		*data = ari_get_response_low(ari_base);
508 
509 	return (int)req.perfmon_status.val;
510 }
511 
512 void ari_misc_ccplex(uint32_t ari_base, uint32_t index, uint32_t value)
513 {
514 	/*
515 	 * This invokes the ARI_MISC_CCPLEX commands. This can be
516 	 * used to enable/disable coresight clock gating.
517 	 */
518 
519 	if ((index > TEGRA_ARI_MISC_CCPLEX_EDBGREQ) ||
520 		((index == TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL) &&
521 		(value > 1))) {
522 		ERROR("%s: invalid parameters \n", __func__);
523 		return;
524 	}
525 
526 	/* clean the previous response state */
527 	ari_clobber_response(ari_base);
528 	(void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, index, value);
529 }
530