9164a4cfd6497d67ef5cfc2d721a44136ec07373
[platform/kernel/u-boot.git] / arch / mips / mach-octeon / include / mach / octeon-model.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020 Marvell International Ltd.
4  */
5
6 #ifndef __OCTEON_MODEL_H__
7 #define __OCTEON_MODEL_H__
8
9 /*
10  * NOTE: These must match what is checked in common-config.mk
11  * Defines to represent the different versions of Octeon.
12  *
13  * IMPORTANT: When the default pass is updated for an Octeon Model,
14  * the corresponding change must also be made in the oct-sim script.
15  *
16  * The defines below should be used with the OCTEON_IS_MODEL() macro to
17  * determine what model of chip the software is running on.  Models ending
18  * in 'XX' match multiple models (families), while specific models match only
19  * that model.  If a pass (revision) is specified, then only that revision
20  * will be matched.  Care should be taken when checking for both specific
21  * models and families that the specific models are checked for first.
22  * While these defines are similar to the processor ID, they are not intended
23  * to be used by anything other that the OCTEON_IS_MODEL framework, and
24  * the values are subject to change at anytime without notice.
25  *
26  * NOTE: only the OCTEON_IS_MODEL() macro/function and the OCTEON_CN* macros
27  * should be used outside of this file.  All other macros are for internal
28  * use only, and may change without notice.
29  */
30
31 #include <asm/mipsregs.h>
32
33 #define OCTEON_FAMILY_MASK      0x00ffff00
34 #define OCTEON_PRID_MASK        0x00ffffff
35
36 /* Flag bits in top byte */
37 /* Ignores revision in model checks */
38 #define OM_IGNORE_REVISION        0x01000000
39 /* Check submodels */
40 #define OM_CHECK_SUBMODEL         0x02000000
41 /* Match all models previous than the one specified */
42 #define OM_MATCH_PREVIOUS_MODELS  0x04000000
43 /* Ignores the minor revison on newer parts */
44 #define OM_IGNORE_MINOR_REVISION  0x08000000
45 #define OM_FLAG_MASK              0xff000000
46
47 /* Match all cn5XXX Octeon models. */
48 #define OM_MATCH_5XXX_FAMILY_MODELS     0x20000000
49 /* Match all cn6XXX Octeon models. */
50 #define OM_MATCH_6XXX_FAMILY_MODELS     0x40000000
51 /* Match all cnf7XXX Octeon models. */
52 #define OM_MATCH_F7XXX_FAMILY_MODELS    0x80000000
53 /* Match all cn7XXX Octeon models. */
54 #define OM_MATCH_7XXX_FAMILY_MODELS     0x10000000
55 #define OM_MATCH_FAMILY_MODELS          (OM_MATCH_5XXX_FAMILY_MODELS | \
56                                          OM_MATCH_6XXX_FAMILY_MODELS |  \
57                                          OM_MATCH_F7XXX_FAMILY_MODELS | \
58                                          OM_MATCH_7XXX_FAMILY_MODELS)
59
60 /*
61  * CN7XXX models with new revision encoding
62  */
63
64 #define OCTEON_CNF75XX_PASS1_0  0x000d9800
65 #define OCTEON_CNF75XX_PASS1_2  0x000d9802
66 #define OCTEON_CNF75XX_PASS1_3  0x000d9803
67 #define OCTEON_CNF75XX          (OCTEON_CNF75XX_PASS1_0 | OM_IGNORE_REVISION)
68 #define OCTEON_CNF75XX_PASS1_X                                  \
69         (OCTEON_CNF75XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
70
71 #define OCTEON_CN73XX_PASS1_0   0x000d9700
72 #define OCTEON_CN73XX_PASS1_1   0x000d9701
73 #define OCTEON_CN73XX_PASS1_2   0x000d9702
74 #define OCTEON_CN73XX_PASS1_3   0x000d9703
75 #define OCTEON_CN73XX           (OCTEON_CN73XX_PASS1_0 | OM_IGNORE_REVISION)
76 #define OCTEON_CN73XX_PASS1_X                                   \
77         (OCTEON_CN73XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
78
79 #define OCTEON_CN72XX           OCTEON_CN73XX
80
81 #define OCTEON_CN23XX           OCTEON_CN73XX
82 #define OCTEON_CN23XX_PASS1_2   OCTEON_CN73XX_PASS1_2
83 #define OCTEON_CN23XX_PASS1_3   OCTEON_CN73XX_PASS1_3
84
85 #define OCTEON_CN70XX_PASS1_0   0x000d9600
86 #define OCTEON_CN70XX_PASS1_1   0x000d9601
87 #define OCTEON_CN70XX_PASS1_2   0x000d9602
88
89 #define OCTEON_CN70XX_PASS2_0   0x000d9608
90
91 #define OCTEON_CN70XX           (OCTEON_CN70XX_PASS1_0 | OM_IGNORE_REVISION)
92 #define OCTEON_CN70XX_PASS1_X                                   \
93         (OCTEON_CN70XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
94 #define OCTEON_CN70XX_PASS2_X                                   \
95         (OCTEON_CN70XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
96
97 #define OCTEON_CN71XX           OCTEON_CN70XX
98
99 #define OCTEON_CN78XX_PASS1_0   0x000d9500
100 #define OCTEON_CN78XX_PASS1_1   0x000d9501
101 #define OCTEON_CN78XX_PASS2_0   0x000d9508
102
103 #define OCTEON_CN78XX           (OCTEON_CN78XX_PASS2_0 | OM_IGNORE_REVISION)
104 #define OCTEON_CN78XX_PASS1_X                                   \
105         (OCTEON_CN78XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
106 #define OCTEON_CN78XX_PASS2_X                                   \
107         (OCTEON_CN78XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
108
109 #define OCTEON_CN76XX             (0x000d9540 | OM_CHECK_SUBMODEL)
110
111 /*
112  * CNF7XXX models with new revision encoding
113  */
114 #define OCTEON_CNF71XX_PASS1_0  0x000d9400
115 #define OCTEON_CNF71XX_PASS1_1  0x000d9401
116
117 #define OCTEON_CNF71XX          (OCTEON_CNF71XX_PASS1_0 | OM_IGNORE_REVISION)
118 #define OCTEON_CNF71XX_PASS1_X                                  \
119         (OCTEON_CNF71XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
120
121 /*
122  * CN6XXX models with new revision encoding
123  */
124 #define OCTEON_CN68XX_PASS1_0   0x000d9100
125 #define OCTEON_CN68XX_PASS1_1   0x000d9101
126 #define OCTEON_CN68XX_PASS2_0   0x000d9108
127 #define OCTEON_CN68XX_PASS2_1   0x000d9109
128 #define OCTEON_CN68XX_PASS2_2   0x000d910a
129
130 #define OCTEON_CN68XX           (OCTEON_CN68XX_PASS2_0 | OM_IGNORE_REVISION)
131 #define OCTEON_CN68XX_PASS1_X                                   \
132         (OCTEON_CN68XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
133 #define OCTEON_CN68XX_PASS2_X                                   \
134         (OCTEON_CN68XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
135
136 #define OCTEON_CN68XX_PASS1     OCTEON_CN68XX_PASS1_X
137 #define OCTEON_CN68XX_PASS2     OCTEON_CN68XX_PASS2_X
138
139 #define OCTEON_CN66XX_PASS1_0   0x000d9200
140 #define OCTEON_CN66XX_PASS1_2   0x000d9202
141
142 #define OCTEON_CN66XX           (OCTEON_CN66XX_PASS1_0 | OM_IGNORE_REVISION)
143 #define OCTEON_CN66XX_PASS1_X                                   \
144         (OCTEON_CN66XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
145
146 #define OCTEON_CN63XX_PASS1_0   0x000d9000
147 #define OCTEON_CN63XX_PASS1_1   0x000d9001
148 #define OCTEON_CN63XX_PASS1_2   0x000d9002
149 #define OCTEON_CN63XX_PASS2_0   0x000d9008
150 #define OCTEON_CN63XX_PASS2_1   0x000d9009
151 #define OCTEON_CN63XX_PASS2_2   0x000d900a
152
153 #define OCTEON_CN63XX           (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_REVISION)
154 #define OCTEON_CN63XX_PASS1_X                                   \
155         (OCTEON_CN63XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
156 #define OCTEON_CN63XX_PASS2_X                                   \
157         (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
158
159 /* CN62XX is same as CN63XX with 1 MB cache */
160 #define OCTEON_CN62XX           OCTEON_CN63XX
161
162 #define OCTEON_CN61XX_PASS1_0   0x000d9300
163 #define OCTEON_CN61XX_PASS1_1   0x000d9301
164
165 #define OCTEON_CN61XX           (OCTEON_CN61XX_PASS1_0 | OM_IGNORE_REVISION)
166 #define OCTEON_CN61XX_PASS1_X                                   \
167         (OCTEON_CN61XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
168
169 /* CN60XX is same as CN61XX with 512 KB cache */
170 #define OCTEON_CN60XX           OCTEON_CN61XX
171
172 /* This matches the complete family of CN3xxx CPUs, and not subsequent models */
173 #define OCTEON_CN6XXX                                           \
174         (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS)
175 #define OCTEON_CNF7XXX                                          \
176         (OCTEON_CNF71XX_PASS1_0 | OM_MATCH_F7XXX_FAMILY_MODELS)
177 #define OCTEON_CN7XXX                                           \
178         (OCTEON_CN78XX_PASS1_0 | OM_MATCH_7XXX_FAMILY_MODELS)
179
180 /*
181  * The revision byte (low byte) has two different encodings.
182  * CN3XXX:
183  *
184  *     bits
185  *     <7:5>: reserved (0)
186  *     <4>:   alternate package
187  *     <3:0>: revision
188  *
189  * CN5XXX and older models:
190  *
191  *     bits
192  *     <7>:   reserved (0)
193  *     <6>:   alternate package
194  *     <5:3>: major revision
195  *     <2:0>: minor revision
196  */
197
198 /* Masks used for the various types of model/family/revision matching */
199 #define OCTEON_38XX_FAMILY_MASK      0x00ffff00
200 #define OCTEON_38XX_FAMILY_REV_MASK  0x00ffff0f
201 #define OCTEON_38XX_MODEL_MASK       0x00ffff10
202 #define OCTEON_38XX_MODEL_REV_MASK                              \
203         (OCTEON_38XX_FAMILY_REV_MASK | OCTEON_38XX_MODEL_MASK)
204
205 /* CN5XXX and later use different layout of bits in the revision ID field */
206 #define OCTEON_58XX_FAMILY_MASK      OCTEON_38XX_FAMILY_MASK
207 #define OCTEON_58XX_FAMILY_REV_MASK  0x00ffff3f
208 #define OCTEON_58XX_MODEL_MASK       0x00ffff40
209 #define OCTEON_58XX_MODEL_REV_MASK                              \
210         (OCTEON_58XX_FAMILY_REV_MASK | OCTEON_58XX_MODEL_MASK)
211 #define OCTEON_58XX_MODEL_MINOR_REV_MASK                \
212         (OCTEON_58XX_MODEL_REV_MASK & 0x00ffff38)
213 #define OCTEON_5XXX_MODEL_MASK       0x00ff0fc0
214
215 #define __OCTEON_MATCH_MASK__(X, Y, Z)               \
216         ({                                           \
217                 typeof(X) x = (X);                   \
218                 typeof(Y) y = (Y);                   \
219                 typeof(Z) z = (Z);                   \
220                 (x & z) == (y & z);                  \
221          })
222
223 /*
224  * __OCTEON_IS_MODEL_COMPILE__(arg_model, chip_model)
225  * returns true if chip_model is identical or belong to the OCTEON
226  * model group specified in arg_model.
227  */
228
229 /* Helper macros to make to following macro compacter */
230 #define OM_MASK                 OM_FLAG_MASK
231 #define OM_MATCH_MASK           __OCTEON_MATCH_MASK__
232 #define OM_MATCH_PREVIOUS       OM_MATCH_PREVIOUS_MODELS
233
234 #define __OCTEON_IS_MODEL_COMPILE__(A, B)                               \
235         ({                                                              \
236         typeof(A) a = (A);                                              \
237         typeof(B) b = (B);                                              \
238         (((((((a) & OM_MASK) == (OM_IGNORE_REVISION | OM_CHECK_SUBMODEL)) && \
239             OM_MATCH_MASK((b), (a), OCTEON_58XX_MODEL_MASK)) ||         \
240            ((((a) & OM_MASK) == 0) &&                                   \
241             OM_MATCH_MASK((b), (a), OCTEON_58XX_FAMILY_REV_MASK)) ||    \
242            ((((a) & OM_MASK) == OM_IGNORE_MINOR_REVISION) &&            \
243             OM_MATCH_MASK((b), (a), OCTEON_58XX_MODEL_MINOR_REV_MASK)) || \
244            ((((a) & OM_MASK) == OM_CHECK_SUBMODEL) &&                   \
245             OM_MATCH_MASK((b), (a), OCTEON_58XX_MODEL_MASK)) ||         \
246            ((((a) & OM_MASK) == OM_IGNORE_REVISION) &&                  \
247             OM_MATCH_MASK((b), (a), OCTEON_58XX_FAMILY_MASK)) ||        \
248            ((((a) & (OM_MATCH_5XXX_FAMILY_MODELS)) ==                   \
249              OM_MATCH_5XXX_FAMILY_MODELS) &&                            \
250             ((b & OCTEON_PRID_MASK) < OCTEON_CN63XX_PASS1_0)) ||        \
251            ((((a) & (OM_MATCH_6XXX_FAMILY_MODELS)) ==                   \
252              OM_MATCH_6XXX_FAMILY_MODELS) &&                            \
253             ((b & OCTEON_PRID_MASK) >= OCTEON_CN63XX_PASS1_0) &&        \
254             ((b & OCTEON_PRID_MASK) < OCTEON_CNF71XX_PASS1_0)) ||       \
255            ((((a) & (OM_MATCH_F7XXX_FAMILY_MODELS)) ==                  \
256              OM_MATCH_F7XXX_FAMILY_MODELS) &&                           \
257             ((b & OCTEON_PRID_MASK) >= OCTEON_CNF71XX_PASS1_0) &&       \
258             ((b & OCTEON_PRID_MASK) < OCTEON_CN78XX_PASS1_0)) ||        \
259            ((((a) & (OM_MATCH_7XXX_FAMILY_MODELS)) ==                   \
260              OM_MATCH_7XXX_FAMILY_MODELS) && ((b & OCTEON_PRID_MASK) >= \
261                                               OCTEON_CN78XX_PASS1_0)) || \
262            ((((a) & (OM_MATCH_PREVIOUS)) == OM_MATCH_PREVIOUS) &&       \
263             (((b) & OCTEON_58XX_MODEL_MASK) < ((a) & OCTEON_58XX_MODEL_MASK))) \
264                   )));                                                  \
265         })
266
267 #ifndef __ASSEMBLY__
268
269 #ifndef OCTEON_IS_MODEL
270
271 static inline int __octeon_is_model_runtime_internal__(u32 model)
272 {
273         u32 cpuid = read_c0_prid();
274
275         return __OCTEON_IS_MODEL_COMPILE__(model, cpuid);
276 }
277
278 static inline int __octeon_is_model_runtime__(u32 model)
279 {
280         return __octeon_is_model_runtime_internal__(model);
281 }
282
283 /*
284  * The OCTEON_IS_MODEL macro should be used for all Octeon model checking done
285  * in a program.
286  * This should be kept runtime if at all possible  and must be conditionalized
287  * with OCTEON_IS_COMMON_BINARY() if runtime checking support is required.
288  *
289  * Use of the macro in preprocessor directives ( #if OCTEON_IS_MODEL(...) )
290  * is NOT SUPPORTED, and should be replaced with CVMX_COMPILED_FOR()
291  * I.e.:
292  * #if OCTEON_IS_MODEL(OCTEON_CN56XX)  ->  #if CVMX_COMPILED_FOR(OCTEON_CN56XX)
293  */
294 #define OCTEON_IS_MODEL(x)      __octeon_is_model_runtime__(x)
295 #define OCTEON_IS_COMMON_BINARY() 1
296 #undef OCTEON_MODEL
297 #endif
298
299 #define OCTEON_IS_OCTEON2()                                             \
300         (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
301
302 #define OCTEON_IS_OCTEON3()     OCTEON_IS_MODEL(OCTEON_CN7XXX)
303
304 const char *octeon_model_get_string(u32 chip_id);
305 const char *octeon_model_get_string_buffer(u32 chip_id, char *buffer);
306
307 /**
308  * Return the octeon family, i.e., ProcessorID of the PrID register.
309  *
310  * @return the octeon family on success, ((u32)-1) on error.
311  */
312 static inline u32 cvmx_get_octeon_family(void)
313 {
314         return (read_c0_prid() & OCTEON_FAMILY_MASK);
315 }
316
317 #endif /* __ASSEMBLY__ */
318
319 #endif /* __OCTEON_MODEL_H__ */