Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/msm/a6xx: Use posamble to reset counters on preemption

Use the postamble to reset perf counters when switching between rings,
except when sysprof is enabled, analogously to how they are reset
between submissions when switching pagetables.

Reviewed-by: Akhil P Oommen <quic_akhilpo@quicinc.com>
Tested-by: Rob Clark <robdclark@gmail.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8450-HDK
Signed-off-by: Antonino Maniscalco <antomani103@gmail.com>
Patchwork: https://patchwork.freedesktop.org/patch/618024/
Signed-off-by: Rob Clark <robdclark@chromium.org>

authored by

Antonino Maniscalco and committed by
Rob Clark
50117cad 3044f928

+81 -2
+12
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
··· 280 280 static void a6xx_emit_set_pseudo_reg(struct msm_ringbuffer *ring, 281 281 struct a6xx_gpu *a6xx_gpu, struct msm_gpu_submitqueue *queue) 282 282 { 283 + u64 preempt_postamble; 284 + 283 285 OUT_PKT7(ring, CP_SET_PSEUDO_REG, 12); 284 286 285 287 OUT_RING(ring, SMMU_INFO); ··· 305 303 /* seems OK to set to 0 to disable it */ 306 304 OUT_RING(ring, 0); 307 305 OUT_RING(ring, 0); 306 + 307 + /* Emit postamble to clear perfcounters */ 308 + preempt_postamble = a6xx_gpu->preempt_postamble_iova; 309 + 310 + OUT_PKT7(ring, CP_SET_AMBLE, 3); 311 + OUT_RING(ring, lower_32_bits(preempt_postamble)); 312 + OUT_RING(ring, upper_32_bits(preempt_postamble)); 313 + OUT_RING(ring, CP_SET_AMBLE_2_DWORDS( 314 + a6xx_gpu->preempt_postamble_len) | 315 + CP_SET_AMBLE_2_TYPE(KMD_AMBLE_TYPE)); 308 316 } 309 317 310 318 static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+6
drivers/gpu/drm/msm/adreno/a6xx_gpu.h
··· 71 71 bool uses_gmem; 72 72 bool skip_save_restore; 73 73 74 + struct drm_gem_object *preempt_postamble_bo; 75 + void *preempt_postamble_ptr; 76 + uint64_t preempt_postamble_iova; 77 + uint64_t preempt_postamble_len; 78 + bool postamble_enabled; 79 + 74 80 struct a6xx_gmu gmu; 75 81 76 82 struct drm_gem_object *shadow_bo;
+58
drivers/gpu/drm/msm/adreno/a6xx_preempt.c
··· 97 97 kthread_queue_work(gpu->worker, &gpu->recover_work); 98 98 } 99 99 100 + static void preempt_prepare_postamble(struct a6xx_gpu *a6xx_gpu) 101 + { 102 + u32 *postamble = a6xx_gpu->preempt_postamble_ptr; 103 + u32 count = 0; 104 + 105 + postamble[count++] = PKT7(CP_REG_RMW, 3); 106 + postamble[count++] = REG_A6XX_RBBM_PERFCTR_SRAM_INIT_CMD; 107 + postamble[count++] = 0; 108 + postamble[count++] = 1; 109 + 110 + postamble[count++] = PKT7(CP_WAIT_REG_MEM, 6); 111 + postamble[count++] = CP_WAIT_REG_MEM_0_FUNCTION(WRITE_EQ); 112 + postamble[count++] = CP_WAIT_REG_MEM_1_POLL_ADDR_LO( 113 + REG_A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS); 114 + postamble[count++] = CP_WAIT_REG_MEM_2_POLL_ADDR_HI(0); 115 + postamble[count++] = CP_WAIT_REG_MEM_3_REF(0x1); 116 + postamble[count++] = CP_WAIT_REG_MEM_4_MASK(0x1); 117 + postamble[count++] = CP_WAIT_REG_MEM_5_DELAY_LOOP_CYCLES(0); 118 + 119 + a6xx_gpu->preempt_postamble_len = count; 120 + 121 + a6xx_gpu->postamble_enabled = true; 122 + } 123 + 124 + static void preempt_disable_postamble(struct a6xx_gpu *a6xx_gpu) 125 + { 126 + u32 *postamble = a6xx_gpu->preempt_postamble_ptr; 127 + 128 + /* 129 + * Disable the postamble by replacing the first packet header with a NOP 130 + * that covers the whole buffer. 131 + */ 132 + *postamble = PKT7(CP_NOP, (a6xx_gpu->preempt_postamble_len - 1)); 133 + 134 + a6xx_gpu->postamble_enabled = false; 135 + } 136 + 100 137 void a6xx_preempt_irq(struct msm_gpu *gpu) 101 138 { 102 139 uint32_t status; ··· 224 187 unsigned long flags; 225 188 struct msm_ringbuffer *ring; 226 189 unsigned int cntl; 190 + bool sysprof; 227 191 228 192 if (gpu->nr_rings == 1) 229 193 return; ··· 308 270 309 271 /* Start a timer to catch a stuck preemption */ 310 272 mod_timer(&a6xx_gpu->preempt_timer, jiffies + msecs_to_jiffies(10000)); 273 + 274 + /* Enable or disable postamble as needed */ 275 + sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; 276 + 277 + if (!sysprof && !a6xx_gpu->postamble_enabled) 278 + preempt_prepare_postamble(a6xx_gpu); 279 + 280 + if (sysprof && a6xx_gpu->postamble_enabled) 281 + preempt_disable_postamble(a6xx_gpu); 311 282 312 283 /* Set the preemption state to triggered */ 313 284 set_preempt_state(a6xx_gpu, PREEMPT_TRIGGERED); ··· 421 374 a6xx_gpu->preempt_level = 1; 422 375 a6xx_gpu->uses_gmem = 1; 423 376 a6xx_gpu->skip_save_restore = 1; 377 + 378 + a6xx_gpu->preempt_postamble_ptr = msm_gem_kernel_new(gpu->dev, 379 + PAGE_SIZE, 380 + MSM_BO_WC | MSM_BO_MAP_PRIV | MSM_BO_GPU_READONLY, 381 + gpu->aspace, &a6xx_gpu->preempt_postamble_bo, 382 + &a6xx_gpu->preempt_postamble_iova); 383 + 384 + preempt_prepare_postamble(a6xx_gpu); 385 + 386 + if (IS_ERR(a6xx_gpu->preempt_postamble_ptr)) 387 + goto fail; 424 388 425 389 timer_setup(&a6xx_gpu->preempt_timer, a6xx_preempt_timer, 0); 426 390
+5 -2
drivers/gpu/drm/msm/adreno/adreno_gpu.h
··· 670 670 OUT_RING(ring, PKT4(regindx, cnt)); 671 671 } 672 672 673 + #define PKT7(opcode, cnt) \ 674 + (CP_TYPE7_PKT | (cnt << 0) | (PM4_PARITY(cnt) << 15) | \ 675 + ((opcode & 0x7F) << 16) | (PM4_PARITY(opcode) << 23)) 676 + 673 677 static inline void 674 678 OUT_PKT7(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt) 675 679 { 676 680 adreno_wait_ring(ring, cnt + 1); 677 - OUT_RING(ring, CP_TYPE7_PKT | (cnt << 0) | (PM4_PARITY(cnt) << 15) | 678 - ((opcode & 0x7F) << 16) | (PM4_PARITY(opcode) << 23)); 681 + OUT_RING(ring, PKT7(opcode, cnt)); 679 682 } 680 683 681 684 struct msm_gpu *a2xx_gpu_init(struct drm_device *dev);