xref: /arm-trusted-firmware/plat/nvidia/tegra/soc/t194/plat_sip_calls.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <arch.h>
8*91f16700Schasinglulu #include <arch_helpers.h>
9*91f16700Schasinglulu #include <assert.h>
10*91f16700Schasinglulu #include <common/bl_common.h>
11*91f16700Schasinglulu #include <lib/el3_runtime/context_mgmt.h>
12*91f16700Schasinglulu #include <common/debug.h>
13*91f16700Schasinglulu #include <errno.h>
14*91f16700Schasinglulu #include <mce.h>
15*91f16700Schasinglulu #include <mce_private.h>
16*91f16700Schasinglulu #include <memctrl.h>
17*91f16700Schasinglulu #include <common/runtime_svc.h>
18*91f16700Schasinglulu #include <tegra_private.h>
19*91f16700Schasinglulu #include <tegra_platform.h>
20*91f16700Schasinglulu #include <smmu.h>
21*91f16700Schasinglulu #include <stdbool.h>
22*91f16700Schasinglulu 
23*91f16700Schasinglulu /*******************************************************************************
24*91f16700Schasinglulu  * Tegra194 SiP SMCs
25*91f16700Schasinglulu  ******************************************************************************/
26*91f16700Schasinglulu #define TEGRA_SIP_GET_SMMU_PER		0xC200FF00U
27*91f16700Schasinglulu #define TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS	0xC200FF01U
28*91f16700Schasinglulu 
29*91f16700Schasinglulu /*******************************************************************************
30*91f16700Schasinglulu  * This function is responsible for handling all T194 SiP calls
31*91f16700Schasinglulu  ******************************************************************************/
32*91f16700Schasinglulu int32_t plat_sip_handler(uint32_t smc_fid,
33*91f16700Schasinglulu 		     uint64_t x1,
34*91f16700Schasinglulu 		     uint64_t x2,
35*91f16700Schasinglulu 		     uint64_t x3,
36*91f16700Schasinglulu 		     uint64_t x4,
37*91f16700Schasinglulu 		     const void *cookie,
38*91f16700Schasinglulu 		     void *handle,
39*91f16700Schasinglulu 		     uint64_t flags)
40*91f16700Schasinglulu {
41*91f16700Schasinglulu 	int32_t ret = 0;
42*91f16700Schasinglulu 	uint32_t i, smmu_per[6] = {0};
43*91f16700Schasinglulu 	uint32_t num_smmu_devices = plat_get_num_smmu_devices();
44*91f16700Schasinglulu 	uint64_t per[3] = {0ULL};
45*91f16700Schasinglulu 
46*91f16700Schasinglulu 	(void)x1;
47*91f16700Schasinglulu 	(void)x4;
48*91f16700Schasinglulu 	(void)cookie;
49*91f16700Schasinglulu 	(void)flags;
50*91f16700Schasinglulu 
51*91f16700Schasinglulu 	switch (smc_fid) {
52*91f16700Schasinglulu 	case TEGRA_SIP_GET_SMMU_PER:
53*91f16700Schasinglulu 
54*91f16700Schasinglulu 		/* make sure we dont go past the array length */
55*91f16700Schasinglulu 		assert(num_smmu_devices <= ARRAY_SIZE(smmu_per));
56*91f16700Schasinglulu 
57*91f16700Schasinglulu 		/* read all supported SMMU_PER records */
58*91f16700Schasinglulu 		for (i = 0U; i < num_smmu_devices; i++) {
59*91f16700Schasinglulu 			smmu_per[i] = tegra_smmu_read_32(i, SMMU_GSR0_PER);
60*91f16700Schasinglulu 		}
61*91f16700Schasinglulu 
62*91f16700Schasinglulu 		/* pack results into 3 64bit variables. */
63*91f16700Schasinglulu 		per[0] = smmu_per[0] | ((uint64_t)smmu_per[1] << 32U);
64*91f16700Schasinglulu 		per[1] = smmu_per[2] | ((uint64_t)smmu_per[3] << 32U);
65*91f16700Schasinglulu 		per[2] = smmu_per[4] | ((uint64_t)smmu_per[5] << 32U);
66*91f16700Schasinglulu 
67*91f16700Schasinglulu 		/* provide the results via X1-X3 CPU registers */
68*91f16700Schasinglulu 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, per[0]);
69*91f16700Schasinglulu 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, per[1]);
70*91f16700Schasinglulu 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X3, per[2]);
71*91f16700Schasinglulu 
72*91f16700Schasinglulu 		break;
73*91f16700Schasinglulu 
74*91f16700Schasinglulu #if ENABLE_FEAT_RAS
75*91f16700Schasinglulu 	case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
76*91f16700Schasinglulu 	{
77*91f16700Schasinglulu 		/*
78*91f16700Schasinglulu 		 * clear all RAS error records for corrected errors at first.
79*91f16700Schasinglulu 		 * x1 shall be 0 for first SMC call after FHI is asserted.
80*91f16700Schasinglulu 		 * */
81*91f16700Schasinglulu 		uint64_t local_x1 = x1;
82*91f16700Schasinglulu 
83*91f16700Schasinglulu 		tegra194_ras_corrected_err_clear(&local_x1);
84*91f16700Schasinglulu 		if (local_x1 == 0ULL) {
85*91f16700Schasinglulu 			/* clear HSM corrected error status after all corrected
86*91f16700Schasinglulu 			 * RAS errors are cleared.
87*91f16700Schasinglulu 			 */
88*91f16700Schasinglulu 			mce_clear_hsm_corr_status();
89*91f16700Schasinglulu 		}
90*91f16700Schasinglulu 
91*91f16700Schasinglulu 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, local_x1);
92*91f16700Schasinglulu 
93*91f16700Schasinglulu 		break;
94*91f16700Schasinglulu 	}
95*91f16700Schasinglulu #endif
96*91f16700Schasinglulu 
97*91f16700Schasinglulu 	default:
98*91f16700Schasinglulu 		ret = -ENOTSUP;
99*91f16700Schasinglulu 		break;
100*91f16700Schasinglulu 	}
101*91f16700Schasinglulu 
102*91f16700Schasinglulu 	return ret;
103*91f16700Schasinglulu }
104