FILE
a6xx_gmu.h
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* Copyright (c) 2017 The Linux Foundation. All rights reserved. */ 3 4#ifndef _A6XX_GMU_H_ 5#define _A6XX_GMU_H_ 6 7#include <linux/completion.h> 8#include <linux/iopoll.h> 9#include <linux/interrupt.h> 10#include <linux/notifier.h> 11#include <linux/soc/qcom/qcom_aoss.h> 12#include "msm_drv.h" 13#include "a6xx_hfi.h" 14 15struct a6xx_gmu_bo { 16 struct drm_gem_object *obj; 17 void *virt; 18 size_t size; 19 u64 iova; 20}; 21 22#define GMU_MAX_GX_FREQS 32 23#define GMU_MAX_CX_FREQS 6 24#define GMU_MAX_BCMS 3 25 26struct a6xx_bcm { 27 char *name; 28 unsigned int buswidth; 29 bool fixed; 30 unsigned int perfmode; 31 unsigned int perfmode_bw; 32}; 33 34/* 35 * These define the different GMU wake up options - these define how both the 36 * CPU and the GMU bring up the hardware 37 */ 38 39/* THe GMU has already been booted and the rentention registers are active */ 40#define GMU_WARM_BOOT 0 41 42/* the GMU is coming up for the first time or back from a power collapse */ 43#define GMU_COLD_BOOT 1 44 45/* 46 * These define the level of control that the GMU has - the higher the number 47 * the more things that the GMU hardware controls on its own. 48 */ 49 50/* The GMU does not do any idle state management */ 51#define GMU_IDLE_STATE_ACTIVE 0 52 53/* Unknown power state. Not exposed by the firmware. For documentation purpose only */ 54#define GMU_IDLE_STATE_RESERVED 1 55 56/* The GMU manages SPTP power collapse */ 57#define GMU_IDLE_STATE_SPTP 2 58 59/* The GMU does automatic IFPC (intra-frame power collapse) */ 60#define GMU_IDLE_STATE_IFPC 3 61 62struct a6xx_gmu { 63 struct device *dev; 64 65 /* For serializing communication with the GMU: */ 66 struct mutex lock; 67 68 struct drm_gpuvm *vm; 69 70 void __iomem *mmio; 71 u32 mmio_offset; 72 void __iomem *rscc; 73 74 int hfi_irq; 75 int gmu_irq; 76 77 struct device *gxpd; 78 struct device *cxpd; 79 80 int idle_level; 81 82 struct a6xx_gmu_bo hfi; 83 struct a6xx_gmu_bo debug; 84 struct a6xx_gmu_bo icache; 85 struct a6xx_gmu_bo dcache; 86 struct a6xx_gmu_bo dummy; 87 struct a6xx_gmu_bo log; 88 89 int nr_clocks; 90 struct clk_bulk_data *clocks; 91 struct clk *core_clk; 92 struct clk *hub_clk; 93 94 /* current performance index set externally */ 95 int current_perf_index; 96 97 int nr_gpu_freqs; 98 unsigned long gpu_freqs[GMU_MAX_GX_FREQS]; 99 u32 gx_arc_votes[GMU_MAX_GX_FREQS]; 100 u32 dep_arc_votes[GMU_MAX_GX_FREQS]; 101 struct a6xx_hfi_acd_table acd_table; 102 103 int nr_gpu_bws; 104 unsigned long gpu_bw_table[GMU_MAX_GX_FREQS]; 105 u32 gpu_ib_votes[GMU_MAX_GX_FREQS][GMU_MAX_BCMS]; 106 107 int nr_gmu_freqs; 108 unsigned long gmu_freqs[GMU_MAX_CX_FREQS]; 109 u32 cx_arc_votes[GMU_MAX_CX_FREQS]; 110 111 unsigned long freq; 112 113 struct a6xx_hfi_queue queues[2]; 114 115 bool initialized; 116 bool hung; 117 bool legacy; /* a618 or a630 */ 118 119 /* For power domain callback */ 120 struct notifier_block pd_nb; 121 struct completion pd_gate; 122 123 struct qmp *qmp; 124 struct a6xx_hfi_msg_bw_table *bw_table; 125 126/* To check if we can trigger sleep seq at PDC. Cleared in a6xx_rpmh_stop() */ 127#define GMU_STATUS_FW_START 0 128/* To track if PDC sleep seq was done */ 129#define GMU_STATUS_PDC_SLEEP 1 130/* To track Perfcounter OOB set status */ 131#define GMU_STATUS_OOB_PERF_SET 2 132 unsigned long status; 133}; 134 135#define GMU_BYTE_OFFSET(gmu, offset) (((offset) << 2) - (gmu)->mmio_offset) 136 137static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) 138{ 139 /* The 'offset' is based on GPU's start address. Adjust it */ 140 return readl(gmu->mmio + GMU_BYTE_OFFSET(gmu, offset)); 141} 142 143static inline void gmu_write(struct a6xx_gmu *gmu, u32 offset, u32 value) 144{ 145 writel(value, gmu->mmio + GMU_BYTE_OFFSET(gmu, offset)); 146} 147 148static inline void 149gmu_write_bulk(struct a6xx_gmu *gmu, u32 offset, const u32 *data, u32 size) 150{ 151 memcpy_toio(gmu->mmio + GMU_BYTE_OFFSET(gmu, offset), data, size); 152 wmb(); 153} 154 155static inline void gmu_rmw(struct a6xx_gmu *gmu, u32 reg, u32 mask, u32 or) 156{ 157 u32 val = gmu_read(gmu, reg); 158 159 val &= ~mask; 160 161 gmu_write(gmu, reg, val | or); 162} 163 164static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi) 165{ 166 u64 val; 167 168 val = gmu_read(gmu, lo); 169 val |= ((u64) gmu_read(gmu, hi) << 32); 170 171 return val; 172} 173 174#define gmu_poll_timeout(gmu, addr, val, cond, interval, timeout) \ 175 readl_poll_timeout((gmu)->mmio + (GMU_BYTE_OFFSET(gmu, addr)), val, \ 176 cond, interval, timeout) 177#define gmu_poll_timeout_atomic(gmu, addr, val, cond, interval, timeout) \ 178 readl_poll_timeout_atomic((gmu)->mmio + (GMU_BYTE_OFFSET(gmu, addr)), val, cond, \ 179 interval, timeout) 180 181static inline u32 gmu_read_rscc(struct a6xx_gmu *gmu, u32 offset) 182{ 183 return readl(gmu->rscc + (offset << 2)); 184} 185 186static inline void gmu_write_rscc(struct a6xx_gmu *gmu, u32 offset, u32 value) 187{ 188 writel(value, gmu->rscc + (offset << 2)); 189} 190 191#define gmu_poll_timeout_rscc(gmu, addr, val, cond, interval, timeout) \ 192 readl_poll_timeout((gmu)->rscc + ((addr) << 2), val, cond, \ 193 interval, timeout) 194 195/* 196 * These are the available OOB (out of band requests) to the GMU where "out of 197 * band" means that the CPU talks to the GMU directly and not through HFI. 198 * Normally this works by writing a ITCM/DTCM register and then triggering a 199 * interrupt (the "request" bit) and waiting for an acknowledgment (the "ack" 200 * bit). The state is cleared by writing the "clear' bit to the GMU interrupt. 201 * 202 * These are used to force the GMU/GPU to stay on during a critical sequence or 203 * for hardware workarounds. 204 */ 205 206enum a6xx_gmu_oob_state { 207 /* 208 * Let the GMU know that a boot or slumber operation has started. The value in 209 * REG_A6XX_GMU_BOOT_SLUMBER_OPTION lets the GMU know which operation we are 210 * doing 211 */ 212 GMU_OOB_BOOT_SLUMBER = 0, 213 /* 214 * Let the GMU know to not turn off any GPU registers while the CPU is in a 215 * critical section 216 */ 217 GMU_OOB_GPU_SET, 218 /* 219 * Set a new power level for the GPU when the CPU is doing frequency scaling 220 */ 221 GMU_OOB_DCVS_SET, 222 /* 223 * Used to keep the GPU on for CPU-side reads of performance counters. 224 */ 225 GMU_OOB_PERFCOUNTER_SET, 226}; 227 228void a6xx_hfi_init(struct a6xx_gmu *gmu); 229int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state); 230void a6xx_hfi_stop(struct a6xx_gmu *gmu); 231int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu); 232int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, u32 perf_index, u32 bw_index); 233 234bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu); 235bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu); 236void a6xx_sptprac_disable(struct a6xx_gmu *gmu); 237int a6xx_sptprac_enable(struct a6xx_gmu *gmu); 238 239#endif
~/
Read-only file preview.