summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
diff options
context:
space:
mode:
authorEryk Brol <eryk.brol@amd.com>2020-08-27 15:45:06 -0400
committerAlex Deucher <alexander.deucher@amd.com>2020-09-15 17:52:41 -0400
commit6b29bb37373bfdcc851b2c907f6a9049427b1661 (patch)
tree411f0174e023691edd1bed61ecb2f2d8e06b0ac1 /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
parent0749ddeb7d6c87e04446c068c03b097d4aa19173 (diff)
drm/amd/display: Add trigger connector unplug
[why] We need a virtual tool that would emulate a physical connector unplug to usermode, while connector is still physically plugged in. [how] Added a new option to debugfs entry "trigger_hotplug". It emulates hotplug irq handling scenario by clearing DC and DM connector states. It can be triggered with the following command: echo 0 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug Signed-off-by: Eryk Brol <eryk.brol@amd.com> Signed-off-by: Mikita Lipski <mikita.lipski@amd.com> Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index 5cf3ba3ec5da..7c7f937166dc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -1058,12 +1058,17 @@ static int dp_dsc_fec_support_show(struct seq_file *m, void *data)
*
* echo 1 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
*
+ * This function can perform HPD unplug:
+ *
+ * echo 0 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
+ *
*/
static ssize_t dp_trigger_hotplug(struct file *f, const char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
struct drm_connector *connector = &aconnector->base;
+ struct dc_link *link = NULL;
struct drm_device *dev = connector->dev;
enum dc_connection_type new_connection_type = dc_connection_none;
char *wr_buf = NULL;
@@ -1114,11 +1119,33 @@ static ssize_t dp_trigger_hotplug(struct file *f, const char __user *buf,
drm_modeset_unlock_all(dev);
drm_kms_helper_hotplug_event(dev);
+ } else if (param[0] == 0) {
+ if (!aconnector->dc_link)
+ goto unlock;
-unlock:
- mutex_unlock(&aconnector->hpd_lock);
+ link = aconnector->dc_link;
+
+ if (link->local_sink) {
+ dc_sink_release(link->local_sink);
+ link->local_sink = NULL;
+ }
+
+ link->dpcd_sink_count = 0;
+ link->type = dc_connection_none;
+ link->dongle_max_pix_clk = 0;
+
+ amdgpu_dm_update_connector_after_detect(aconnector);
+
+ drm_modeset_lock_all(dev);
+ dm_restore_drm_connector_state(dev, connector);
+ drm_modeset_unlock_all(dev);
+
+ drm_kms_helper_hotplug_event(dev);
}
+unlock:
+ mutex_unlock(&aconnector->hpd_lock);
+
kfree(wr_buf);
return size;
}