| .. | .. |
|---|
| 4 | 4 | #ifndef _A6XX_GMU_H_ |
|---|
| 5 | 5 | #define _A6XX_GMU_H_ |
|---|
| 6 | 6 | |
|---|
| 7 | +#include <linux/iopoll.h> |
|---|
| 7 | 8 | #include <linux/interrupt.h> |
|---|
| 8 | 9 | #include "msm_drv.h" |
|---|
| 9 | 10 | #include "a6xx_hfi.h" |
|---|
| 10 | 11 | |
|---|
| 11 | 12 | struct a6xx_gmu_bo { |
|---|
| 13 | + struct drm_gem_object *obj; |
|---|
| 12 | 14 | void *virt; |
|---|
| 13 | 15 | size_t size; |
|---|
| 14 | 16 | u64 iova; |
|---|
| 15 | | - struct page **pages; |
|---|
| 16 | 17 | }; |
|---|
| 17 | 18 | |
|---|
| 18 | 19 | /* |
|---|
| .. | .. |
|---|
| 25 | 26 | |
|---|
| 26 | 27 | /* the GMU is coming up for the first time or back from a power collapse */ |
|---|
| 27 | 28 | #define GMU_COLD_BOOT 1 |
|---|
| 28 | | - |
|---|
| 29 | | -/* The GMU is being soft reset after a fault */ |
|---|
| 30 | | -#define GMU_RESET 2 |
|---|
| 31 | 29 | |
|---|
| 32 | 30 | /* |
|---|
| 33 | 31 | * These define the level of control that the GMU has - the higher the number |
|---|
| .. | .. |
|---|
| 46 | 44 | struct a6xx_gmu { |
|---|
| 47 | 45 | struct device *dev; |
|---|
| 48 | 46 | |
|---|
| 47 | + struct msm_gem_address_space *aspace; |
|---|
| 48 | + |
|---|
| 49 | 49 | void * __iomem mmio; |
|---|
| 50 | | - void * __iomem pdc_mmio; |
|---|
| 50 | + void * __iomem rscc; |
|---|
| 51 | 51 | |
|---|
| 52 | 52 | int hfi_irq; |
|---|
| 53 | 53 | int gmu_irq; |
|---|
| 54 | 54 | |
|---|
| 55 | | - struct regulator *gx; |
|---|
| 56 | | - |
|---|
| 57 | | - struct iommu_domain *domain; |
|---|
| 58 | | - u64 uncached_iova_base; |
|---|
| 55 | + struct device *gxpd; |
|---|
| 59 | 56 | |
|---|
| 60 | 57 | int idle_level; |
|---|
| 61 | 58 | |
|---|
| 62 | | - struct a6xx_gmu_bo *hfi; |
|---|
| 63 | | - struct a6xx_gmu_bo *debug; |
|---|
| 59 | + struct a6xx_gmu_bo hfi; |
|---|
| 60 | + struct a6xx_gmu_bo debug; |
|---|
| 61 | + struct a6xx_gmu_bo icache; |
|---|
| 62 | + struct a6xx_gmu_bo dcache; |
|---|
| 63 | + struct a6xx_gmu_bo dummy; |
|---|
| 64 | + struct a6xx_gmu_bo log; |
|---|
| 64 | 65 | |
|---|
| 65 | 66 | int nr_clocks; |
|---|
| 66 | 67 | struct clk_bulk_data *clocks; |
|---|
| 67 | 68 | struct clk *core_clk; |
|---|
| 69 | + |
|---|
| 70 | + /* current performance index set externally */ |
|---|
| 71 | + int current_perf_index; |
|---|
| 68 | 72 | |
|---|
| 69 | 73 | int nr_gpu_freqs; |
|---|
| 70 | 74 | unsigned long gpu_freqs[16]; |
|---|
| .. | .. |
|---|
| 74 | 78 | unsigned long gmu_freqs[4]; |
|---|
| 75 | 79 | u32 cx_arc_votes[4]; |
|---|
| 76 | 80 | |
|---|
| 81 | + unsigned long freq; |
|---|
| 82 | + |
|---|
| 77 | 83 | struct a6xx_hfi_queue queues[2]; |
|---|
| 78 | 84 | |
|---|
| 79 | | - struct tasklet_struct hfi_tasklet; |
|---|
| 85 | + bool initialized; |
|---|
| 86 | + bool hung; |
|---|
| 87 | + bool legacy; /* a618 or a630 */ |
|---|
| 80 | 88 | }; |
|---|
| 81 | 89 | |
|---|
| 82 | 90 | static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) |
|---|
| .. | .. |
|---|
| 89 | 97 | return msm_writel(value, gmu->mmio + (offset << 2)); |
|---|
| 90 | 98 | } |
|---|
| 91 | 99 | |
|---|
| 92 | | -static inline void pdc_write(struct a6xx_gmu *gmu, u32 offset, u32 value) |
|---|
| 100 | +static inline void |
|---|
| 101 | +gmu_write_bulk(struct a6xx_gmu *gmu, u32 offset, const u32 *data, u32 size) |
|---|
| 93 | 102 | { |
|---|
| 94 | | - return msm_writel(value, gmu->pdc_mmio + (offset << 2)); |
|---|
| 103 | + memcpy_toio(gmu->mmio + (offset << 2), data, size); |
|---|
| 104 | + wmb(); |
|---|
| 95 | 105 | } |
|---|
| 96 | 106 | |
|---|
| 97 | 107 | static inline void gmu_rmw(struct a6xx_gmu *gmu, u32 reg, u32 mask, u32 or) |
|---|
| .. | .. |
|---|
| 103 | 113 | gmu_write(gmu, reg, val | or); |
|---|
| 104 | 114 | } |
|---|
| 105 | 115 | |
|---|
| 116 | +static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi) |
|---|
| 117 | +{ |
|---|
| 118 | + u64 val; |
|---|
| 119 | + |
|---|
| 120 | + val = (u64) msm_readl(gmu->mmio + (lo << 2)); |
|---|
| 121 | + val |= ((u64) msm_readl(gmu->mmio + (hi << 2)) << 32); |
|---|
| 122 | + |
|---|
| 123 | + return val; |
|---|
| 124 | +} |
|---|
| 125 | + |
|---|
| 106 | 126 | #define gmu_poll_timeout(gmu, addr, val, cond, interval, timeout) \ |
|---|
| 107 | 127 | readl_poll_timeout((gmu)->mmio + ((addr) << 2), val, cond, \ |
|---|
| 128 | + interval, timeout) |
|---|
| 129 | + |
|---|
| 130 | +static inline u32 gmu_read_rscc(struct a6xx_gmu *gmu, u32 offset) |
|---|
| 131 | +{ |
|---|
| 132 | + return msm_readl(gmu->rscc + (offset << 2)); |
|---|
| 133 | +} |
|---|
| 134 | + |
|---|
| 135 | +static inline void gmu_write_rscc(struct a6xx_gmu *gmu, u32 offset, u32 value) |
|---|
| 136 | +{ |
|---|
| 137 | + return msm_writel(value, gmu->rscc + (offset << 2)); |
|---|
| 138 | +} |
|---|
| 139 | + |
|---|
| 140 | +#define gmu_poll_timeout_rscc(gmu, addr, val, cond, interval, timeout) \ |
|---|
| 141 | + readl_poll_timeout((gmu)->rscc + ((addr) << 2), val, cond, \ |
|---|
| 108 | 142 | interval, timeout) |
|---|
| 109 | 143 | |
|---|
| 110 | 144 | /* |
|---|
| .. | .. |
|---|
| 122 | 156 | GMU_OOB_BOOT_SLUMBER = 0, |
|---|
| 123 | 157 | GMU_OOB_GPU_SET, |
|---|
| 124 | 158 | GMU_OOB_DCVS_SET, |
|---|
| 159 | + GMU_OOB_PERFCOUNTER_SET, |
|---|
| 125 | 160 | }; |
|---|
| 126 | 161 | |
|---|
| 127 | 162 | /* These are the interrupt / ack bits for each OOB request that are set |
|---|
| .. | .. |
|---|
| 152 | 187 | #define GMU_OOB_GPU_SET_ACK 24 |
|---|
| 153 | 188 | #define GMU_OOB_GPU_SET_CLEAR 24 |
|---|
| 154 | 189 | |
|---|
| 190 | +#define GMU_OOB_GPU_SET_REQUEST_NEW 30 |
|---|
| 191 | +#define GMU_OOB_GPU_SET_ACK_NEW 31 |
|---|
| 192 | +#define GMU_OOB_GPU_SET_CLEAR_NEW 31 |
|---|
| 193 | + |
|---|
| 194 | +#define GMU_OOB_PERFCOUNTER_REQUEST 17 |
|---|
| 195 | +#define GMU_OOB_PERFCOUNTER_ACK 25 |
|---|
| 196 | +#define GMU_OOB_PERFCOUNTER_CLEAR 25 |
|---|
| 197 | + |
|---|
| 198 | +#define GMU_OOB_PERFCOUNTER_REQUEST_NEW 28 |
|---|
| 199 | +#define GMU_OOB_PERFCOUNTER_ACK_NEW 30 |
|---|
| 200 | +#define GMU_OOB_PERFCOUNTER_CLEAR_NEW 30 |
|---|
| 155 | 201 | |
|---|
| 156 | 202 | void a6xx_hfi_init(struct a6xx_gmu *gmu); |
|---|
| 157 | 203 | int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state); |
|---|
| 158 | 204 | void a6xx_hfi_stop(struct a6xx_gmu *gmu); |
|---|
| 205 | +int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu); |
|---|
| 206 | +int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index); |
|---|
| 159 | 207 | |
|---|
| 160 | | -void a6xx_hfi_task(unsigned long data); |
|---|
| 208 | +bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu); |
|---|
| 209 | +bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu); |
|---|
| 161 | 210 | |
|---|
| 162 | 211 | #endif |
|---|