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 */ 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 */ 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 */ 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 */ 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 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 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 99 bool tegra_chipid_is_t210_b01(void) 100 { 101 return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U)); 102 } 103 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 */ 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 228 bool tegra_platform_is_silicon(void) 229 { 230 return ((tegra_get_platform() == TEGRA_PLATFORM_SILICON) ? true : false); 231 } 232 233 bool tegra_platform_is_qt(void) 234 { 235 return ((tegra_get_platform() == TEGRA_PLATFORM_QT) ? true : false); 236 } 237 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 246 bool tegra_platform_is_fpga(void) 247 { 248 return ((tegra_get_platform() == TEGRA_PLATFORM_FPGA) ? true : false); 249 } 250 251 bool tegra_platform_is_emulation(void) 252 { 253 return (tegra_get_platform() == TEGRA_PLATFORM_EMULATION); 254 } 255 256 bool tegra_platform_is_unit_fpga(void) 257 { 258 return ((tegra_get_platform() == TEGRA_PLATFORM_UNIT_FPGA) ? true : false); 259 } 260 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 */ 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 */ 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 *****************************************************************************/ 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