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 }; 118 119 struct adreno_info { 120 struct adreno_rev rev; 121 uint32_t revn; 122 const char *name; 123 const char *pm4fw, *pfpfw; 124 uint32_t gmem; 125 struct msm_gpu *(*init)(struct drm_device *dev); 126 }; 127 128 const struct adreno_info *adreno_info(struct adreno_rev rev); 129 130 struct adreno_rbmemptrs { 131 volatile uint32_t rptr; 132 volatile uint32_t wptr; 133 volatile uint32_t fence; 134 }; 135 136 struct adreno_gpu { 137 struct msm_gpu base; 138 struct adreno_rev rev; 139 const struct adreno_info *info; 140 uint32_t gmem; /* actual gmem size */ 141 uint32_t revn; /* numeric revision name */ 142 const struct adreno_gpu_funcs *funcs; 143 144 /* interesting register offsets to dump: */ 145 const unsigned int *registers; 146 147 /* firmware: */ 148 const struct firmware *pm4, *pfp; 149 150 /* ringbuffer rptr/wptr: */ 151 // TODO should this be in msm_ringbuffer? I think it would be 152 // different for z180.. 153 struct adreno_rbmemptrs *memptrs; 154 struct drm_gem_object *memptrs_bo; 155 uint32_t memptrs_iova; 156 157 /* 158 * Register offsets are different between some GPUs. 159 * GPU specific offsets will be exported by GPU specific 160 * code (a3xx_gpu.c) and stored in this common location. 161 */ 162 const unsigned int *reg_offsets; 163 }; 164 #define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base) 165 166 /* platform config data (ie. from DT, or pdata) */ 167 struct adreno_platform_config { 168 struct adreno_rev rev; 169 uint32_t fast_rate, slow_rate, bus_freq; 170 #ifdef DOWNSTREAM_CONFIG_MSM_BUS_SCALING 171 struct msm_bus_scale_pdata *bus_scale_table; 172 #endif 173 }; 174 175 #define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000) 176 177 #define spin_until(X) ({ \ 178 int __ret = -ETIMEDOUT; \ 179 unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \ 180 do { \ 181 if (X) { \ 182 __ret = 0; \ 183 break; \ 184 } \ 185 } while (time_before(jiffies, __t)); \ 186 __ret; \ 187 }) 188 189 190 static inline bool adreno_is_a3xx(struct adreno_gpu *gpu) 191 { 192 return (gpu->revn >= 300) && (gpu->revn < 400); 193 } 194 195 static inline bool adreno_is_a305(struct adreno_gpu *gpu) 196 { 197 return gpu->revn == 305; 198 } 199 200 static inline bool adreno_is_a306(struct adreno_gpu *gpu) 201 { 202 /* yes, 307, because a305c is 306 */ 203 return gpu->revn == 307; 204 } 205 206 static inline bool adreno_is_a320(struct adreno_gpu *gpu) 207 { 208 return gpu->revn == 320; 209 } 210 211 static inline bool adreno_is_a330(struct adreno_gpu *gpu) 212 { 213 return gpu->revn == 330; 214 } 215 216 static inline bool adreno_is_a330v2(struct adreno_gpu *gpu) 217 { 218 return adreno_is_a330(gpu) && (gpu->rev.patchid > 0); 219 } 220 221 static inline bool adreno_is_a4xx(struct adreno_gpu *gpu) 222 { 223 return (gpu->revn >= 400) && (gpu->revn < 500); 224 } 225 226 static inline int adreno_is_a420(struct adreno_gpu *gpu) 227 { 228 return gpu->revn == 420; 229 } 230 231 int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value); 232 int adreno_hw_init(struct msm_gpu *gpu); 233 uint32_t adreno_last_fence(struct msm_gpu *gpu); 234 void adreno_recover(struct msm_gpu *gpu); 235 int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, 236 struct msm_file_private *ctx); 237 void adreno_flush(struct msm_gpu *gpu); 238 void adreno_idle(struct msm_gpu *gpu); 239 #ifdef CONFIG_DEBUG_FS 240 void adreno_show(struct msm_gpu *gpu, struct seq_file *m); 241 #endif 242 void adreno_dump_info(struct msm_gpu *gpu); 243 void adreno_dump(struct msm_gpu *gpu); 244 void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords); 245 246 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, 247 struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs); 248 void adreno_gpu_cleanup(struct adreno_gpu *gpu); 249 250 251 /* ringbuffer helpers (the parts that are adreno specific) */ 252 253 static inline void 254 OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt) 255 { 256 adreno_wait_ring(ring->gpu, cnt+1); 257 OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF)); 258 } 259 260 /* no-op packet: */ 261 static inline void 262 OUT_PKT2(struct msm_ringbuffer *ring) 263 { 264 adreno_wait_ring(ring->gpu, 1); 265 OUT_RING(ring, CP_TYPE2_PKT); 266 } 267 268 static inline void 269 OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) 270 { 271 adreno_wait_ring(ring->gpu, cnt+1); 272 OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8)); 273 } 274 275 /* 276 * adreno_checkreg_off() - Checks the validity of a register enum 277 * @gpu: Pointer to struct adreno_gpu 278 * @offset_name: The register enum that is checked 279 */ 280 static inline bool adreno_reg_check(struct adreno_gpu *gpu, 281 enum adreno_regs offset_name) 282 { 283 if (offset_name >= REG_ADRENO_REGISTER_MAX || 284 !gpu->reg_offsets[offset_name]) { 285 BUG(); 286 } 287 return true; 288 } 289 290 static inline u32 adreno_gpu_read(struct adreno_gpu *gpu, 291 enum adreno_regs offset_name) 292 { 293 u32 reg = gpu->reg_offsets[offset_name]; 294 u32 val = 0; 295 if(adreno_reg_check(gpu,offset_name)) 296 val = gpu_read(&gpu->base, reg - 1); 297 return val; 298 } 299 300 static inline void adreno_gpu_write(struct adreno_gpu *gpu, 301 enum adreno_regs offset_name, u32 data) 302 { 303 u32 reg = gpu->reg_offsets[offset_name]; 304 if(adreno_reg_check(gpu, offset_name)) 305 gpu_write(&gpu->base, reg - 1, data); 306 } 307 308 #endif /* __ADRENO_GPU_H__ */ 309