1 /* Copyright (c) 2016 The Linux Foundation. All rights reserved. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License version 2 and 5 * only version 2 as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 */ 13 14 #include "msm_gem.h" 15 #include "a5xx_gpu.h" 16 17 extern bool hang_debug; 18 static void a5xx_dump(struct msm_gpu *gpu); 19 20 static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, 21 struct msm_file_private *ctx) 22 { 23 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 24 struct msm_drm_private *priv = gpu->dev->dev_private; 25 struct msm_ringbuffer *ring = gpu->rb; 26 unsigned int i, ibs = 0; 27 28 for (i = 0; i < submit->nr_cmds; i++) { 29 switch (submit->cmd[i].type) { 30 case MSM_SUBMIT_CMD_IB_TARGET_BUF: 31 break; 32 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: 33 if (priv->lastctx == ctx) 34 break; 35 case MSM_SUBMIT_CMD_BUF: 36 OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3); 37 OUT_RING(ring, lower_32_bits(submit->cmd[i].iova)); 38 OUT_RING(ring, upper_32_bits(submit->cmd[i].iova)); 39 OUT_RING(ring, submit->cmd[i].size); 40 ibs++; 41 break; 42 } 43 } 44 45 OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1); 46 OUT_RING(ring, submit->fence->seqno); 47 48 OUT_PKT7(ring, CP_EVENT_WRITE, 4); 49 OUT_RING(ring, CACHE_FLUSH_TS | (1 << 31)); 50 OUT_RING(ring, lower_32_bits(rbmemptr(adreno_gpu, fence))); 51 OUT_RING(ring, upper_32_bits(rbmemptr(adreno_gpu, fence))); 52 OUT_RING(ring, submit->fence->seqno); 53 54 gpu->funcs->flush(gpu); 55 } 56 57 struct a5xx_hwcg { 58 u32 offset; 59 u32 value; 60 }; 61 62 static const struct a5xx_hwcg a530_hwcg[] = { 63 {REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, 64 {REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222}, 65 {REG_A5XX_RBBM_CLOCK_CNTL_SP2, 0x02222222}, 66 {REG_A5XX_RBBM_CLOCK_CNTL_SP3, 0x02222222}, 67 {REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, 68 {REG_A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220}, 69 {REG_A5XX_RBBM_CLOCK_CNTL2_SP2, 0x02222220}, 70 {REG_A5XX_RBBM_CLOCK_CNTL2_SP3, 0x02222220}, 71 {REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF}, 72 {REG_A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF}, 73 {REG_A5XX_RBBM_CLOCK_HYST_SP2, 0x0000F3CF}, 74 {REG_A5XX_RBBM_CLOCK_HYST_SP3, 0x0000F3CF}, 75 {REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080}, 76 {REG_A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080}, 77 {REG_A5XX_RBBM_CLOCK_DELAY_SP2, 0x00000080}, 78 {REG_A5XX_RBBM_CLOCK_DELAY_SP3, 0x00000080}, 79 {REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222}, 80 {REG_A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222}, 81 {REG_A5XX_RBBM_CLOCK_CNTL_TP2, 0x22222222}, 82 {REG_A5XX_RBBM_CLOCK_CNTL_TP3, 0x22222222}, 83 {REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, 84 {REG_A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222}, 85 {REG_A5XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222}, 86 {REG_A5XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222}, 87 {REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222}, 88 {REG_A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222}, 89 {REG_A5XX_RBBM_CLOCK_CNTL3_TP2, 0x00002222}, 90 {REG_A5XX_RBBM_CLOCK_CNTL3_TP3, 0x00002222}, 91 {REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, 92 {REG_A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777}, 93 {REG_A5XX_RBBM_CLOCK_HYST_TP2, 0x77777777}, 94 {REG_A5XX_RBBM_CLOCK_HYST_TP3, 0x77777777}, 95 {REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, 96 {REG_A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777}, 97 {REG_A5XX_RBBM_CLOCK_HYST2_TP2, 0x77777777}, 98 {REG_A5XX_RBBM_CLOCK_HYST2_TP3, 0x77777777}, 99 {REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777}, 100 {REG_A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777}, 101 {REG_A5XX_RBBM_CLOCK_HYST3_TP2, 0x00007777}, 102 {REG_A5XX_RBBM_CLOCK_HYST3_TP3, 0x00007777}, 103 {REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, 104 {REG_A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111}, 105 {REG_A5XX_RBBM_CLOCK_DELAY_TP2, 0x11111111}, 106 {REG_A5XX_RBBM_CLOCK_DELAY_TP3, 0x11111111}, 107 {REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, 108 {REG_A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111}, 109 {REG_A5XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111}, 110 {REG_A5XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111}, 111 {REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111}, 112 {REG_A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111}, 113 {REG_A5XX_RBBM_CLOCK_DELAY3_TP2, 0x00001111}, 114 {REG_A5XX_RBBM_CLOCK_DELAY3_TP3, 0x00001111}, 115 {REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, 116 {REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222}, 117 {REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222}, 118 {REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222}, 119 {REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444}, 120 {REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, 121 {REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, 122 {REG_A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222}, 123 {REG_A5XX_RBBM_CLOCK_CNTL_RB2, 0x22222222}, 124 {REG_A5XX_RBBM_CLOCK_CNTL_RB3, 0x22222222}, 125 {REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222}, 126 {REG_A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222}, 127 {REG_A5XX_RBBM_CLOCK_CNTL2_RB2, 0x00222222}, 128 {REG_A5XX_RBBM_CLOCK_CNTL2_RB3, 0x00222222}, 129 {REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220}, 130 {REG_A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220}, 131 {REG_A5XX_RBBM_CLOCK_CNTL_CCU2, 0x00022220}, 132 {REG_A5XX_RBBM_CLOCK_CNTL_CCU3, 0x00022220}, 133 {REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222}, 134 {REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555}, 135 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404}, 136 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404}, 137 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU2, 0x04040404}, 138 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU3, 0x04040404}, 139 {REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044}, 140 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002}, 141 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002}, 142 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_2, 0x00000002}, 143 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_3, 0x00000002}, 144 {REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011}, 145 {REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, 146 {REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222}, 147 {REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, 148 {REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, 149 {REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, 150 {REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, 151 {REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, 152 {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, 153 {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, 154 {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222} 155 }; 156 157 static const struct { 158 int (*test)(struct adreno_gpu *gpu); 159 const struct a5xx_hwcg *regs; 160 unsigned int count; 161 } a5xx_hwcg_regs[] = { 162 { adreno_is_a530, a530_hwcg, ARRAY_SIZE(a530_hwcg), }, 163 }; 164 165 static void _a5xx_enable_hwcg(struct msm_gpu *gpu, 166 const struct a5xx_hwcg *regs, unsigned int count) 167 { 168 unsigned int i; 169 170 for (i = 0; i < count; i++) 171 gpu_write(gpu, regs[i].offset, regs[i].value); 172 173 gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xAAA8AA00); 174 gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, 0x182); 175 } 176 177 static void a5xx_enable_hwcg(struct msm_gpu *gpu) 178 { 179 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 180 unsigned int i; 181 182 for (i = 0; i < ARRAY_SIZE(a5xx_hwcg_regs); i++) { 183 if (a5xx_hwcg_regs[i].test(adreno_gpu)) { 184 _a5xx_enable_hwcg(gpu, a5xx_hwcg_regs[i].regs, 185 a5xx_hwcg_regs[i].count); 186 return; 187 } 188 } 189 } 190 191 static int a5xx_me_init(struct msm_gpu *gpu) 192 { 193 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 194 struct msm_ringbuffer *ring = gpu->rb; 195 196 OUT_PKT7(ring, CP_ME_INIT, 8); 197 198 OUT_RING(ring, 0x0000002F); 199 200 /* Enable multiple hardware contexts */ 201 OUT_RING(ring, 0x00000003); 202 203 /* Enable error detection */ 204 OUT_RING(ring, 0x20000000); 205 206 /* Don't enable header dump */ 207 OUT_RING(ring, 0x00000000); 208 OUT_RING(ring, 0x00000000); 209 210 /* Specify workarounds for various microcode issues */ 211 if (adreno_is_a530(adreno_gpu)) { 212 /* Workaround for token end syncs 213 * Force a WFI after every direct-render 3D mode draw and every 214 * 2D mode 3 draw 215 */ 216 OUT_RING(ring, 0x0000000B); 217 } else { 218 /* No workarounds enabled */ 219 OUT_RING(ring, 0x00000000); 220 } 221 222 OUT_RING(ring, 0x00000000); 223 OUT_RING(ring, 0x00000000); 224 225 gpu->funcs->flush(gpu); 226 227 return gpu->funcs->idle(gpu) ? 0 : -EINVAL; 228 } 229 230 static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu, 231 const struct firmware *fw, u64 *iova) 232 { 233 struct drm_device *drm = gpu->dev; 234 struct drm_gem_object *bo; 235 void *ptr; 236 237 mutex_lock(&drm->struct_mutex); 238 bo = msm_gem_new(drm, fw->size - 4, MSM_BO_UNCACHED); 239 mutex_unlock(&drm->struct_mutex); 240 241 if (IS_ERR(bo)) 242 return bo; 243 244 ptr = msm_gem_get_vaddr(bo); 245 if (!ptr) { 246 drm_gem_object_unreference_unlocked(bo); 247 return ERR_PTR(-ENOMEM); 248 } 249 250 if (iova) { 251 int ret = msm_gem_get_iova(bo, gpu->id, iova); 252 253 if (ret) { 254 drm_gem_object_unreference_unlocked(bo); 255 return ERR_PTR(ret); 256 } 257 } 258 259 memcpy(ptr, &fw->data[4], fw->size - 4); 260 261 msm_gem_put_vaddr(bo); 262 return bo; 263 } 264 265 static int a5xx_ucode_init(struct msm_gpu *gpu) 266 { 267 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 268 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); 269 int ret; 270 271 if (!a5xx_gpu->pm4_bo) { 272 a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pm4, 273 &a5xx_gpu->pm4_iova); 274 275 if (IS_ERR(a5xx_gpu->pm4_bo)) { 276 ret = PTR_ERR(a5xx_gpu->pm4_bo); 277 a5xx_gpu->pm4_bo = NULL; 278 dev_err(gpu->dev->dev, "could not allocate PM4: %d\n", 279 ret); 280 return ret; 281 } 282 } 283 284 if (!a5xx_gpu->pfp_bo) { 285 a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pfp, 286 &a5xx_gpu->pfp_iova); 287 288 if (IS_ERR(a5xx_gpu->pfp_bo)) { 289 ret = PTR_ERR(a5xx_gpu->pfp_bo); 290 a5xx_gpu->pfp_bo = NULL; 291 dev_err(gpu->dev->dev, "could not allocate PFP: %d\n", 292 ret); 293 return ret; 294 } 295 } 296 297 gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO, 298 REG_A5XX_CP_ME_INSTR_BASE_HI, a5xx_gpu->pm4_iova); 299 300 gpu_write64(gpu, REG_A5XX_CP_PFP_INSTR_BASE_LO, 301 REG_A5XX_CP_PFP_INSTR_BASE_HI, a5xx_gpu->pfp_iova); 302 303 return 0; 304 } 305 306 #define A5XX_INT_MASK (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \ 307 A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \ 308 A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \ 309 A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \ 310 A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \ 311 A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \ 312 A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \ 313 A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \ 314 A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \ 315 A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP) 316 317 static int a5xx_hw_init(struct msm_gpu *gpu) 318 { 319 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 320 int ret; 321 322 gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003); 323 324 /* Make all blocks contribute to the GPU BUSY perf counter */ 325 gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_GPU_BUSY_MASKED, 0xFFFFFFFF); 326 327 /* Enable RBBM error reporting bits */ 328 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL0, 0x00000001); 329 330 if (adreno_gpu->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) { 331 /* 332 * Mask out the activity signals from RB1-3 to avoid false 333 * positives 334 */ 335 336 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL11, 337 0xF0000000); 338 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL12, 339 0xFFFFFFFF); 340 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL13, 341 0xFFFFFFFF); 342 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL14, 343 0xFFFFFFFF); 344 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL15, 345 0xFFFFFFFF); 346 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL16, 347 0xFFFFFFFF); 348 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL17, 349 0xFFFFFFFF); 350 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL18, 351 0xFFFFFFFF); 352 } 353 354 /* Enable fault detection */ 355 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_INT_CNTL, 356 (1 << 30) | 0xFFFF); 357 358 /* Turn on performance counters */ 359 gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_CNTL, 0x01); 360 361 /* Increase VFD cache access so LRZ and other data gets evicted less */ 362 gpu_write(gpu, REG_A5XX_UCHE_CACHE_WAYS, 0x02); 363 364 /* Disable L2 bypass in the UCHE */ 365 gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_LO, 0xFFFF0000); 366 gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_HI, 0x0001FFFF); 367 gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_LO, 0xFFFF0000); 368 gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_HI, 0x0001FFFF); 369 370 /* Set the GMEM VA range (0 to gpu->gmem) */ 371 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_LO, 0x00100000); 372 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_HI, 0x00000000); 373 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_LO, 374 0x00100000 + adreno_gpu->gmem - 1); 375 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000); 376 377 gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40); 378 gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40); 379 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060); 380 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16); 381 382 gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22)); 383 384 if (adreno_gpu->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) 385 gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); 386 387 gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); 388 389 /* Enable USE_RETENTION_FLOPS */ 390 gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000); 391 392 /* Enable ME/PFP split notification */ 393 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF); 394 395 /* Enable HWCG */ 396 a5xx_enable_hwcg(gpu); 397 398 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F); 399 400 /* Set the highest bank bit */ 401 gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, 2 << 7); 402 gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, 2 << 1); 403 404 /* Protect registers from the CP */ 405 gpu_write(gpu, REG_A5XX_CP_PROTECT_CNTL, 0x00000007); 406 407 /* RBBM */ 408 gpu_write(gpu, REG_A5XX_CP_PROTECT(0), ADRENO_PROTECT_RW(0x04, 4)); 409 gpu_write(gpu, REG_A5XX_CP_PROTECT(1), ADRENO_PROTECT_RW(0x08, 8)); 410 gpu_write(gpu, REG_A5XX_CP_PROTECT(2), ADRENO_PROTECT_RW(0x10, 16)); 411 gpu_write(gpu, REG_A5XX_CP_PROTECT(3), ADRENO_PROTECT_RW(0x20, 32)); 412 gpu_write(gpu, REG_A5XX_CP_PROTECT(4), ADRENO_PROTECT_RW(0x40, 64)); 413 gpu_write(gpu, REG_A5XX_CP_PROTECT(5), ADRENO_PROTECT_RW(0x80, 64)); 414 415 /* Content protect */ 416 gpu_write(gpu, REG_A5XX_CP_PROTECT(6), 417 ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO, 418 16)); 419 gpu_write(gpu, REG_A5XX_CP_PROTECT(7), 420 ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TRUST_CNTL, 2)); 421 422 /* CP */ 423 gpu_write(gpu, REG_A5XX_CP_PROTECT(8), ADRENO_PROTECT_RW(0x800, 64)); 424 gpu_write(gpu, REG_A5XX_CP_PROTECT(9), ADRENO_PROTECT_RW(0x840, 8)); 425 gpu_write(gpu, REG_A5XX_CP_PROTECT(10), ADRENO_PROTECT_RW(0x880, 32)); 426 gpu_write(gpu, REG_A5XX_CP_PROTECT(11), ADRENO_PROTECT_RW(0xAA0, 1)); 427 428 /* RB */ 429 gpu_write(gpu, REG_A5XX_CP_PROTECT(12), ADRENO_PROTECT_RW(0xCC0, 1)); 430 gpu_write(gpu, REG_A5XX_CP_PROTECT(13), ADRENO_PROTECT_RW(0xCF0, 2)); 431 432 /* VPC */ 433 gpu_write(gpu, REG_A5XX_CP_PROTECT(14), ADRENO_PROTECT_RW(0xE68, 8)); 434 gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 4)); 435 436 /* UCHE */ 437 gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16)); 438 439 if (adreno_is_a530(adreno_gpu)) 440 gpu_write(gpu, REG_A5XX_CP_PROTECT(17), 441 ADRENO_PROTECT_RW(0x10000, 0x8000)); 442 443 gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_CNTL, 0); 444 /* 445 * Disable the trusted memory range - we don't actually supported secure 446 * memory rendering at this point in time and we don't want to block off 447 * part of the virtual memory space. 448 */ 449 gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO, 450 REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x00000000); 451 gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000); 452 453 /* Load the GPMU firmware before starting the HW init */ 454 a5xx_gpmu_ucode_init(gpu); 455 456 ret = adreno_hw_init(gpu); 457 if (ret) 458 return ret; 459 460 ret = a5xx_ucode_init(gpu); 461 if (ret) 462 return ret; 463 464 /* Disable the interrupts through the initial bringup stage */ 465 gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK, A5XX_INT_MASK); 466 467 /* Clear ME_HALT to start the micro engine */ 468 gpu_write(gpu, REG_A5XX_CP_PFP_ME_CNTL, 0); 469 ret = a5xx_me_init(gpu); 470 if (ret) 471 return ret; 472 473 ret = a5xx_power_init(gpu); 474 if (ret) 475 return ret; 476 477 /* 478 * Send a pipeline event stat to get misbehaving counters to start 479 * ticking correctly 480 */ 481 if (adreno_is_a530(adreno_gpu)) { 482 OUT_PKT7(gpu->rb, CP_EVENT_WRITE, 1); 483 OUT_RING(gpu->rb, 0x0F); 484 485 gpu->funcs->flush(gpu); 486 if (!gpu->funcs->idle(gpu)) 487 return -EINVAL; 488 } 489 490 /* Put the GPU into unsecure mode */ 491 gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0); 492 493 return 0; 494 } 495 496 static void a5xx_recover(struct msm_gpu *gpu) 497 { 498 int i; 499 500 adreno_dump_info(gpu); 501 502 for (i = 0; i < 8; i++) { 503 printk("CP_SCRATCH_REG%d: %u\n", i, 504 gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(i))); 505 } 506 507 if (hang_debug) 508 a5xx_dump(gpu); 509 510 gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 1); 511 gpu_read(gpu, REG_A5XX_RBBM_SW_RESET_CMD); 512 gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 0); 513 adreno_recover(gpu); 514 } 515 516 static void a5xx_destroy(struct msm_gpu *gpu) 517 { 518 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 519 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); 520 521 DBG("%s", gpu->name); 522 523 if (a5xx_gpu->pm4_bo) { 524 if (a5xx_gpu->pm4_iova) 525 msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->id); 526 drm_gem_object_unreference_unlocked(a5xx_gpu->pm4_bo); 527 } 528 529 if (a5xx_gpu->pfp_bo) { 530 if (a5xx_gpu->pfp_iova) 531 msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->id); 532 drm_gem_object_unreference_unlocked(a5xx_gpu->pfp_bo); 533 } 534 535 if (a5xx_gpu->gpmu_bo) { 536 if (a5xx_gpu->gpmu_bo) 537 msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->id); 538 drm_gem_object_unreference_unlocked(a5xx_gpu->gpmu_bo); 539 } 540 541 adreno_gpu_cleanup(adreno_gpu); 542 kfree(a5xx_gpu); 543 } 544 545 static inline bool _a5xx_check_idle(struct msm_gpu *gpu) 546 { 547 if (gpu_read(gpu, REG_A5XX_RBBM_STATUS) & ~A5XX_RBBM_STATUS_HI_BUSY) 548 return false; 549 550 /* 551 * Nearly every abnormality ends up pausing the GPU and triggering a 552 * fault so we can safely just watch for this one interrupt to fire 553 */ 554 return !(gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS) & 555 A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT); 556 } 557 558 static bool a5xx_idle(struct msm_gpu *gpu) 559 { 560 /* wait for CP to drain ringbuffer: */ 561 if (!adreno_idle(gpu)) 562 return false; 563 564 if (spin_until(_a5xx_check_idle(gpu))) { 565 DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X\n", 566 gpu->name, __builtin_return_address(0), 567 gpu_read(gpu, REG_A5XX_RBBM_STATUS), 568 gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS)); 569 570 return false; 571 } 572 573 return true; 574 } 575 576 static void a5xx_cp_err_irq(struct msm_gpu *gpu) 577 { 578 u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS); 579 580 if (status & A5XX_CP_INT_CP_OPCODE_ERROR) { 581 u32 val; 582 583 gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, 0); 584 585 /* 586 * REG_A5XX_CP_PFP_STAT_DATA is indexed, and we want index 1 so 587 * read it twice 588 */ 589 590 gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA); 591 val = gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA); 592 593 dev_err_ratelimited(gpu->dev->dev, "CP | opcode error | possible opcode=0x%8.8X\n", 594 val); 595 } 596 597 if (status & A5XX_CP_INT_CP_HW_FAULT_ERROR) 598 dev_err_ratelimited(gpu->dev->dev, "CP | HW fault | status=0x%8.8X\n", 599 gpu_read(gpu, REG_A5XX_CP_HW_FAULT)); 600 601 if (status & A5XX_CP_INT_CP_DMA_ERROR) 602 dev_err_ratelimited(gpu->dev->dev, "CP | DMA error\n"); 603 604 if (status & A5XX_CP_INT_CP_REGISTER_PROTECTION_ERROR) { 605 u32 val = gpu_read(gpu, REG_A5XX_CP_PROTECT_STATUS); 606 607 dev_err_ratelimited(gpu->dev->dev, 608 "CP | protected mode error | %s | addr=0x%8.8X | status=0x%8.8X\n", 609 val & (1 << 24) ? "WRITE" : "READ", 610 (val & 0xFFFFF) >> 2, val); 611 } 612 613 if (status & A5XX_CP_INT_CP_AHB_ERROR) { 614 u32 status = gpu_read(gpu, REG_A5XX_CP_AHB_FAULT); 615 const char *access[16] = { "reserved", "reserved", 616 "timestamp lo", "timestamp hi", "pfp read", "pfp write", 617 "", "", "me read", "me write", "", "", "crashdump read", 618 "crashdump write" }; 619 620 dev_err_ratelimited(gpu->dev->dev, 621 "CP | AHB error | addr=%X access=%s error=%d | status=0x%8.8X\n", 622 status & 0xFFFFF, access[(status >> 24) & 0xF], 623 (status & (1 << 31)), status); 624 } 625 } 626 627 static void a5xx_rbbm_err_irq(struct msm_gpu *gpu) 628 { 629 u32 status = gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS); 630 631 if (status & A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR) { 632 u32 val = gpu_read(gpu, REG_A5XX_RBBM_AHB_ERROR_STATUS); 633 634 dev_err_ratelimited(gpu->dev->dev, 635 "RBBM | AHB bus error | %s | addr=0x%X | ports=0x%X:0x%X\n", 636 val & (1 << 28) ? "WRITE" : "READ", 637 (val & 0xFFFFF) >> 2, (val >> 20) & 0x3, 638 (val >> 24) & 0xF); 639 640 /* Clear the error */ 641 gpu_write(gpu, REG_A5XX_RBBM_AHB_CMD, (1 << 4)); 642 } 643 644 if (status & A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT) 645 dev_err_ratelimited(gpu->dev->dev, "RBBM | AHB transfer timeout\n"); 646 647 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT) 648 dev_err_ratelimited(gpu->dev->dev, "RBBM | ME master split | status=0x%X\n", 649 gpu_read(gpu, REG_A5XX_RBBM_AHB_ME_SPLIT_STATUS)); 650 651 if (status & A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT) 652 dev_err_ratelimited(gpu->dev->dev, "RBBM | PFP master split | status=0x%X\n", 653 gpu_read(gpu, REG_A5XX_RBBM_AHB_PFP_SPLIT_STATUS)); 654 655 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT) 656 dev_err_ratelimited(gpu->dev->dev, "RBBM | ETS master split | status=0x%X\n", 657 gpu_read(gpu, REG_A5XX_RBBM_AHB_ETS_SPLIT_STATUS)); 658 659 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW) 660 dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB ASYNC overflow\n"); 661 662 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW) 663 dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB bus overflow\n"); 664 } 665 666 static void a5xx_uche_err_irq(struct msm_gpu *gpu) 667 { 668 uint64_t addr = (uint64_t) gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_HI); 669 670 addr |= gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_LO); 671 672 dev_err_ratelimited(gpu->dev->dev, "UCHE | Out of bounds access | addr=0x%llX\n", 673 addr); 674 } 675 676 static void a5xx_gpmu_err_irq(struct msm_gpu *gpu) 677 { 678 dev_err_ratelimited(gpu->dev->dev, "GPMU | voltage droop\n"); 679 } 680 681 #define RBBM_ERROR_MASK \ 682 (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \ 683 A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \ 684 A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \ 685 A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \ 686 A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \ 687 A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW) 688 689 static irqreturn_t a5xx_irq(struct msm_gpu *gpu) 690 { 691 u32 status = gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS); 692 693 gpu_write(gpu, REG_A5XX_RBBM_INT_CLEAR_CMD, status); 694 695 if (status & RBBM_ERROR_MASK) 696 a5xx_rbbm_err_irq(gpu); 697 698 if (status & A5XX_RBBM_INT_0_MASK_CP_HW_ERROR) 699 a5xx_cp_err_irq(gpu); 700 701 if (status & A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS) 702 a5xx_uche_err_irq(gpu); 703 704 if (status & A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP) 705 a5xx_gpmu_err_irq(gpu); 706 707 if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) 708 msm_gpu_retire(gpu); 709 710 return IRQ_HANDLED; 711 } 712 713 static const u32 a5xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { 714 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A5XX_CP_RB_BASE), 715 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE_HI, REG_A5XX_CP_RB_BASE_HI), 716 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A5XX_CP_RB_RPTR_ADDR), 717 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR_HI, 718 REG_A5XX_CP_RB_RPTR_ADDR_HI), 719 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A5XX_CP_RB_RPTR), 720 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A5XX_CP_RB_WPTR), 721 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A5XX_CP_RB_CNTL), 722 }; 723 724 static const u32 a5xx_registers[] = { 725 0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B, 726 0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095, 727 0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3, 728 0x04E0, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, 0xF800, 0xF807, 729 0x0800, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860, 0x0880, 0x08A0, 730 0x0B00, 0x0B12, 0x0B15, 0x0B28, 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD, 731 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61, 0x0C80, 0x0C82, 732 0x0C84, 0x0C85, 0x0C90, 0x0C98, 0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2, 733 0x2180, 0x2185, 0x2580, 0x2585, 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7, 734 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8, 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8, 735 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E, 0x2100, 0x211E, 0x2140, 0x2145, 736 0x2500, 0x251E, 0x2540, 0x2545, 0x0D10, 0x0D17, 0x0D20, 0x0D23, 737 0x0D30, 0x0D30, 0x20C0, 0x20C0, 0x24C0, 0x24C0, 0x0E40, 0x0E43, 738 0x0E4A, 0x0E4A, 0x0E50, 0x0E57, 0x0E60, 0x0E7C, 0x0E80, 0x0E8E, 739 0x0E90, 0x0E96, 0x0EA0, 0x0EA8, 0x0EB0, 0x0EB2, 0xE140, 0xE147, 740 0xE150, 0xE187, 0xE1A0, 0xE1A9, 0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7, 741 0xE1D0, 0xE1D1, 0xE200, 0xE201, 0xE210, 0xE21C, 0xE240, 0xE268, 742 0xE000, 0xE006, 0xE010, 0xE09A, 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB, 743 0xE100, 0xE105, 0xE380, 0xE38F, 0xE3B0, 0xE3B0, 0xE400, 0xE405, 744 0xE408, 0xE4E9, 0xE4F0, 0xE4F0, 0xE280, 0xE280, 0xE282, 0xE2A3, 745 0xE2A5, 0xE2C2, 0xE940, 0xE947, 0xE950, 0xE987, 0xE9A0, 0xE9A9, 746 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7, 0xE9D0, 0xE9D1, 0xEA00, 0xEA01, 747 0xEA10, 0xEA1C, 0xEA40, 0xEA68, 0xE800, 0xE806, 0xE810, 0xE89A, 748 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB, 0xE900, 0xE905, 0xEB80, 0xEB8F, 749 0xEBB0, 0xEBB0, 0xEC00, 0xEC05, 0xEC08, 0xECE9, 0xECF0, 0xECF0, 750 0xEA80, 0xEA80, 0xEA82, 0xEAA3, 0xEAA5, 0xEAC2, 0xA800, 0xA8FF, 751 0xAC60, 0xAC60, 0xB000, 0xB97F, 0xB9A0, 0xB9BF, 752 ~0 753 }; 754 755 static void a5xx_dump(struct msm_gpu *gpu) 756 { 757 dev_info(gpu->dev->dev, "status: %08x\n", 758 gpu_read(gpu, REG_A5XX_RBBM_STATUS)); 759 adreno_dump(gpu); 760 } 761 762 static int a5xx_pm_resume(struct msm_gpu *gpu) 763 { 764 int ret; 765 766 /* Turn on the core power */ 767 ret = msm_gpu_pm_resume(gpu); 768 if (ret) 769 return ret; 770 771 /* Turn the RBCCU domain first to limit the chances of voltage droop */ 772 gpu_write(gpu, REG_A5XX_GPMU_RBCCU_POWER_CNTL, 0x778000); 773 774 /* Wait 3 usecs before polling */ 775 udelay(3); 776 777 ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS, 778 (1 << 20), (1 << 20)); 779 if (ret) { 780 DRM_ERROR("%s: timeout waiting for RBCCU GDSC enable: %X\n", 781 gpu->name, 782 gpu_read(gpu, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS)); 783 return ret; 784 } 785 786 /* Turn on the SP domain */ 787 gpu_write(gpu, REG_A5XX_GPMU_SP_POWER_CNTL, 0x778000); 788 ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_SP_PWR_CLK_STATUS, 789 (1 << 20), (1 << 20)); 790 if (ret) 791 DRM_ERROR("%s: timeout waiting for SP GDSC enable\n", 792 gpu->name); 793 794 return ret; 795 } 796 797 static int a5xx_pm_suspend(struct msm_gpu *gpu) 798 { 799 /* Clear the VBIF pipe before shutting down */ 800 gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0xF); 801 spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) & 0xF) == 0xF); 802 803 gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0); 804 805 /* 806 * Reset the VBIF before power collapse to avoid issue with FIFO 807 * entries 808 */ 809 gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C0000); 810 gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x00000000); 811 812 return msm_gpu_pm_suspend(gpu); 813 } 814 815 static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) 816 { 817 *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_CP_0_LO, 818 REG_A5XX_RBBM_PERFCTR_CP_0_HI); 819 820 return 0; 821 } 822 823 #ifdef CONFIG_DEBUG_FS 824 static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m) 825 { 826 gpu->funcs->pm_resume(gpu); 827 828 seq_printf(m, "status: %08x\n", 829 gpu_read(gpu, REG_A5XX_RBBM_STATUS)); 830 gpu->funcs->pm_suspend(gpu); 831 832 adreno_show(gpu, m); 833 } 834 #endif 835 836 static const struct adreno_gpu_funcs funcs = { 837 .base = { 838 .get_param = adreno_get_param, 839 .hw_init = a5xx_hw_init, 840 .pm_suspend = a5xx_pm_suspend, 841 .pm_resume = a5xx_pm_resume, 842 .recover = a5xx_recover, 843 .last_fence = adreno_last_fence, 844 .submit = a5xx_submit, 845 .flush = adreno_flush, 846 .idle = a5xx_idle, 847 .irq = a5xx_irq, 848 .destroy = a5xx_destroy, 849 .show = a5xx_show, 850 }, 851 .get_timestamp = a5xx_get_timestamp, 852 }; 853 854 struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) 855 { 856 struct msm_drm_private *priv = dev->dev_private; 857 struct platform_device *pdev = priv->gpu_pdev; 858 struct a5xx_gpu *a5xx_gpu = NULL; 859 struct adreno_gpu *adreno_gpu; 860 struct msm_gpu *gpu; 861 int ret; 862 863 if (!pdev) { 864 dev_err(dev->dev, "No A5XX device is defined\n"); 865 return ERR_PTR(-ENXIO); 866 } 867 868 a5xx_gpu = kzalloc(sizeof(*a5xx_gpu), GFP_KERNEL); 869 if (!a5xx_gpu) 870 return ERR_PTR(-ENOMEM); 871 872 adreno_gpu = &a5xx_gpu->base; 873 gpu = &adreno_gpu->base; 874 875 a5xx_gpu->pdev = pdev; 876 adreno_gpu->registers = a5xx_registers; 877 adreno_gpu->reg_offsets = a5xx_register_offsets; 878 879 a5xx_gpu->lm_leakage = 0x4E001A; 880 881 ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs); 882 if (ret) { 883 a5xx_destroy(&(a5xx_gpu->base.base)); 884 return ERR_PTR(ret); 885 } 886 887 return gpu; 888 } 889