1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3 *
4 * (C) COPYRIGHT 2012-2023 ARM Limited. All rights reserved.
5 *
6 * This program is free software and is provided to you under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation, and any use by you of this program is subject to the terms
9 * of such GNU license.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you can access it online at
18 * http://www.gnu.org/licenses/gpl-2.0.html.
19 *
20 */
21
22 /*
23 * Run-time work-arounds helpers
24 */
25
26 #include <mali_base_hwconfig_features.h>
27 #include <mali_base_hwconfig_issues.h>
28 #include "gpu/mali_kbase_gpu_regmap.h"
29 #include "mali_kbase.h"
30 #include "mali_kbase_hw.h"
31
kbase_hw_set_features_mask(struct kbase_device * kbdev)32 void kbase_hw_set_features_mask(struct kbase_device *kbdev)
33 {
34 const enum base_hw_feature *features;
35 u32 gpu_id;
36
37 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
38
39 switch (gpu_id & GPU_ID2_PRODUCT_MODEL) {
40 case GPU_ID2_PRODUCT_TMIX:
41 features = base_hw_features_tMIx;
42 break;
43 case GPU_ID2_PRODUCT_THEX:
44 features = base_hw_features_tHEx;
45 break;
46 case GPU_ID2_PRODUCT_TSIX:
47 features = base_hw_features_tSIx;
48 break;
49 case GPU_ID2_PRODUCT_TDVX:
50 features = base_hw_features_tDVx;
51 break;
52 case GPU_ID2_PRODUCT_TNOX:
53 features = base_hw_features_tNOx;
54 break;
55 case GPU_ID2_PRODUCT_TGOX:
56 features = base_hw_features_tGOx;
57 break;
58 case GPU_ID2_PRODUCT_TTRX:
59 features = base_hw_features_tTRx;
60 break;
61 case GPU_ID2_PRODUCT_TNAX:
62 features = base_hw_features_tNAx;
63 break;
64 case GPU_ID2_PRODUCT_LBEX:
65 case GPU_ID2_PRODUCT_TBEX:
66 features = base_hw_features_tBEx;
67 break;
68 case GPU_ID2_PRODUCT_TBAX:
69 features = base_hw_features_tBAx;
70 break;
71 case GPU_ID2_PRODUCT_TODX:
72 case GPU_ID2_PRODUCT_LODX:
73 features = base_hw_features_tODx;
74 break;
75 case GPU_ID2_PRODUCT_TGRX:
76 features = base_hw_features_tGRx;
77 break;
78 case GPU_ID2_PRODUCT_TVAX:
79 features = base_hw_features_tVAx;
80 break;
81 case GPU_ID2_PRODUCT_TTUX:
82 case GPU_ID2_PRODUCT_LTUX:
83 features = base_hw_features_tTUx;
84 break;
85 case GPU_ID2_PRODUCT_TTIX:
86 case GPU_ID2_PRODUCT_LTIX:
87 features = base_hw_features_tTIx;
88 break;
89 default:
90 features = base_hw_features_generic;
91 break;
92 }
93
94 for (; *features != BASE_HW_FEATURE_END; features++)
95 set_bit(*features, &kbdev->hw_features_mask[0]);
96
97 #if defined(CONFIG_MALI_VECTOR_DUMP)
98 /* When dumping is enabled, need to disable flush reduction optimization
99 * for GPUs on which it is safe to have only cache clean operation at
100 * the end of job chain.
101 * This is required to make vector dump work. There is some discrepancy
102 * in the implementation of flush reduction optimization due to
103 * unclear or ambiguous ARCH spec.
104 */
105 if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_CLEAN_ONLY_SAFE))
106 clear_bit(BASE_HW_FEATURE_FLUSH_REDUCTION,
107 &kbdev->hw_features_mask[0]);
108 #endif
109 }
110
111 /**
112 * kbase_hw_get_issues_for_new_id - Get the hardware issues for a new GPU ID
113 * @kbdev: Device pointer
114 *
115 * Return: pointer to an array of hardware issues, terminated by
116 * BASE_HW_ISSUE_END.
117 *
118 * In debugging versions of the driver, unknown versions of a known GPU will
119 * be treated as the most recent known version not later than the actual
120 * version. In such circumstances, the GPU ID in @kbdev will also be replaced
121 * with the most recent known version.
122 *
123 * Note: The GPU configuration must have been read by kbase_gpuprops_get_props()
124 * before calling this function.
125 */
kbase_hw_get_issues_for_new_id(struct kbase_device * kbdev)126 static const enum base_hw_issue *kbase_hw_get_issues_for_new_id(
127 struct kbase_device *kbdev)
128 {
129 const enum base_hw_issue *issues = NULL;
130
131 struct base_hw_product {
132 u32 product_model;
133 struct {
134 u32 version;
135 const enum base_hw_issue *issues;
136 } map[7];
137 };
138
139 static const struct base_hw_product base_hw_products[] = {
140 { GPU_ID2_PRODUCT_TMIX,
141 { { GPU_ID2_VERSION_MAKE(0, 0, 1), base_hw_issues_tMIx_r0p0_05dev0 },
142 { GPU_ID2_VERSION_MAKE(0, 0, 2), base_hw_issues_tMIx_r0p0 },
143 { GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tMIx_r0p1 },
144 { U32_MAX /* sentinel value */, NULL } } },
145
146 { GPU_ID2_PRODUCT_THEX,
147 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tHEx_r0p0 },
148 { GPU_ID2_VERSION_MAKE(0, 0, 1), base_hw_issues_tHEx_r0p0 },
149 { GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tHEx_r0p1 },
150 { GPU_ID2_VERSION_MAKE(0, 1, 1), base_hw_issues_tHEx_r0p1 },
151 { GPU_ID2_VERSION_MAKE(0, 2, 0), base_hw_issues_tHEx_r0p2 },
152 { GPU_ID2_VERSION_MAKE(0, 3, 0), base_hw_issues_tHEx_r0p3 },
153 { U32_MAX, NULL } } },
154
155 { GPU_ID2_PRODUCT_TSIX,
156 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tSIx_r0p0 },
157 { GPU_ID2_VERSION_MAKE(0, 0, 1), base_hw_issues_tSIx_r0p0 },
158 { GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tSIx_r0p1 },
159 { GPU_ID2_VERSION_MAKE(1, 0, 0), base_hw_issues_tSIx_r1p0 },
160 { GPU_ID2_VERSION_MAKE(1, 1, 0), base_hw_issues_tSIx_r1p1 },
161 { U32_MAX, NULL } } },
162
163 { GPU_ID2_PRODUCT_TDVX,
164 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tDVx_r0p0 },
165 { U32_MAX, NULL } } },
166
167 { GPU_ID2_PRODUCT_TNOX,
168 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tNOx_r0p0 },
169 { U32_MAX, NULL } } },
170
171 { GPU_ID2_PRODUCT_TGOX,
172 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tGOx_r0p0 },
173 { GPU_ID2_VERSION_MAKE(1, 0, 0), base_hw_issues_tGOx_r1p0 },
174 { U32_MAX, NULL } } },
175
176 { GPU_ID2_PRODUCT_TTRX,
177 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tTRx_r0p0 },
178 { GPU_ID2_VERSION_MAKE(0, 0, 3), base_hw_issues_tTRx_r0p0 },
179 { GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tTRx_r0p1 },
180 { GPU_ID2_VERSION_MAKE(0, 1, 1), base_hw_issues_tTRx_r0p1 },
181 { GPU_ID2_VERSION_MAKE(0, 2, 0), base_hw_issues_tTRx_r0p2 },
182 { U32_MAX, NULL } } },
183
184 { GPU_ID2_PRODUCT_TNAX,
185 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tNAx_r0p0 },
186 { GPU_ID2_VERSION_MAKE(0, 0, 3), base_hw_issues_tNAx_r0p0 },
187 { GPU_ID2_VERSION_MAKE(0, 0, 4), base_hw_issues_tNAx_r0p0 },
188 { GPU_ID2_VERSION_MAKE(0, 0, 5), base_hw_issues_tNAx_r0p0 },
189 { GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tNAx_r0p1 },
190 { GPU_ID2_VERSION_MAKE(0, 1, 1), base_hw_issues_tNAx_r0p1 },
191 { U32_MAX, NULL } } },
192
193 { GPU_ID2_PRODUCT_LBEX,
194 { { GPU_ID2_VERSION_MAKE(1, 0, 0), base_hw_issues_lBEx_r1p0 },
195 { GPU_ID2_VERSION_MAKE(1, 1, 0), base_hw_issues_lBEx_r1p1 },
196 { U32_MAX, NULL } } },
197
198 { GPU_ID2_PRODUCT_TBEX,
199 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tBEx_r0p0 },
200 { GPU_ID2_VERSION_MAKE(0, 0, 3), base_hw_issues_tBEx_r0p0 },
201 { GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tBEx_r0p1 },
202 { GPU_ID2_VERSION_MAKE(1, 0, 0), base_hw_issues_tBEx_r1p0 },
203 { U32_MAX, NULL } } },
204
205 { GPU_ID2_PRODUCT_TBAX,
206 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tBAx_r0p0 },
207 { GPU_ID2_VERSION_MAKE(0, 0, 1), base_hw_issues_tBAx_r0p0 },
208 { GPU_ID2_VERSION_MAKE(0, 0, 2), base_hw_issues_tBAx_r0p0 },
209 { U32_MAX, NULL } } },
210
211 { GPU_ID2_PRODUCT_TODX,
212 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tODx_r0p0 },
213 { GPU_ID2_VERSION_MAKE(0, 0, 4), base_hw_issues_tODx_r0p0 },
214 { GPU_ID2_VERSION_MAKE(0, 0, 5), base_hw_issues_tODx_r0p0 },
215 { U32_MAX, NULL } } },
216
217 { GPU_ID2_PRODUCT_LODX,
218 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tODx_r0p0 },
219 { U32_MAX, NULL } } },
220
221 { GPU_ID2_PRODUCT_TGRX,
222 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tGRx_r0p0 },
223 { U32_MAX, NULL } } },
224
225 { GPU_ID2_PRODUCT_TVAX,
226 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tVAx_r0p0 },
227 { U32_MAX, NULL } } },
228
229 { GPU_ID2_PRODUCT_TTUX,
230 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tTUx_r0p0 },
231 { GPU_ID2_VERSION_MAKE(0, 1, 0), base_hw_issues_tTUx_r0p1 },
232 { GPU_ID2_VERSION_MAKE(1, 0, 0), base_hw_issues_tTUx_r1p0 },
233 { GPU_ID2_VERSION_MAKE(1, 1, 0), base_hw_issues_tTUx_r1p1 },
234 { GPU_ID2_VERSION_MAKE(1, 2, 0), base_hw_issues_tTUx_r1p2 },
235 { GPU_ID2_VERSION_MAKE(1, 3, 0), base_hw_issues_tTUx_r1p3 },
236 { U32_MAX, NULL } } },
237
238 { GPU_ID2_PRODUCT_LTUX,
239 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tTUx_r0p0 },
240 { GPU_ID2_VERSION_MAKE(1, 0, 0), base_hw_issues_tTUx_r1p0 },
241 { GPU_ID2_VERSION_MAKE(1, 1, 0), base_hw_issues_tTUx_r1p1 },
242 { GPU_ID2_VERSION_MAKE(1, 2, 0), base_hw_issues_tTUx_r1p2 },
243 { GPU_ID2_VERSION_MAKE(1, 3, 0), base_hw_issues_tTUx_r1p3 },
244 { U32_MAX, NULL } } },
245
246 { GPU_ID2_PRODUCT_TTIX,
247 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tTIx_r0p0 },
248 { U32_MAX, NULL } } },
249
250 { GPU_ID2_PRODUCT_LTIX,
251 { { GPU_ID2_VERSION_MAKE(0, 0, 0), base_hw_issues_tTIx_r0p0 },
252 { U32_MAX, NULL } } },
253
254 };
255
256 u32 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
257 const u32 product_model = gpu_id & GPU_ID2_PRODUCT_MODEL;
258 const struct base_hw_product *product = NULL;
259 size_t p;
260
261 /* Stop when we reach the end of the products array. */
262 for (p = 0; p < ARRAY_SIZE(base_hw_products); ++p) {
263 if (product_model == base_hw_products[p].product_model) {
264 product = &base_hw_products[p];
265 break;
266 }
267 }
268
269 if (product != NULL) {
270 /* Found a matching product. */
271 const u32 version = gpu_id & GPU_ID2_VERSION;
272 u32 fallback_version = 0;
273 const enum base_hw_issue *fallback_issues = NULL;
274 size_t v;
275
276 /* Stop when we reach the end of the map. */
277 for (v = 0; product->map[v].version != U32_MAX; ++v) {
278
279 if (version == product->map[v].version) {
280 /* Exact match so stop. */
281 issues = product->map[v].issues;
282 break;
283 }
284
285 /* Check whether this is a candidate for most recent
286 * known version not later than the actual version.
287 */
288 if ((version > product->map[v].version) &&
289 (product->map[v].version >= fallback_version)) {
290 #if MALI_CUSTOMER_RELEASE
291 /* Match on version's major and minor fields */
292 if (((version ^ product->map[v].version) >>
293 GPU_ID2_VERSION_MINOR_SHIFT) == 0)
294 #endif
295 {
296 fallback_version = product->map[v].version;
297 fallback_issues = product->map[v].issues;
298 }
299 }
300 }
301
302 if ((issues == NULL) && (fallback_issues != NULL)) {
303 /* Fall back to the issue set of the most recent known
304 * version not later than the actual version.
305 */
306 issues = fallback_issues;
307
308 dev_notice(kbdev->dev, "r%dp%d status %d not found in HW issues table;\n",
309 (gpu_id & GPU_ID2_VERSION_MAJOR) >> GPU_ID2_VERSION_MAJOR_SHIFT,
310 (gpu_id & GPU_ID2_VERSION_MINOR) >> GPU_ID2_VERSION_MINOR_SHIFT,
311 (gpu_id & GPU_ID2_VERSION_STATUS) >>
312 GPU_ID2_VERSION_STATUS_SHIFT);
313 dev_notice(kbdev->dev, "falling back to closest match: r%dp%d status %d\n",
314 (fallback_version & GPU_ID2_VERSION_MAJOR) >>
315 GPU_ID2_VERSION_MAJOR_SHIFT,
316 (fallback_version & GPU_ID2_VERSION_MINOR) >>
317 GPU_ID2_VERSION_MINOR_SHIFT,
318 (fallback_version & GPU_ID2_VERSION_STATUS) >>
319 GPU_ID2_VERSION_STATUS_SHIFT);
320 dev_notice(kbdev->dev,
321 "Execution proceeding normally with fallback match\n");
322
323 gpu_id &= ~GPU_ID2_VERSION;
324 gpu_id |= fallback_version;
325 kbdev->gpu_props.props.raw_props.gpu_id = gpu_id;
326
327 kbase_gpuprops_update_core_props_gpu_id(
328 &kbdev->gpu_props.props);
329 }
330 }
331 return issues;
332 }
333
kbase_hw_set_issues_mask(struct kbase_device * kbdev)334 int kbase_hw_set_issues_mask(struct kbase_device *kbdev)
335 {
336 const enum base_hw_issue *issues;
337 u32 gpu_id;
338 u32 impl_tech;
339
340 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
341 impl_tech = kbdev->gpu_props.props.thread_props.impl_tech;
342
343 if (impl_tech != IMPLEMENTATION_MODEL) {
344 issues = kbase_hw_get_issues_for_new_id(kbdev);
345 if (issues == NULL) {
346 dev_err(kbdev->dev,
347 "HW product - Unknown GPU ID %x", gpu_id);
348 return -EINVAL;
349 }
350
351 #if !MALI_CUSTOMER_RELEASE
352 /* The GPU ID might have been replaced with the last
353 * known version of the same GPU.
354 */
355 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
356 #endif
357 } else {
358 /* Software model */
359 switch (gpu_id & GPU_ID2_PRODUCT_MODEL) {
360 case GPU_ID2_PRODUCT_TMIX:
361 issues = base_hw_issues_model_tMIx;
362 break;
363 case GPU_ID2_PRODUCT_THEX:
364 issues = base_hw_issues_model_tHEx;
365 break;
366 case GPU_ID2_PRODUCT_TSIX:
367 issues = base_hw_issues_model_tSIx;
368 break;
369 case GPU_ID2_PRODUCT_TDVX:
370 issues = base_hw_issues_model_tDVx;
371 break;
372 case GPU_ID2_PRODUCT_TNOX:
373 issues = base_hw_issues_model_tNOx;
374 break;
375 case GPU_ID2_PRODUCT_TGOX:
376 issues = base_hw_issues_model_tGOx;
377 break;
378 case GPU_ID2_PRODUCT_TTRX:
379 issues = base_hw_issues_model_tTRx;
380 break;
381 case GPU_ID2_PRODUCT_TNAX:
382 issues = base_hw_issues_model_tNAx;
383 break;
384 case GPU_ID2_PRODUCT_LBEX:
385 case GPU_ID2_PRODUCT_TBEX:
386 issues = base_hw_issues_model_tBEx;
387 break;
388 case GPU_ID2_PRODUCT_TBAX:
389 issues = base_hw_issues_model_tBAx;
390 break;
391 case GPU_ID2_PRODUCT_TODX:
392 case GPU_ID2_PRODUCT_LODX:
393 issues = base_hw_issues_model_tODx;
394 break;
395 case GPU_ID2_PRODUCT_TGRX:
396 issues = base_hw_issues_model_tGRx;
397 break;
398 case GPU_ID2_PRODUCT_TVAX:
399 issues = base_hw_issues_model_tVAx;
400 break;
401 case GPU_ID2_PRODUCT_TTUX:
402 case GPU_ID2_PRODUCT_LTUX:
403 issues = base_hw_issues_model_tTUx;
404 break;
405 case GPU_ID2_PRODUCT_TTIX:
406 case GPU_ID2_PRODUCT_LTIX:
407 issues = base_hw_issues_model_tTIx;
408 break;
409 default:
410 dev_err(kbdev->dev,
411 "HW issues - Unknown GPU ID %x", gpu_id);
412 return -EINVAL;
413 }
414 }
415
416 dev_info(kbdev->dev,
417 "GPU identified as 0x%x arch %d.%d.%d r%dp%d status %d",
418 (gpu_id & GPU_ID2_PRODUCT_MAJOR) >>
419 GPU_ID2_PRODUCT_MAJOR_SHIFT,
420 (gpu_id & GPU_ID2_ARCH_MAJOR) >>
421 GPU_ID2_ARCH_MAJOR_SHIFT,
422 (gpu_id & GPU_ID2_ARCH_MINOR) >>
423 GPU_ID2_ARCH_MINOR_SHIFT,
424 (gpu_id & GPU_ID2_ARCH_REV) >>
425 GPU_ID2_ARCH_REV_SHIFT,
426 (gpu_id & GPU_ID2_VERSION_MAJOR) >>
427 GPU_ID2_VERSION_MAJOR_SHIFT,
428 (gpu_id & GPU_ID2_VERSION_MINOR) >>
429 GPU_ID2_VERSION_MINOR_SHIFT,
430 (gpu_id & GPU_ID2_VERSION_STATUS) >>
431 GPU_ID2_VERSION_STATUS_SHIFT);
432
433 for (; *issues != BASE_HW_ISSUE_END; issues++)
434 set_bit(*issues, &kbdev->hw_issues_mask[0]);
435
436 return 0;
437 }
438