blob: 38802845d2c0bf62454883df1adf88b4c3d5b81c [file] [log] [blame]
Varun Wadekarecd6a5a2018-04-09 17:48:58 -07001/*
2 * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
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>
15#include <memctrl.h>
16#include <common/runtime_svc.h>
17#include <tegra_private.h>
Vignesh Radhakrishnand7a5c252017-05-25 16:27:42 -070018#include <tegra_platform.h>
19#include <stdbool.h>
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070020
Vignesh Radhakrishnand7a5c252017-05-25 16:27:42 -070021extern bool tegra_fake_system_suspend;
22
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070023/*******************************************************************************
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +080024 * Offset to read the ref_clk counter value
25 ******************************************************************************/
26#define REF_CLK_OFFSET 4ULL
27
28/*******************************************************************************
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070029 * Tegra186 SiP SMCs
30 ******************************************************************************/
Varun Wadekar221093b2017-02-22 11:57:15 -080031#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE 0xC2FFFE01
32#define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS 0xC2FFFE02
Vignesh Radhakrishnand7a5c252017-05-25 16:27:42 -070033#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2FFFE03
Varun Wadekar221093b2017-02-22 11:57:15 -080034#define TEGRA_SIP_MCE_CMD_ENTER_CSTATE 0xC2FFFF00
35#define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO 0xC2FFFF01
36#define TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME 0xC2FFFF02
37#define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS 0xC2FFFF03
38#define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS 0xC2FFFF04
39#define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED 0xC2FFFF05
40#define TEGRA_SIP_MCE_CMD_ONLINE_CORE 0xC2FFFF06
41#define TEGRA_SIP_MCE_CMD_CC3_CTRL 0xC2FFFF07
42#define TEGRA_SIP_MCE_CMD_ECHO_DATA 0xC2FFFF08
43#define TEGRA_SIP_MCE_CMD_READ_VERSIONS 0xC2FFFF09
44#define TEGRA_SIP_MCE_CMD_ENUM_FEATURES 0xC2FFFF0A
45#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS 0xC2FFFF0B
46#define TEGRA_SIP_MCE_CMD_ENUM_READ_MCA 0xC2FFFF0C
47#define TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA 0xC2FFFF0D
48#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE 0xC2FFFF0E
49#define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0xC2FFFF0F
50#define TEGRA_SIP_MCE_CMD_ENABLE_LATIC 0xC2FFFF10
51#define TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ 0xC2FFFF11
52#define TEGRA_SIP_MCE_CMD_MISC_CCPLEX 0xC2FFFF12
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070053
54/*******************************************************************************
55 * This function is responsible for handling all T186 SiP calls
56 ******************************************************************************/
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +080057int32_t plat_sip_handler(uint32_t smc_fid,
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070058 uint64_t x1,
59 uint64_t x2,
60 uint64_t x3,
61 uint64_t x4,
Varun Wadekar5c5f78c2017-04-28 18:15:09 -070062 const void *cookie,
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070063 void *handle,
64 uint64_t flags)
65{
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +080066 int32_t mce_ret, ret = -ENOTSUP;
67 uint32_t local_smc_fid = smc_fid;
68 uint64_t local_x1 = x1;
69
70 (void)x4;
71 (void)cookie;
72 (void)flags;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070073
Varun Wadekar221093b2017-02-22 11:57:15 -080074 /*
75 * Convert SMC FID to SMC64 until the linux driver uses
76 * SMC64 encoding.
77 */
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +080078 local_smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
Varun Wadekar221093b2017-02-22 11:57:15 -080079
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +080080 switch (local_smc_fid) {
Varun Wadekarecd6a5a2018-04-09 17:48:58 -070081
82 /*
83 * Micro Coded Engine (MCE) commands reside in the 0x82FFFF00 -
84 * 0x82FFFFFF SiP SMC space
85 */
86 case TEGRA_SIP_MCE_CMD_ENTER_CSTATE:
87 case TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO:
88 case TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME:
89 case TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS:
90 case TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS:
91 case TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED:
92 case TEGRA_SIP_MCE_CMD_CC3_CTRL:
93 case TEGRA_SIP_MCE_CMD_ECHO_DATA:
94 case TEGRA_SIP_MCE_CMD_READ_VERSIONS:
95 case TEGRA_SIP_MCE_CMD_ENUM_FEATURES:
96 case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
97 case TEGRA_SIP_MCE_CMD_ENUM_READ_MCA:
98 case TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA:
99 case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE:
100 case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE:
101 case TEGRA_SIP_MCE_CMD_ENABLE_LATIC:
102 case TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ:
103 case TEGRA_SIP_MCE_CMD_MISC_CCPLEX:
104
105 /* clean up the high bits */
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +0800106 local_smc_fid &= MCE_CMD_MASK;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700107
108 /* execute the command and store the result */
109 mce_ret = mce_command_handler(smc_fid, x1, x2, x3);
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +0800110 write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X0, (uint64_t)mce_ret);
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700111
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +0800112 ret = 0;
113 break;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700114
115 case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
116
117 /* clean up the high bits */
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +0800118 local_x1 = (uint32_t)x1;
119 (void)local_x1;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700120
121 /*
122 * SC8 is a special Tegra186 system state where the CPUs and
123 * DRAM are powered down but the other subsystem is still
124 * alive.
125 */
126
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +0800127 ret = 0;
128 break;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700129
Vignesh Radhakrishnand7a5c252017-05-25 16:27:42 -0700130 case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
131 /*
132 * System suspend mode is set if the platform ATF is running is
133 * VDK and there is a debug SIP call. This mode ensures that the
134 * debug path is excercied, instead of regular code path to suit
135 * the pre-silicon platform needs. These include replacing the
136 * the call to WFI with calls to system suspend exit procedures.
137 */
138 if (tegra_platform_is_virt_dev_kit()) {
139
140 tegra_fake_system_suspend = true;
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +0800141 ret = 0;
Vignesh Radhakrishnand7a5c252017-05-25 16:27:42 -0700142 }
143
144 break;
145
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700146 default:
147 break;
148 }
149
Anthony Zhou8bf6d4e2017-09-20 17:44:43 +0800150 return ret;
Varun Wadekarecd6a5a2018-04-09 17:48:58 -0700151}