xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t194/plat_sip_calls.c (revision 6f802c44e9c2b926cf887a03e596b4ada841d3a5)
141612559SVarun Wadekar /*
28ad1e475SVarun Wadekar  * 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 <lib/el3_runtime/context_mgmt.h>
1241612559SVarun Wadekar #include <common/debug.h>
1341612559SVarun Wadekar #include <errno.h>
1441612559SVarun Wadekar #include <mce.h>
150d851195SVarun Wadekar #include <mce_private.h>
1641612559SVarun Wadekar #include <memctrl.h>
1741612559SVarun Wadekar #include <common/runtime_svc.h>
1841612559SVarun Wadekar #include <tegra_private.h>
19b0a86254SVignesh Radhakrishnan #include <tegra_platform.h>
208f0e22d5SVarun Wadekar #include <smmu.h>
21b0a86254SVignesh Radhakrishnan #include <stdbool.h>
2241612559SVarun Wadekar 
2341612559SVarun Wadekar /*******************************************************************************
241c62509eSVarun Wadekar  * Tegra194 SiP SMCs
2541612559SVarun Wadekar  ******************************************************************************/
268f0e22d5SVarun Wadekar #define TEGRA_SIP_GET_SMMU_PER		0xC200FF00U
270d851195SVarun Wadekar #define TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS	0xC200FF01U
2841612559SVarun Wadekar 
2941612559SVarun Wadekar /*******************************************************************************
301c62509eSVarun Wadekar  * This function is responsible for handling all T194 SiP calls
3141612559SVarun Wadekar  ******************************************************************************/
plat_sip_handler(uint32_t smc_fid,uint64_t x1,uint64_t x2,uint64_t x3,uint64_t x4,const void * cookie,void * handle,uint64_t flags)32b6533b56SAnthony Zhou int32_t plat_sip_handler(uint32_t smc_fid,
3341612559SVarun Wadekar 		     uint64_t x1,
3441612559SVarun Wadekar 		     uint64_t x2,
3541612559SVarun Wadekar 		     uint64_t x3,
3641612559SVarun Wadekar 		     uint64_t x4,
372e446f50SVarun Wadekar 		     const void *cookie,
3841612559SVarun Wadekar 		     void *handle,
3941612559SVarun Wadekar 		     uint64_t flags)
4041612559SVarun Wadekar {
418f0e22d5SVarun Wadekar 	int32_t ret = 0;
428f0e22d5SVarun Wadekar 	uint32_t i, smmu_per[6] = {0};
438f0e22d5SVarun Wadekar 	uint32_t num_smmu_devices = plat_get_num_smmu_devices();
448f0e22d5SVarun Wadekar 	uint64_t per[3] = {0ULL};
45b6533b56SAnthony Zhou 
4608c085dcSVarun Wadekar 	(void)x1;
47b6533b56SAnthony Zhou 	(void)x4;
48b6533b56SAnthony Zhou 	(void)cookie;
49b6533b56SAnthony Zhou 	(void)flags;
5041612559SVarun Wadekar 
518f0e22d5SVarun Wadekar 	switch (smc_fid) {
528f0e22d5SVarun Wadekar 	case TEGRA_SIP_GET_SMMU_PER:
538f0e22d5SVarun Wadekar 
548f0e22d5SVarun Wadekar 		/* make sure we dont go past the array length */
558f0e22d5SVarun Wadekar 		assert(num_smmu_devices <= ARRAY_SIZE(smmu_per));
568f0e22d5SVarun Wadekar 
578f0e22d5SVarun Wadekar 		/* read all supported SMMU_PER records */
588f0e22d5SVarun Wadekar 		for (i = 0U; i < num_smmu_devices; i++) {
598f0e22d5SVarun Wadekar 			smmu_per[i] = tegra_smmu_read_32(i, SMMU_GSR0_PER);
608f0e22d5SVarun Wadekar 		}
618f0e22d5SVarun Wadekar 
628f0e22d5SVarun Wadekar 		/* pack results into 3 64bit variables. */
638f0e22d5SVarun Wadekar 		per[0] = smmu_per[0] | ((uint64_t)smmu_per[1] << 32U);
648f0e22d5SVarun Wadekar 		per[1] = smmu_per[2] | ((uint64_t)smmu_per[3] << 32U);
658f0e22d5SVarun Wadekar 		per[2] = smmu_per[4] | ((uint64_t)smmu_per[5] << 32U);
668f0e22d5SVarun Wadekar 
678f0e22d5SVarun Wadekar 		/* provide the results via X1-X3 CPU registers */
688f0e22d5SVarun Wadekar 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, per[0]);
698f0e22d5SVarun Wadekar 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, per[1]);
708f0e22d5SVarun Wadekar 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X3, per[2]);
718f0e22d5SVarun Wadekar 
728f0e22d5SVarun Wadekar 		break;
738f0e22d5SVarun Wadekar 
74*f87e54f7SManish Pandey #if ENABLE_FEAT_RAS
750d851195SVarun Wadekar 	case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
76ebd720d0SDavid Pu 	{
77ebd720d0SDavid Pu 		/*
78ebd720d0SDavid Pu 		 * clear all RAS error records for corrected errors at first.
79ebd720d0SDavid Pu 		 * x1 shall be 0 for first SMC call after FHI is asserted.
80ebd720d0SDavid Pu 		 * */
81ebd720d0SDavid Pu 		uint64_t local_x1 = x1;
82ebd720d0SDavid Pu 
83ebd720d0SDavid Pu 		tegra194_ras_corrected_err_clear(&local_x1);
84ebd720d0SDavid Pu 		if (local_x1 == 0ULL) {
85ebd720d0SDavid Pu 			/* clear HSM corrected error status after all corrected
86ebd720d0SDavid Pu 			 * RAS errors are cleared.
87ebd720d0SDavid Pu 			 */
880d851195SVarun Wadekar 			mce_clear_hsm_corr_status();
89ebd720d0SDavid Pu 		}
90ebd720d0SDavid Pu 
91ebd720d0SDavid Pu 		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, local_x1);
92ebd720d0SDavid Pu 
930d851195SVarun Wadekar 		break;
94ebd720d0SDavid Pu 	}
950d851195SVarun Wadekar #endif
960d851195SVarun Wadekar 
978f0e22d5SVarun Wadekar 	default:
988f0e22d5SVarun Wadekar 		ret = -ENOTSUP;
998f0e22d5SVarun Wadekar 		break;
1008f0e22d5SVarun Wadekar 	}
1018f0e22d5SVarun Wadekar 
102b6533b56SAnthony Zhou 	return ret;
10341612559SVarun Wadekar }
104