1 /***********************license start*********************************** 2 * Copyright (C) 2021-2026 Marvell. 3 * SPDX-License-Identifier: BSD-3-Clause 4 * https://spdx.org/licenses 5 ***********************license end**************************************/ 6 7 /** 8 * @file 9 * 10 * Functions for determining which chip you are running on. 11 * 12 * <hr>$Revision: 49448 $<hr> 13 * @addtogroup chips 14 * @{ 15 */ 16 17 18 /* Flag bits in top byte. The top byte of MIDR_EL1 is defined 19 as ox43, the Cavium implementer code. In this number, bits 20 7,5,4 are defined as zero. We use these bits to signal 21 that revision numbers should be ignored. It isn't ideal 22 that these are in the middle of an already defined field, 23 but this keeps the model numbers as 32 bits */ 24 #define __OM_IGNORE_REVISION 0x80000000 25 #define __OM_IGNORE_MINOR_REVISION 0x20000000 26 #define __OM_IGNORE_MODEL 0x10000000 27 28 /* Variant, or major pass numbers are stored in bits [23:20] */ 29 #define __OM_PASS_SHIFT 8 30 #define __OM_PASS_MASK (0x7 << __OM_PASS_SHIFT) 31 32 /* 33 * Partnum is divied into two fields for our chips. Bits [7:4] are the 34 * processor family. Bits [3:0] are the processor ID 35 */ 36 #define __OM_PARTNUM_MASK 0xff 37 #define __OM_FAMILY_MASK 0xf0 38 39 /* Minor pass numbers are stored in bits [13:11] */ 40 #define __OM_MINOR_SHIFT 11 41 #define __OM_MINOR_MASK (0x7 << __OM_MINOR_SHIFT) 42 43 #define __OM_BUILD(partnum, major, minor) \ 44 ((partnum) | \ 45 (((major) - 1) << __OM_PASS_SHIFT) | \ 46 ((minor) << __OM_MINOR_SHIFT)) 47 48 49 /* Per chip definitions */ 50 #define ODYSSEY_PASS1_0 __OM_BUILD(0xBF, 1, 0) 51 #define ODYSSEY_PASS1_1 __OM_BUILD(0xBF, 1, 1) 52 #define ODYSSEY (ODYSSEY_CN10KA_PASS1_0 | __OM_IGNORE_REVISION) 53 #define ODYSSEY_PASS1_X (ODYSSEY_CN10KA_PASS1_0 | __OM_IGNORE_MINOR_REVISION) 54 55 #define FUS_CACHE0_ADDRESS 0x87e003001000ll 56 57 /** 58 * Return non-zero if the chip matech the passed model. 59 * 60 * @param arg_model One of the ODYSSEY_* constants for chip models and 61 * passes 62 * 63 * @return Non-zero if match 64 */ 65 static inline int ody_is_model(uint32_t arg_model) __attribute__ ((pure, always_inline)); 66 static inline int ody_is_model(uint32_t arg_model) 67 { 68 uint64_t fuse_val = *(volatile uint64_t *)FUS_CACHE0_ADDRESS; 69 uint64_t mask; 70 uint32_t my_model = fuse_val & 0xffffffff; 71 72 if (arg_model & __OM_IGNORE_REVISION) 73 mask = __OM_PARTNUM_MASK; 74 else if (arg_model & __OM_IGNORE_MINOR_REVISION) 75 mask = __OM_PARTNUM_MASK | __OM_PASS_MASK; 76 else 77 mask = __OM_PARTNUM_MASK | __OM_PASS_MASK | __OM_MINOR_MASK; 78 79 return ((arg_model) & mask) == (my_model & mask); 80 } 81 82 /** 83 * Return non-zero if the die is in an alternate package. The 84 * normal is_model() checks will treat alternate package parts 85 * as all the same, where this function can be used to detect 86 * them. The return value is the upper two bits of 87 * MIO_FUS_DAT2[chip_id]. Most alternate packages use bit 6, 88 * which will return 1 here. Parts with a second alternative 89 * will use bit 7, which will return 2. 90 * 91 * @param arg_model One of the constants for chip models and 92 * passes 93 * 94 * @return Non-zero if an alternate package 95 * 0 = Normal package 96 */ 97 extern int ody_is_altpkg(uint32_t arg_model); 98 99 #define ODY_MODEL_MAX_SKU 32 /* Maximum length of SKU is 31 plus zero terminator */ 100 101 /** 102 * Return the SKU string for a chip 103 * 104 * @return Chip's SKU 105 */ 106 extern const char *ody_model_get_sku(void); 107 108 /** @} */ 109