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