On Wed, Mar 8, 2023 at 7:17 AM Guchun Chen <guchun.chen@xxxxxxx> wrote: > > Some amd asics having reliable hotplug support don't call > drm_kms_helper_poll_init in driver init sequence. However, > due to the unified suspend/resume path for all asics, because > the output_poll_work->func is not set for these asics, a warning > arrives when suspending. > > [ 90.656049] <TASK> > [ 90.656050] ? console_unlock+0x4d/0x100 > [ 90.656053] ? __irq_work_queue_local+0x27/0x60 > [ 90.656056] ? irq_work_queue+0x2b/0x50 > [ 90.656057] ? __wake_up_klogd+0x40/0x60 > [ 90.656059] __cancel_work_timer+0xed/0x180 > [ 90.656061] drm_kms_helper_poll_disable.cold+0x1f/0x2c [drm_kms_helper] > [ 90.656072] amdgpu_device_suspend+0x81/0x170 [amdgpu] > [ 90.656180] amdgpu_pmops_runtime_suspend+0xb5/0x1b0 [amdgpu] > [ 90.656269] pci_pm_runtime_suspend+0x61/0x1b0 > > So add use_kms_poll flag as the initialization check in amdgpu code before > calling drm_kms_helper_poll_disable/drm_kms_helper_poll_enable in suspend/resume > path. > > Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2411 > Fixes: a4e771729a51("drm/probe_helper: sort out poll_running vs poll_enabled") > Reported-by: Bert Karwatzki <spasswolf@xxxxxx> > Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> > Signed-off-by: Guchun Chen <guchun.chen@xxxxxxx> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 ++++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 1 + > drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 1 + > drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 1 + > drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 1 + > drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 1 + > 7 files changed, 10 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index c4a4e2fe6681..74af0b8c0d08 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -4145,7 +4145,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) > if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3)) > DRM_WARN("smart shift update failed\n"); > > - drm_kms_helper_poll_disable(dev); > + if (adev->mode_info.use_kms_poll) > + drm_kms_helper_poll_disable(dev); > > if (fbcon) > drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); > @@ -4243,7 +4244,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) > if (fbcon) > drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false); > > - drm_kms_helper_poll_enable(dev); > + if (adev->mode_info.use_kms_poll) > + drm_kms_helper_poll_enable(dev); > Since polling is only enabled for analog outputs and DC doesn't support any analog outputs, I think we can simplify this to diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c4a4e2fe6681..74af0b8c0d08 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4145,7 +4145,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3)) DRM_WARN("smart shift update failed\n"); - drm_kms_helper_poll_disable(dev); + if (!adev->dc_enabled) + drm_kms_helper_poll_disable(dev); if (fbcon) drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); @@ -4243,7 +4244,8 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon) if (fbcon) drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false); - drm_kms_helper_poll_enable(dev); + if (!adev->dc_enabled) + drm_kms_helper_poll_enable(dev); amdgpu_ras_resume(adev); Alternatively, we could also just move drm_kms_helper_poll_disable() into amdgpu_display_suspend_helper() and drm_kms_helper_poll_enable() into amdgpu_display_resume_helper(), but I'm not sure if the ordering here is important or not off hand. Alex > amdgpu_ras_resume(adev); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > index 32fe05c810c6..d383ea3e8e94 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h > @@ -343,6 +343,7 @@ struct amdgpu_mode_info { > int disp_priority; > const struct amdgpu_display_funcs *funcs; > const enum drm_plane_type *plane_type; > + bool use_kms_poll; > }; > > #define AMDGPU_MAX_BL_LEVEL 0xFF > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c > index 53ff91fc6cf6..3277799a80bb 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c > @@ -518,6 +518,7 @@ static int amdgpu_vkms_sw_init(void *handle) > return r; > > drm_kms_helper_poll_init(adev_to_drm(adev)); > + adev->mode_info.use_kms_poll = true; > > adev->mode_info.mode_config_initialized = true; > return 0; > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c > index 9a24ed463abd..f4d0a7cf588b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c > @@ -2842,6 +2842,7 @@ static int dce_v10_0_sw_init(void *handle) > amdgpu_display_hotplug_work_func); > > drm_kms_helper_poll_init(adev_to_drm(adev)); > + adev->mode_info.use_kms_poll = true; > > adev->mode_info.mode_config_initialized = true; > return 0; > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c > index c14b70350a51..25d0a866ca28 100644 > --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c > @@ -2961,6 +2961,7 @@ static int dce_v11_0_sw_init(void *handle) > amdgpu_display_hotplug_work_func); > > drm_kms_helper_poll_init(adev_to_drm(adev)); > + adev->mode_info.use_kms_poll = true; > > adev->mode_info.mode_config_initialized = true; > return 0; > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c > index 7f85ba5b726f..3936c6bfe2e3 100644 > --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c > @@ -2720,6 +2720,7 @@ static int dce_v6_0_sw_init(void *handle) > amdgpu_display_hotplug_work_func); > > drm_kms_helper_poll_init(adev_to_drm(adev)); > + adev->mode_info.use_kms_poll = true; > > return r; > } > diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c > index d421a268c9ff..29fb837f5ebf 100644 > --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c > @@ -2744,6 +2744,7 @@ static int dce_v8_0_sw_init(void *handle) > amdgpu_display_hotplug_work_func); > > drm_kms_helper_poll_init(adev_to_drm(adev)); > + adev->mode_info.use_kms_poll = true; > > adev->mode_info.mode_config_initialized = true; > return 0; > -- > 2.25.1 >