2 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
8 #include <arch_helpers.h>
10 #include <bl_common.h>
11 #include <context_mgmt.h>
17 #include <runtime_svc.h>
19 #include <tegra_private.h>
21 extern uint32_t tegra186_system_powerdn_state
;
23 /*******************************************************************************
24 * Offset to read the ref_clk counter value
25 ******************************************************************************/
26 #define REF_CLK_OFFSET 4
28 /*******************************************************************************
30 ******************************************************************************/
31 #define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE 0xC2FFFE01
32 #define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS 0xC2FFFE02
33 #define TEGRA_SIP_MCE_CMD_ENTER_CSTATE 0xC2FFFF00
34 #define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO 0xC2FFFF01
35 #define TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME 0xC2FFFF02
36 #define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS 0xC2FFFF03
37 #define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS 0xC2FFFF04
38 #define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED 0xC2FFFF05
39 #define TEGRA_SIP_MCE_CMD_ONLINE_CORE 0xC2FFFF06
40 #define TEGRA_SIP_MCE_CMD_CC3_CTRL 0xC2FFFF07
41 #define TEGRA_SIP_MCE_CMD_ECHO_DATA 0xC2FFFF08
42 #define TEGRA_SIP_MCE_CMD_READ_VERSIONS 0xC2FFFF09
43 #define TEGRA_SIP_MCE_CMD_ENUM_FEATURES 0xC2FFFF0A
44 #define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS 0xC2FFFF0B
45 #define TEGRA_SIP_MCE_CMD_ENUM_READ_MCA 0xC2FFFF0C
46 #define TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA 0xC2FFFF0D
47 #define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE 0xC2FFFF0E
48 #define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0xC2FFFF0F
49 #define TEGRA_SIP_MCE_CMD_ENABLE_LATIC 0xC2FFFF10
50 #define TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ 0xC2FFFF11
51 #define TEGRA_SIP_MCE_CMD_MISC_CCPLEX 0xC2FFFF12
53 /*******************************************************************************
54 * This function is responsible for handling all T186 SiP calls
55 ******************************************************************************/
56 int plat_sip_handler(uint32_t smc_fid
,
67 uint32_t base
, core_clk_ctr
, ref_clk_ctr
;
69 if (((smc_fid
>> FUNCID_CC_SHIFT
) & FUNCID_CC_MASK
) == SMC_32
) {
70 /* 32-bit function, clear top parameter bits */
78 * Convert SMC FID to SMC64, to support SMC32/SMC64 configurations
80 smc_fid
|= (SMC_64
<< FUNCID_CC_SHIFT
);
84 * Micro Coded Engine (MCE) commands reside in the 0x82FFFF00 -
85 * 0x82FFFFFF SiP SMC space
87 case TEGRA_SIP_MCE_CMD_ENTER_CSTATE
:
88 case TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO
:
89 case TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME
:
90 case TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS
:
91 case TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS
:
92 case TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED
:
93 case TEGRA_SIP_MCE_CMD_CC3_CTRL
:
94 case TEGRA_SIP_MCE_CMD_ECHO_DATA
:
95 case TEGRA_SIP_MCE_CMD_READ_VERSIONS
:
96 case TEGRA_SIP_MCE_CMD_ENUM_FEATURES
:
97 case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS
:
98 case TEGRA_SIP_MCE_CMD_ENUM_READ_MCA
:
99 case TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA
:
100 case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE
:
101 case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE
:
102 case TEGRA_SIP_MCE_CMD_ENABLE_LATIC
:
103 case TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ
:
104 case TEGRA_SIP_MCE_CMD_MISC_CCPLEX
:
106 /* clean up the high bits */
107 smc_fid
&= MCE_CMD_MASK
;
109 /* execute the command and store the result */
110 mce_ret
= mce_command_handler(smc_fid
, x1
, x2
, x3
);
111 write_ctx_reg(get_gpregs_ctx(handle
), CTX_GPREG_X0
,
116 case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE
:
118 /* clean up the high bits */
122 * SC8 is a special Tegra186 system state where the CPUs and
123 * DRAM are powered down but the other subsystem is still
126 if ((x1
== TEGRA_ARI_SYSTEM_SC8
) ||
127 (x1
== TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF
)) {
129 tegra186_system_powerdn_state
= x1
;
131 (uintptr_t)&tegra186_system_powerdn_state
,
132 sizeof(tegra186_system_powerdn_state
));
136 ERROR("%s: unhandled powerdn state (%d)\n", __func__
,
144 * This function ID reads the Activity monitor's core/ref clock
145 * counter values for a core/cluster.
147 * x1 = MPIDR of the target core
148 * x2 = MIDR of the target core
150 case TEGRA_SIP_GET_ACTMON_CLK_COUNTERS
:
152 cpu
= (uint32_t)x1
& MPIDR_CPU_MASK
;
153 impl
= ((uint32_t)x2
>> MIDR_IMPL_SHIFT
) & MIDR_IMPL_MASK
;
155 /* sanity check target CPU number */
156 if (cpu
> PLATFORM_MAX_CPUS_PER_CLUSTER
)
159 /* get the base address for the current CPU */
160 base
= (impl
== DENVER_IMPL
) ? TEGRA_DENVER_ACTMON_CTR_BASE
:
161 TEGRA_ARM_ACTMON_CTR_BASE
;
163 /* read the clock counter values */
164 core_clk_ctr
= mmio_read_32(base
+ (8 * cpu
));
165 ref_clk_ctr
= mmio_read_32(base
+ (8 * cpu
) + REF_CLK_OFFSET
);
167 /* return the counter values as two different parameters */
168 write_ctx_reg(get_gpregs_ctx(handle
), CTX_GPREG_X1
,
169 (uint64_t)core_clk_ctr
);
170 write_ctx_reg(get_gpregs_ctx(handle
), CTX_GPREG_X2
,
171 (uint64_t)ref_clk_ctr
);