1 /*
2 * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include <arch_helpers.h>
9 #include <assert.h>
10 #include <lib/mmio.h>
11 #include <lib/smccc.h>
12 #include <services/arm_arch_svc.h>
13 #include <tegra_def.h>
14 #include <tegra_platform.h>
15 #include <tegra_private.h>
16
17 /*******************************************************************************
18 * Tegra platforms
19 ******************************************************************************/
20 typedef enum tegra_platform {
21 TEGRA_PLATFORM_SILICON = 0U,
22 TEGRA_PLATFORM_QT,
23 TEGRA_PLATFORM_FPGA,
24 TEGRA_PLATFORM_EMULATION,
25 TEGRA_PLATFORM_LINSIM,
26 TEGRA_PLATFORM_UNIT_FPGA,
27 TEGRA_PLATFORM_VIRT_DEV_KIT,
28 TEGRA_PLATFORM_MAX,
29 } tegra_platform_t;
30
31 /*******************************************************************************
32 * Tegra macros defining all the SoC minor versions
33 ******************************************************************************/
34 #define TEGRA_MINOR_QT U(0)
35 #define TEGRA_MINOR_FPGA U(1)
36 #define TEGRA_MINOR_ASIM_QT U(2)
37 #define TEGRA_MINOR_ASIM_LINSIM U(3)
38 #define TEGRA_MINOR_DSIM_ASIM_LINSIM U(4)
39 #define TEGRA_MINOR_UNIT_FPGA U(5)
40 #define TEGRA_MINOR_VIRT_DEV_KIT U(6)
41
42 /*******************************************************************************
43 * Tegra macros defining all the SoC pre_si_platform
44 ******************************************************************************/
45 #define TEGRA_PRE_SI_QT U(1)
46 #define TEGRA_PRE_SI_FPGA U(2)
47 #define TEGRA_PRE_SI_UNIT_FPGA U(3)
48 #define TEGRA_PRE_SI_ASIM_QT U(4)
49 #define TEGRA_PRE_SI_ASIM_LINSIM U(5)
50 #define TEGRA_PRE_SI_DSIM_ASIM_LINSIM U(6)
51 #define TEGRA_PRE_SI_VDK U(8)
52
53 /*
54 * Read the chip ID value
55 */
tegra_get_chipid(void)56 static uint32_t tegra_get_chipid(void)
57 {
58 return mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET);
59 }
60
61 /*
62 * Read the chip's major version from chip ID value
63 */
tegra_get_chipid_major(void)64 uint32_t tegra_get_chipid_major(void)
65 {
66 return (tegra_get_chipid() >> MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK;
67 }
68
69 /*
70 * Read the chip's minor version from the chip ID value
71 */
tegra_get_chipid_minor(void)72 uint32_t tegra_get_chipid_minor(void)
73 {
74 return (tegra_get_chipid() >> MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK;
75 }
76
77 /*
78 * Read the chip's pre_si_platform valus from the chip ID value
79 */
tegra_get_chipid_pre_si_platform(void)80 static uint32_t tegra_get_chipid_pre_si_platform(void)
81 {
82 return (tegra_get_chipid() >> PRE_SI_PLATFORM_SHIFT) & PRE_SI_PLATFORM_MASK;
83 }
84
tegra_chipid_is_t186(void)85 bool tegra_chipid_is_t186(void)
86 {
87 uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
88
89 return (chip_id == TEGRA_CHIPID_TEGRA18);
90 }
91
tegra_chipid_is_t210(void)92 bool tegra_chipid_is_t210(void)
93 {
94 uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
95
96 return (chip_id == TEGRA_CHIPID_TEGRA21);
97 }
98
tegra_chipid_is_t210_b01(void)99 bool tegra_chipid_is_t210_b01(void)
100 {
101 return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
102 }
103
tegra_chipid_is_t194(void)104 bool tegra_chipid_is_t194(void)
105 {
106 uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
107
108 return (chip_id == TEGRA_CHIPID_TEGRA19);
109 }
110
111 /*
112 * Read the chip ID value and derive the platform
113 */
tegra_get_platform(void)114 static tegra_platform_t tegra_get_platform(void)
115 {
116 uint32_t major, minor, pre_si_platform;
117 tegra_platform_t ret;
118
119 /* get the major/minor chip ID values */
120 major = tegra_get_chipid_major();
121 minor = tegra_get_chipid_minor();
122 pre_si_platform = tegra_get_chipid_pre_si_platform();
123
124 if (major == 0U) {
125 /*
126 * The minor version number is used by simulation platforms
127 */
128 switch (minor) {
129 /*
130 * Cadence's QuickTurn emulation system is a Solaris-based
131 * chip emulation system
132 */
133 case TEGRA_MINOR_QT:
134 case TEGRA_MINOR_ASIM_QT:
135 ret = TEGRA_PLATFORM_QT;
136 break;
137
138 /*
139 * FPGAs are used during early software/hardware development
140 */
141 case TEGRA_MINOR_FPGA:
142 ret = TEGRA_PLATFORM_FPGA;
143 break;
144 /*
145 * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
146 * simulation framework.
147 */
148 case TEGRA_MINOR_ASIM_LINSIM:
149 case TEGRA_MINOR_DSIM_ASIM_LINSIM:
150 ret = TEGRA_PLATFORM_LINSIM;
151 break;
152
153 /*
154 * Unit FPGAs run the actual hardware block IP on the FPGA with
155 * the other parts of the system using Linsim.
156 */
157 case TEGRA_MINOR_UNIT_FPGA:
158 ret = TEGRA_PLATFORM_UNIT_FPGA;
159 break;
160 /*
161 * The Virtualizer Development Kit (VDK) is the standard chip
162 * development from Synopsis.
163 */
164 case TEGRA_MINOR_VIRT_DEV_KIT:
165 ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
166 break;
167
168 default:
169 ret = TEGRA_PLATFORM_MAX;
170 break;
171 }
172
173 } else if (pre_si_platform > 0U) {
174
175 switch (pre_si_platform) {
176 /*
177 * Cadence's QuickTurn emulation system is a Solaris-based
178 * chip emulation system
179 */
180 case TEGRA_PRE_SI_QT:
181 case TEGRA_PRE_SI_ASIM_QT:
182 ret = TEGRA_PLATFORM_QT;
183 break;
184
185 /*
186 * FPGAs are used during early software/hardware development
187 */
188 case TEGRA_PRE_SI_FPGA:
189 ret = TEGRA_PLATFORM_FPGA;
190 break;
191 /*
192 * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
193 * simulation framework.
194 */
195 case TEGRA_PRE_SI_ASIM_LINSIM:
196 case TEGRA_PRE_SI_DSIM_ASIM_LINSIM:
197 ret = TEGRA_PLATFORM_LINSIM;
198 break;
199
200 /*
201 * Unit FPGAs run the actual hardware block IP on the FPGA with
202 * the other parts of the system using Linsim.
203 */
204 case TEGRA_PRE_SI_UNIT_FPGA:
205 ret = TEGRA_PLATFORM_UNIT_FPGA;
206 break;
207 /*
208 * The Virtualizer Development Kit (VDK) is the standard chip
209 * development from Synopsis.
210 */
211 case TEGRA_PRE_SI_VDK:
212 ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
213 break;
214
215 default:
216 ret = TEGRA_PLATFORM_MAX;
217 break;
218 }
219
220 } else {
221 /* Actual silicon platforms have a non-zero major version */
222 ret = TEGRA_PLATFORM_SILICON;
223 }
224
225 return ret;
226 }
227
tegra_platform_is_silicon(void)228 bool tegra_platform_is_silicon(void)
229 {
230 return ((tegra_get_platform() == TEGRA_PLATFORM_SILICON) ? true : false);
231 }
232
tegra_platform_is_qt(void)233 bool tegra_platform_is_qt(void)
234 {
235 return ((tegra_get_platform() == TEGRA_PLATFORM_QT) ? true : false);
236 }
237
tegra_platform_is_linsim(void)238 bool tegra_platform_is_linsim(void)
239 {
240 tegra_platform_t plat = tegra_get_platform();
241
242 return (((plat == TEGRA_PLATFORM_LINSIM) ||
243 (plat == TEGRA_PLATFORM_UNIT_FPGA)) ? true : false);
244 }
245
tegra_platform_is_fpga(void)246 bool tegra_platform_is_fpga(void)
247 {
248 return ((tegra_get_platform() == TEGRA_PLATFORM_FPGA) ? true : false);
249 }
250
tegra_platform_is_emulation(void)251 bool tegra_platform_is_emulation(void)
252 {
253 return (tegra_get_platform() == TEGRA_PLATFORM_EMULATION);
254 }
255
tegra_platform_is_unit_fpga(void)256 bool tegra_platform_is_unit_fpga(void)
257 {
258 return ((tegra_get_platform() == TEGRA_PLATFORM_UNIT_FPGA) ? true : false);
259 }
260
tegra_platform_is_virt_dev_kit(void)261 bool tegra_platform_is_virt_dev_kit(void)
262 {
263 return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false);
264 }
265
266 /*
267 * This function returns soc version which mainly consist of below fields
268 *
269 * soc_version[30:24] = JEP-106 continuation code for the SiP
270 * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
271 * soc_version[0:15] = chip identification
272 */
plat_get_soc_version(void)273 int32_t plat_get_soc_version(void)
274 {
275 uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
276 uint32_t major_rev = tegra_get_chipid_major();
277 uint32_t manfid = SOC_ID_SET_JEP_106(JEDEC_NVIDIA_BKID, JEDEC_NVIDIA_MFID);
278
279 return (int32_t)(manfid | (((chip_id << MAJOR_VERSION_SHIFT) | major_rev) &
280 SOC_ID_IMPL_DEF_MASK));
281 }
282
283 /*
284 * This function returns soc revision in below format
285 *
286 * soc_revision[8:15] = major version number
287 * soc_revision[0:7] = minor version number
288 */
plat_get_soc_revision(void)289 int32_t plat_get_soc_revision(void)
290 {
291 return (int32_t)(((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor()) &
292 SOC_ID_REV_MASK);
293 }
294
295 /*****************************************************************************
296 * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
297 * is availabile for the platform or not.
298 * @fid: SMCCC function id
299 *
300 * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
301 * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
302 *****************************************************************************/
plat_is_smccc_feature_available(u_register_t fid)303 int32_t plat_is_smccc_feature_available(u_register_t fid)
304 {
305 switch (fid) {
306 case SMCCC_ARCH_SOC_ID:
307 return SMC_ARCH_CALL_SUCCESS;
308 default:
309 return SMC_ARCH_CALL_NOT_SUPPORTED;
310 }
311 }
312