diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-07-28 07:05:08 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2023-07-28 07:05:08 +0000 |
commit | bd8a9ff6b67922dd3b566e4aa47b106c16956f12 (patch) | |
tree | 2137195e5fb39eede2b35ea195fa302fd4168d1c /sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |
parent | e9ea36de80848855440858f551c39e23691ff0ae (diff) |
drm/amd/display: fix linux dp link lost handled only one time
From Hersen Wu
78ea2ed76ce94f090d2a9c36b1b58f79ce3b93b8 in linux-6.1.y/6.1.42
e322843e5e33e72ff218d661f3d15ff9c9f2f1b5 in mainline linux
Diffstat (limited to 'sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c')
-rw-r--r-- | sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 87b0d88e6c9..b68f8778dfe 100644 --- a/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1348,10 +1348,28 @@ static void dm_handle_hpd_rx_offload_work(struct work_struct *work) } else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) && hpd_rx_irq_check_link_loss_status(dc_link, &offload_work->data) && dc_link_dp_allow_hpd_rx_irq(dc_link)) { - dc_link_dp_handle_link_loss(dc_link); + /* offload_work->data is from handle_hpd_rx_irq-> + * schedule_hpd_rx_offload_work.this is defer handle + * for hpd short pulse. upon here, link status may be + * changed, need get latest link status from dpcd + * registers. if link status is good, skip run link + * training again. + */ + union hpd_irq_data irq_data; + + memset(&irq_data, 0, sizeof(irq_data)); + + /* before dc_link_dp_handle_link_loss, allow new link lost handle + * request be added to work queue if link lost at end of dc_link_ + * dp_handle_link_loss + */ spin_lock_irqsave(&offload_work->offload_wq->offload_lock, flags); offload_work->offload_wq->is_handling_link_loss = false; spin_unlock_irqrestore(&offload_work->offload_wq->offload_lock, flags); + + if ((read_hpd_rx_irq_data(dc_link, &irq_data) == DC_OK) && + hpd_rx_irq_check_link_loss_status(dc_link, &irq_data)) + dc_link_dp_handle_link_loss(dc_link); } mutex_unlock(&adev->dm.dc_lock); @@ -3326,7 +3344,7 @@ static void handle_hpd_rx_irq(void *param) union hpd_irq_data hpd_irq_data; bool link_loss = false; bool has_left_work = false; - int idx = aconnector->base.index; + int idx = dc_link->link_index; struct hpd_rx_irq_offload_work_queue *offload_wq = &adev->dm.hpd_rx_offload_wq[idx]; memset(&hpd_irq_data, 0, sizeof(hpd_irq_data)); @@ -3468,7 +3486,7 @@ static void register_hpd_handlers(struct amdgpu_device *adev) (void *) aconnector); if (adev->dm.hpd_rx_offload_wq) - adev->dm.hpd_rx_offload_wq[connector->index].aconnector = + adev->dm.hpd_rx_offload_wq[dc_link->link_index].aconnector = aconnector; } } |