From: Meenakshikumar Somasundaram <meenakshikumar.somasunda...@amd.com>

[Why]
For dpia link, link->hpd_status indicates current state, but driver
fails to capture hpd transitions in certain scenarios such as during
link training.

[How]
Added link->hpd_pending flag that captures arrival of new hpd.

Reviewed-by: Jun Lei <jun....@amd.com>
Acked-by: Anson Jacob <anson.ja...@amd.com>
Signed-off-by: Meenakshikumar Somasundaram <meenakshikumar.somasunda...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |  6 +++---
 .../drm/amd/display/dc/core/dc_link_dpia.c    | 20 +++++++++----------
 drivers/gpu/drm/amd/display/dc/dc_link.h      |  1 +
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index c4944ba59ec6..2e2dcd5518da 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -270,10 +270,10 @@ bool dc_link_detect_sink(struct dc_link *link, enum 
dc_connection_type *type)
 
        /* Link may not have physical HPD pin. */
        if (link->ep_type != DISPLAY_ENDPOINT_PHY) {
-               if (link->hpd_status)
-                       *type = dc_connection_single;
-               else
+               if (link->is_hpd_pending || !link->hpd_status)
                        *type = dc_connection_none;
+               else
+                       *type = dc_connection_single;
 
                return true;
        }
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
index b1c9f77d6bf4..d72122593959 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dpia.c
@@ -94,17 +94,17 @@ static enum link_training_result dpia_configure_link(struct 
dc_link *link,
                lt_settings);
 
        status = dpcd_configure_channel_coding(link, lt_settings);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        /* Configure lttpr mode */
        status = dpcd_configure_lttpr_mode(link, lt_settings);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        /* Set link rate, lane count and spread. */
        status = dpcd_set_link_settings(link, lt_settings);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        if (link->preferred_training_settings.fec_enable)
@@ -112,7 +112,7 @@ static enum link_training_result dpia_configure_link(struct 
dc_link *link,
        else
                fec_enable = true;
        status = dp_set_fec_ready(link, fec_enable);
-       if (status != DC_OK && !link->hpd_status)
+       if (status != DC_OK && link->is_hpd_pending)
                return LINK_TRAINING_ABORT;
 
        return LINK_TRAINING_SUCCESS;
@@ -388,7 +388,7 @@ static enum link_training_result 
dpia_training_cr_non_transparent(struct dc_link
        }
 
        /* Abort link training if clock recovery failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) clock recovery\n"
@@ -490,7 +490,7 @@ static enum link_training_result 
dpia_training_cr_transparent(struct dc_link *li
        }
 
        /* Abort link training if clock recovery failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) clock recovery\n"
@@ -675,7 +675,7 @@ static enum link_training_result 
dpia_training_eq_non_transparent(struct dc_link
        }
 
        /* Abort link training if equalization failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) equalization\n"
@@ -758,7 +758,7 @@ static enum link_training_result 
dpia_training_eq_transparent(struct dc_link *li
        }
 
        /* Abort link training if equalization failed due to HPD unplug. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                result = LINK_TRAINING_ABORT;
 
        DC_LOG_HW_LINK_TRAINING("%s\n DPIA(%d) equalization\n"
@@ -892,10 +892,10 @@ static void dpia_training_abort(struct dc_link *link, 
uint32_t hop)
                                __func__,
                                link->link_id.enum_id - ENUM_ID_1,
                                link->lttpr_mode,
-                               link->hpd_status);
+                               link->is_hpd_pending);
 
        /* Abandon clean-up if sink unplugged. */
-       if (!link->hpd_status)
+       if (link->is_hpd_pending)
                return;
 
        if (hop != DPRX)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h 
b/drivers/gpu/drm/amd/display/dc/dc_link.h
index b732398dac89..d449e72a4e2a 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -113,6 +113,7 @@ struct dc_link {
         * DIG encoder. */
        bool is_dig_mapping_flexible;
        bool hpd_status; /* HPD status of link without physical HPD pin. */
+       bool is_hpd_pending; /* Indicates a new received hpd */
 
        bool edp_sink_present;
 
-- 
2.25.1

Reply via email to