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