• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
3  * Copyright (c) 2020, 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_t132(void)85 bool tegra_chipid_is_t132(void)
86 {
87 	uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
88 
89 	return (chip_id == TEGRA_CHIPID_TEGRA13);
90 }
91 
tegra_chipid_is_t186(void)92 bool tegra_chipid_is_t186(void)
93 {
94 	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
95 
96 	return (chip_id == TEGRA_CHIPID_TEGRA18);
97 }
98 
tegra_chipid_is_t210(void)99 bool tegra_chipid_is_t210(void)
100 {
101 	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
102 
103 	return (chip_id == TEGRA_CHIPID_TEGRA21);
104 }
105 
tegra_chipid_is_t210_b01(void)106 bool tegra_chipid_is_t210_b01(void)
107 {
108 	return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
109 }
110 
tegra_chipid_is_t194(void)111 bool tegra_chipid_is_t194(void)
112 {
113 	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
114 
115 	return (chip_id == TEGRA_CHIPID_TEGRA19);
116 }
117 
118 /*
119  * Read the chip ID value and derive the platform
120  */
tegra_get_platform(void)121 static tegra_platform_t tegra_get_platform(void)
122 {
123 	uint32_t major, minor, pre_si_platform;
124 	tegra_platform_t ret;
125 
126 	/* get the major/minor chip ID values */
127 	major = tegra_get_chipid_major();
128 	minor = tegra_get_chipid_minor();
129 	pre_si_platform = tegra_get_chipid_pre_si_platform();
130 
131 	if (major == 0U) {
132 		/*
133 		 * The minor version number is used by simulation platforms
134 		 */
135 		switch (minor) {
136 		/*
137 		 * Cadence's QuickTurn emulation system is a Solaris-based
138 		 * chip emulation system
139 		 */
140 		case TEGRA_MINOR_QT:
141 		case TEGRA_MINOR_ASIM_QT:
142 			ret = TEGRA_PLATFORM_QT;
143 			break;
144 
145 		/*
146 		 * FPGAs are used during early software/hardware development
147 		 */
148 		case TEGRA_MINOR_FPGA:
149 			ret = TEGRA_PLATFORM_FPGA;
150 			break;
151 		/*
152 		 * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
153 		 * simulation framework.
154 		 */
155 		case TEGRA_MINOR_ASIM_LINSIM:
156 		case TEGRA_MINOR_DSIM_ASIM_LINSIM:
157 			ret = TEGRA_PLATFORM_LINSIM;
158 			break;
159 
160 		/*
161 		 * Unit FPGAs run the actual hardware block IP on the FPGA with
162 		 * the other parts of the system using Linsim.
163 		 */
164 		case TEGRA_MINOR_UNIT_FPGA:
165 			ret = TEGRA_PLATFORM_UNIT_FPGA;
166 			break;
167 		/*
168 		 * The Virtualizer Development Kit (VDK) is the standard chip
169 		 * development from Synopsis.
170 		 */
171 		case TEGRA_MINOR_VIRT_DEV_KIT:
172 			ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
173 			break;
174 
175 		default:
176 			ret = TEGRA_PLATFORM_MAX;
177 			break;
178 		}
179 
180 	} else if (pre_si_platform > 0U) {
181 
182 		switch (pre_si_platform) {
183 		/*
184 		 * Cadence's QuickTurn emulation system is a Solaris-based
185 		 * chip emulation system
186 		 */
187 		case TEGRA_PRE_SI_QT:
188 		case TEGRA_PRE_SI_ASIM_QT:
189 			ret = TEGRA_PLATFORM_QT;
190 			break;
191 
192 		/*
193 		 * FPGAs are used during early software/hardware development
194 		 */
195 		case TEGRA_PRE_SI_FPGA:
196 			ret = TEGRA_PLATFORM_FPGA;
197 			break;
198 		/*
199 		 * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
200 		 * simulation framework.
201 		 */
202 		case TEGRA_PRE_SI_ASIM_LINSIM:
203 		case TEGRA_PRE_SI_DSIM_ASIM_LINSIM:
204 			ret = TEGRA_PLATFORM_LINSIM;
205 			break;
206 
207 		/*
208 		 * Unit FPGAs run the actual hardware block IP on the FPGA with
209 		 * the other parts of the system using Linsim.
210 		 */
211 		case TEGRA_PRE_SI_UNIT_FPGA:
212 			ret = TEGRA_PLATFORM_UNIT_FPGA;
213 			break;
214 		/*
215 		 * The Virtualizer Development Kit (VDK) is the standard chip
216 		 * development from Synopsis.
217 		 */
218 		case TEGRA_PRE_SI_VDK:
219 			ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
220 			break;
221 
222 		default:
223 			ret = TEGRA_PLATFORM_MAX;
224 			break;
225 		}
226 
227 	} else {
228 		/* Actual silicon platforms have a non-zero major version */
229 		ret = TEGRA_PLATFORM_SILICON;
230 	}
231 
232 	return ret;
233 }
234 
tegra_platform_is_silicon(void)235 bool tegra_platform_is_silicon(void)
236 {
237 	return ((tegra_get_platform() == TEGRA_PLATFORM_SILICON) ? true : false);
238 }
239 
tegra_platform_is_qt(void)240 bool tegra_platform_is_qt(void)
241 {
242 	return ((tegra_get_platform() == TEGRA_PLATFORM_QT) ? true : false);
243 }
244 
tegra_platform_is_linsim(void)245 bool tegra_platform_is_linsim(void)
246 {
247 	tegra_platform_t plat = tegra_get_platform();
248 
249 	return (((plat == TEGRA_PLATFORM_LINSIM) ||
250 	       (plat == TEGRA_PLATFORM_UNIT_FPGA)) ? true : false);
251 }
252 
tegra_platform_is_fpga(void)253 bool tegra_platform_is_fpga(void)
254 {
255 	return ((tegra_get_platform() == TEGRA_PLATFORM_FPGA) ? true : false);
256 }
257 
tegra_platform_is_emulation(void)258 bool tegra_platform_is_emulation(void)
259 {
260 	return (tegra_get_platform() == TEGRA_PLATFORM_EMULATION);
261 }
262 
tegra_platform_is_unit_fpga(void)263 bool tegra_platform_is_unit_fpga(void)
264 {
265 	return ((tegra_get_platform() == TEGRA_PLATFORM_UNIT_FPGA) ? true : false);
266 }
267 
tegra_platform_is_virt_dev_kit(void)268 bool tegra_platform_is_virt_dev_kit(void)
269 {
270 	return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false);
271 }
272 
273 /*
274  * This function returns soc version which mainly consist of below fields
275  *
276  *  soc_version[30:24] = JEP-106 continuation code for the SiP
277  *  soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
278  *  soc_version[0:15]  = chip identification
279  */
plat_get_soc_version(void)280 int32_t plat_get_soc_version(void)
281 {
282 	uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
283 	uint32_t manfid = (JEDEC_NVIDIA_BKID << 24) | (JEDEC_NVIDIA_MFID << 16);
284 
285 	return (int32_t)(manfid | (chip_id & 0xFFFF));
286 }
287 
288 /*
289  * This function returns soc revision in below format
290  *
291  *   soc_revision[8:15] = major version number
292  *   soc_revision[0:7]  = minor version number
293  */
plat_get_soc_revision(void)294 int32_t plat_get_soc_revision(void)
295 {
296 	return (int32_t)((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor());
297 }
298 
299 /*****************************************************************************
300  * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
301  *                                  is availabile for the platform or not.
302  * @fid: SMCCC function id
303  *
304  * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
305  * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
306  *****************************************************************************/
plat_is_smccc_feature_available(u_register_t fid)307 int32_t plat_is_smccc_feature_available(u_register_t fid)
308 {
309 	switch (fid) {
310 	case SMCCC_ARCH_SOC_ID:
311 		return SMC_ARCH_CALL_SUCCESS;
312 	default:
313 		return SMC_ARCH_CALL_NOT_SUPPORTED;
314 	}
315 }
316