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/amdgpu/gfx12: Implement the GFX12 KCQ pipe reset

Implement the GFX12 KCQ pipe reset, and disable the GFX12
kernel compute queue until the CPFW fully supports it.

Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Prike Liang and committed by
Alex Deucher
9a218d6f 732c6cef

+87 -2
+87 -2
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
··· 5316 5316 return amdgpu_ring_test_ring(ring); 5317 5317 } 5318 5318 5319 + static int gfx_v12_0_reset_compute_pipe(struct amdgpu_ring *ring) 5320 + { 5321 + struct amdgpu_device *adev = ring->adev; 5322 + uint32_t reset_pipe = 0, clean_pipe = 0; 5323 + int r = 0; 5324 + 5325 + if (!gfx_v12_pipe_reset_support(adev)) 5326 + return -EOPNOTSUPP; 5327 + 5328 + gfx_v12_0_set_safe_mode(adev, 0); 5329 + mutex_lock(&adev->srbm_mutex); 5330 + soc24_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0); 5331 + 5332 + reset_pipe = RREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL); 5333 + clean_pipe = reset_pipe; 5334 + 5335 + if (adev->gfx.rs64_enable) { 5336 + switch (ring->pipe) { 5337 + case 0: 5338 + reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_RS64_CNTL, 5339 + MEC_PIPE0_RESET, 1); 5340 + clean_pipe = REG_SET_FIELD(clean_pipe, CP_MEC_RS64_CNTL, 5341 + MEC_PIPE0_RESET, 0); 5342 + break; 5343 + case 1: 5344 + reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_RS64_CNTL, 5345 + MEC_PIPE1_RESET, 1); 5346 + clean_pipe = REG_SET_FIELD(clean_pipe, CP_MEC_RS64_CNTL, 5347 + MEC_PIPE1_RESET, 0); 5348 + break; 5349 + case 2: 5350 + reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_RS64_CNTL, 5351 + MEC_PIPE2_RESET, 1); 5352 + clean_pipe = REG_SET_FIELD(clean_pipe, CP_MEC_RS64_CNTL, 5353 + MEC_PIPE2_RESET, 0); 5354 + break; 5355 + case 3: 5356 + reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_RS64_CNTL, 5357 + MEC_PIPE3_RESET, 1); 5358 + clean_pipe = REG_SET_FIELD(clean_pipe, CP_MEC_RS64_CNTL, 5359 + MEC_PIPE3_RESET, 0); 5360 + break; 5361 + default: 5362 + break; 5363 + } 5364 + WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, reset_pipe); 5365 + WREG32_SOC15(GC, 0, regCP_MEC_RS64_CNTL, clean_pipe); 5366 + r = (RREG32_SOC15(GC, 0, regCP_MEC_RS64_INSTR_PNTR) << 2) - 5367 + RS64_FW_UC_START_ADDR_LO; 5368 + } else { 5369 + switch (ring->pipe) { 5370 + case 0: 5371 + reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL, 5372 + MEC_ME1_PIPE0_RESET, 1); 5373 + clean_pipe = REG_SET_FIELD(clean_pipe, CP_MEC_CNTL, 5374 + MEC_ME1_PIPE0_RESET, 0); 5375 + break; 5376 + case 1: 5377 + reset_pipe = REG_SET_FIELD(reset_pipe, CP_MEC_CNTL, 5378 + MEC_ME1_PIPE1_RESET, 1); 5379 + clean_pipe = REG_SET_FIELD(clean_pipe, CP_MEC_CNTL, 5380 + MEC_ME1_PIPE1_RESET, 0); 5381 + break; 5382 + default: 5383 + break; 5384 + } 5385 + WREG32_SOC15(GC, 0, regCP_MEC_CNTL, reset_pipe); 5386 + WREG32_SOC15(GC, 0, regCP_MEC_CNTL, clean_pipe); 5387 + /* Doesn't find the F32 MEC instruction pointer register, and suppose 5388 + * the driver won't run into the F32 mode. 5389 + */ 5390 + } 5391 + 5392 + soc24_grbm_select(adev, 0, 0, 0, 0); 5393 + mutex_unlock(&adev->srbm_mutex); 5394 + gfx_v12_0_unset_safe_mode(adev, 0); 5395 + 5396 + dev_info(adev->dev, "The ring %s pipe resets: %s\n", ring->name, 5397 + r == 0 ? "successfully" : "failed"); 5398 + /* Need the ring test to verify the pipe reset result.*/ 5399 + return 0; 5400 + } 5401 + 5319 5402 static int gfx_v12_0_reset_kcq(struct amdgpu_ring *ring, unsigned int vmid) 5320 5403 { 5321 5404 struct amdgpu_device *adev = ring->adev; ··· 5409 5326 5410 5327 r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, true); 5411 5328 if (r) { 5412 - dev_err(adev->dev, "reset via MMIO failed %d\n", r); 5413 - return r; 5329 + dev_warn(adev->dev, "fail(%d) to reset kcq and try pipe reset\n", r); 5330 + r = gfx_v12_0_reset_compute_pipe(ring); 5331 + if (r) 5332 + return r; 5414 5333 } 5415 5334 5416 5335 r = gfx_v12_0_kcq_init_queue(ring, true);