1 /* 2 * Copyright (c) 2016-2021, 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 */ 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_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 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 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 106 bool tegra_chipid_is_t210_b01(void) 107 { 108 return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U)); 109 } 110 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 */ 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 235 bool tegra_platform_is_silicon(void) 236 { 237 return ((tegra_get_platform() == TEGRA_PLATFORM_SILICON) ? true : false); 238 } 239 240 bool tegra_platform_is_qt(void) 241 { 242 return ((tegra_get_platform() == TEGRA_PLATFORM_QT) ? true : false); 243 } 244 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 253 bool tegra_platform_is_fpga(void) 254 { 255 return ((tegra_get_platform() == TEGRA_PLATFORM_FPGA) ? true : false); 256 } 257 258 bool tegra_platform_is_emulation(void) 259 { 260 return (tegra_get_platform() == TEGRA_PLATFORM_EMULATION); 261 } 262 263 bool tegra_platform_is_unit_fpga(void) 264 { 265 return ((tegra_get_platform() == TEGRA_PLATFORM_UNIT_FPGA) ? true : false); 266 } 267 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 */ 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 = SOC_ID_SET_JEP_106(JEDEC_NVIDIA_BKID, JEDEC_NVIDIA_MFID); 284 285 return (int32_t)(manfid | (chip_id & SOC_ID_IMPL_DEF_MASK)); 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 */ 294 int32_t plat_get_soc_revision(void) 295 { 296 return (int32_t)(((tegra_get_chipid_major() << 8) | tegra_get_chipid_minor()) & 297 SOC_ID_REV_MASK); 298 } 299 300 /***************************************************************************** 301 * plat_is_smccc_feature_available() - This function checks whether SMCCC feature 302 * is availabile for the platform or not. 303 * @fid: SMCCC function id 304 * 305 * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and 306 * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. 307 *****************************************************************************/ 308 int32_t plat_is_smccc_feature_available(u_register_t fid) 309 { 310 switch (fid) { 311 case SMCCC_ARCH_SOC_ID: 312 return SMC_ARCH_CALL_SUCCESS; 313 default: 314 return SMC_ARCH_CALL_NOT_SUPPORTED; 315 } 316 } 317