1 /*
2 *
3 * (C) COPYRIGHT 2012-2017 ARM Limited. All rights reserved.
4 *
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
8 * of such GNU licence.
9 *
10 * A copy of the licence is included with the program, and can also be obtained
11 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12 * Boston, MA 02110-1301, USA.
13 *
14 */
15
16
17
18
19
20 /*
21 * Run-time work-arounds helpers
22 */
23
24 #include <mali_base_hwconfig_features.h>
25 #include <mali_base_hwconfig_issues.h>
26 #include <mali_midg_regmap.h>
27 #include "mali_kbase.h"
28 #include "mali_kbase_hw.h"
29
kbase_hw_set_features_mask(struct kbase_device *kbdev)30 void kbase_hw_set_features_mask(struct kbase_device *kbdev)
31 {
32 const enum base_hw_feature *features;
33 u32 gpu_id;
34 u32 product_id;
35
36 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
37 product_id = gpu_id & GPU_ID_VERSION_PRODUCT_ID;
38 product_id >>= GPU_ID_VERSION_PRODUCT_ID_SHIFT;
39
40 if (GPU_ID_IS_NEW_FORMAT(product_id)) {
41 switch (gpu_id & GPU_ID2_PRODUCT_MODEL) {
42 case GPU_ID2_PRODUCT_TMIX:
43 features = base_hw_features_tMIx;
44 break;
45 case GPU_ID2_PRODUCT_THEX:
46 features = base_hw_features_tHEx;
47 break;
48 case GPU_ID2_PRODUCT_TSIX:
49 features = base_hw_features_tSIx;
50 break;
51 #ifdef MALI_INCLUDE_TKAX
52 case GPU_ID2_PRODUCT_TKAX:
53 features = base_hw_features_tKAx;
54 break;
55 #endif /* MALI_INCLUDE_TKAX */
56 #ifdef MALI_INCLUDE_TTRX
57 case GPU_ID2_PRODUCT_TTRX:
58 features = base_hw_features_tTRx;
59 break;
60 #endif /* MALI_INCLUDE_TTRX */
61 default:
62 features = base_hw_features_generic;
63 break;
64 }
65 } else {
66 switch (product_id) {
67 case GPU_ID_PI_TFRX:
68 /* FALLTHROUGH */
69 case GPU_ID_PI_T86X:
70 features = base_hw_features_tFxx;
71 break;
72 case GPU_ID_PI_T83X:
73 features = base_hw_features_t83x;
74 break;
75 case GPU_ID_PI_T82X:
76 features = base_hw_features_t82x;
77 break;
78 case GPU_ID_PI_T76X:
79 features = base_hw_features_t76x;
80 break;
81 case GPU_ID_PI_T72X:
82 features = base_hw_features_t72x;
83 break;
84 case GPU_ID_PI_T62X:
85 features = base_hw_features_t62x;
86 break;
87 case GPU_ID_PI_T60X:
88 features = base_hw_features_t60x;
89 break;
90 default:
91 features = base_hw_features_generic;
92 break;
93 }
94 }
95
96 for (; *features != BASE_HW_FEATURE_END; features++)
97 set_bit(*features, &kbdev->hw_features_mask[0]);
98 }
99
100 /**
101 * kbase_hw_get_issues_for_new_id - Get the hardware issues for a new GPU ID
102 * @kbdev: Device pointer
103 *
104 * Return: pointer to an array of hardware issues, terminated by
105 * BASE_HW_ISSUE_END.
106 *
107 * This function can only be used on new-format GPU IDs, i.e. those for which
108 * GPU_ID_IS_NEW_FORMAT evaluates as true. The GPU ID is read from the @kbdev.
109 *
110 * In debugging versions of the driver, unknown versions of a known GPU will
111 * be treated as the most recent known version not later than the actual
112 * version. In such circumstances, the GPU ID in @kbdev will also be replaced
113 * with the most recent known version.
114 *
115 * Note: The GPU configuration must have been read by kbase_gpuprops_get_props()
116 * before calling this function.
117 */
kbase_hw_get_issues_for_new_id( struct kbase_device *kbdev)118 static const enum base_hw_issue *kbase_hw_get_issues_for_new_id(
119 struct kbase_device *kbdev)
120 {
121 const enum base_hw_issue *issues = NULL;
122
123 struct base_hw_product {
124 u32 product_model;
125 struct {
126 u32 version;
127 const enum base_hw_issue *issues;
128 } map[7];
129 };
130
131 static const struct base_hw_product base_hw_products[] = {
132 {GPU_ID2_PRODUCT_TMIX,
133 {{GPU_ID2_VERSION_MAKE(0, 0, 1),
134 base_hw_issues_tMIx_r0p0_05dev0},
135 {GPU_ID2_VERSION_MAKE(0, 0, 2), base_hw_issues_tMIx_r0p0},
136 {U32_MAX /* sentinel value */, NULL} } },
137
138 {GPU_ID2_PRODUCT_THEX,
139 {{GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tHEx_r0p0},
140 {GPU_ID2_VERSION_MAKE(0, 0, 1), base_hw_issues_tHEx_r0p0},
141 {GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tHEx_r0p1},
142 {U32_MAX, NULL} } },
143
144 {GPU_ID2_PRODUCT_TSIX,
145 {{GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tSIx_r0p0},
146 {GPU_ID2_VERSION_MAKE(0, 0, 1), base_hw_issues_tSIx_r0p0},
147 {GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tSIx_r0p1},
148 {GPU_ID2_VERSION_MAKE(0, 1, 1), base_hw_issues_tSIx_r0p1},
149 {GPU_ID2_VERSION_MAKE(1, 0, 0), base_hw_issues_tSIx_r1p0},
150 {GPU_ID2_VERSION_MAKE(1, 0, 1), base_hw_issues_tSIx_r1p0},
151 {U32_MAX, NULL} } },
152
153
154 #ifdef MALI_INCLUDE_TKAX
155 {GPU_ID2_PRODUCT_TKAX,
156 {{GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tKAx_r0p0},
157 {U32_MAX, NULL} } },
158 #endif /* MALI_INCLUDE_TKAX */
159
160 #ifdef MALI_INCLUDE_TTRX
161 {GPU_ID2_PRODUCT_TTRX,
162 {{GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tTRx_r0p0},
163 {U32_MAX, NULL} } },
164 #endif /* MALI_INCLUDE_TTRX */
165 };
166
167 u32 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
168 const u32 product_model = gpu_id & GPU_ID2_PRODUCT_MODEL;
169 const struct base_hw_product *product = NULL;
170 size_t p;
171
172 /* Stop when we reach the end of the products array. */
173 for (p = 0; p < ARRAY_SIZE(base_hw_products); ++p) {
174 if (product_model == base_hw_products[p].product_model) {
175 product = &base_hw_products[p];
176 break;
177 }
178 }
179
180 if (product != NULL) {
181 /* Found a matching product. */
182 const u32 version = gpu_id & GPU_ID2_VERSION;
183 u32 fallback_version = 0;
184 const enum base_hw_issue *fallback_issues = NULL;
185 size_t v;
186
187 /* Stop when we reach the end of the map. */
188 for (v = 0; product->map[v].version != U32_MAX; ++v) {
189
190 if (version == product->map[v].version) {
191 /* Exact match so stop. */
192 issues = product->map[v].issues;
193 break;
194 }
195
196 /* Check whether this is a candidate for most recent
197 known version not later than the actual
198 version. */
199 if ((version > product->map[v].version) &&
200 (product->map[v].version >= fallback_version)) {
201 fallback_version = product->map[v].version;
202 fallback_issues = product->map[v].issues;
203 }
204 }
205
206 if ((issues == NULL) && (fallback_issues != NULL)) {
207 /* Fall back to the issue set of the most recent known
208 version not later than the actual version. */
209 issues = fallback_issues;
210
211 dev_info(kbdev->dev,
212 "r%dp%d status %d is unknown; treating as r%dp%d status %d",
213 (gpu_id & GPU_ID2_VERSION_MAJOR) >>
214 GPU_ID2_VERSION_MAJOR_SHIFT,
215 (gpu_id & GPU_ID2_VERSION_MINOR) >>
216 GPU_ID2_VERSION_MINOR_SHIFT,
217 (gpu_id & GPU_ID2_VERSION_STATUS) >>
218 GPU_ID2_VERSION_STATUS_SHIFT,
219 (fallback_version & GPU_ID2_VERSION_MAJOR) >>
220 GPU_ID2_VERSION_MAJOR_SHIFT,
221 (fallback_version & GPU_ID2_VERSION_MINOR) >>
222 GPU_ID2_VERSION_MINOR_SHIFT,
223 (fallback_version & GPU_ID2_VERSION_STATUS) >>
224 GPU_ID2_VERSION_STATUS_SHIFT);
225
226 gpu_id &= ~GPU_ID2_VERSION;
227 gpu_id |= fallback_version;
228 kbdev->gpu_props.props.raw_props.gpu_id = gpu_id;
229
230 kbase_gpuprops_update_core_props_gpu_id(&kbdev->gpu_props.props);
231 }
232 }
233 return issues;
234 }
235
kbase_hw_set_issues_mask(struct kbase_device *kbdev)236 int kbase_hw_set_issues_mask(struct kbase_device *kbdev)
237 {
238 const enum base_hw_issue *issues;
239 u32 gpu_id;
240 u32 product_id;
241 u32 impl_tech;
242
243 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
244 product_id = gpu_id & GPU_ID_VERSION_PRODUCT_ID;
245 product_id >>= GPU_ID_VERSION_PRODUCT_ID_SHIFT;
246 impl_tech = kbdev->gpu_props.props.thread_props.impl_tech;
247
248 if (impl_tech != IMPLEMENTATION_MODEL) {
249 if (GPU_ID_IS_NEW_FORMAT(product_id)) {
250 issues = kbase_hw_get_issues_for_new_id(kbdev);
251 if (issues == NULL) {
252 dev_err(kbdev->dev,
253 "Unknown GPU ID %x", gpu_id);
254 return -EINVAL;
255 }
256
257 /* The GPU ID might have been replaced with the last
258 known version of the same GPU. */
259 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
260
261 } else {
262 switch (gpu_id) {
263 case GPU_ID_MAKE(GPU_ID_PI_T60X, 0, 0, GPU_ID_S_15DEV0):
264 issues = base_hw_issues_t60x_r0p0_15dev0;
265 break;
266 case GPU_ID_MAKE(GPU_ID_PI_T60X, 0, 0, GPU_ID_S_EAC):
267 issues = base_hw_issues_t60x_r0p0_eac;
268 break;
269 case GPU_ID_MAKE(GPU_ID_PI_T60X, 0, 1, 0):
270 issues = base_hw_issues_t60x_r0p1;
271 break;
272 case GPU_ID_MAKE(GPU_ID_PI_T62X, 0, 1, 0):
273 issues = base_hw_issues_t62x_r0p1;
274 break;
275 case GPU_ID_MAKE(GPU_ID_PI_T62X, 1, 0, 0):
276 case GPU_ID_MAKE(GPU_ID_PI_T62X, 1, 0, 1):
277 issues = base_hw_issues_t62x_r1p0;
278 break;
279 case GPU_ID_MAKE(GPU_ID_PI_T62X, 1, 1, 0):
280 issues = base_hw_issues_t62x_r1p1;
281 break;
282 case GPU_ID_MAKE(GPU_ID_PI_T76X, 0, 0, 1):
283 issues = base_hw_issues_t76x_r0p0;
284 break;
285 case GPU_ID_MAKE(GPU_ID_PI_T76X, 0, 1, 1):
286 issues = base_hw_issues_t76x_r0p1;
287 break;
288 case GPU_ID_MAKE(GPU_ID_PI_T76X, 0, 1, 9):
289 issues = base_hw_issues_t76x_r0p1_50rel0;
290 break;
291 case GPU_ID_MAKE(GPU_ID_PI_T76X, 0, 2, 1):
292 issues = base_hw_issues_t76x_r0p2;
293 break;
294 case GPU_ID_MAKE(GPU_ID_PI_T76X, 0, 3, 1):
295 issues = base_hw_issues_t76x_r0p3;
296 break;
297 case GPU_ID_MAKE(GPU_ID_PI_T76X, 1, 0, 0):
298 issues = base_hw_issues_t76x_r1p0;
299 break;
300 case GPU_ID_MAKE(GPU_ID_PI_T72X, 0, 0, 0):
301 case GPU_ID_MAKE(GPU_ID_PI_T72X, 0, 0, 1):
302 case GPU_ID_MAKE(GPU_ID_PI_T72X, 0, 0, 2):
303 issues = base_hw_issues_t72x_r0p0;
304 break;
305 case GPU_ID_MAKE(GPU_ID_PI_T72X, 1, 0, 0):
306 issues = base_hw_issues_t72x_r1p0;
307 break;
308 case GPU_ID_MAKE(GPU_ID_PI_T72X, 1, 1, 0):
309 issues = base_hw_issues_t72x_r1p1;
310 break;
311 case GPU_ID_MAKE(GPU_ID_PI_TFRX, 0, 1, 2):
312 issues = base_hw_issues_tFRx_r0p1;
313 break;
314 case GPU_ID_MAKE(GPU_ID_PI_TFRX, 0, 2, 0):
315 issues = base_hw_issues_tFRx_r0p2;
316 break;
317 case GPU_ID_MAKE(GPU_ID_PI_TFRX, 1, 0, 0):
318 case GPU_ID_MAKE(GPU_ID_PI_TFRX, 1, 0, 8):
319 issues = base_hw_issues_tFRx_r1p0;
320 break;
321 case GPU_ID_MAKE(GPU_ID_PI_TFRX, 2, 0, 0):
322 issues = base_hw_issues_tFRx_r2p0;
323 break;
324 case GPU_ID_MAKE(GPU_ID_PI_T86X, 0, 2, 0):
325 issues = base_hw_issues_t86x_r0p2;
326 break;
327 case GPU_ID_MAKE(GPU_ID_PI_T86X, 1, 0, 0):
328 case GPU_ID_MAKE(GPU_ID_PI_T86X, 1, 0, 8):
329 issues = base_hw_issues_t86x_r1p0;
330 break;
331 case GPU_ID_MAKE(GPU_ID_PI_T86X, 2, 0, 0):
332 issues = base_hw_issues_t86x_r2p0;
333 break;
334 case GPU_ID_MAKE(GPU_ID_PI_T83X, 0, 1, 0):
335 issues = base_hw_issues_t83x_r0p1;
336 break;
337 case GPU_ID_MAKE(GPU_ID_PI_T83X, 1, 0, 0):
338 case GPU_ID_MAKE(GPU_ID_PI_T83X, 1, 0, 8):
339 issues = base_hw_issues_t83x_r1p0;
340 break;
341 case GPU_ID_MAKE(GPU_ID_PI_T82X, 0, 0, 0):
342 issues = base_hw_issues_t82x_r0p0;
343 break;
344 case GPU_ID_MAKE(GPU_ID_PI_T82X, 0, 1, 0):
345 issues = base_hw_issues_t82x_r0p1;
346 break;
347 case GPU_ID_MAKE(GPU_ID_PI_T82X, 1, 0, 0):
348 case GPU_ID_MAKE(GPU_ID_PI_T82X, 1, 0, 8):
349 issues = base_hw_issues_t82x_r1p0;
350 break;
351 default:
352 dev_err(kbdev->dev,
353 "Unknown GPU ID %x", gpu_id);
354 return -EINVAL;
355 }
356 }
357 } else {
358 /* Software model */
359 if (GPU_ID_IS_NEW_FORMAT(product_id)) {
360 switch (gpu_id & GPU_ID2_PRODUCT_MODEL) {
361 case GPU_ID2_PRODUCT_TMIX:
362 issues = base_hw_issues_model_tMIx;
363 break;
364 case GPU_ID2_PRODUCT_THEX:
365 issues = base_hw_issues_model_tHEx;
366 break;
367 case GPU_ID2_PRODUCT_TSIX:
368 issues = base_hw_issues_model_tSIx;
369 break;
370 #ifdef MALI_INCLUDE_TKAX
371 case GPU_ID2_PRODUCT_TKAX:
372 issues = base_hw_issues_model_tKAx;
373 break;
374 #endif /* MALI_INCLUDE_TKAX */
375 #ifdef MALI_INCLUDE_TTRX
376 case GPU_ID2_PRODUCT_TTRX:
377 issues = base_hw_issues_model_tTRx;
378 break;
379 #endif /* MALI_INCLUDE_TTRX */
380 default:
381 dev_err(kbdev->dev,
382 "Unknown GPU ID %x", gpu_id);
383 return -EINVAL;
384 }
385 } else {
386 switch (product_id) {
387 case GPU_ID_PI_T60X:
388 issues = base_hw_issues_model_t60x;
389 break;
390 case GPU_ID_PI_T62X:
391 issues = base_hw_issues_model_t62x;
392 break;
393 case GPU_ID_PI_T72X:
394 issues = base_hw_issues_model_t72x;
395 break;
396 case GPU_ID_PI_T76X:
397 issues = base_hw_issues_model_t76x;
398 break;
399 case GPU_ID_PI_TFRX:
400 issues = base_hw_issues_model_tFRx;
401 break;
402 case GPU_ID_PI_T86X:
403 issues = base_hw_issues_model_t86x;
404 break;
405 case GPU_ID_PI_T83X:
406 issues = base_hw_issues_model_t83x;
407 break;
408 case GPU_ID_PI_T82X:
409 issues = base_hw_issues_model_t82x;
410 break;
411 default:
412 dev_err(kbdev->dev, "Unknown GPU ID %x",
413 gpu_id);
414 return -EINVAL;
415 }
416 }
417 }
418
419 if (GPU_ID_IS_NEW_FORMAT(product_id)) {
420 dev_info(kbdev->dev,
421 "GPU identified as 0x%x arch %d.%d.%d r%dp%d status %d",
422 (gpu_id & GPU_ID2_PRODUCT_MAJOR) >>
423 GPU_ID2_PRODUCT_MAJOR_SHIFT,
424 (gpu_id & GPU_ID2_ARCH_MAJOR) >>
425 GPU_ID2_ARCH_MAJOR_SHIFT,
426 (gpu_id & GPU_ID2_ARCH_MINOR) >>
427 GPU_ID2_ARCH_MINOR_SHIFT,
428 (gpu_id & GPU_ID2_ARCH_REV) >>
429 GPU_ID2_ARCH_REV_SHIFT,
430 (gpu_id & GPU_ID2_VERSION_MAJOR) >>
431 GPU_ID2_VERSION_MAJOR_SHIFT,
432 (gpu_id & GPU_ID2_VERSION_MINOR) >>
433 GPU_ID2_VERSION_MINOR_SHIFT,
434 (gpu_id & GPU_ID2_VERSION_STATUS) >>
435 GPU_ID2_VERSION_STATUS_SHIFT);
436 } else {
437 dev_info(kbdev->dev,
438 "GPU identified as 0x%04x r%dp%d status %d",
439 (gpu_id & GPU_ID_VERSION_PRODUCT_ID) >>
440 GPU_ID_VERSION_PRODUCT_ID_SHIFT,
441 (gpu_id & GPU_ID_VERSION_MAJOR) >>
442 GPU_ID_VERSION_MAJOR_SHIFT,
443 (gpu_id & GPU_ID_VERSION_MINOR) >>
444 GPU_ID_VERSION_MINOR_SHIFT,
445 (gpu_id & GPU_ID_VERSION_STATUS) >>
446 GPU_ID_VERSION_STATUS_SHIFT);
447 }
448
449 for (; *issues != BASE_HW_ISSUE_END; issues++)
450 set_bit(*issues, &kbdev->hw_issues_mask[0]);
451
452 return 0;
453 }
454