xref: /rk3399_ARM-atf/include/plat/marvell/odyssey/csr/ody-model.h (revision 55877c6341b29c416ed88b705dca1a6343db194f)
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