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