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

drm/amdgpu: Clear overflow for SRIOV

For VF, it doesn't have the permission to clear overflow, clear the bit
by reset.

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

authored by

Emily Deng and committed by
Alex Deucher
5ae4591f fb20954c

+24 -4
+13 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c
··· 25 25 26 26 #include "amdgpu.h" 27 27 #include "amdgpu_ih.h" 28 + #include "amdgpu_reset.h" 28 29 29 30 /** 30 31 * amdgpu_ih_ring_init - initialize the IH state ··· 228 227 ih->rptr &= ih->ptr_mask; 229 228 } 230 229 231 - amdgpu_ih_set_rptr(adev, ih); 230 + if (!ih->overflow) 231 + amdgpu_ih_set_rptr(adev, ih); 232 + 232 233 wake_up_all(&ih->wait_process); 233 234 234 235 /* make sure wptr hasn't changed while processing */ 235 236 wptr = amdgpu_ih_get_wptr(adev, ih); 236 237 if (wptr != ih->rptr) 237 - goto restart_ih; 238 + if (!ih->overflow) 239 + goto restart_ih; 240 + 241 + if (ih->overflow) 242 + if (amdgpu_sriov_runtime(adev)) 243 + WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain, 244 + &adev->virt.flr_work), 245 + "Failed to queue work! at %s", 246 + __func__); 238 247 239 248 return IRQ_HANDLED; 240 249 }
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
··· 72 72 /* For waiting on IH processing at checkpoint. */ 73 73 wait_queue_head_t wait_process; 74 74 uint64_t processed_timestamp; 75 + bool overflow; 75 76 }; 76 77 77 78 /* return true if time stamp t2 is after t1 with 48bit wrap around */
+5 -1
drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
··· 349 349 if (ret) 350 350 return ret; 351 351 } 352 + ih[i]->overflow = false; 352 353 } 353 354 354 355 /* update doorbell range for ih ring 0 */ ··· 447 446 wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr); 448 447 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) 449 448 goto out; 450 - wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 449 + if (!amdgpu_sriov_vf(adev)) 450 + wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 451 + else 452 + ih->overflow = true; 451 453 452 454 /* When a ring buffer overflow happen start parsing interrupt 453 455 * from the last not overwritten vector (wptr + 32). Hopefully
+5 -1
drivers/gpu/drm/amd/amdgpu/vega20_ih.c
··· 350 350 if (ret) 351 351 return ret; 352 352 } 353 + ih[i]->overflow = false; 353 354 } 354 355 355 356 if (!amdgpu_sriov_vf(adev)) ··· 438 437 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) 439 438 goto out; 440 439 441 - wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 440 + if (!amdgpu_sriov_vf(adev)) 441 + wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 442 + else 443 + ih->overflow = true; 442 444 443 445 /* When a ring buffer overflow happen start parsing interrupt 444 446 * from the last not overwritten vector (wptr + 32). Hopefully