xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c (revision 28623c102d6fec0ba0271be64951679bf20681ba)
141612559SVarun Wadekar /*
2a3c2c0e9SSteven Kao  * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
341612559SVarun Wadekar  *
441612559SVarun Wadekar  * SPDX-License-Identifier: BSD-3-Clause
541612559SVarun Wadekar  */
641612559SVarun Wadekar 
741612559SVarun Wadekar #include <arch.h>
841612559SVarun Wadekar #include <arch_helpers.h>
941612559SVarun Wadekar #include <assert.h>
1041612559SVarun Wadekar #include <common/bl_common.h>
1141612559SVarun Wadekar #include <context.h>
1241612559SVarun Wadekar #include <lib/el3_runtime/context_mgmt.h>
1341612559SVarun Wadekar #include <common/debug.h>
1441612559SVarun Wadekar #include <denver.h>
1541612559SVarun Wadekar #include <mce.h>
1641612559SVarun Wadekar #include <mce_private.h>
179808032cSSteven Kao #include <platform_def.h>
182bda9202SSteven Kao #include <stdbool.h>
19*4ce3e99aSScott Branden #include <stdint.h>
2041612559SVarun Wadekar #include <string.h>
2141612559SVarun Wadekar #include <errno.h>
22*4ce3e99aSScott Branden #include <inttypes.h>
239808032cSSteven Kao #include <t194_nvg.h>
2441612559SVarun Wadekar #include <tegra_def.h>
2541612559SVarun Wadekar #include <tegra_platform.h>
26ac252f95SDilan Lee #include <tegra_private.h>
2741612559SVarun Wadekar 
282bda9202SSteven Kao /* Handler to check if MCE firmware is supported */
mce_firmware_not_supported(void)292bda9202SSteven Kao static bool mce_firmware_not_supported(void)
302bda9202SSteven Kao {
312bda9202SSteven Kao 	bool status;
322bda9202SSteven Kao 
332bda9202SSteven Kao 	/* these platforms do not load MCE firmware */
342bda9202SSteven Kao 	status = tegra_platform_is_linsim() || tegra_platform_is_qt() ||
352bda9202SSteven Kao 		 tegra_platform_is_virt_dev_kit();
362bda9202SSteven Kao 
372bda9202SSteven Kao 	return status;
382bda9202SSteven Kao }
392bda9202SSteven Kao 
4041612559SVarun Wadekar /*******************************************************************************
4141612559SVarun Wadekar  * Common handler for all MCE commands
4241612559SVarun Wadekar  ******************************************************************************/
mce_command_handler(uint64_t cmd,uint64_t arg0,uint64_t arg1,uint64_t arg2)4373dad7f9SAnthony Zhou int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
4441612559SVarun Wadekar 			uint64_t arg2)
4541612559SVarun Wadekar {
469808032cSSteven Kao 	int32_t ret = 0;
4741612559SVarun Wadekar 
4841612559SVarun Wadekar 	switch (cmd) {
496152de3bSAnthony Zhou 	case (uint64_t)MCE_CMD_ENTER_CSTATE:
509808032cSSteven Kao 		ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1);
519808032cSSteven Kao 		if (ret < 0) {
529808032cSSteven Kao 			ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
539808032cSSteven Kao 		}
549808032cSSteven Kao 
5541612559SVarun Wadekar 		break;
5641612559SVarun Wadekar 
576152de3bSAnthony Zhou 	case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
589808032cSSteven Kao 		ret = nvg_is_sc7_allowed();
599808032cSSteven Kao 		if (ret < 0) {
609808032cSSteven Kao 			ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
619808032cSSteven Kao 		}
6241612559SVarun Wadekar 
6341612559SVarun Wadekar 		break;
6441612559SVarun Wadekar 
656152de3bSAnthony Zhou 	case (uint64_t)MCE_CMD_ONLINE_CORE:
669808032cSSteven Kao 		ret = nvg_online_core((uint32_t)arg0);
679808032cSSteven Kao 		if (ret < 0) {
689808032cSSteven Kao 			ERROR("%s: online_core failed(%d)\n", __func__, ret);
699808032cSSteven Kao 		}
7041612559SVarun Wadekar 
7141612559SVarun Wadekar 		break;
7241612559SVarun Wadekar 
7341612559SVarun Wadekar 	default:
74*4ce3e99aSScott Branden 		ERROR("unknown MCE command (%" PRIu64 ")\n", cmd);
7508c085dcSVarun Wadekar 		ret = -EINVAL;
769808032cSSteven Kao 		break;
7741612559SVarun Wadekar 	}
7841612559SVarun Wadekar 
7941612559SVarun Wadekar 	return ret;
8041612559SVarun Wadekar }
8141612559SVarun Wadekar 
8241612559SVarun Wadekar /*******************************************************************************
8341612559SVarun Wadekar  * Handler to update carveout values for Video Memory Carveout region
8441612559SVarun Wadekar  ******************************************************************************/
mce_update_gsc_videomem(void)859808032cSSteven Kao int32_t mce_update_gsc_videomem(void)
8641612559SVarun Wadekar {
872bda9202SSteven Kao 	int32_t ret;
882bda9202SSteven Kao 
892bda9202SSteven Kao 	/*
902bda9202SSteven Kao 	 * MCE firmware is not running on simulation platforms.
912bda9202SSteven Kao 	 */
922bda9202SSteven Kao 	if (mce_firmware_not_supported()) {
932bda9202SSteven Kao 		ret = -EINVAL;
942bda9202SSteven Kao 	} else {
952bda9202SSteven Kao 		ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR);
962bda9202SSteven Kao 	}
972bda9202SSteven Kao 
982bda9202SSteven Kao 	return ret;
9941612559SVarun Wadekar }
10041612559SVarun Wadekar 
10141612559SVarun Wadekar /*******************************************************************************
10241612559SVarun Wadekar  * Handler to update carveout values for TZDRAM aperture
10341612559SVarun Wadekar  ******************************************************************************/
mce_update_gsc_tzdram(void)1049808032cSSteven Kao int32_t mce_update_gsc_tzdram(void)
10541612559SVarun Wadekar {
1062bda9202SSteven Kao 	int32_t ret;
1072bda9202SSteven Kao 
1082bda9202SSteven Kao 	/*
1092bda9202SSteven Kao 	 * MCE firmware is not running on simulation platforms.
1102bda9202SSteven Kao 	 */
1112bda9202SSteven Kao 	if (mce_firmware_not_supported()) {
1122bda9202SSteven Kao 		ret = -EINVAL;
1132bda9202SSteven Kao 	} else {
1142bda9202SSteven Kao 		ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM);
1152bda9202SSteven Kao 	}
1162bda9202SSteven Kao 
1172bda9202SSteven Kao 	return ret;
11841612559SVarun Wadekar }
11941612559SVarun Wadekar 
12041612559SVarun Wadekar /*******************************************************************************
12141612559SVarun Wadekar  * Handler to issue the UPDATE_CSTATE_INFO request
12241612559SVarun Wadekar  ******************************************************************************/
mce_update_cstate_info(const mce_cstate_info_t * cstate)12373dad7f9SAnthony Zhou void mce_update_cstate_info(const mce_cstate_info_t *cstate)
12441612559SVarun Wadekar {
12541612559SVarun Wadekar 	/* issue the UPDATE_CSTATE_INFO request */
1269808032cSSteven Kao 	nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
1279808032cSSteven Kao 		cstate->wake_mask, cstate->update_wake_mask);
12841612559SVarun Wadekar }
12941612559SVarun Wadekar 
13041612559SVarun Wadekar /*******************************************************************************
13141612559SVarun Wadekar  * Handler to read the MCE firmware version and check if it is compatible
13241612559SVarun Wadekar  * with interface header the BL3-1 was compiled against
13341612559SVarun Wadekar  ******************************************************************************/
mce_verify_firmware_version(void)13441612559SVarun Wadekar void mce_verify_firmware_version(void)
13541612559SVarun Wadekar {
13641612559SVarun Wadekar 	uint64_t version;
13741612559SVarun Wadekar 	uint32_t major, minor;
13841612559SVarun Wadekar 
13941612559SVarun Wadekar 	/*
14041612559SVarun Wadekar 	 * MCE firmware is not running on simulation platforms.
14141612559SVarun Wadekar 	 */
1422bda9202SSteven Kao 	if (mce_firmware_not_supported()) {
14341612559SVarun Wadekar 		return;
1449808032cSSteven Kao 	}
14541612559SVarun Wadekar 
14641612559SVarun Wadekar 	/*
14741612559SVarun Wadekar 	 * Read the MCE firmware version and extract the major and minor
14841612559SVarun Wadekar 	 * version fields
14941612559SVarun Wadekar 	 */
1509808032cSSteven Kao 	version = nvg_get_version();
1519808032cSSteven Kao 	minor = (uint32_t)version;
1529808032cSSteven Kao 	major = (uint32_t)(version >> 32);
15341612559SVarun Wadekar 
154ac2cc6b0SVarun Wadekar 	INFO("MCE Version - HW=%u:%u, SW=%u:%u\n", major, minor,
155ac2cc6b0SVarun Wadekar 		TEGRA_NVG_VERSION_MAJOR, TEGRA_NVG_VERSION_MINOR);
15641612559SVarun Wadekar 
15741612559SVarun Wadekar 	/*
15841612559SVarun Wadekar 	 * Verify that the MCE firmware version and the interface header
15941612559SVarun Wadekar 	 * match
16041612559SVarun Wadekar 	 */
1619808032cSSteven Kao 	if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
16241612559SVarun Wadekar 		ERROR("MCE major version mismatch\n");
16341612559SVarun Wadekar 		panic();
16441612559SVarun Wadekar 	}
16541612559SVarun Wadekar 
1669808032cSSteven Kao 	if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
16741612559SVarun Wadekar 		ERROR("MCE minor version mismatch\n");
16841612559SVarun Wadekar 		panic();
16941612559SVarun Wadekar 	}
17041612559SVarun Wadekar }
171ac252f95SDilan Lee 
172a3c2c0e9SSteven Kao #if ENABLE_STRICT_CHECKING_MODE
173ac252f95SDilan Lee /*******************************************************************************
174ac252f95SDilan Lee  * Handler to enable the strict checking mode
175ac252f95SDilan Lee  ******************************************************************************/
mce_enable_strict_checking(void)176ac252f95SDilan Lee void mce_enable_strict_checking(void)
177ac252f95SDilan Lee {
178ac252f95SDilan Lee 	uint64_t sctlr = read_sctlr_el3();
179ac252f95SDilan Lee 	int32_t ret = 0;
180ac252f95SDilan Lee 
181ac252f95SDilan Lee 	if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) {
182ac252f95SDilan Lee 		/*
183ac252f95SDilan Lee 		 * Step1: TZ-DRAM and TZRAM should be setup before the MMU is
184ac252f95SDilan Lee 		 * enabled.
185ac252f95SDilan Lee 		 *
186ac252f95SDilan Lee 		 * The common code makes sure that TZDRAM/TZRAM are already
187ac252f95SDilan Lee 		 * enabled before calling into this handler. If this is not the
188ac252f95SDilan Lee 		 * case, the following sequence must be executed before moving
189ac252f95SDilan Lee 		 * on to step 2.
190ac252f95SDilan Lee 		 *
191ac252f95SDilan Lee 		 * tlbialle1is();
192ac252f95SDilan Lee 		 * tlbialle3is();
193ac252f95SDilan Lee 		 * dsbsy();
194ac252f95SDilan Lee 		 * isb();
195ac252f95SDilan Lee 		 *
196ac252f95SDilan Lee 		 */
197ac252f95SDilan Lee 		if ((sctlr & (uint64_t)SCTLR_M_BIT) == (uint64_t)SCTLR_M_BIT) {
198ac252f95SDilan Lee 			tlbialle1is();
199ac252f95SDilan Lee 			tlbialle3is();
200ac252f95SDilan Lee 			dsbsy();
201ac252f95SDilan Lee 			isb();
202ac252f95SDilan Lee 		}
203ac252f95SDilan Lee 
204ac252f95SDilan Lee 		/*
205ac252f95SDilan Lee 		 * Step2: SCF flush - Clean and invalidate caches and clear the
206ac252f95SDilan Lee 		 * TR-bits
207ac252f95SDilan Lee 		 */
208ac252f95SDilan Lee 		ret = nvg_roc_clean_cache_trbits();
209ac252f95SDilan Lee 		if (ret < 0) {
210ac252f95SDilan Lee 			ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
211ac252f95SDilan Lee 				ret);
212ac252f95SDilan Lee 			return;
213ac252f95SDilan Lee 		}
214ac252f95SDilan Lee 
215ac252f95SDilan Lee 		/*
216ac252f95SDilan Lee 		 * Step3: Issue the SECURITY_CONFIG request to MCE to enable
217ac252f95SDilan Lee 		 * strict checking mode.
218ac252f95SDilan Lee 		 */
219ac252f95SDilan Lee 		nvg_enable_strict_checking_mode();
220ac252f95SDilan Lee 	}
221ac252f95SDilan Lee }
mce_verify_strict_checking(void)2225ce05d6bSAnthony Zhou void mce_verify_strict_checking(void)
2235ce05d6bSAnthony Zhou {
2245ce05d6bSAnthony Zhou 	bool is_silicon = tegra_platform_is_silicon();
2255ce05d6bSAnthony Zhou 	bool is_fpga = tegra_platform_is_fpga();
2265ce05d6bSAnthony Zhou 
2275ce05d6bSAnthony Zhou 	if (is_silicon || is_fpga) {
2285ce05d6bSAnthony Zhou 		nvg_verify_strict_checking_mode();
2295ce05d6bSAnthony Zhou 	}
2305ce05d6bSAnthony Zhou }
231a3c2c0e9SSteven Kao #endif
2320789758aSVignesh Radhakrishnan 
2330789758aSVignesh Radhakrishnan /*******************************************************************************
2340789758aSVignesh Radhakrishnan  * Handler to power down the entire system
2350789758aSVignesh Radhakrishnan  ******************************************************************************/
mce_system_shutdown(void)2360789758aSVignesh Radhakrishnan void mce_system_shutdown(void)
2370789758aSVignesh Radhakrishnan {
2380789758aSVignesh Radhakrishnan 	nvg_system_shutdown();
2390789758aSVignesh Radhakrishnan }
2400789758aSVignesh Radhakrishnan 
2410789758aSVignesh Radhakrishnan /*******************************************************************************
2420789758aSVignesh Radhakrishnan  * Handler to reboot the entire system
2430789758aSVignesh Radhakrishnan  ******************************************************************************/
mce_system_reboot(void)2440789758aSVignesh Radhakrishnan void mce_system_reboot(void)
2450789758aSVignesh Radhakrishnan {
2460789758aSVignesh Radhakrishnan 	nvg_system_reboot();
2470789758aSVignesh Radhakrishnan }
2480d851195SVarun Wadekar 
2490d851195SVarun Wadekar /*******************************************************************************
2500d851195SVarun Wadekar  * Handler to clear CCPLEX->HSM correctable RAS error signal.
2510d851195SVarun Wadekar  ******************************************************************************/
mce_clear_hsm_corr_status(void)2520d851195SVarun Wadekar void mce_clear_hsm_corr_status(void)
2530d851195SVarun Wadekar {
2540d851195SVarun Wadekar 	nvg_clear_hsm_corr_status();
2550d851195SVarun Wadekar }
256