1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
---|---|
2 | /* |
3 | * Copyright (C) 2013 Red Hat |
4 | * Author: Rob Clark <robdclark@gmail.com> |
5 | * |
6 | * Copyright (c) 2014,2017, 2019 The Linux Foundation. All rights reserved. |
7 | */ |
8 | |
9 | #ifndef __ADRENO_GPU_H__ |
10 | #define __ADRENO_GPU_H__ |
11 | |
12 | #include <linux/firmware.h> |
13 | #include <linux/iopoll.h> |
14 | |
15 | #include "msm_gpu.h" |
16 | |
17 | #include "adreno_common.xml.h" |
18 | #include "adreno_pm4.xml.h" |
19 | |
20 | extern bool snapshot_debugbus; |
21 | extern bool allow_vram_carveout; |
22 | |
23 | enum { |
24 | ADRENO_FW_PM4 = 0, |
25 | ADRENO_FW_SQE = 0, /* a6xx */ |
26 | ADRENO_FW_PFP = 1, |
27 | ADRENO_FW_GMU = 1, /* a6xx */ |
28 | ADRENO_FW_GPMU = 2, |
29 | ADRENO_FW_MAX, |
30 | }; |
31 | |
32 | /** |
33 | * @enum adreno_family: identify generation and possibly sub-generation |
34 | * |
35 | * In some cases there are distinct sub-generations within a major revision |
36 | * so it helps to be able to group the GPU devices by generation and if |
37 | * necessary sub-generation. |
38 | */ |
39 | enum adreno_family { |
40 | ADRENO_2XX_GEN1, /* a20x */ |
41 | ADRENO_2XX_GEN2, /* a22x */ |
42 | ADRENO_3XX, |
43 | ADRENO_4XX, |
44 | ADRENO_5XX, |
45 | ADRENO_6XX_GEN1, /* a630 family */ |
46 | ADRENO_6XX_GEN2, /* a640 family */ |
47 | ADRENO_6XX_GEN3, /* a650 family */ |
48 | ADRENO_6XX_GEN4, /* a660 family */ |
49 | ADRENO_7XX_GEN1, /* a730 family */ |
50 | ADRENO_7XX_GEN2, /* a740 family */ |
51 | ADRENO_7XX_GEN3, /* a750 family */ |
52 | }; |
53 | |
54 | #define ADRENO_QUIRK_TWO_PASS_USE_WFI BIT(0) |
55 | #define ADRENO_QUIRK_FAULT_DETECT_MASK BIT(1) |
56 | #define ADRENO_QUIRK_LMLOADKILL_DISABLE BIT(2) |
57 | #define ADRENO_QUIRK_HAS_HW_APRIV BIT(3) |
58 | #define ADRENO_QUIRK_HAS_CACHED_COHERENT BIT(4) |
59 | #define ADRENO_QUIRK_PREEMPTION BIT(5) |
60 | #define ADRENO_QUIRK_4GB_VA BIT(6) |
61 | |
62 | /* Helper for formating the chip_id in the way that userspace tools like |
63 | * crashdec expect. |
64 | */ |
65 | #define ADRENO_CHIPID_FMT "u.%u.%u.%u" |
66 | #define ADRENO_CHIPID_ARGS(_c) \ |
67 | (((_c) >> 24) & 0xff), \ |
68 | (((_c) >> 16) & 0xff), \ |
69 | (((_c) >> 8) & 0xff), \ |
70 | ((_c) & 0xff) |
71 | |
72 | struct adreno_gpu_funcs { |
73 | struct msm_gpu_funcs base; |
74 | int (*get_timestamp)(struct msm_gpu *gpu, uint64_t *value); |
75 | }; |
76 | |
77 | struct adreno_reglist { |
78 | u32 offset; |
79 | u32 value; |
80 | }; |
81 | |
82 | struct adreno_speedbin { |
83 | uint16_t fuse; |
84 | uint16_t speedbin; |
85 | }; |
86 | |
87 | struct a6xx_info; |
88 | |
89 | struct adreno_info { |
90 | const char *machine; |
91 | /** |
92 | * @chipids: Table of matching chip-ids |
93 | * |
94 | * Terminated with 0 sentinal |
95 | */ |
96 | uint32_t *chip_ids; |
97 | enum adreno_family family; |
98 | uint32_t revn; |
99 | const char *fw[ADRENO_FW_MAX]; |
100 | uint32_t gmem; |
101 | u64 quirks; |
102 | struct msm_gpu *(*init)(struct drm_device *dev); |
103 | const char *zapfw; |
104 | u32 inactive_period; |
105 | union { |
106 | const struct a6xx_info *a6xx; |
107 | }; |
108 | /** |
109 | * @speedbins: Optional table of fuse to speedbin mappings |
110 | * |
111 | * Consists of pairs of fuse, index mappings, terminated with |
112 | * {SHRT_MAX, 0} sentinal. |
113 | */ |
114 | struct adreno_speedbin *speedbins; |
115 | u64 preempt_record_size; |
116 | }; |
117 | |
118 | #define ADRENO_CHIP_IDS(tbl...) (uint32_t[]) { tbl, 0 } |
119 | |
120 | struct adreno_gpulist { |
121 | const struct adreno_info *gpus; |
122 | unsigned gpus_count; |
123 | }; |
124 | |
125 | #define DECLARE_ADRENO_GPULIST(name) \ |
126 | const struct adreno_gpulist name ## _gpulist = { \ |
127 | name ## _gpus, ARRAY_SIZE(name ## _gpus) \ |
128 | } |
129 | |
130 | /* |
131 | * Helper to build a speedbin table, ie. the table: |
132 | * fuse | speedbin |
133 | * -----+--------- |
134 | * 0 | 0 |
135 | * 169 | 1 |
136 | * 174 | 2 |
137 | * |
138 | * would be declared as: |
139 | * |
140 | * .speedbins = ADRENO_SPEEDBINS( |
141 | * { 0, 0 }, |
142 | * { 169, 1 }, |
143 | * { 174, 2 }, |
144 | * ), |
145 | */ |
146 | #define ADRENO_SPEEDBINS(tbl...) (struct adreno_speedbin[]) { tbl {SHRT_MAX, 0} } |
147 | |
148 | struct adreno_protect { |
149 | const uint32_t *regs; |
150 | uint32_t count; |
151 | uint32_t count_max; |
152 | }; |
153 | |
154 | #define DECLARE_ADRENO_PROTECT(name, __count_max) \ |
155 | static const struct adreno_protect name = { \ |
156 | .regs = name ## _regs, \ |
157 | .count = ARRAY_SIZE(name ## _regs), \ |
158 | .count_max = __count_max, \ |
159 | }; |
160 | |
161 | struct adreno_reglist_list { |
162 | /** @reg: List of register **/ |
163 | const u32 *regs; |
164 | /** @count: Number of registers in the list **/ |
165 | u32 count; |
166 | }; |
167 | |
168 | #define DECLARE_ADRENO_REGLIST_LIST(name) \ |
169 | static const struct adreno_reglist_list name = { \ |
170 | .regs = name ## _regs, \ |
171 | .count = ARRAY_SIZE(name ## _regs), \ |
172 | }; |
173 | |
174 | struct adreno_gpu { |
175 | struct msm_gpu base; |
176 | const struct adreno_info *info; |
177 | uint32_t chip_id; |
178 | uint16_t speedbin; |
179 | const struct adreno_gpu_funcs *funcs; |
180 | |
181 | /* interesting register offsets to dump: */ |
182 | const unsigned int *registers; |
183 | |
184 | /* |
185 | * Are we loading fw from legacy path? Prior to addition |
186 | * of gpu firmware to linux-firmware, the fw files were |
187 | * placed in toplevel firmware directory, following qcom's |
188 | * android kernel. But linux-firmware preferred they be |
189 | * placed in a 'qcom' subdirectory. |
190 | * |
191 | * For backwards compatibility, we try first to load from |
192 | * the new path, using request_firmware_direct() to avoid |
193 | * any potential timeout waiting for usermode helper, then |
194 | * fall back to the old path (with direct load). And |
195 | * finally fall back to request_firmware() with the new |
196 | * path to allow the usermode helper. |
197 | */ |
198 | enum { |
199 | FW_LOCATION_UNKNOWN = 0, |
200 | FW_LOCATION_NEW, /* /lib/firmware/qcom/$fwfile */ |
201 | FW_LOCATION_LEGACY, /* /lib/firmware/$fwfile */ |
202 | FW_LOCATION_HELPER, |
203 | } fwloc; |
204 | |
205 | /* firmware: */ |
206 | const struct firmware *fw[ADRENO_FW_MAX]; |
207 | |
208 | struct { |
209 | /** |
210 | * @rgb565_predicator: Unknown, introduced with A650 family, |
211 | * related to UBWC mode/ver 4 |
212 | */ |
213 | u32 rgb565_predicator; |
214 | /** @uavflagprd_inv: Unknown, introduced with A650 family */ |
215 | u32 uavflagprd_inv; |
216 | /** @min_acc_len: Whether the minimum access length is 64 bits */ |
217 | u32 min_acc_len; |
218 | /** |
219 | * @ubwc_swizzle: Whether to enable level 1, 2 & 3 bank swizzling. |
220 | * |
221 | * UBWC 1.0 always enables all three levels. |
222 | * UBWC 2.0 removes level 1 bank swizzling, leaving levels 2 & 3. |
223 | * UBWC 4.0 adds the optional ability to disable levels 2 & 3. |
224 | * |
225 | * This is a bitmask where BIT(0) enables level 1, BIT(1) |
226 | * controls level 2, and BIT(2) enables level 3. |
227 | */ |
228 | u32 ubwc_swizzle; |
229 | /** |
230 | * @highest_bank_bit: Highest Bank Bit |
231 | * |
232 | * The Highest Bank Bit value represents the bit of the highest |
233 | * DDR bank. This should ideally use DRAM type detection. |
234 | */ |
235 | u32 highest_bank_bit; |
236 | u32 amsbc; |
237 | /** |
238 | * @macrotile_mode: Macrotile Mode |
239 | * |
240 | * Whether to use 4-channel macrotiling mode or the newer |
241 | * 8-channel macrotiling mode introduced in UBWC 3.1. 0 is |
242 | * 4-channel and 1 is 8-channel. |
243 | */ |
244 | u32 macrotile_mode; |
245 | } ubwc_config; |
246 | |
247 | /* |
248 | * Register offsets are different between some GPUs. |
249 | * GPU specific offsets will be exported by GPU specific |
250 | * code (a3xx_gpu.c) and stored in this common location. |
251 | */ |
252 | const unsigned int *reg_offsets; |
253 | bool gmu_is_wrapper; |
254 | |
255 | bool has_ray_tracing; |
256 | |
257 | u64 uche_trap_base; |
258 | }; |
259 | #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base) |
260 | |
261 | struct adreno_ocmem { |
262 | struct ocmem *ocmem; |
263 | unsigned long base; |
264 | void *hdl; |
265 | }; |
266 | |
267 | /* platform config data (ie. from DT, or pdata) */ |
268 | struct adreno_platform_config { |
269 | uint32_t chip_id; |
270 | const struct adreno_info *info; |
271 | }; |
272 | |
273 | #define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000) |
274 | |
275 | #define spin_until(X) ({ \ |
276 | int __ret = -ETIMEDOUT; \ |
277 | unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \ |
278 | do { \ |
279 | if (X) { \ |
280 | __ret = 0; \ |
281 | break; \ |
282 | } \ |
283 | } while (time_before(jiffies, __t)); \ |
284 | __ret; \ |
285 | }) |
286 | |
287 | static inline uint8_t adreno_patchid(const struct adreno_gpu *gpu) |
288 | { |
289 | /* It is probably ok to assume legacy "adreno_rev" format |
290 | * for all a6xx devices, but probably best to limit this |
291 | * to older things. |
292 | */ |
293 | WARN_ON_ONCE(gpu->info->family >= ADRENO_6XX_GEN1); |
294 | return gpu->chip_id & 0xff; |
295 | } |
296 | |
297 | static inline bool adreno_is_revn(const struct adreno_gpu *gpu, uint32_t revn) |
298 | { |
299 | if (WARN_ON_ONCE(!gpu->info)) |
300 | return false; |
301 | return gpu->info->revn == revn; |
302 | } |
303 | |
304 | static inline bool adreno_has_gmu_wrapper(const struct adreno_gpu *gpu) |
305 | { |
306 | return gpu->gmu_is_wrapper; |
307 | } |
308 | |
309 | static inline bool adreno_is_a2xx(const struct adreno_gpu *gpu) |
310 | { |
311 | if (WARN_ON_ONCE(!gpu->info)) |
312 | return false; |
313 | return gpu->info->family <= ADRENO_2XX_GEN2; |
314 | } |
315 | |
316 | static inline bool adreno_is_a20x(const struct adreno_gpu *gpu) |
317 | { |
318 | if (WARN_ON_ONCE(!gpu->info)) |
319 | return false; |
320 | return gpu->info->family == ADRENO_2XX_GEN1; |
321 | } |
322 | |
323 | static inline bool adreno_is_a225(const struct adreno_gpu *gpu) |
324 | { |
325 | return adreno_is_revn(gpu, revn: 225); |
326 | } |
327 | |
328 | static inline bool adreno_is_a305(const struct adreno_gpu *gpu) |
329 | { |
330 | return adreno_is_revn(gpu, revn: 305); |
331 | } |
332 | |
333 | static inline bool adreno_is_a305b(const struct adreno_gpu *gpu) |
334 | { |
335 | return gpu->info->chip_ids[0] == 0x03000512; |
336 | } |
337 | |
338 | static inline bool adreno_is_a306(const struct adreno_gpu *gpu) |
339 | { |
340 | /* yes, 307, because a305c is 306 */ |
341 | return adreno_is_revn(gpu, revn: 307); |
342 | } |
343 | |
344 | static inline bool adreno_is_a306a(const struct adreno_gpu *gpu) |
345 | { |
346 | /* a306a (marketing name is a308) */ |
347 | return adreno_is_revn(gpu, revn: 308); |
348 | } |
349 | |
350 | static inline bool adreno_is_a320(const struct adreno_gpu *gpu) |
351 | { |
352 | return adreno_is_revn(gpu, revn: 320); |
353 | } |
354 | |
355 | static inline bool adreno_is_a330(const struct adreno_gpu *gpu) |
356 | { |
357 | return adreno_is_revn(gpu, revn: 330); |
358 | } |
359 | |
360 | static inline bool adreno_is_a330v2(const struct adreno_gpu *gpu) |
361 | { |
362 | return adreno_is_a330(gpu) && (adreno_patchid(gpu) > 0); |
363 | } |
364 | |
365 | static inline int adreno_is_a405(const struct adreno_gpu *gpu) |
366 | { |
367 | return adreno_is_revn(gpu, revn: 405); |
368 | } |
369 | |
370 | static inline int adreno_is_a420(const struct adreno_gpu *gpu) |
371 | { |
372 | return adreno_is_revn(gpu, revn: 420); |
373 | } |
374 | |
375 | static inline int adreno_is_a430(const struct adreno_gpu *gpu) |
376 | { |
377 | return adreno_is_revn(gpu, revn: 430); |
378 | } |
379 | |
380 | static inline int adreno_is_a505(const struct adreno_gpu *gpu) |
381 | { |
382 | return adreno_is_revn(gpu, revn: 505); |
383 | } |
384 | |
385 | static inline int adreno_is_a506(const struct adreno_gpu *gpu) |
386 | { |
387 | return adreno_is_revn(gpu, revn: 506); |
388 | } |
389 | |
390 | static inline int adreno_is_a508(const struct adreno_gpu *gpu) |
391 | { |
392 | return adreno_is_revn(gpu, revn: 508); |
393 | } |
394 | |
395 | static inline int adreno_is_a509(const struct adreno_gpu *gpu) |
396 | { |
397 | return adreno_is_revn(gpu, revn: 509); |
398 | } |
399 | |
400 | static inline int adreno_is_a510(const struct adreno_gpu *gpu) |
401 | { |
402 | return adreno_is_revn(gpu, revn: 510); |
403 | } |
404 | |
405 | static inline int adreno_is_a512(const struct adreno_gpu *gpu) |
406 | { |
407 | return adreno_is_revn(gpu, revn: 512); |
408 | } |
409 | |
410 | static inline int adreno_is_a530(const struct adreno_gpu *gpu) |
411 | { |
412 | return adreno_is_revn(gpu, revn: 530); |
413 | } |
414 | |
415 | static inline int adreno_is_a540(const struct adreno_gpu *gpu) |
416 | { |
417 | return adreno_is_revn(gpu, revn: 540); |
418 | } |
419 | |
420 | static inline int adreno_is_a610(const struct adreno_gpu *gpu) |
421 | { |
422 | return adreno_is_revn(gpu, revn: 610); |
423 | } |
424 | |
425 | static inline int adreno_is_a618(const struct adreno_gpu *gpu) |
426 | { |
427 | return adreno_is_revn(gpu, revn: 618); |
428 | } |
429 | |
430 | static inline int adreno_is_a619(const struct adreno_gpu *gpu) |
431 | { |
432 | return adreno_is_revn(gpu, revn: 619); |
433 | } |
434 | |
435 | static inline int adreno_is_a619_holi(const struct adreno_gpu *gpu) |
436 | { |
437 | return adreno_is_a619(gpu) && adreno_has_gmu_wrapper(gpu); |
438 | } |
439 | |
440 | static inline int adreno_is_a621(const struct adreno_gpu *gpu) |
441 | { |
442 | return gpu->info->chip_ids[0] == 0x06020100; |
443 | } |
444 | |
445 | static inline int adreno_is_a623(const struct adreno_gpu *gpu) |
446 | { |
447 | return gpu->info->chip_ids[0] == 0x06020300; |
448 | } |
449 | |
450 | static inline int adreno_is_a630(const struct adreno_gpu *gpu) |
451 | { |
452 | return adreno_is_revn(gpu, revn: 630); |
453 | } |
454 | |
455 | static inline int adreno_is_a640(const struct adreno_gpu *gpu) |
456 | { |
457 | return adreno_is_revn(gpu, revn: 640); |
458 | } |
459 | |
460 | static inline int adreno_is_a650(const struct adreno_gpu *gpu) |
461 | { |
462 | return adreno_is_revn(gpu, revn: 650); |
463 | } |
464 | |
465 | static inline int adreno_is_7c3(const struct adreno_gpu *gpu) |
466 | { |
467 | return gpu->info->chip_ids[0] == 0x06030500; |
468 | } |
469 | |
470 | static inline int adreno_is_a660(const struct adreno_gpu *gpu) |
471 | { |
472 | return adreno_is_revn(gpu, revn: 660); |
473 | } |
474 | |
475 | static inline int adreno_is_a680(const struct adreno_gpu *gpu) |
476 | { |
477 | return adreno_is_revn(gpu, revn: 680); |
478 | } |
479 | |
480 | static inline int adreno_is_a663(const struct adreno_gpu *gpu) |
481 | { |
482 | return gpu->info->chip_ids[0] == 0x06060300; |
483 | } |
484 | |
485 | static inline int adreno_is_a690(const struct adreno_gpu *gpu) |
486 | { |
487 | return gpu->info->chip_ids[0] == 0x06090000; |
488 | } |
489 | |
490 | static inline int adreno_is_a702(const struct adreno_gpu *gpu) |
491 | { |
492 | return gpu->info->chip_ids[0] == 0x07000200; |
493 | } |
494 | |
495 | static inline int adreno_is_a610_family(const struct adreno_gpu *gpu) |
496 | { |
497 | if (WARN_ON_ONCE(!gpu->info)) |
498 | return false; |
499 | |
500 | /* TODO: A612 */ |
501 | return adreno_is_a610(gpu) || adreno_is_a702(gpu); |
502 | } |
503 | |
504 | /* TODO: 615/616 */ |
505 | static inline int adreno_is_a615_family(const struct adreno_gpu *gpu) |
506 | { |
507 | return adreno_is_a618(gpu) || |
508 | adreno_is_a619(gpu); |
509 | } |
510 | |
511 | static inline int adreno_is_a630_family(const struct adreno_gpu *gpu) |
512 | { |
513 | if (WARN_ON_ONCE(!gpu->info)) |
514 | return false; |
515 | return gpu->info->family == ADRENO_6XX_GEN1; |
516 | } |
517 | |
518 | static inline int adreno_is_a660_family(const struct adreno_gpu *gpu) |
519 | { |
520 | if (WARN_ON_ONCE(!gpu->info)) |
521 | return false; |
522 | return gpu->info->family == ADRENO_6XX_GEN4; |
523 | } |
524 | |
525 | /* check for a650, a660, or any derivatives */ |
526 | static inline int adreno_is_a650_family(const struct adreno_gpu *gpu) |
527 | { |
528 | if (WARN_ON_ONCE(!gpu->info)) |
529 | return false; |
530 | return gpu->info->family == ADRENO_6XX_GEN3 || |
531 | gpu->info->family == ADRENO_6XX_GEN4; |
532 | } |
533 | |
534 | static inline int adreno_is_a640_family(const struct adreno_gpu *gpu) |
535 | { |
536 | if (WARN_ON_ONCE(!gpu->info)) |
537 | return false; |
538 | return gpu->info->family == ADRENO_6XX_GEN2; |
539 | } |
540 | |
541 | static inline int adreno_is_a730(struct adreno_gpu *gpu) |
542 | { |
543 | return gpu->info->chip_ids[0] == 0x07030001; |
544 | } |
545 | |
546 | static inline int adreno_is_a740(struct adreno_gpu *gpu) |
547 | { |
548 | return gpu->info->chip_ids[0] == 0x43050a01; |
549 | } |
550 | |
551 | static inline int adreno_is_a750(struct adreno_gpu *gpu) |
552 | { |
553 | return gpu->info->chip_ids[0] == 0x43051401; |
554 | } |
555 | |
556 | static inline int adreno_is_x185(struct adreno_gpu *gpu) |
557 | { |
558 | return gpu->info->chip_ids[0] == 0x43050c01; |
559 | } |
560 | |
561 | static inline int adreno_is_a740_family(struct adreno_gpu *gpu) |
562 | { |
563 | if (WARN_ON_ONCE(!gpu->info)) |
564 | return false; |
565 | return gpu->info->family == ADRENO_7XX_GEN2 || |
566 | gpu->info->family == ADRENO_7XX_GEN3; |
567 | } |
568 | |
569 | static inline int adreno_is_a750_family(struct adreno_gpu *gpu) |
570 | { |
571 | return gpu->info->family == ADRENO_7XX_GEN3; |
572 | } |
573 | |
574 | static inline int adreno_is_a7xx(struct adreno_gpu *gpu) |
575 | { |
576 | /* Update with non-fake (i.e. non-A702) Gen 7 GPUs */ |
577 | return gpu->info->family == ADRENO_7XX_GEN1 || |
578 | adreno_is_a740_family(gpu); |
579 | } |
580 | |
581 | /* Put vm_start above 32b to catch issues with not setting xyz_BASE_HI */ |
582 | #define ADRENO_VM_START 0x100000000ULL |
583 | u64 adreno_private_address_space_size(struct msm_gpu *gpu); |
584 | int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, |
585 | uint32_t param, uint64_t *value, uint32_t *len); |
586 | int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, |
587 | uint32_t param, uint64_t value, uint32_t len); |
588 | const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu, |
589 | const char *fwname); |
590 | struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu, |
591 | const struct firmware *fw, u64 *iova); |
592 | int adreno_hw_init(struct msm_gpu *gpu); |
593 | void adreno_recover(struct msm_gpu *gpu); |
594 | void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, u32 reg); |
595 | bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring); |
596 | #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) |
597 | void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, |
598 | struct drm_printer *p); |
599 | #endif |
600 | void adreno_dump_info(struct msm_gpu *gpu); |
601 | void adreno_dump(struct msm_gpu *gpu); |
602 | void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords); |
603 | struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu); |
604 | |
605 | int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu, |
606 | struct adreno_ocmem *ocmem); |
607 | void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *ocmem); |
608 | |
609 | int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, |
610 | struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs, |
611 | int nr_rings); |
612 | void adreno_gpu_cleanup(struct adreno_gpu *gpu); |
613 | int adreno_load_fw(struct adreno_gpu *adreno_gpu); |
614 | |
615 | void adreno_gpu_state_destroy(struct msm_gpu_state *state); |
616 | |
617 | int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state); |
618 | int adreno_gpu_state_put(struct msm_gpu_state *state); |
619 | void adreno_show_object(struct drm_printer *p, void **ptr, int len, |
620 | bool *encoded); |
621 | |
622 | /* |
623 | * Common helper function to initialize the default address space for arm-smmu |
624 | * attached targets |
625 | */ |
626 | struct msm_gem_address_space * |
627 | adreno_create_address_space(struct msm_gpu *gpu, |
628 | struct platform_device *pdev); |
629 | |
630 | struct msm_gem_address_space * |
631 | adreno_iommu_create_address_space(struct msm_gpu *gpu, |
632 | struct platform_device *pdev, |
633 | unsigned long quirks); |
634 | |
635 | int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags, |
636 | struct adreno_smmu_fault_info *info, const char *block, |
637 | u32 scratch[4]); |
638 | |
639 | int adreno_read_speedbin(struct device *dev, u32 *speedbin); |
640 | |
641 | /* |
642 | * For a5xx and a6xx targets load the zap shader that is used to pull the GPU |
643 | * out of secure mode |
644 | */ |
645 | int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid); |
646 | |
647 | /* ringbuffer helpers (the parts that are adreno specific) */ |
648 | |
649 | static inline void |
650 | OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt) |
651 | { |
652 | adreno_wait_ring(ring, ndwords: cnt+1); |
653 | OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF)); |
654 | } |
655 | |
656 | /* no-op packet: */ |
657 | static inline void |
658 | OUT_PKT2(struct msm_ringbuffer *ring) |
659 | { |
660 | adreno_wait_ring(ring, ndwords: 1); |
661 | OUT_RING(ring, CP_TYPE2_PKT); |
662 | } |
663 | |
664 | static inline void |
665 | OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) |
666 | { |
667 | adreno_wait_ring(ring, ndwords: cnt+1); |
668 | OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8)); |
669 | } |
670 | |
671 | static inline u32 PM4_PARITY(u32 val) |
672 | { |
673 | return (0x9669 >> (0xF & (val ^ |
674 | (val >> 4) ^ (val >> 8) ^ (val >> 12) ^ |
675 | (val >> 16) ^ ((val) >> 20) ^ (val >> 24) ^ |
676 | (val >> 28)))) & 1; |
677 | } |
678 | |
679 | /* Maximum number of values that can be executed for one opcode */ |
680 | #define TYPE4_MAX_PAYLOAD 127 |
681 | |
682 | #define PKT4(_reg, _cnt) \ |
683 | (CP_TYPE4_PKT | ((_cnt) << 0) | (PM4_PARITY((_cnt)) << 7) | \ |
684 | (((_reg) & 0x3FFFF) << 8) | (PM4_PARITY((_reg)) << 27)) |
685 | |
686 | static inline void |
687 | OUT_PKT4(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt) |
688 | { |
689 | adreno_wait_ring(ring, ndwords: cnt + 1); |
690 | OUT_RING(ring, PKT4(regindx, cnt)); |
691 | } |
692 | |
693 | #define PKT7(opcode, cnt) \ |
694 | (CP_TYPE7_PKT | (cnt << 0) | (PM4_PARITY(cnt) << 15) | \ |
695 | ((opcode & 0x7F) << 16) | (PM4_PARITY(opcode) << 23)) |
696 | |
697 | static inline void |
698 | OUT_PKT7(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) |
699 | { |
700 | adreno_wait_ring(ring, ndwords: cnt + 1); |
701 | OUT_RING(ring, PKT7(opcode, cnt)); |
702 | } |
703 | |
704 | struct msm_gpu *a2xx_gpu_init(struct drm_device *dev); |
705 | struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); |
706 | struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); |
707 | struct msm_gpu *a5xx_gpu_init(struct drm_device *dev); |
708 | struct msm_gpu *a6xx_gpu_init(struct drm_device *dev); |
709 | |
710 | static inline uint32_t get_wptr(struct msm_ringbuffer *ring) |
711 | { |
712 | return (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2); |
713 | } |
714 | |
715 | /* |
716 | * Given a register and a count, return a value to program into |
717 | * REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len |
718 | * registers starting at _reg. |
719 | * |
720 | * The register base needs to be a multiple of the length. If it is not, the |
721 | * hardware will quietly mask off the bits for you and shift the size. For |
722 | * example, if you intend the protection to start at 0x07 for a length of 4 |
723 | * (0x07-0x0A) the hardware will actually protect (0x04-0x07) which might |
724 | * expose registers you intended to protect! |
725 | */ |
726 | #define ADRENO_PROTECT_RW(_reg, _len) \ |
727 | ((1 << 30) | (1 << 29) | \ |
728 | ((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF)) |
729 | |
730 | /* |
731 | * Same as above, but allow reads over the range. For areas of mixed use (such |
732 | * as performance counters) this allows us to protect a much larger range with a |
733 | * single register |
734 | */ |
735 | #define ADRENO_PROTECT_RDONLY(_reg, _len) \ |
736 | ((1 << 29) \ |
737 | ((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF)) |
738 | |
739 | |
740 | #define gpu_poll_timeout(gpu, addr, val, cond, interval, timeout) \ |
741 | readl_poll_timeout((gpu)->mmio + ((addr) << 2), val, cond, \ |
742 | interval, timeout) |
743 | |
744 | #endif /* __ADRENO_GPU_H__ */ |
745 |
Definitions
- adreno_family
- adreno_gpu_funcs
- adreno_reglist
- adreno_speedbin
- adreno_info
- adreno_gpulist
- adreno_protect
- adreno_reglist_list
- adreno_gpu
- adreno_ocmem
- adreno_platform_config
- adreno_patchid
- adreno_is_revn
- adreno_has_gmu_wrapper
- adreno_is_a2xx
- adreno_is_a20x
- adreno_is_a225
- adreno_is_a305
- adreno_is_a305b
- adreno_is_a306
- adreno_is_a306a
- adreno_is_a320
- adreno_is_a330
- adreno_is_a330v2
- adreno_is_a405
- adreno_is_a420
- adreno_is_a430
- adreno_is_a505
- adreno_is_a506
- adreno_is_a508
- adreno_is_a509
- adreno_is_a510
- adreno_is_a512
- adreno_is_a530
- adreno_is_a540
- adreno_is_a610
- adreno_is_a618
- adreno_is_a619
- adreno_is_a619_holi
- adreno_is_a621
- adreno_is_a623
- adreno_is_a630
- adreno_is_a640
- adreno_is_a650
- adreno_is_7c3
- adreno_is_a660
- adreno_is_a680
- adreno_is_a663
- adreno_is_a690
- adreno_is_a702
- adreno_is_a610_family
- adreno_is_a615_family
- adreno_is_a630_family
- adreno_is_a660_family
- adreno_is_a650_family
- adreno_is_a640_family
- adreno_is_a730
- adreno_is_a740
- adreno_is_a750
- adreno_is_x185
- adreno_is_a740_family
- adreno_is_a750_family
- adreno_is_a7xx
- OUT_PKT0
- OUT_PKT2
- OUT_PKT3
- PM4_PARITY
- OUT_PKT4
- OUT_PKT7
Improve your Profiling and Debugging skills
Find out more