summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Li <roman.li@amd.com>2024-06-13 10:41:51 -0400
committerAlex Deucher <alexander.deucher@amd.com>2024-06-27 17:10:38 -0400
commit9862ef7bae47b9292a38a0a1b30bff7f56d7815b (patch)
tree7cfcbf17a8b05a8151e0eccfcc523c47f2c78e9b
parent58acedd7849a238d2d06430b030b365cf069cca8 (diff)
drm/amd/display: Use periodic detection for ipx/headless
[WHY] Hotplug is not detected in headless (no eDP) mode on dcn35x. With no display dcn35x goes to IPS2 powersaving state where HPD interrupt is not handled. [HOW] Use idle worker thread for periodic detection of HPD in headless mode. Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Cc: Mario Limonciello <mario.limonciello@amd.com> Cc: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Roman Li <roman.li@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c48
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c5
3 files changed, 46 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index dfcbc1970fe6..5fd1b6b44577 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -989,4 +989,7 @@ void *dm_allocate_gpu_mem(struct amdgpu_device *adev,
enum dc_gpu_mem_alloc_type type,
size_t size,
long long *addr);
+
+bool amdgpu_dm_is_headless(struct amdgpu_device *adev);
+
#endif /* __AMDGPU_DM_H__ */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index e16eecb146fd..99014339aaa3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -162,33 +162,63 @@ static void amdgpu_dm_crtc_set_panel_sr_feature(
}
}
+bool amdgpu_dm_is_headless(struct amdgpu_device *adev)
+{
+ struct drm_connector *connector;
+ struct drm_connector_list_iter iter;
+ struct drm_device *dev;
+ bool is_headless = true;
+
+ if (adev == NULL)
+ return true;
+
+ dev = adev->dm.ddev;
+
+ drm_connector_list_iter_begin(dev, &iter);
+ drm_for_each_connector_iter(connector, &iter) {
+
+ if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+ continue;
+
+ if (connector->status == connector_status_connected) {
+ is_headless = false;
+ break;
+ }
+ }
+ drm_connector_list_iter_end(&iter);
+ return is_headless;
+}
+
static void amdgpu_dm_idle_worker(struct work_struct *work)
{
struct idle_workqueue *idle_work;
idle_work = container_of(work, struct idle_workqueue, work);
idle_work->dm->idle_workqueue->running = true;
- fsleep(HPD_DETECTION_PERIOD_uS);
- mutex_lock(&idle_work->dm->dc_lock);
+
while (idle_work->enable) {
- if (!idle_work->dm->dc->idle_optimizations_allowed)
+ fsleep(HPD_DETECTION_PERIOD_uS);
+ mutex_lock(&idle_work->dm->dc_lock);
+ if (!idle_work->dm->dc->idle_optimizations_allowed) {
+ mutex_unlock(&idle_work->dm->dc_lock);
break;
-
+ }
dc_allow_idle_optimizations(idle_work->dm->dc, false);
mutex_unlock(&idle_work->dm->dc_lock);
fsleep(HPD_DETECTION_TIME_uS);
mutex_lock(&idle_work->dm->dc_lock);
- if (!amdgpu_dm_psr_is_active_allowed(idle_work->dm))
+ if (!amdgpu_dm_is_headless(idle_work->dm->adev) &&
+ !amdgpu_dm_psr_is_active_allowed(idle_work->dm)) {
+ mutex_unlock(&idle_work->dm->dc_lock);
break;
+ }
- dc_allow_idle_optimizations(idle_work->dm->dc, true);
+ if (idle_work->enable)
+ dc_allow_idle_optimizations(idle_work->dm->dc, true);
mutex_unlock(&idle_work->dm->dc_lock);
- fsleep(HPD_DETECTION_PERIOD_uS);
- mutex_lock(&idle_work->dm->dc_lock);
}
- mutex_unlock(&idle_work->dm->dc_lock);
idle_work->dm->idle_workqueue->running = false;
}
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index adbf560d6a74..97614947d75b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -1239,8 +1239,11 @@ void dm_helpers_enable_periodic_detection(struct dc_context *ctx, bool enable)
{
struct amdgpu_device *adev = ctx->driver_context;
- if (adev->dm.idle_workqueue)
+ if (adev->dm.idle_workqueue) {
adev->dm.idle_workqueue->enable = enable;
+ if (enable && !adev->dm.idle_workqueue->running && amdgpu_dm_is_headless(adev))
+ schedule_work(&adev->dm.idle_workqueue->work);
+ }
}
void dm_helpers_dp_mst_update_branch_bandwidth(