summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2023-04-27 02:36:58 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2023-04-27 02:36:58 +0000
commitb3984885df43a0c0e82bfb876afd8cf7244a4c16 (patch)
tree4f89dc693d2f1aea8b01699dce2ce77916379f82
parent3790eaf9d299969b2d5d83f6c647951b255d6b37 (diff)
drm/amdgpu: Fix desktop freezed after gpu-reset
From Alan Liu bef774effb278ff0b65ea2dbaa1ab32ba6a1dc13 in linux-6.1.y/6.1.26 c8b5a95b570949536a2b75cd8fc4f1de0bc60629 in mainline linux
-rw-r--r--sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c3
-rw-r--r--sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c17
2 files changed, 17 insertions, 3 deletions
diff --git a/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c b/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c
index 22c69ae5e7b..9190712d2ec 100644
--- a/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c
+++ b/sys/dev/pci/drm/amd/amdgpu/amdgpu_irq.c
@@ -664,6 +664,9 @@ int amdgpu_irq_put(struct amdgpu_device *adev, struct amdgpu_irq_src *src,
if (!src->enabled_types || !src->funcs->set)
return -EINVAL;
+ if (WARN_ON(!amdgpu_irq_enabled(adev, src, type)))
+ return -EINVAL;
+
if (atomic_dec_and_test(&src->enabled_types[type]))
return amdgpu_irq_update(adev, src, type);
diff --git a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index b87f50e8fa6..1ec643a0d00 100644
--- a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -167,10 +167,21 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
if (rc)
return rc;
- irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst;
+ if (amdgpu_in_reset(adev)) {
+ irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst;
+ /* During gpu-reset we disable and then enable vblank irq, so
+ * don't use amdgpu_irq_get/put() to avoid refcount change.
+ */
+ if (!dc_interrupt_set(adev->dm.dc, irq_source, enable))
+ rc = -EBUSY;
+ } else {
+ rc = (enable)
+ ? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id)
+ : amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id);
+ }
- if (!dc_interrupt_set(adev->dm.dc, irq_source, enable))
- return -EBUSY;
+ if (rc)
+ return rc;
skip:
if (amdgpu_in_reset(adev))