1 /* 2 * Copyright (C) 2013 Red Hat 3 * Author: Rob Clark <robdclark@gmail.com> 4 * 5 * Copyright (c) 2014 The Linux Foundation. All rights reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 as published by 9 * the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 * more details. 15 * 16 * You should have received a copy of the GNU General Public License along with 17 * this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef __ADRENO_GPU_H__ 21 #define __ADRENO_GPU_H__ 22 23 #include <linux/firmware.h> 24 25 #include "msm_gpu.h" 26 27 #include "adreno_common.xml.h" 28 #include "adreno_pm4.xml.h" 29 30 #define REG_ADRENO_DEFINE(_offset, _reg) [_offset] = (_reg) + 1 31 /** 32 * adreno_regs: List of registers that are used in across all 33 * 3D devices. Each device type has different offset value for the same 34 * register, so an array of register offsets are declared for every device 35 * and are indexed by the enumeration values defined in this enum 36 */ 37 enum adreno_regs { 38 REG_ADRENO_CP_DEBUG, 39 REG_ADRENO_CP_ME_RAM_WADDR, 40 REG_ADRENO_CP_ME_RAM_DATA, 41 REG_ADRENO_CP_PFP_UCODE_DATA, 42 REG_ADRENO_CP_PFP_UCODE_ADDR, 43 REG_ADRENO_CP_WFI_PEND_CTR, 44 REG_ADRENO_CP_RB_BASE, 45 REG_ADRENO_CP_RB_RPTR_ADDR, 46 REG_ADRENO_CP_RB_RPTR, 47 REG_ADRENO_CP_RB_WPTR, 48 REG_ADRENO_CP_PROTECT_CTRL, 49 REG_ADRENO_CP_ME_CNTL, 50 REG_ADRENO_CP_RB_CNTL, 51 REG_ADRENO_CP_IB1_BASE, 52 REG_ADRENO_CP_IB1_BUFSZ, 53 REG_ADRENO_CP_IB2_BASE, 54 REG_ADRENO_CP_IB2_BUFSZ, 55 REG_ADRENO_CP_TIMESTAMP, 56 REG_ADRENO_CP_ME_RAM_RADDR, 57 REG_ADRENO_CP_ROQ_ADDR, 58 REG_ADRENO_CP_ROQ_DATA, 59 REG_ADRENO_CP_MERCIU_ADDR, 60 REG_ADRENO_CP_MERCIU_DATA, 61 REG_ADRENO_CP_MERCIU_DATA2, 62 REG_ADRENO_CP_MEQ_ADDR, 63 REG_ADRENO_CP_MEQ_DATA, 64 REG_ADRENO_CP_HW_FAULT, 65 REG_ADRENO_CP_PROTECT_STATUS, 66 REG_ADRENO_SCRATCH_ADDR, 67 REG_ADRENO_SCRATCH_UMSK, 68 REG_ADRENO_SCRATCH_REG2, 69 REG_ADRENO_RBBM_STATUS, 70 REG_ADRENO_RBBM_PERFCTR_CTL, 71 REG_ADRENO_RBBM_PERFCTR_LOAD_CMD0, 72 REG_ADRENO_RBBM_PERFCTR_LOAD_CMD1, 73 REG_ADRENO_RBBM_PERFCTR_LOAD_CMD2, 74 REG_ADRENO_RBBM_PERFCTR_PWR_1_LO, 75 REG_ADRENO_RBBM_INT_0_MASK, 76 REG_ADRENO_RBBM_INT_0_STATUS, 77 REG_ADRENO_RBBM_AHB_ERROR_STATUS, 78 REG_ADRENO_RBBM_PM_OVERRIDE2, 79 REG_ADRENO_RBBM_AHB_CMD, 80 REG_ADRENO_RBBM_INT_CLEAR_CMD, 81 REG_ADRENO_RBBM_SW_RESET_CMD, 82 REG_ADRENO_RBBM_CLOCK_CTL, 83 REG_ADRENO_RBBM_AHB_ME_SPLIT_STATUS, 84 REG_ADRENO_RBBM_AHB_PFP_SPLIT_STATUS, 85 REG_ADRENO_VPC_DEBUG_RAM_SEL, 86 REG_ADRENO_VPC_DEBUG_RAM_READ, 87 REG_ADRENO_VSC_SIZE_ADDRESS, 88 REG_ADRENO_VFD_CONTROL_0, 89 REG_ADRENO_VFD_INDEX_MAX, 90 REG_ADRENO_SP_VS_PVT_MEM_ADDR_REG, 91 REG_ADRENO_SP_FS_PVT_MEM_ADDR_REG, 92 REG_ADRENO_SP_VS_OBJ_START_REG, 93 REG_ADRENO_SP_FS_OBJ_START_REG, 94 REG_ADRENO_PA_SC_AA_CONFIG, 95 REG_ADRENO_SQ_GPR_MANAGEMENT, 96 REG_ADRENO_SQ_INST_STORE_MANAGMENT, 97 REG_ADRENO_TP0_CHICKEN, 98 REG_ADRENO_RBBM_RBBM_CTL, 99 REG_ADRENO_UCHE_INVALIDATE0, 100 REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_LO, 101 REG_ADRENO_RBBM_PERFCTR_LOAD_VALUE_HI, 102 REG_ADRENO_REGISTER_MAX, 103 }; 104 105 struct adreno_rev { 106 uint8_t core; 107 uint8_t major; 108 uint8_t minor; 109 uint8_t patchid; 110 }; 111 112 #define ADRENO_REV(core, major, minor, patchid) \ 113 ((struct adreno_rev){ core, major, minor, patchid }) 114 115 struct adreno_gpu_funcs { 116 struct msm_gpu_funcs base; 117 int (*get_timestamp)(struct msm_gpu *gpu, uint64_t *value); 118 }; 119 120 struct adreno_info { 121 struct adreno_rev rev; 122 uint32_t revn; 123 const char *name; 124 const char *pm4fw, *pfpfw; 125 uint32_t gmem; 126 struct msm_gpu *(*init)(struct drm_device *dev); 127 }; 128 129 const struct adreno_info *adreno_info(struct adreno_rev rev); 130 131 struct adreno_rbmemptrs { 132 volatile uint32_t rptr; 133 volatile uint32_t wptr; 134 volatile uint32_t fence; 135 }; 136 137 struct adreno_gpu { 138 struct msm_gpu base; 139 struct adreno_rev rev; 140 const struct adreno_info *info; 141 uint32_t gmem; /* actual gmem size */ 142 uint32_t revn; /* numeric revision name */ 143 const struct adreno_gpu_funcs *funcs; 144 145 /* interesting register offsets to dump: */ 146 const unsigned int *registers; 147 148 /* firmware: */ 149 const struct firmware *pm4, *pfp; 150 151 /* ringbuffer rptr/wptr: */ 152 // TODO should this be in msm_ringbuffer? I think it would be 153 // different for z180.. 154 struct adreno_rbmemptrs *memptrs; 155 struct drm_gem_object *memptrs_bo; 156 uint32_t memptrs_iova; 157 158 /* 159 * Register offsets are different between some GPUs. 160 * GPU specific offsets will be exported by GPU specific 161 * code (a3xx_gpu.c) and stored in this common location. 162 */ 163 const unsigned int *reg_offsets; 164 }; 165 #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base) 166 167 /* platform config data (ie. from DT, or pdata) */ 168 struct adreno_platform_config { 169 struct adreno_rev rev; 170 uint32_t fast_rate, slow_rate, bus_freq; 171 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING 172 struct msm_bus_scale_pdata *bus_scale_table; 173 #endif 174 }; 175 176 #define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000) 177 178 #define spin_until(X) ({ \ 179 int __ret = -ETIMEDOUT; \ 180 unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \ 181 do { \ 182 if (X) { \ 183 __ret = 0; \ 184 break; \ 185 } \ 186 } while (time_before(jiffies, __t)); \ 187 __ret; \ 188 }) 189 190 191 static inline bool adreno_is_a3xx(struct adreno_gpu *gpu) 192 { 193 return (gpu->revn >= 300) && (gpu->revn < 400); 194 } 195 196 static inline bool adreno_is_a305(struct adreno_gpu *gpu) 197 { 198 return gpu->revn == 305; 199 } 200 201 static inline bool adreno_is_a306(struct adreno_gpu *gpu) 202 { 203 /* yes, 307, because a305c is 306 */ 204 return gpu->revn == 307; 205 } 206 207 static inline bool adreno_is_a320(struct adreno_gpu *gpu) 208 { 209 return gpu->revn == 320; 210 } 211 212 static inline bool adreno_is_a330(struct adreno_gpu *gpu) 213 { 214 return gpu->revn == 330; 215 } 216 217 static inline bool adreno_is_a330v2(struct adreno_gpu *gpu) 218 { 219 return adreno_is_a330(gpu) && (gpu->rev.patchid > 0); 220 } 221 222 static inline bool adreno_is_a4xx(struct adreno_gpu *gpu) 223 { 224 return (gpu->revn >= 400) && (gpu->revn < 500); 225 } 226 227 static inline int adreno_is_a420(struct adreno_gpu *gpu) 228 { 229 return gpu->revn == 420; 230 } 231 232 static inline int adreno_is_a430(struct adreno_gpu *gpu) 233 { 234 return gpu->revn == 430; 235 } 236 237 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value); 238 int adreno_hw_init(struct msm_gpu *gpu); 239 uint32_t adreno_last_fence(struct msm_gpu *gpu); 240 void adreno_recover(struct msm_gpu *gpu); 241 void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, 242 struct msm_file_private *ctx); 243 void adreno_flush(struct msm_gpu *gpu); 244 void adreno_idle(struct msm_gpu *gpu); 245 #ifdef CONFIG_DEBUG_FS 246 void adreno_show(struct msm_gpu *gpu, struct seq_file *m); 247 #endif 248 void adreno_dump_info(struct msm_gpu *gpu); 249 void adreno_dump(struct msm_gpu *gpu); 250 void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords); 251 252 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, 253 struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs); 254 void adreno_gpu_cleanup(struct adreno_gpu *gpu); 255 256 257 /* ringbuffer helpers (the parts that are adreno specific) */ 258 259 static inline void 260 OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt) 261 { 262 adreno_wait_ring(ring->gpu, cnt+1); 263 OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF)); 264 } 265 266 /* no-op packet: */ 267 static inline void 268 OUT_PKT2(struct msm_ringbuffer *ring) 269 { 270 adreno_wait_ring(ring->gpu, 1); 271 OUT_RING(ring, CP_TYPE2_PKT); 272 } 273 274 static inline void 275 OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) 276 { 277 adreno_wait_ring(ring->gpu, cnt+1); 278 OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8)); 279 } 280 281 /* 282 * adreno_checkreg_off() - Checks the validity of a register enum 283 * @gpu: Pointer to struct adreno_gpu 284 * @offset_name: The register enum that is checked 285 */ 286 static inline bool adreno_reg_check(struct adreno_gpu *gpu, 287 enum adreno_regs offset_name) 288 { 289 if (offset_name >= REG_ADRENO_REGISTER_MAX || 290 !gpu->reg_offsets[offset_name]) { 291 BUG(); 292 } 293 return true; 294 } 295 296 static inline u32 adreno_gpu_read(struct adreno_gpu *gpu, 297 enum adreno_regs offset_name) 298 { 299 u32 reg = gpu->reg_offsets[offset_name]; 300 u32 val = 0; 301 if(adreno_reg_check(gpu,offset_name)) 302 val = gpu_read(&gpu->base, reg - 1); 303 return val; 304 } 305 306 static inline void adreno_gpu_write(struct adreno_gpu *gpu, 307 enum adreno_regs offset_name, u32 data) 308 { 309 u32 reg = gpu->reg_offsets[offset_name]; 310 if(adreno_reg_check(gpu, offset_name)) 311 gpu_write(&gpu->base, reg - 1, data); 312 } 313 314 #endif /* __ADRENO_GPU_H__ */ 315