1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. */ |
3 | |
4 | #ifndef __A6XX_GPU_H__ |
5 | #define __A6XX_GPU_H__ |
6 | |
7 | |
8 | #include "adreno_gpu.h" |
9 | #include "a6xx.xml.h" |
10 | |
11 | #include "a6xx_gmu.h" |
12 | |
13 | extern bool hang_debug; |
14 | |
15 | struct a6xx_gpu { |
16 | struct adreno_gpu base; |
17 | |
18 | struct drm_gem_object *sqe_bo; |
19 | uint64_t sqe_iova; |
20 | |
21 | struct msm_ringbuffer *cur_ring; |
22 | |
23 | struct a6xx_gmu gmu; |
24 | |
25 | struct drm_gem_object *shadow_bo; |
26 | uint64_t shadow_iova; |
27 | uint32_t *shadow; |
28 | |
29 | bool has_whereami; |
30 | |
31 | void __iomem *llc_mmio; |
32 | void *llc_slice; |
33 | void *htw_llc_slice; |
34 | bool have_mmu500; |
35 | bool hung; |
36 | }; |
37 | |
38 | #define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base) |
39 | |
40 | /* |
41 | * Given a register and a count, return a value to program into |
42 | * REG_CP_PROTECT_REG(n) - this will block both reads and writes for |
43 | * _len + 1 registers starting at _reg. |
44 | */ |
45 | #define A6XX_PROTECT_NORDWR(_reg, _len) \ |
46 | ((1 << 31) | \ |
47 | (((_len) & 0x3FFF) << 18) | ((_reg) & 0x3FFFF)) |
48 | |
49 | /* |
50 | * Same as above, but allow reads over the range. For areas of mixed use (such |
51 | * as performance counters) this allows us to protect a much larger range with a |
52 | * single register |
53 | */ |
54 | #define A6XX_PROTECT_RDONLY(_reg, _len) \ |
55 | ((((_len) & 0x3FFF) << 18) | ((_reg) & 0x3FFFF)) |
56 | |
57 | static inline bool a6xx_has_gbif(struct adreno_gpu *gpu) |
58 | { |
59 | if(adreno_is_a630(gpu)) |
60 | return false; |
61 | |
62 | return true; |
63 | } |
64 | |
65 | static inline void a6xx_llc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or) |
66 | { |
67 | return msm_rmw(a6xx_gpu->llc_mmio + (reg << 2), mask, or); |
68 | } |
69 | |
70 | static inline u32 a6xx_llc_read(struct a6xx_gpu *a6xx_gpu, u32 reg) |
71 | { |
72 | return msm_readl(a6xx_gpu->llc_mmio + (reg << 2)); |
73 | } |
74 | |
75 | static inline void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value) |
76 | { |
77 | msm_writel(value, a6xx_gpu->llc_mmio + (reg << 2)); |
78 | } |
79 | |
80 | #define shadowptr(_a6xx_gpu, _ring) ((_a6xx_gpu)->shadow_iova + \ |
81 | ((_ring)->id * sizeof(uint32_t))) |
82 | |
83 | int a6xx_gmu_resume(struct a6xx_gpu *gpu); |
84 | int a6xx_gmu_stop(struct a6xx_gpu *gpu); |
85 | |
86 | int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu); |
87 | |
88 | bool a6xx_gmu_isidle(struct a6xx_gmu *gmu); |
89 | |
90 | int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); |
91 | void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); |
92 | |
93 | int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node); |
94 | int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node); |
95 | void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu); |
96 | |
97 | void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp, |
98 | bool suspended); |
99 | unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu); |
100 | |
101 | void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, |
102 | struct drm_printer *p); |
103 | |
104 | struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu); |
105 | int a6xx_gpu_state_put(struct msm_gpu_state *state); |
106 | |
107 | void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off); |
108 | void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert); |
109 | |
110 | #endif /* __A6XX_GPU_H__ */ |
111 | |