Skip to content

Commit 78ea2ed

Browse files
Hersen Wugregkh
authored andcommitted
drm/amd/display: fix linux dp link lost handled only one time
commit e322843 upstream. [Why] linux amdgpu defer handle link lost irq. dm add handle request to irq work queue for the first irq of link lost. if link training fails for link lost handle, link will not be enabled anymore. [How] allow adding handle request of link lost to work queue before running dp link training for link lost. Signed-off-by: Hersen Wu <[email protected]> Acked-by: Alex Hung <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]> [ Modified due to not having c5a31f1 ("drm/amd/display: move dp irq handler functions from dc_link_dp to link_dp_irq_handler") until kernel 6.3-rc1.] Signed-off-by: Mario Limonciello <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b31143b commit 78ea2ed

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,10 +1346,28 @@ static void dm_handle_hpd_rx_offload_work(struct work_struct *work)
13461346
} else if ((dc_link->connector_signal != SIGNAL_TYPE_EDP) &&
13471347
hpd_rx_irq_check_link_loss_status(dc_link, &offload_work->data) &&
13481348
dc_link_dp_allow_hpd_rx_irq(dc_link)) {
1349-
dc_link_dp_handle_link_loss(dc_link);
1349+
/* offload_work->data is from handle_hpd_rx_irq->
1350+
* schedule_hpd_rx_offload_work.this is defer handle
1351+
* for hpd short pulse. upon here, link status may be
1352+
* changed, need get latest link status from dpcd
1353+
* registers. if link status is good, skip run link
1354+
* training again.
1355+
*/
1356+
union hpd_irq_data irq_data;
1357+
1358+
memset(&irq_data, 0, sizeof(irq_data));
1359+
1360+
/* before dc_link_dp_handle_link_loss, allow new link lost handle
1361+
* request be added to work queue if link lost at end of dc_link_
1362+
* dp_handle_link_loss
1363+
*/
13501364
spin_lock_irqsave(&offload_work->offload_wq->offload_lock, flags);
13511365
offload_work->offload_wq->is_handling_link_loss = false;
13521366
spin_unlock_irqrestore(&offload_work->offload_wq->offload_lock, flags);
1367+
1368+
if ((read_hpd_rx_irq_data(dc_link, &irq_data) == DC_OK) &&
1369+
hpd_rx_irq_check_link_loss_status(dc_link, &irq_data))
1370+
dc_link_dp_handle_link_loss(dc_link);
13531371
}
13541372
mutex_unlock(&adev->dm.dc_lock);
13551373

@@ -3324,7 +3342,7 @@ static void handle_hpd_rx_irq(void *param)
33243342
union hpd_irq_data hpd_irq_data;
33253343
bool link_loss = false;
33263344
bool has_left_work = false;
3327-
int idx = aconnector->base.index;
3345+
int idx = dc_link->link_index;
33283346
struct hpd_rx_irq_offload_work_queue *offload_wq = &adev->dm.hpd_rx_offload_wq[idx];
33293347

33303348
memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
@@ -3466,7 +3484,7 @@ static void register_hpd_handlers(struct amdgpu_device *adev)
34663484
(void *) aconnector);
34673485

34683486
if (adev->dm.hpd_rx_offload_wq)
3469-
adev->dm.hpd_rx_offload_wq[connector->index].aconnector =
3487+
adev->dm.hpd_rx_offload_wq[dc_link->link_index].aconnector =
34703488
aconnector;
34713489
}
34723490
}

drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3115,7 +3115,7 @@ struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
31153115
return max_link_cap;
31163116
}
31173117

3118-
static enum dc_status read_hpd_rx_irq_data(
3118+
enum dc_status read_hpd_rx_irq_data(
31193119
struct dc_link *link,
31203120
union hpd_irq_data *irq_data)
31213121
{

drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ bool perform_link_training_with_retries(
8282
enum signal_type signal,
8383
bool do_fallback);
8484

85+
enum dc_status read_hpd_rx_irq_data(
86+
struct dc_link *link,
87+
union hpd_irq_data *irq_data);
88+
8589
bool hpd_rx_irq_check_link_loss_status(
8690
struct dc_link *link,
8791
union hpd_irq_data *hpd_irq_dpcd_data);

0 commit comments

Comments
 (0)