1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2013 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 * 6 * Copyright (c) 2014 The Linux Foundation. All rights reserved. 7 */ 8 9 #include "a3xx_gpu.h" 10 11 #define A3XX_INT0_MASK \ 12 (A3XX_INT0_RBBM_AHB_ERROR | \ 13 A3XX_INT0_RBBM_ATB_BUS_OVERFLOW | \ 14 A3XX_INT0_CP_T0_PACKET_IN_IB | \ 15 A3XX_INT0_CP_OPCODE_ERROR | \ 16 A3XX_INT0_CP_RESERVED_BIT_ERROR | \ 17 A3XX_INT0_CP_HW_FAULT | \ 18 A3XX_INT0_CP_IB1_INT | \ 19 A3XX_INT0_CP_IB2_INT | \ 20 A3XX_INT0_CP_RB_INT | \ 21 A3XX_INT0_CP_REG_PROTECT_FAULT | \ 22 A3XX_INT0_CP_AHB_ERROR_HALT | \ 23 A3XX_INT0_CACHE_FLUSH_TS | \ 24 A3XX_INT0_UCHE_OOB_ACCESS) 25 26 extern bool hang_debug; 27 28 #define A3XX_VBIF_XIN_HALT_CTRL0_MASK GENMASK(5, 0) 29 30 static void a3xx_dump(struct msm_gpu *gpu); 31 static bool a3xx_idle(struct msm_gpu *gpu); 32 33 static void a3xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) 34 { 35 struct msm_ringbuffer *ring = submit->ring; 36 unsigned int i; 37 38 for (i = 0; i < submit->nr_cmds; i++) { 39 switch (submit->cmd[i].type) { 40 case MSM_SUBMIT_CMD_IB_TARGET_BUF: 41 /* ignore IB-targets */ 42 break; 43 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: 44 /* ignore if there has not been a ctx switch: */ 45 if (ring->cur_ctx_seqno == submit->queue->ctx->seqno) 46 break; 47 fallthrough; 48 case MSM_SUBMIT_CMD_BUF: 49 OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFD, 2); 50 OUT_RING(ring, lower_32_bits(submit->cmd[i].iova)); 51 OUT_RING(ring, submit->cmd[i].size); 52 OUT_PKT2(ring); 53 break; 54 } 55 } 56 57 OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1); 58 OUT_RING(ring, submit->seqno); 59 60 /* Flush HLSQ lazy updates to make sure there is nothing 61 * pending for indirect loads after the timestamp has 62 * passed: 63 */ 64 OUT_PKT3(ring, CP_EVENT_WRITE, 1); 65 OUT_RING(ring, HLSQ_FLUSH); 66 67 /* wait for idle before cache flush/interrupt */ 68 OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1); 69 OUT_RING(ring, 0x00000000); 70 71 /* BIT(31) of CACHE_FLUSH_TS triggers CACHE_FLUSH_TS IRQ from GPU */ 72 OUT_PKT3(ring, CP_EVENT_WRITE, 3); 73 OUT_RING(ring, CACHE_FLUSH_TS | CP_EVENT_WRITE_0_IRQ); 74 OUT_RING(ring, rbmemptr(ring, fence)); 75 OUT_RING(ring, submit->seqno); 76 77 #if 0 78 /* Dummy set-constant to trigger context rollover */ 79 OUT_PKT3(ring, CP_SET_CONSTANT, 2); 80 OUT_RING(ring, CP_REG(REG_A3XX_HLSQ_CL_KERNEL_GROUP_X_REG)); 81 OUT_RING(ring, 0x00000000); 82 #endif 83 84 adreno_flush(gpu, ring, REG_AXXX_CP_RB_WPTR); 85 } 86 87 static bool a3xx_me_init(struct msm_gpu *gpu) 88 { 89 struct msm_ringbuffer *ring = gpu->rb[0]; 90 91 OUT_PKT3(ring, CP_ME_INIT, 17); 92 OUT_RING(ring, 0x000003f7); 93 OUT_RING(ring, 0x00000000); 94 OUT_RING(ring, 0x00000000); 95 OUT_RING(ring, 0x00000000); 96 OUT_RING(ring, 0x00000080); 97 OUT_RING(ring, 0x00000100); 98 OUT_RING(ring, 0x00000180); 99 OUT_RING(ring, 0x00006600); 100 OUT_RING(ring, 0x00000150); 101 OUT_RING(ring, 0x0000014e); 102 OUT_RING(ring, 0x00000154); 103 OUT_RING(ring, 0x00000001); 104 OUT_RING(ring, 0x00000000); 105 OUT_RING(ring, 0x00000000); 106 OUT_RING(ring, 0x00000000); 107 OUT_RING(ring, 0x00000000); 108 OUT_RING(ring, 0x00000000); 109 110 adreno_flush(gpu, ring, REG_AXXX_CP_RB_WPTR); 111 return a3xx_idle(gpu); 112 } 113 114 static int a3xx_hw_init(struct msm_gpu *gpu) 115 { 116 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 117 struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu); 118 uint32_t *ptr, len; 119 int i, ret; 120 121 DBG("%s", gpu->name); 122 123 if (adreno_is_a305(adreno_gpu)) { 124 /* Set up 16 deep read/write request queues: */ 125 gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010); 126 gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010); 127 gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010); 128 gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010); 129 gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); 130 gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010); 131 gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010); 132 /* Enable WR-REQ: */ 133 gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff); 134 /* Set up round robin arbitration between both AXI ports: */ 135 gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030); 136 /* Set up AOOO: */ 137 gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c); 138 gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c); 139 } else if (adreno_is_a305b(adreno_gpu)) { 140 gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x00181818); 141 gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x00181818); 142 gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x00000018); 143 gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x00000018); 144 gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x00000303); 145 gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003); 146 } else if (adreno_is_a306(adreno_gpu)) { 147 gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003); 148 gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x0000000a); 149 gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x0000000a); 150 } else if (adreno_is_a306a(adreno_gpu)) { 151 gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003); 152 gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x00000010); 153 gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x00000010); 154 } else if (adreno_is_a320(adreno_gpu)) { 155 /* Set up 16 deep read/write request queues: */ 156 gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010); 157 gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010); 158 gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010); 159 gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010); 160 gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); 161 gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010); 162 gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010); 163 /* Enable WR-REQ: */ 164 gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff); 165 /* Set up round robin arbitration between both AXI ports: */ 166 gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030); 167 /* Set up AOOO: */ 168 gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c); 169 gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c); 170 /* Enable 1K sort: */ 171 gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x000000ff); 172 gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4); 173 174 } else if (adreno_is_a330v2(adreno_gpu)) { 175 /* 176 * Most of the VBIF registers on 8974v2 have the correct 177 * values at power on, so we won't modify those if we don't 178 * need to 179 */ 180 /* Enable 1k sort: */ 181 gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x0001003f); 182 gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4); 183 /* Enable WR-REQ: */ 184 gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003f); 185 gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); 186 /* Set up VBIF_ROUND_ROBIN_QOS_ARB: */ 187 gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003); 188 189 } else if (adreno_is_a330(adreno_gpu)) { 190 /* Set up 16 deep read/write request queues: */ 191 gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x18181818); 192 gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x18181818); 193 gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x18181818); 194 gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x18181818); 195 gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); 196 gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x18181818); 197 gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x18181818); 198 /* Enable WR-REQ: */ 199 gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003f); 200 /* Set up round robin arbitration between both AXI ports: */ 201 gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030); 202 /* Set up VBIF_ROUND_ROBIN_QOS_ARB: */ 203 gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0001); 204 /* Set up AOOO: */ 205 gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003f); 206 gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003f003f); 207 /* Enable 1K sort: */ 208 gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x0001003f); 209 gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4); 210 /* Disable VBIF clock gating. This is to enable AXI running 211 * higher frequency than GPU: 212 */ 213 gpu_write(gpu, REG_A3XX_VBIF_CLKON, 0x00000001); 214 215 } else { 216 BUG(); 217 } 218 219 /* Make all blocks contribute to the GPU BUSY perf counter: */ 220 gpu_write(gpu, REG_A3XX_RBBM_GPU_BUSY_MASKED, 0xffffffff); 221 222 /* Tune the hystersis counters for SP and CP idle detection: */ 223 gpu_write(gpu, REG_A3XX_RBBM_SP_HYST_CNT, 0x10); 224 gpu_write(gpu, REG_A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10); 225 226 /* Enable the RBBM error reporting bits. This lets us get 227 * useful information on failure: 228 */ 229 gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL0, 0x00000001); 230 231 /* Enable AHB error reporting: */ 232 gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL1, 0xa6ffffff); 233 234 /* Turn on the power counters: */ 235 gpu_write(gpu, REG_A3XX_RBBM_RBBM_CTL, 0x00030000); 236 237 /* Turn on hang detection - this spews a lot of useful information 238 * into the RBBM registers on a hang: 239 */ 240 gpu_write(gpu, REG_A3XX_RBBM_INTERFACE_HANG_INT_CTL, 0x00010fff); 241 242 /* Enable 64-byte cacheline size. HW Default is 32-byte (0x000000E0): */ 243 gpu_write(gpu, REG_A3XX_UCHE_CACHE_MODE_CONTROL_REG, 0x00000001); 244 245 /* Enable Clock gating: */ 246 if (adreno_is_a305b(adreno_gpu) || 247 adreno_is_a306(adreno_gpu) || 248 adreno_is_a306a(adreno_gpu)) 249 gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xaaaaaaaa); 250 else if (adreno_is_a320(adreno_gpu)) 251 gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbfffffff); 252 else if (adreno_is_a330v2(adreno_gpu)) 253 gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xaaaaaaaa); 254 else if (adreno_is_a330(adreno_gpu)) 255 gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbffcffff); 256 257 if (adreno_is_a330v2(adreno_gpu)) 258 gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x05515455); 259 else if (adreno_is_a330(adreno_gpu)) 260 gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x00000000); 261 262 /* Set the OCMEM base address for A330, etc */ 263 if (a3xx_gpu->ocmem.hdl) { 264 gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR, 265 (unsigned int)(a3xx_gpu->ocmem.base >> 14)); 266 } 267 268 /* Turn on performance counters: */ 269 gpu_write(gpu, REG_A3XX_RBBM_PERFCTR_CTL, 0x01); 270 271 gpu_write(gpu, REG_A3XX_RBBM_INT_0_MASK, A3XX_INT0_MASK); 272 273 ret = adreno_hw_init(gpu); 274 if (ret) 275 return ret; 276 277 /* 278 * Use the default ringbuffer size and block size but disable the RPTR 279 * shadow 280 */ 281 gpu_write(gpu, REG_AXXX_CP_RB_CNTL, 282 MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); 283 284 /* Set the ringbuffer address */ 285 gpu_write(gpu, REG_AXXX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova)); 286 287 /* setup access protection: */ 288 gpu_write(gpu, REG_A3XX_CP_PROTECT_CTRL, 0x00000007); 289 290 /* RBBM registers */ 291 gpu_write(gpu, REG_A3XX_CP_PROTECT(0), 0x63000040); 292 gpu_write(gpu, REG_A3XX_CP_PROTECT(1), 0x62000080); 293 gpu_write(gpu, REG_A3XX_CP_PROTECT(2), 0x600000cc); 294 gpu_write(gpu, REG_A3XX_CP_PROTECT(3), 0x60000108); 295 gpu_write(gpu, REG_A3XX_CP_PROTECT(4), 0x64000140); 296 gpu_write(gpu, REG_A3XX_CP_PROTECT(5), 0x66000400); 297 298 /* CP registers */ 299 gpu_write(gpu, REG_A3XX_CP_PROTECT(6), 0x65000700); 300 gpu_write(gpu, REG_A3XX_CP_PROTECT(7), 0x610007d8); 301 gpu_write(gpu, REG_A3XX_CP_PROTECT(8), 0x620007e0); 302 gpu_write(gpu, REG_A3XX_CP_PROTECT(9), 0x61001178); 303 gpu_write(gpu, REG_A3XX_CP_PROTECT(10), 0x64001180); 304 305 /* RB registers */ 306 gpu_write(gpu, REG_A3XX_CP_PROTECT(11), 0x60003300); 307 308 /* VBIF registers */ 309 gpu_write(gpu, REG_A3XX_CP_PROTECT(12), 0x6b00c000); 310 311 /* NOTE: PM4/micro-engine firmware registers look to be the same 312 * for a2xx and a3xx.. we could possibly push that part down to 313 * adreno_gpu base class. Or push both PM4 and PFP but 314 * parameterize the pfp ucode addr/data registers.. 315 */ 316 317 /* Load PM4: */ 318 ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data); 319 len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4; 320 DBG("loading PM4 ucode version: %x", ptr[1]); 321 322 gpu_write(gpu, REG_AXXX_CP_DEBUG, 323 AXXX_CP_DEBUG_DYNAMIC_CLK_DISABLE | 324 AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE); 325 gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0); 326 for (i = 1; i < len; i++) 327 gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]); 328 329 /* Load PFP: */ 330 ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data); 331 len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4; 332 DBG("loading PFP ucode version: %x", ptr[5]); 333 334 gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0); 335 for (i = 1; i < len; i++) 336 gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_DATA, ptr[i]); 337 338 /* CP ROQ queue sizes (bytes) - RB:16, ST:16, IB1:32, IB2:64 */ 339 if (adreno_is_a305(adreno_gpu) || 340 adreno_is_a306(adreno_gpu) || 341 adreno_is_a306a(adreno_gpu) || 342 adreno_is_a320(adreno_gpu)) { 343 gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS, 344 AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START(2) | 345 AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START(6) | 346 AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START(14)); 347 } else if (adreno_is_a330(adreno_gpu) || adreno_is_a305b(adreno_gpu)) { 348 /* NOTE: this (value take from downstream android driver) 349 * includes some bits outside of the known bitfields. But 350 * A330 has this "MERCIU queue" thing too, which might 351 * explain a new bitfield or reshuffling: 352 */ 353 gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS, 0x003e2008); 354 } 355 356 /* clear ME_HALT to start micro engine */ 357 gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0); 358 359 return a3xx_me_init(gpu) ? 0 : -EINVAL; 360 } 361 362 static void a3xx_recover(struct msm_gpu *gpu) 363 { 364 int i; 365 366 adreno_dump_info(gpu); 367 368 for (i = 0; i < 8; i++) { 369 printk("CP_SCRATCH_REG%d: %u\n", i, 370 gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i)); 371 } 372 373 /* dump registers before resetting gpu, if enabled: */ 374 if (hang_debug) 375 a3xx_dump(gpu); 376 377 gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 1); 378 gpu_read(gpu, REG_A3XX_RBBM_SW_RESET_CMD); 379 gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 0); 380 adreno_recover(gpu); 381 } 382 383 static void a3xx_destroy(struct msm_gpu *gpu) 384 { 385 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 386 struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu); 387 388 DBG("%s", gpu->name); 389 390 adreno_gpu_cleanup(adreno_gpu); 391 392 adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem); 393 394 kfree(a3xx_gpu); 395 } 396 397 static bool a3xx_idle(struct msm_gpu *gpu) 398 { 399 /* wait for ringbuffer to drain: */ 400 if (!adreno_idle(gpu, gpu->rb[0])) 401 return false; 402 403 /* then wait for GPU to finish: */ 404 if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) & 405 A3XX_RBBM_STATUS_GPU_BUSY))) { 406 DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name); 407 408 /* TODO maybe we need to reset GPU here to recover from hang? */ 409 return false; 410 } 411 412 return true; 413 } 414 415 static irqreturn_t a3xx_irq(struct msm_gpu *gpu) 416 { 417 uint32_t status; 418 419 status = gpu_read(gpu, REG_A3XX_RBBM_INT_0_STATUS); 420 DBG("%s: %08x", gpu->name, status); 421 422 // TODO 423 424 gpu_write(gpu, REG_A3XX_RBBM_INT_CLEAR_CMD, status); 425 426 msm_gpu_retire(gpu); 427 428 return IRQ_HANDLED; 429 } 430 431 static const unsigned int a3xx_registers[] = { 432 0x0000, 0x0002, 0x0010, 0x0012, 0x0018, 0x0018, 0x0020, 0x0027, 433 0x0029, 0x002b, 0x002e, 0x0033, 0x0040, 0x0042, 0x0050, 0x005c, 434 0x0060, 0x006c, 0x0080, 0x0082, 0x0084, 0x0088, 0x0090, 0x00e5, 435 0x00ea, 0x00ed, 0x0100, 0x0100, 0x0110, 0x0123, 0x01c0, 0x01c1, 436 0x01c3, 0x01c5, 0x01c7, 0x01c7, 0x01d5, 0x01d9, 0x01dc, 0x01dd, 437 0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff, 438 0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f, 439 0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f, 440 0x0578, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e, 441 0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f, 442 0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7, 443 0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05, 444 0x0e0c, 0x0e0c, 0x0e22, 0x0e23, 0x0e41, 0x0e45, 0x0e64, 0x0e65, 445 0x0e80, 0x0e82, 0x0e84, 0x0e89, 0x0ea0, 0x0ea1, 0x0ea4, 0x0ea7, 446 0x0ec4, 0x0ecb, 0x0ee0, 0x0ee0, 0x0f00, 0x0f01, 0x0f03, 0x0f09, 447 0x2040, 0x2040, 0x2044, 0x2044, 0x2048, 0x204d, 0x2068, 0x2069, 448 0x206c, 0x206d, 0x2070, 0x2070, 0x2072, 0x2072, 0x2074, 0x2075, 449 0x2079, 0x207a, 0x20c0, 0x20d3, 0x20e4, 0x20ef, 0x2100, 0x2109, 450 0x210c, 0x210c, 0x210e, 0x210e, 0x2110, 0x2111, 0x2114, 0x2115, 451 0x21e4, 0x21e4, 0x21ea, 0x21ea, 0x21ec, 0x21ed, 0x21f0, 0x21f0, 452 0x2200, 0x2212, 0x2214, 0x2217, 0x221a, 0x221a, 0x2240, 0x227e, 453 0x2280, 0x228b, 0x22c0, 0x22c0, 0x22c4, 0x22ce, 0x22d0, 0x22d8, 454 0x22df, 0x22e6, 0x22e8, 0x22e9, 0x22ec, 0x22ec, 0x22f0, 0x22f7, 455 0x22ff, 0x22ff, 0x2340, 0x2343, 0x2440, 0x2440, 0x2444, 0x2444, 456 0x2448, 0x244d, 0x2468, 0x2469, 0x246c, 0x246d, 0x2470, 0x2470, 457 0x2472, 0x2472, 0x2474, 0x2475, 0x2479, 0x247a, 0x24c0, 0x24d3, 458 0x24e4, 0x24ef, 0x2500, 0x2509, 0x250c, 0x250c, 0x250e, 0x250e, 459 0x2510, 0x2511, 0x2514, 0x2515, 0x25e4, 0x25e4, 0x25ea, 0x25ea, 460 0x25ec, 0x25ed, 0x25f0, 0x25f0, 0x2600, 0x2612, 0x2614, 0x2617, 461 0x261a, 0x261a, 0x2640, 0x267e, 0x2680, 0x268b, 0x26c0, 0x26c0, 462 0x26c4, 0x26ce, 0x26d0, 0x26d8, 0x26df, 0x26e6, 0x26e8, 0x26e9, 463 0x26ec, 0x26ec, 0x26f0, 0x26f7, 0x26ff, 0x26ff, 0x2740, 0x2743, 464 0x300c, 0x300e, 0x301c, 0x301d, 0x302a, 0x302a, 0x302c, 0x302d, 465 0x3030, 0x3031, 0x3034, 0x3036, 0x303c, 0x303c, 0x305e, 0x305f, 466 ~0 /* sentinel */ 467 }; 468 469 /* would be nice to not have to duplicate the _show() stuff with printk(): */ 470 static void a3xx_dump(struct msm_gpu *gpu) 471 { 472 printk("status: %08x\n", 473 gpu_read(gpu, REG_A3XX_RBBM_STATUS)); 474 adreno_dump(gpu); 475 } 476 477 static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu) 478 { 479 struct msm_gpu_state *state = kzalloc_obj(*state); 480 481 if (!state) 482 return ERR_PTR(-ENOMEM); 483 484 adreno_gpu_state_get(gpu, state); 485 486 state->rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS); 487 488 return state; 489 } 490 491 static u64 a3xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate) 492 { 493 u64 busy_cycles; 494 495 busy_cycles = gpu_read64(gpu, REG_A3XX_RBBM_PERFCTR_RBBM_1_LO); 496 *out_sample_rate = clk_get_rate(gpu->core_clk); 497 498 return busy_cycles; 499 } 500 501 static int a3xx_vbif_halt(struct msm_gpu *gpu) 502 { 503 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 504 u32 mask = A3XX_VBIF_XIN_HALT_CTRL0_MASK; 505 u32 ack; 506 int ret; 507 508 /* A306(A) only have three VBIF XIN ports. */ 509 if (adreno_is_a306(adreno_gpu) || adreno_is_a306a(adreno_gpu)) 510 mask = GENMASK(2, 0); 511 512 gpu_write(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL0, mask); 513 ret = spin_until(((ack = gpu_read(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL1)) & 514 mask) == mask); 515 gpu_write(gpu, REG_A3XX_VBIF_XIN_HALT_CTRL0, 0); 516 517 if (ret) 518 return -EBUSY; 519 520 return 0; 521 } 522 523 static int a3xx_pm_suspend(struct msm_gpu *gpu) 524 { 525 int ret; 526 527 if (!a3xx_idle(gpu)) 528 return -EBUSY; 529 530 ret = a3xx_vbif_halt(gpu); 531 if (ret) 532 return ret; 533 534 return msm_gpu_pm_suspend(gpu); 535 } 536 537 static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) 538 { 539 ring->memptrs->rptr = gpu_read(gpu, REG_AXXX_CP_RB_RPTR); 540 return ring->memptrs->rptr; 541 } 542 543 static bool a3xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring) 544 { 545 struct msm_cp_state cp_state = { 546 .ib1_base = gpu_read(gpu, REG_AXXX_CP_IB1_BASE), 547 .ib2_base = gpu_read(gpu, REG_AXXX_CP_IB2_BASE), 548 .ib1_rem = gpu_read(gpu, REG_AXXX_CP_IB1_BUFSZ), 549 .ib2_rem = gpu_read(gpu, REG_AXXX_CP_IB2_BUFSZ), 550 }; 551 bool progress; 552 553 progress = !!memcmp(&cp_state, &ring->last_cp_state, sizeof(cp_state)); 554 555 ring->last_cp_state = cp_state; 556 557 return progress; 558 } 559 560 static struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) 561 { 562 struct a3xx_gpu *a3xx_gpu = NULL; 563 struct adreno_gpu *adreno_gpu; 564 struct msm_gpu *gpu; 565 struct msm_drm_private *priv = dev->dev_private; 566 struct platform_device *pdev = priv->gpu_pdev; 567 struct adreno_platform_config *config = pdev->dev.platform_data; 568 struct icc_path *ocmem_icc_path; 569 struct icc_path *icc_path; 570 int ret; 571 572 if (!pdev) { 573 DRM_DEV_ERROR(dev->dev, "no a3xx device\n"); 574 ret = -ENXIO; 575 goto fail; 576 } 577 578 a3xx_gpu = kzalloc_obj(*a3xx_gpu); 579 if (!a3xx_gpu) { 580 ret = -ENOMEM; 581 goto fail; 582 } 583 584 adreno_gpu = &a3xx_gpu->base; 585 gpu = &adreno_gpu->base; 586 587 adreno_gpu->registers = a3xx_registers; 588 589 ret = adreno_gpu_init(dev, pdev, adreno_gpu, config->info->funcs, 1); 590 if (ret) 591 goto fail; 592 593 /* if needed, allocate gmem: */ 594 if (adreno_is_a330(adreno_gpu) || adreno_is_a305b(adreno_gpu)) { 595 ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev, 596 adreno_gpu, &a3xx_gpu->ocmem); 597 if (ret) 598 goto fail; 599 } 600 601 icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem"); 602 if (IS_ERR(icc_path)) { 603 ret = PTR_ERR(icc_path); 604 goto fail; 605 } 606 607 ocmem_icc_path = devm_of_icc_get(&pdev->dev, "ocmem"); 608 if (IS_ERR(ocmem_icc_path)) { 609 ret = PTR_ERR(ocmem_icc_path); 610 /* allow -ENODATA, ocmem icc is optional */ 611 if (ret != -ENODATA) 612 goto fail; 613 ocmem_icc_path = NULL; 614 } 615 616 617 /* 618 * Set the ICC path to maximum speed for now by multiplying the fastest 619 * frequency by the bus width (8). We'll want to scale this later on to 620 * improve battery life. 621 */ 622 icc_set_bw(icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); 623 icc_set_bw(ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8); 624 625 return gpu; 626 627 fail: 628 if (a3xx_gpu) 629 a3xx_destroy(&a3xx_gpu->base.base); 630 631 return ERR_PTR(ret); 632 } 633 634 const struct adreno_gpu_funcs a3xx_gpu_funcs = { 635 .base = { 636 .get_param = adreno_get_param, 637 .set_param = adreno_set_param, 638 .hw_init = a3xx_hw_init, 639 .pm_suspend = a3xx_pm_suspend, 640 .pm_resume = msm_gpu_pm_resume, 641 .recover = a3xx_recover, 642 .submit = a3xx_submit, 643 .active_ring = adreno_active_ring, 644 .irq = a3xx_irq, 645 .destroy = a3xx_destroy, 646 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) 647 .show = adreno_show, 648 #endif 649 .gpu_busy = a3xx_gpu_busy, 650 .gpu_state_get = a3xx_gpu_state_get, 651 .gpu_state_put = adreno_gpu_state_put, 652 .create_vm = adreno_create_vm, 653 .get_rptr = a3xx_get_rptr, 654 .progress = a3xx_progress, 655 }, 656 .init = a3xx_gpu_init, 657 }; 658