From be5c2680ed4b3b4121af4f692c905d88d7b6cc00 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 28 Dec 2021 17:26:24 -0500 Subject: [PATCH 1/2] drm/amdgpu: don't runtime suspend if there are displays attached We normally runtime suspend when there are displays attached if they are in the DPMS off state, however, if something wakes the GPU we send a hotplug event on resume (in case any displays were connected while the GPU was in suspend) which can cause userspace to light up the displays again soon after they were turned off. Prior to commit 087451f372bf76 ("drm/amdgpu: use generic fb helpers instead of setting up AMD own's."), the driver took a runtime pm reference when the fbdev emulation was enabled because we didn't implement proper shadowing support for vram access when the device was off so the device never runtime suspended when there was a console bound. Once that commit landed, we now utilize the core fb helper implementation which properly handles the emulation, so runtime pm now suspends in cases where it did not before. Ultimately, we need to sort out why runtime suspend in not working in this case for some users, but this should restore similar behavior to before. Fixes: 087451f372bf76 ("drm/amdgpu: use generic fb helpers instead of setting up AMD own's.") Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 4efaa183abcd..cf795a9b8aef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2508,6 +2508,8 @@ static int amdgpu_pmops_runtime_idle(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(drm_dev); + struct drm_connector *list_connector; + struct drm_connector_list_iter iter; /* we don't want the main rpm_idle to call suspend - we want to autosuspend */ int ret = 1; @@ -2516,6 +2518,22 @@ static int amdgpu_pmops_runtime_idle(struct device *dev) return -EBUSY; } + /* XXX: Return busy if any displays are connected to avoid + * possible display wake ups after runtime resume due to + * hotplug events in case any displays were connected while + * the GPU was in suspend. Remove this once that is fixed. + */ + mutex_lock(&drm_dev->mode_config.mutex); + drm_connector_list_iter_begin(drm_dev, &iter); + drm_for_each_connector_iter(list_connector, &iter) { + if (list_connector->status == connector_status_connected) { + ret = -EBUSY; + break; + } + } + drm_connector_list_iter_end(&iter); + mutex_unlock(&drm_dev->mode_config.mutex); + if (amdgpu_device_has_dc_support(adev)) { struct drm_crtc *crtc; @@ -2527,11 +2545,7 @@ static int amdgpu_pmops_runtime_idle(struct device *dev) if (ret < 0) break; } - } else { - struct drm_connector *list_connector; - struct drm_connector_list_iter iter; - mutex_lock(&drm_dev->mode_config.mutex); drm_modeset_lock(&drm_dev->mode_config.connection_mutex, NULL); -- 2.35.1