diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-04-27 02:36:58 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-04-27 02:36:58 +0000 |
commit | b3984885df43a0c0e82bfb876afd8cf7244a4c16 (patch) | |
tree | 4f89dc693d2f1aea8b01699dce2ce77916379f82 | |
parent | 3790eaf9d299969b2d5d83f6c647951b255d6b37 (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.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 17 |
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)) |