mirror of
https://github.com/torvalds/linux.git
synced 2026-05-13 16:59:27 +02:00
drm/amd/display: refactor HPD to increase flexibility
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 <dillon.varone@amd.com> Signed-off-by: Dmytro Laktyushkin <dmytro.laktyushkin@amd.com> Signed-off-by: Roman Li <roman.li@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
6afc422e1a
commit
def3488eb0
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -728,7 +728,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 ?
|
||||
|
|
@ -752,31 +751,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;
|
||||
}
|
||||
|
|
@ -786,10 +770,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__);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,99 +530,6 @@ 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,
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
switch (link->link_id.id) {
|
||||
case CONNECTOR_ID_HDMI_TYPE_A:
|
||||
link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
|
||||
if (link->hpd_gpio)
|
||||
link->irq_source_read_request =
|
||||
dal_irq_get_read_request(link->hpd_gpio);
|
||||
break;
|
||||
case CONNECTOR_ID_SINGLE_LINK_DVID:
|
||||
case CONNECTOR_ID_SINGLE_LINK_DVII:
|
||||
link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
|
||||
break;
|
||||
case CONNECTOR_ID_DUAL_LINK_DVID:
|
||||
case CONNECTOR_ID_DUAL_LINK_DVII:
|
||||
link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
|
||||
break;
|
||||
case CONNECTOR_ID_VGA:
|
||||
link->connector_signal = SIGNAL_TYPE_RGB;
|
||||
break;
|
||||
case CONNECTOR_ID_DISPLAY_PORT:
|
||||
case CONNECTOR_ID_MXM:
|
||||
case CONNECTOR_ID_USBC:
|
||||
link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
|
||||
|
||||
if (link->hpd_gpio)
|
||||
link->irq_source_hpd_rx =
|
||||
dal_irq_get_rx_source(link->hpd_gpio);
|
||||
|
||||
break;
|
||||
case CONNECTOR_ID_EDP:
|
||||
// If smartmux is supported, only create the link on the primary eDP.
|
||||
// Dual eDP is not supported with smartmux.
|
||||
if (!(!link->dc->config.smart_mux_version || dc_ctx->dc_edp_id_count == 0))
|
||||
goto create_fail;
|
||||
|
||||
link->connector_signal = SIGNAL_TYPE_EDP;
|
||||
|
||||
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:
|
||||
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)
|
||||
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)
|
||||
link->irq_source_hpd_rx =
|
||||
dal_irq_get_rx_source(link->hpd_gpio);
|
||||
else
|
||||
link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
|
||||
break;
|
||||
default:
|
||||
link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case CONNECTOR_ID_LVDS:
|
||||
link->connector_signal = SIGNAL_TYPE_LVDS;
|
||||
break;
|
||||
default:
|
||||
DC_LOG_WARNING("Unsupported Connector type:%d!\n",
|
||||
link->link_id.id);
|
||||
goto create_fail;
|
||||
}
|
||||
|
||||
LINK_INFO("Connector[%d] description: signal: %s\n",
|
||||
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;
|
||||
|
|
@ -650,12 +551,34 @@ static bool construct_phy(struct dc_link *link,
|
|||
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;
|
||||
enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
|
||||
link->ctx->gpio_service);
|
||||
|
||||
link->hpd_src = enc_init_data.hpd_source;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
link->link_enc =
|
||||
link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data);
|
||||
|
|
@ -668,6 +591,99 @@ static bool construct_phy(struct dc_link *link,
|
|||
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->link_enc->hpd_gpio)
|
||||
link->irq_source_read_request =
|
||||
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:
|
||||
link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
|
||||
break;
|
||||
case CONNECTOR_ID_DUAL_LINK_DVID:
|
||||
case CONNECTOR_ID_DUAL_LINK_DVII:
|
||||
link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
|
||||
break;
|
||||
case CONNECTOR_ID_VGA:
|
||||
link->connector_signal = SIGNAL_TYPE_RGB;
|
||||
break;
|
||||
case CONNECTOR_ID_DISPLAY_PORT:
|
||||
case CONNECTOR_ID_MXM:
|
||||
case CONNECTOR_ID_USBC:
|
||||
link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
|
||||
|
||||
if (link->link_enc->hpd_gpio)
|
||||
link->irq_source_hpd_rx =
|
||||
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:
|
||||
// If smartmux is supported, only create the link on the primary eDP.
|
||||
// Dual eDP is not supported with smartmux.
|
||||
if (!(!link->dc->config.smart_mux_version || dc_ctx->dc_edp_id_count == 0))
|
||||
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;
|
||||
|
||||
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->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->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->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;
|
||||
default:
|
||||
link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CONNECTOR_ID_LVDS:
|
||||
link->connector_signal = SIGNAL_TYPE_LVDS;
|
||||
break;
|
||||
default:
|
||||
DC_LOG_WARNING("Unsupported Connector type:%d!\n",
|
||||
link->link_id.id);
|
||||
goto create_fail;
|
||||
}
|
||||
|
||||
LINK_INFO("Connector[%d] description: signal: %s\n",
|
||||
init_params->connector_index,
|
||||
signal_type_to_string(link->connector_signal));
|
||||
|
||||
/* 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;
|
||||
|
|
|
|||
|
|
@ -35,64 +35,77 @@
|
|||
|
||||
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;
|
||||
|
||||
config.delay_on_connect = 0;
|
||||
config.delay_on_disconnect = 0;
|
||||
|
||||
dal_irq_setup_hpd_filter(hpd, &config);
|
||||
|
||||
dal_gpio_close(hpd);
|
||||
} else {
|
||||
ASSERT_CRITICAL(false);
|
||||
}
|
||||
/* Release HPD handle */
|
||||
dal_gpio_destroy_irq(&hpd);
|
||||
if (link->link_enc)
|
||||
link->link_enc->funcs->program_hpd_filter(link->link_enc, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool program_hpd_filter(const struct dc_link *link)
|
||||
{
|
||||
int delay_on_connect_in_ms = 0;
|
||||
int delay_on_disconnect_in_ms = 0;
|
||||
|
||||
if (link->is_hpd_filter_disabled || !link->link_enc) {
|
||||
ASSERT(link->link_enc);
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
struct graphics_object_id link_id,
|
||||
struct gpio_service *gpio_service)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user