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