From 5db6d8bd4d7ebb2712e86f5926feffc38c41ddfe Mon Sep 17 00:00:00 2001 From: jsg Date: Thu, 24 Aug 2023 06:21:03 +0000 Subject: [PATCH] drm/amdgpu: skip fence GFX interrupts disable/enable for S0ix From Tim Huang 9c8c2cf9f9bce4fa4c4c4e821bdaa4e15762e403 in linux-6.1.y/6.1.47 f1740b1ab2703b2a057da7cf33b03297e0381aa0 in mainline linux --- sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c | 41 +++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c index 8770aa59de9..07aa8c32255 100644 --- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c +++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_fence.c @@ -518,6 +518,41 @@ int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev) return 0; } +/** + * amdgpu_fence_need_ring_interrupt_restore - helper function to check whether + * fence driver interrupts need to be restored. + * + * @ring: ring that to be checked + * + * Interrupts for rings that belong to GFX IP don't need to be restored + * when the target power state is s0ix. + * + * Return true if need to restore interrupts, false otherwise. + */ +static bool amdgpu_fence_need_ring_interrupt_restore(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + bool is_gfx_power_domain = false; + + switch (ring->funcs->type) { + case AMDGPU_RING_TYPE_SDMA: + /* SDMA 5.x+ is part of GFX power domain so it's covered by GFXOFF */ + if (adev->ip_versions[SDMA0_HWIP][0] >= IP_VERSION(5, 0, 0)) + is_gfx_power_domain = true; + break; + case AMDGPU_RING_TYPE_GFX: + case AMDGPU_RING_TYPE_COMPUTE: + case AMDGPU_RING_TYPE_KIQ: + case AMDGPU_RING_TYPE_MES: + is_gfx_power_domain = true; + break; + default: + break; + } + + return !(adev->in_s0ix && is_gfx_power_domain); +} + /** * amdgpu_fence_driver_hw_fini - tear down the fence driver * for all possible rings. @@ -546,7 +581,8 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) amdgpu_fence_driver_force_completion(ring); if (!drm_dev_is_unplugged(adev_to_drm(adev)) && - ring->fence_drv.irq_src) + ring->fence_drv.irq_src && + amdgpu_fence_need_ring_interrupt_restore(ring)) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); @@ -624,7 +660,8 @@ void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev) continue; /* enable the interrupt */ - if (ring->fence_drv.irq_src) + if (ring->fence_drv.irq_src && + amdgpu_fence_need_ring_interrupt_restore(ring)) amdgpu_irq_get(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); } -- 2.20.1