From: Dmytro Laktyushkin <[email protected]>

Currently all dcn revisions have to follow the same codepath for
hotplug detection. This change allows per dcn hpd handling consolidating
hpd code in link_encoder.

Reviewed-by: Dillon Varone <[email protected]>
Signed-off-by: Dmytro Laktyushkin <[email protected]>
Signed-off-by: Roman Li <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/dc.h           |   1 -
 .../drm/amd/display/dc/dce/dce_link_encoder.c |  47 ++++-
 .../drm/amd/display/dc/dce/dce_link_encoder.h |   8 +-
 .../display/dc/dcn201/dcn201_link_encoder.c   |   3 +
 .../amd/display/dc/dcn21/dcn21_link_encoder.c |   3 +
 .../display/dc/dio/dcn10/dcn10_link_encoder.c |  43 ++++
 .../display/dc/dio/dcn10/dcn10_link_encoder.h |  11 +-
 .../display/dc/dio/dcn20/dcn20_link_encoder.c |   3 +
 .../dc/dio/dcn30/dcn30_dio_link_encoder.c     |   3 +
 .../dc/dio/dcn301/dcn301_dio_link_encoder.c   |   3 +
 .../dc/dio/dcn31/dcn31_dio_link_encoder.c     |   3 +
 .../dc/dio/dcn32/dcn32_dio_link_encoder.c     |   3 +
 .../dc/dio/dcn321/dcn321_dio_link_encoder.c   |   3 +
 .../dc/dio/dcn35/dcn35_dio_link_encoder.c     |   3 +
 .../dc/dio/dcn401/dcn401_dio_link_encoder.c   |   3 +
 .../amd/display/dc/hwss/dce110/dce110_hwseq.c |  22 +-
 .../drm/amd/display/dc/inc/hw/link_encoder.h  |   4 +
 .../gpu/drm/amd/display/dc/inc/link_service.h |   3 -
 .../drm/amd/display/dc/link/link_detection.c  |  10 +-
 .../drm/amd/display/dc/link/link_factory.c    | 193 ++++++++++--------
 .../amd/display/dc/link/protocols/link_hpd.c  | 165 +++++----------
 .../amd/display/dc/link/protocols/link_hpd.h  |   1 -
 .../dc/resource/dcn32/dcn32_resource.h        |   5 +-
 23 files changed, 293 insertions(+), 250 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 60c5d8627bc7..458883adfc28 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1708,7 +1708,6 @@ struct dc_scratch_space {
        struct dc_link_status link_status;
        struct dprx_states dprx_states;
 
-       struct gpio *hpd_gpio;
        enum dc_link_fec_state fec_state;
        bool is_dds;
        bool is_display_mux_present;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
index 87dbb8d7ed27..b44c364519dc 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
@@ -117,6 +117,8 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs 
= {
        .destroy = dce110_link_encoder_destroy,
        .get_max_link_cap = dce110_link_encoder_get_max_link_cap,
        .get_dig_frontend = dce110_get_dig_frontend,
+       .get_hpd_state = dce110_get_hpd_state,
+       .program_hpd_filter = dce110_program_hpd_filter,
 };
 
 static enum bp_result link_transmitter_control(
@@ -851,6 +853,7 @@ void dce110_link_encoder_construct(
        enc110->base.ctx = init_data->ctx;
        enc110->base.id = init_data->encoder;
 
+       enc110->base.hpd_gpio = init_data->hpd_gpio;
        enc110->base.hpd_source = init_data->hpd_source;
        enc110->base.connector = init_data->connector;
 
@@ -1053,6 +1056,11 @@ void dce110_link_encoder_hw_init(
 
 void dce110_link_encoder_destroy(struct link_encoder **enc)
 {
+       if ((*enc)->hpd_gpio) {
+               dal_gpio_destroy_irq(&(*enc)->hpd_gpio);
+               (*enc)->hpd_gpio = NULL;
+       }
+
        kfree(TO_DCE110_LINK_ENC(*enc));
        *enc = NULL;
 }
@@ -1751,6 +1759,40 @@ void dce110_link_encoder_get_max_link_cap(struct 
link_encoder *enc,
        *link_settings = max_link_cap;
 }
 
+bool dce110_get_hpd_state(struct link_encoder *enc)
+{
+       uint32_t state = 0;
+
+       if (!enc->hpd_gpio)
+               return false;
+
+       dal_gpio_lock_pin(enc->hpd_gpio);
+       dal_gpio_get_value(enc->hpd_gpio, &state);
+       dal_gpio_unlock_pin(enc->hpd_gpio);
+
+       return state;
+}
+
+bool dce110_program_hpd_filter(struct link_encoder *enc, int 
delay_on_connect_in_ms, int delay_on_disconnect_in_ms)
+{
+       /* Setup HPD filtering */
+       if (enc->hpd_gpio && dal_gpio_lock_pin(enc->hpd_gpio) == 
GPIO_RESULT_OK) {
+               struct gpio_hpd_config config;
+
+               config.delay_on_connect = delay_on_connect_in_ms;
+               config.delay_on_disconnect = delay_on_disconnect_in_ms;
+
+               dal_irq_setup_hpd_filter(enc->hpd_gpio, &config);
+
+               dal_gpio_unlock_pin(enc->hpd_gpio);
+
+               return true;
+       } else {
+               ASSERT(0);
+               return false;
+       }
+}
+
 #if defined(CONFIG_DRM_AMD_DC_SI)
 static const struct link_encoder_funcs dce60_lnk_enc_funcs = {
        .validate_output_with_stream =
@@ -1775,7 +1817,9 @@ static const struct link_encoder_funcs 
dce60_lnk_enc_funcs = {
        .is_dig_enabled = dce110_is_dig_enabled,
        .destroy = dce110_link_encoder_destroy,
        .get_max_link_cap = dce110_link_encoder_get_max_link_cap,
-       .get_dig_frontend = dce110_get_dig_frontend
+       .get_dig_frontend = dce110_get_dig_frontend,
+       .get_hpd_state = dce110_get_hpd_state,
+       .program_hpd_filter = dce110_program_hpd_filter,
 };
 
 void dce60_link_encoder_construct(
@@ -1794,6 +1838,7 @@ void dce60_link_encoder_construct(
        enc110->base.ctx = init_data->ctx;
        enc110->base.id = init_data->encoder;
 
+       enc110->base.hpd_gpio = init_data->hpd_gpio;
        enc110->base.hpd_source = init_data->hpd_source;
        enc110->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h 
b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
index c58b69bc319b..9ba533aa6f88 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
@@ -130,11 +130,6 @@
        SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id), \
        SR(DCI_MEM_PWR_STATUS)
 
-#define LE_DCN10_REG_LIST(id)\
-       LE_COMMON_REG_LIST_BASE(id), \
-       SRI(DP_DPHY_BS_SR_SWAP_CNTL, DP, id), \
-       SRI(DP_DPHY_INTERNAL_CTRL, DP, id), \
-       SRI(DP_DPHY_HBR2_PATTERN_CONTROL, DP, id)
 
 struct dce110_link_enc_aux_registers {
        uint32_t AUX_CONTROL;
@@ -319,4 +314,7 @@ bool dce110_is_dig_enabled(struct link_encoder *enc);
 void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc,
        struct dc_link_settings *link_settings);
 
+bool dce110_get_hpd_state(struct link_encoder *enc);
+bool dce110_program_hpd_filter(struct link_encoder *enc, int 
delay_on_connect_in_ms, int delay_on_disconnect_in_ms);
+
 #endif /* __DC_LINK_ENCODER__DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c
index 8d31fa131cd6..9459e8f28338 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c
@@ -104,6 +104,8 @@ static const struct link_encoder_funcs 
dcn201_link_enc_funcs = {
        .fec_is_active = enc2_fec_is_active,
        .is_in_alt_mode = dcn201_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn201_link_encoder_get_max_link_cap,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn201_link_encoder_construct(
@@ -125,6 +127,7 @@ void dcn201_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c
index eb9abb9f9698..36456c9971c8 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c
@@ -325,6 +325,8 @@ static const struct link_encoder_funcs dcn21_link_enc_funcs 
= {
        .get_dig_frontend = dcn10_get_dig_frontend,
        .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn21_link_encoder_construct(
@@ -346,6 +348,7 @@ void dcn21_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c
index 1c1228116487..13e14aad3daa 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.c
@@ -88,8 +88,11 @@ static const struct link_encoder_funcs dcn10_lnk_enc_funcs = 
{
        .get_dig_mode = dcn10_get_dig_mode,
        .destroy = dcn10_link_encoder_destroy,
        .get_max_link_cap = dcn10_link_encoder_get_max_link_cap,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
+
 static enum bp_result link_transmitter_control(
        struct dcn10_link_encoder *enc10,
        struct bp_transmitter_control *cntl)
@@ -682,6 +685,7 @@ void dcn10_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
@@ -873,6 +877,11 @@ void dcn10_link_encoder_hw_init(
 
 void dcn10_link_encoder_destroy(struct link_encoder **enc)
 {
+       if ((*enc)->hpd_gpio) {
+               dal_gpio_destroy_irq(&(*enc)->hpd_gpio);
+               (*enc)->hpd_gpio = NULL;
+       }
+
        kfree(TO_DCN10_LINK_ENC(*enc));
        *enc = NULL;
 }
@@ -1472,3 +1481,37 @@ void dcn10_link_encoder_get_max_link_cap(struct 
link_encoder *enc,
 
        *link_settings = max_link_cap;
 }
+
+bool dcn10_get_hpd_state(struct link_encoder *enc)
+{
+       uint32_t state = 0;
+
+       if (!enc->hpd_gpio)
+               return false;
+
+       dal_gpio_lock_pin(enc->hpd_gpio);
+       dal_gpio_get_value(enc->hpd_gpio, &state);
+       dal_gpio_unlock_pin(enc->hpd_gpio);
+
+       return state;
+}
+
+bool dcn10_program_hpd_filter(struct link_encoder *enc, int 
delay_on_connect_in_ms, int delay_on_disconnect_in_ms)
+{
+       /* Setup HPD filtering */
+       if (enc->hpd_gpio && dal_gpio_lock_pin(enc->hpd_gpio) == 
GPIO_RESULT_OK) {
+               struct gpio_hpd_config config;
+
+               config.delay_on_connect = delay_on_connect_in_ms;
+               config.delay_on_disconnect = delay_on_disconnect_in_ms;
+
+               dal_irq_setup_hpd_filter(enc->hpd_gpio, &config);
+
+               dal_gpio_unlock_pin(enc->hpd_gpio);
+
+               return true;
+       } else {
+               ASSERT(0);
+               return false;
+       }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.h 
b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.h
index b7a89c39f445..eedbd5d2756e 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_link_encoder.h
@@ -79,6 +79,8 @@ struct dcn10_link_enc_aux_registers {
 
 struct dcn10_link_enc_hpd_registers {
        uint32_t DC_HPD_CONTROL;
+       uint32_t DC_HPD_INT_STATUS;
+       uint32_t DC_HPD_TOGGLE_FILT_CNTL;
 };
 
 struct dcn10_link_enc_registers {
@@ -274,7 +276,10 @@ struct dcn10_link_enc_registers {
        type TMDS_CTL0;\
        type AUX_HPD_SEL;\
        type AUX_LS_READ_EN;\
-       type AUX_RX_RECEIVE_WINDOW
+       type AUX_RX_RECEIVE_WINDOW;\
+       type DC_HPD_SENSE;\
+       type DC_HPD_CONNECT_INT_DELAY;\
+       type DC_HPD_DISCONNECT_INT_DELAY
 
 
 #define DCN20_LINK_ENCODER_DPCS_REG_FIELD_LIST(type) \
@@ -656,4 +661,8 @@ enum signal_type dcn10_get_dig_mode(
 
 void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
        struct dc_link_settings *link_settings);
+
+bool dcn10_get_hpd_state(struct link_encoder *enc);
+bool dcn10_program_hpd_filter(struct link_encoder *enc, int 
delay_on_connect_in_ms, int delay_on_disconnect_in_ms);
+
 #endif /* __DC_LINK_ENCODER__DCN10_H__ */
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn20/dcn20_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn20/dcn20_link_encoder.c
index 51a57dae1811..3bd35f3392dc 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn20/dcn20_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn20/dcn20_link_encoder.c
@@ -384,6 +384,8 @@ static const struct link_encoder_funcs dcn20_link_enc_funcs 
= {
        .get_dig_frontend = dcn10_get_dig_frontend,
        .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn20_link_encoder_construct(
@@ -405,6 +407,7 @@ void dcn20_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_link_encoder.c
index b8e31b5ea114..57b9ae5fca1d 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn30/dcn30_dio_link_encoder.c
@@ -84,6 +84,8 @@ static const struct link_encoder_funcs dcn30_link_enc_funcs = 
{
        .get_dig_mode = dcn10_get_dig_mode,
        .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn30_link_encoder_construct(
@@ -105,6 +107,7 @@ void dcn30_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git 
a/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.c
index 1b39a6e8a1ac..47d84a2a48ce 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn301/dcn301_dio_link_encoder.c
@@ -73,6 +73,8 @@ static const struct link_encoder_funcs dcn301_link_enc_funcs 
= {
        .get_dig_mode = dcn10_get_dig_mode,
        .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn301_link_encoder_construct(
@@ -94,6 +96,7 @@ void dcn301_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn31/dcn31_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn31/dcn31_dio_link_encoder.c
index 84cc2ddc52fe..07d362ef0daf 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn31/dcn31_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn31/dcn31_dio_link_encoder.c
@@ -276,6 +276,8 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs 
= {
        .is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn31_link_encoder_get_max_link_cap,
        .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn31_link_encoder_construct(
@@ -297,6 +299,7 @@ void dcn31_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn32/dcn32_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn32/dcn32_dio_link_encoder.c
index 06907e8a4eda..44a4e3c4efb9 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn32/dcn32_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn32/dcn32_dio_link_encoder.c
@@ -224,6 +224,8 @@ static const struct link_encoder_funcs dcn32_link_enc_funcs 
= {
        .is_in_alt_mode = dcn32_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn32_link_encoder_get_max_link_cap,
        .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn32_link_encoder_construct(
@@ -245,6 +247,7 @@ void dcn32_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git 
a/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c
index 2ed382a8e79c..968f89295b64 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn321/dcn321_dio_link_encoder.c
@@ -89,6 +89,8 @@ static const struct link_encoder_funcs dcn321_link_enc_funcs 
= {
        .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
        .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn321_link_encoder_construct(
@@ -110,6 +112,7 @@ void dcn321_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c
index 9972911330b6..319eb1061ba8 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn35/dcn35_dio_link_encoder.c
@@ -162,6 +162,8 @@ static const struct link_encoder_funcs dcn35_link_enc_funcs 
= {
        .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
        .enable_dpia_output = dcn35_link_encoder_enable_dpia_output,
        .disable_dpia_output = dcn35_link_encoder_disable_dpia_output,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn35_link_encoder_construct(
@@ -183,6 +185,7 @@ void dcn35_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git 
a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_link_encoder.c
index 7e558ca195ef..e1f0a1bf1075 100644
--- a/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dio/dcn401/dcn401_dio_link_encoder.c
@@ -215,6 +215,8 @@ static const struct link_encoder_funcs 
dcn401_link_enc_funcs = {
        .is_in_alt_mode = dcn32_link_encoder_is_in_alt_mode,
        .get_max_link_cap = dcn32_link_encoder_get_max_link_cap,
        .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
+       .get_hpd_state = dcn10_get_hpd_state,
+       .program_hpd_filter = dcn10_program_hpd_filter,
 };
 
 void dcn401_link_encoder_construct(
@@ -236,6 +238,7 @@ void dcn401_link_encoder_construct(
        enc10->base.ctx = init_data->ctx;
        enc10->base.id = init_data->encoder;
 
+       enc10->base.hpd_gpio = init_data->hpd_gpio;
        enc10->base.hpd_source = init_data->hpd_source;
        enc10->base.connector = init_data->connector;
 
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 21cee49c128f..1783a3c59061 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -729,7 +729,6 @@ void dce110_edp_wait_for_hpd_ready(
 {
        struct dc_context *ctx = link->ctx;
        struct graphics_object_id connector = link->link_enc->connector;
-       struct gpio *hpd;
        bool edp_hpd_high = false;
        uint32_t time_elapsed = 0;
        uint32_t timeout = power_up ?
@@ -753,31 +752,16 @@ void dce110_edp_wait_for_hpd_ready(
         * we need to wait until SENSE bit is high/low.
         */
 
-       /* obtain HPD */
-       /* TODO what to do with this? */
-       hpd = ctx->dc->link_srv->get_hpd_gpio(ctx->dc_bios, connector, 
ctx->gpio_service);
-
-       if (!hpd) {
-               BREAK_TO_DEBUGGER();
-               return;
-       }
-
        if (link->panel_config.pps.extra_t3_ms > 0) {
                int extra_t3_in_ms = link->panel_config.pps.extra_t3_ms;
 
                msleep(extra_t3_in_ms);
        }
 
-       dal_gpio_open(hpd, GPIO_MODE_INTERRUPT);
-
        /* wait until timeout or panel detected */
 
        do {
-               uint32_t detected = 0;
-
-               dal_gpio_get_value(hpd, &detected);
-
-               if (!(detected ^ power_up)) {
+               if (!(link->dc->link_srv->get_hpd_state(link) ^ power_up)) {
                        edp_hpd_high = true;
                        break;
                }
@@ -787,10 +771,6 @@ void dce110_edp_wait_for_hpd_ready(
                time_elapsed += HPD_CHECK_INTERVAL;
        } while (time_elapsed < timeout);
 
-       dal_gpio_close(hpd);
-
-       dal_gpio_destroy_irq(&hpd);
-
        /* ensure that the panel is detected */
        if (!edp_hpd_high)
                DC_LOG_DC("%s: wait timed out!\n", __func__);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index df512920a9fa..cff705c49564 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -44,6 +44,7 @@ struct pipe_ctx;
 struct encoder_init_data {
        enum channel_id channel;
        struct graphics_object_id connector;
+       struct gpio *hpd_gpio;
        enum hpd_source_id hpd_source;
        /* TODO: in DAL2, here was pointer to EventManagerInterface */
        struct graphics_object_id encoder;
@@ -87,6 +88,7 @@ struct link_encoder {
        enum engine_id analog_engine;
        struct encoder_feature_support features;
        enum transmitter transmitter;
+       struct gpio *hpd_gpio;
        enum hpd_source_id hpd_source;
        bool usbc_combo_phy;
 };
@@ -178,6 +180,8 @@ struct link_encoder_funcs {
        void (*disable_dpia_output)(struct link_encoder *link_enc,
                uint8_t dpia_id,
                uint8_t digmode);
+       bool (*get_hpd_state)(struct link_encoder *enc);
+       bool (*program_hpd_filter)(struct link_encoder *enc, int 
delay_on_connect_in_ms, int delay_on_disconnect_in_ms);
 };
 
 /*
diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_service.h 
b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
index 2f805ba19a52..4b092a9ee4c6 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/link_service.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/link_service.h
@@ -114,9 +114,6 @@ struct link_service {
                        struct dc_sink_init_data *init_data);
        void (*remove_remote_sink)(struct dc_link *link, struct dc_sink *sink);
        bool (*get_hpd_state)(struct dc_link *link);
-       struct gpio *(*get_hpd_gpio)(struct dc_bios *dcb,
-                       struct graphics_object_id link_id,
-                       struct gpio_service *gpio_service);
        void (*enable_hpd)(const struct dc_link *link);
        void (*disable_hpd)(const struct dc_link *link);
        void (*enable_hpd_filter)(struct dc_link *link, bool enable);
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c 
b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index f9258d71b68e..373e68cf2bde 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -1400,8 +1400,6 @@ static bool link_detect_analog(struct dc_link *link, enum 
dc_connection_type *ty
  */
 bool link_detect_connection_type(struct dc_link *link, enum dc_connection_type 
*type)
 {
-       uint32_t is_hpd_high = 0;
-
        if (link->connector_signal == SIGNAL_TYPE_LVDS) {
                *type = dc_connection_single;
                return true;
@@ -1436,10 +1434,7 @@ bool link_detect_connection_type(struct dc_link *link, 
enum dc_connection_type *
        }
 
 
-       if (!query_hpd_status(link, &is_hpd_high))
-               goto hpd_gpio_failure;
-
-       if (is_hpd_high) {
+       if (link_get_hpd_state(link)) {
                *type = dc_connection_single;
                /* TODO: need to do the actual detection */
        } else {
@@ -1452,9 +1447,6 @@ bool link_detect_connection_type(struct dc_link *link, 
enum dc_connection_type *
        }
 
        return true;
-
-hpd_gpio_failure:
-       return false;
 }
 
 bool link_detect(struct dc_link *link, enum dc_detect_reason reason)
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c 
b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
index 90a4f37a5da3..56fdd1446a59 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
@@ -73,7 +73,6 @@ static void construct_link_service_detection(struct 
link_service *link_srv)
        link_srv->add_remote_sink = link_add_remote_sink;
        link_srv->remove_remote_sink = link_remove_remote_sink;
        link_srv->get_hpd_state = link_get_hpd_state;
-       link_srv->get_hpd_gpio = link_get_hpd_gpio;
        link_srv->enable_hpd = link_enable_hpd;
        link_srv->disable_hpd = link_disable_hpd;
        link_srv->enable_hpd_filter = link_enable_hpd_filter;
@@ -363,11 +362,6 @@ static void link_destruct(struct dc_link *link)
 {
        int i;
 
-       if (link->hpd_gpio) {
-               dal_gpio_destroy_irq(&link->hpd_gpio);
-               link->hpd_gpio = NULL;
-       }
-
        if (link->ddc)
                link_destroy_ddc_service(&link->ddc);
 
@@ -536,25 +530,76 @@ static bool construct_phy(struct dc_link *link,
        if (link->dc->res_pool->funcs->link_init)
                link->dc->res_pool->funcs->link_init(link);
 
-       link->hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
+       ddc_service_init_data.ctx = link->ctx;
+       ddc_service_init_data.id = link->link_id;
+       ddc_service_init_data.link = link;
+       link->ddc = link_create_ddc_service(&ddc_service_init_data);
+
+       if (!link->ddc) {
+               DC_ERROR("Failed to create ddc_service!\n");
+               goto ddc_create_fail;
+       }
+
+       if (!link->ddc->ddc_pin) {
+               DC_ERROR("Failed to get I2C info for connector!\n");
+               goto ddc_create_fail;
+       }
+
+       link->ddc_hw_inst =
+               dal_ddc_get_line(get_ddc_pin(link->ddc));
+
+       enc_init_data.ctx = dc_ctx;
+       enc_init_data.connector = link->link_id;
+       enc_init_data.channel = get_ddc_line(link);
+       enc_init_data.transmitter = transmitter_from_encoder;
+       enc_init_data.encoder = link_encoder;
+       enc_init_data.analog_engine = link_analog_engine;
+       enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, 
link->link_id,
                                      link->ctx->gpio_service);
 
-       if (link->hpd_gpio) {
-               dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
-               dal_gpio_unlock_pin(link->hpd_gpio);
-               link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
+       if (enc_init_data.hpd_gpio) {
+               dal_gpio_open(enc_init_data.hpd_gpio, GPIO_MODE_INTERRUPT);
+               dal_gpio_unlock_pin(enc_init_data.hpd_gpio);
+               link->irq_source_hpd = 
dal_irq_get_source(enc_init_data.hpd_gpio);
+               enc_init_data.hpd_source = get_hpd_line(link);
+               link->hpd_src = enc_init_data.hpd_source;
+
+               DC_LOG_DC("BIOS object table - hpd_gpio id: %d", 
enc_init_data.hpd_gpio->id);
+               DC_LOG_DC("BIOS object table - hpd_gpio en: %d", 
enc_init_data.hpd_gpio->en);
+       } else {
+               struct graphics_object_hpd_info hpd_info;
+
+               if (link->ctx->dc_bios->funcs->get_hpd_info(link->ctx->dc_bios, 
link->link_id, &hpd_info) == BP_RESULT_OK) {
+                       link->hpd_src = hpd_info.hpd_int_gpio_uid - 1;
+                       link->irq_source_hpd =  DC_IRQ_SOURCE_HPD1 + 
link->hpd_src;
+                       enc_init_data.hpd_source = link->hpd_src;
+                       DC_LOG_DC("BIOS object table - hpd_int_gpio_uid id: 
%d", hpd_info.hpd_int_gpio_uid);
+               } else {
+                       ASSERT(0);
+                       enc_init_data.hpd_source = HPD_SOURCEID_UNKNOWN;
+               }
+       }
 
-               DC_LOG_DC("BIOS object table - hpd_gpio id: %d", 
link->hpd_gpio->id);
-               DC_LOG_DC("BIOS object table - hpd_gpio en: %d", 
link->hpd_gpio->en);
+       link->link_enc =
+               link->dc->res_pool->funcs->link_enc_create(dc_ctx, 
&enc_init_data);
+
+       if (!link->link_enc) {
+               DC_ERROR("Failed to create link encoder!\n");
+               goto link_enc_create_fail;
        }
 
+       DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", 
link->link_enc->features.flags.bits.DP_IS_USB_C);
+       DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", 
link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
+
        switch (link->link_id.id) {
        case CONNECTOR_ID_HDMI_TYPE_A:
                link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
 
-               if (link->hpd_gpio)
+               if (link->link_enc->hpd_gpio)
                        link->irq_source_read_request =
-                                       
dal_irq_get_read_request(link->hpd_gpio);
+                                       
dal_irq_get_read_request(link->link_enc->hpd_gpio);
+               else if (link->hpd_src != HPD_SOURCEID_UNKNOWN)
+                       link->irq_source_read_request = 
DC_IRQ_SOURCE_DCI2C_RR_DDC1 + link->hpd_src;
                break;
        case CONNECTOR_ID_SINGLE_LINK_DVID:
        case CONNECTOR_ID_SINGLE_LINK_DVII:
@@ -572,9 +617,11 @@ static bool construct_phy(struct dc_link *link,
        case CONNECTOR_ID_USBC:
                link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
 
-               if (link->hpd_gpio)
+               if (link->link_enc->hpd_gpio)
                        link->irq_source_hpd_rx =
-                                       dal_irq_get_rx_source(link->hpd_gpio);
+                                       
dal_irq_get_rx_source(link->link_enc->hpd_gpio);
+               else if (link->hpd_src != HPD_SOURCEID_UNKNOWN)
+                       link->irq_source_hpd_rx = DC_IRQ_SOURCE_HPD1RX + 
link->hpd_src;
 
                break;
        case CONNECTOR_ID_EDP:
@@ -584,37 +631,45 @@ static bool construct_phy(struct dc_link *link,
                        goto create_fail;
 
                link->connector_signal = SIGNAL_TYPE_EDP;
+               if (!link->dc->config.allow_edp_hotplug_detection
+                       && !is_smartmux_suported(link))
+                       link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
 
-               if (link->hpd_gpio) {
-                       if (!link->dc->config.allow_edp_hotplug_detection
-                               && !is_smartmux_suported(link))
-                               link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
-
-                       switch (link->dc->config.allow_edp_hotplug_detection) {
-                       case HPD_EN_FOR_ALL_EDP:
+               switch (link->dc->config.allow_edp_hotplug_detection) {
+               case HPD_EN_FOR_ALL_EDP:
+                       if (link->link_enc->hpd_gpio) {
                                link->irq_source_hpd_rx =
-                                               
dal_irq_get_rx_source(link->hpd_gpio);
-                               break;
-                       case HPD_EN_FOR_PRIMARY_EDP_ONLY:
-                               if (link->link_index == 0)
+                                               
dal_irq_get_rx_source(link->link_enc->hpd_gpio);
+                               } else if (link->hpd_src != 
HPD_SOURCEID_UNKNOWN) {
+                                       link->irq_source_hpd_rx = 
DC_IRQ_SOURCE_HPD1RX + link->hpd_src;
+                               }
+                       break;
+               case HPD_EN_FOR_PRIMARY_EDP_ONLY:
+                       if (link->link_index == 0) {
+                               if (link->link_enc->hpd_gpio) {
                                        link->irq_source_hpd_rx =
-                                               
dal_irq_get_rx_source(link->hpd_gpio);
-                               else
-                                       link->irq_source_hpd = 
DC_IRQ_SOURCE_INVALID;
-                               break;
-                       case HPD_EN_FOR_SECONDARY_EDP_ONLY:
-                               if (link->link_index == 1)
+                                               
dal_irq_get_rx_source(link->link_enc->hpd_gpio);
+                               } else if (link->hpd_src != 
HPD_SOURCEID_UNKNOWN) {
+                                       link->irq_source_hpd_rx = 
DC_IRQ_SOURCE_HPD1RX + link->hpd_src;
+                               }
+                       } else
+                               link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
+                       break;
+               case HPD_EN_FOR_SECONDARY_EDP_ONLY:
+                       if (link->link_index == 1) {
+                               if (link->link_enc->hpd_gpio) {
                                        link->irq_source_hpd_rx =
-                                               
dal_irq_get_rx_source(link->hpd_gpio);
-                               else
-                                       link->irq_source_hpd = 
DC_IRQ_SOURCE_INVALID;
-                               break;
-                       default:
+                                               
dal_irq_get_rx_source(link->link_enc->hpd_gpio);
+                               } else if (link->hpd_src != 
HPD_SOURCEID_UNKNOWN) {
+                                       link->irq_source_hpd_rx = 
DC_IRQ_SOURCE_HPD1RX + link->hpd_src;
+                               }
+                       } else
                                link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
-                               break;
-                       }
+                       break;
+               default:
+                       link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
+                       break;
                }
-
                break;
        case CONNECTOR_ID_LVDS:
                link->connector_signal = SIGNAL_TYPE_LVDS;
@@ -629,45 +684,6 @@ static bool construct_phy(struct dc_link *link,
                  init_params->connector_index,
                  signal_type_to_string(link->connector_signal));
 
-       ddc_service_init_data.ctx = link->ctx;
-       ddc_service_init_data.id = link->link_id;
-       ddc_service_init_data.link = link;
-       link->ddc = link_create_ddc_service(&ddc_service_init_data);
-
-       if (!link->ddc) {
-               DC_ERROR("Failed to create ddc_service!\n");
-               goto ddc_create_fail;
-       }
-
-       if (!link->ddc->ddc_pin) {
-               DC_ERROR("Failed to get I2C info for connector!\n");
-               goto ddc_create_fail;
-       }
-
-       link->ddc_hw_inst =
-               dal_ddc_get_line(get_ddc_pin(link->ddc));
-
-       enc_init_data.ctx = dc_ctx;
-       enc_init_data.connector = link->link_id;
-       enc_init_data.channel = get_ddc_line(link);
-       enc_init_data.hpd_source = get_hpd_line(link);
-       enc_init_data.transmitter = transmitter_from_encoder;
-       enc_init_data.encoder = link_encoder;
-       enc_init_data.analog_engine = link_analog_engine;
-
-       link->hpd_src = enc_init_data.hpd_source;
-
-       link->link_enc =
-               link->dc->res_pool->funcs->link_enc_create(dc_ctx, 
&enc_init_data);
-
-       if (!link->link_enc) {
-               DC_ERROR("Failed to create link encoder!\n");
-               goto link_enc_create_fail;
-       }
-
-       DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", 
link->link_enc->features.flags.bits.DP_IS_USB_C);
-       DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", 
link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
-
        /* Update link encoder tracking variables. These are used for the 
dynamic
         * assignment of link encoders to streams.
         */
@@ -776,19 +792,16 @@ static bool construct_phy(struct dc_link *link,
        DC_LOG_DC("BIOS object table - %s finished successfully.\n", __func__);
        return true;
 device_tag_fail:
-       link->link_enc->funcs->destroy(&link->link_enc);
 link_enc_create_fail:
-       if (link->panel_cntl != NULL)
-               link->panel_cntl->funcs->destroy(&link->panel_cntl);
 panel_cntl_create_fail:
-       link_destroy_ddc_service(&link->ddc);
 ddc_create_fail:
 create_fail:
-
-       if (link->hpd_gpio) {
-               dal_gpio_destroy_irq(&link->hpd_gpio);
-               link->hpd_gpio = NULL;
-       }
+       if (link->ddc)
+               link_destroy_ddc_service(&link->ddc);
+       if (link->panel_cntl)
+               link->panel_cntl->funcs->destroy(&link->panel_cntl);
+       if (link->link_enc)
+               link->link_enc->funcs->destroy(&link->link_enc);
 
        DC_LOG_DC("BIOS object table - %s failed.\n", __func__);
        return false;
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c
index caa617883f62..29f3a03687b2 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c
@@ -35,62 +35,75 @@
 
 bool link_get_hpd_state(struct dc_link *link)
 {
-       uint32_t state = 0;
-
-       dal_gpio_lock_pin(link->hpd_gpio);
-       dal_gpio_get_value(link->hpd_gpio, &state);
-       dal_gpio_unlock_pin(link->hpd_gpio);
-
-       return state;
+       if (link->link_enc)
+               return link->link_enc->funcs->get_hpd_state(link->link_enc);
+       else
+               return false;
 }
 
 void link_enable_hpd(const struct dc_link *link)
 {
-       struct link_encoder *encoder = link->link_enc;
-
-       if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
-               encoder->funcs->enable_hpd(encoder);
+       if (link->link_enc)
+               link->link_enc->funcs->enable_hpd(link->link_enc);
 }
 
 void link_disable_hpd(const struct dc_link *link)
 {
-       struct link_encoder *encoder = link->link_enc;
-
-       if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
-               encoder->funcs->disable_hpd(encoder);
+       if (link->link_enc)
+               link->link_enc->funcs->disable_hpd(link->link_enc);
 }
 
 void link_enable_hpd_filter(struct dc_link *link, bool enable)
 {
-       struct gpio *hpd;
-
        if (enable) {
                link->is_hpd_filter_disabled = false;
                program_hpd_filter(link);
        } else {
                link->is_hpd_filter_disabled = true;
-               /* Obtain HPD handle */
-               hpd = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, 
link->ctx->gpio_service);
-
-               if (!hpd)
-                       return;
-
-               /* Setup HPD filtering */
-               if (dal_gpio_open(hpd, GPIO_MODE_INTERRUPT) == GPIO_RESULT_OK) {
-                       struct gpio_hpd_config config;
+               if (link->link_enc)
+                       
link->link_enc->funcs->program_hpd_filter(link->link_enc, 0, 0);
+       }
+}
 
-                       config.delay_on_connect = 0;
-                       config.delay_on_disconnect = 0;
+bool program_hpd_filter(const struct dc_link *link)
+{
+       int delay_on_connect_in_ms = 0;
+       int delay_on_disconnect_in_ms = 0;
 
-                       dal_irq_setup_hpd_filter(hpd, &config);
+       if (link->is_hpd_filter_disabled || !link->link_enc) {
+               ASSERT(link->link_enc);
+               return false;
+       }
 
-                       dal_gpio_close(hpd);
-               } else {
-                       ASSERT_CRITICAL(false);
-               }
-               /* Release HPD handle */
-               dal_gpio_destroy_irq(&hpd);
+       /* Verify feature is supported */
+       switch (link->connector_signal) {
+       case SIGNAL_TYPE_DVI_SINGLE_LINK:
+       case SIGNAL_TYPE_DVI_DUAL_LINK:
+       case SIGNAL_TYPE_HDMI_TYPE_A:
+               /* Program hpd filter */
+               delay_on_connect_in_ms = 500;
+               delay_on_disconnect_in_ms = 100;
+               break;
+       case SIGNAL_TYPE_DISPLAY_PORT:
+       case SIGNAL_TYPE_DISPLAY_PORT_MST:
+               /* Program hpd filter to allow DP signal to settle */
+               /* 500: not able to detect MST <-> SST switch as HPD is low for
+                * only 100ms on DELL U2413
+                * 0: some passive dongle still show aux mode instead of i2c
+                * 20-50: not enough to hide bouncing HPD with passive dongle.
+                * also see intermittent i2c read issues.
+                */
+               delay_on_connect_in_ms = 80;
+               delay_on_disconnect_in_ms = 0;
+               break;
+       case SIGNAL_TYPE_LVDS:
+       case SIGNAL_TYPE_EDP:
+       default:
+               /* Don't program hpd filter */
+               return false;
        }
+
+       return link->link_enc->funcs->program_hpd_filter(link->link_enc, 
delay_on_connect_in_ms, delay_on_disconnect_in_ms);
 }
 
 struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
@@ -108,7 +121,6 @@ struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
                hpd_info.hpd_int_gpio_uid, &pin_info);
 
        if (bp_result != BP_RESULT_OK) {
-               ASSERT(bp_result == BP_RESULT_NORECORD);
                return NULL;
        }
 
@@ -117,21 +129,6 @@ struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
                                           pin_info.mask);
 }
 
-bool query_hpd_status(struct dc_link *link, uint32_t *is_hpd_high)
-{
-       struct gpio *hpd_pin = link_get_hpd_gpio(
-                       link->ctx->dc_bios, link->link_id,
-                       link->ctx->gpio_service);
-       if (!hpd_pin)
-               return false;
-
-       dal_gpio_open(hpd_pin, GPIO_MODE_INTERRUPT);
-       dal_gpio_get_value(hpd_pin, is_hpd_high);
-       dal_gpio_close(hpd_pin);
-       dal_gpio_destroy_irq(&hpd_pin);
-       return true;
-}
-
 enum hpd_source_id get_hpd_line(struct dc_link *link)
 {
        struct gpio *hpd;
@@ -172,69 +169,3 @@ enum hpd_source_id get_hpd_line(struct dc_link *link)
 
        return hpd_id;
 }
-
-bool program_hpd_filter(const struct dc_link *link)
-{
-       bool result = false;
-       struct gpio *hpd;
-       int delay_on_connect_in_ms = 0;
-       int delay_on_disconnect_in_ms = 0;
-
-       if (link->is_hpd_filter_disabled)
-               return false;
-       /* Verify feature is supported */
-       switch (link->connector_signal) {
-       case SIGNAL_TYPE_DVI_SINGLE_LINK:
-       case SIGNAL_TYPE_DVI_DUAL_LINK:
-       case SIGNAL_TYPE_HDMI_TYPE_A:
-               /* Program hpd filter */
-               delay_on_connect_in_ms = 500;
-               delay_on_disconnect_in_ms = 100;
-               break;
-       case SIGNAL_TYPE_DISPLAY_PORT:
-       case SIGNAL_TYPE_DISPLAY_PORT_MST:
-               /* Program hpd filter to allow DP signal to settle */
-               /* 500: not able to detect MST <-> SST switch as HPD is low for
-                * only 100ms on DELL U2413
-                * 0: some passive dongle still show aux mode instead of i2c
-                * 20-50: not enough to hide bouncing HPD with passive dongle.
-                * also see intermittent i2c read issues.
-                */
-               delay_on_connect_in_ms = 80;
-               delay_on_disconnect_in_ms = 0;
-               break;
-       case SIGNAL_TYPE_LVDS:
-       case SIGNAL_TYPE_EDP:
-       default:
-               /* Don't program hpd filter */
-               return false;
-       }
-
-       /* Obtain HPD handle */
-       hpd = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
-                          link->ctx->gpio_service);
-
-       if (!hpd)
-               return result;
-
-       /* Setup HPD filtering */
-       if (dal_gpio_open(hpd, GPIO_MODE_INTERRUPT) == GPIO_RESULT_OK) {
-               struct gpio_hpd_config config;
-
-               config.delay_on_connect = delay_on_connect_in_ms;
-               config.delay_on_disconnect = delay_on_disconnect_in_ms;
-
-               dal_irq_setup_hpd_filter(hpd, &config);
-
-               dal_gpio_close(hpd);
-
-               result = true;
-       } else {
-               ASSERT_CRITICAL(false);
-       }
-
-       /* Release HPD handle */
-       dal_gpio_destroy_irq(&hpd);
-
-       return result;
-}
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h
index af529328ba17..b4e449de960e 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.h
@@ -43,7 +43,6 @@ bool program_hpd_filter(const struct dc_link *link);
  * Returns true if HPD high.
  */
 bool dpia_query_hpd_status(struct dc_link *link);
-bool query_hpd_status(struct dc_link *link, uint32_t *is_hpd_high);
 bool link_get_hpd_state(struct dc_link *link);
 struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
                struct graphics_object_id link_id,
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h 
b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
index 99f0432288b4..684945fdd378 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
@@ -317,7 +317,10 @@ unsigned int dcn32_get_max_hw_cursor_size(const struct dc 
*dc,
   AUX_REG_LIST_RI(id), SRI_ARR(AUX_DPHY_TX_CONTROL, DP_AUX, id)
 
 /* HDP */
-#define HPD_REG_LIST_RI(id) SRI_ARR(DC_HPD_CONTROL, HPD, id)
+#define HPD_REG_LIST_RI(id)                                                  \
+  SRI_ARR(DC_HPD_CONTROL, HPD, id),                                          \
+      SRI_ARR(DC_HPD_INT_STATUS, HPD, id),                                   \
+      SRI_ARR(DC_HPD_TOGGLE_FILT_CNTL, HPD, id)
 
 /* Link encoder */
 #define LE_DCN3_REG_LIST_RI(id)                                                
\
-- 
2.34.1

Reply via email to