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