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