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