mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
drm/amd/display: determine USB C DP2 mode only when USB DP Alt is enabled
[why] When display is connected with a native DP port, DP2 mode register value is a don't care. Driver mistakenly reduce max supported lane count to 2 lane based on the don't care value. [how] Add additional check only if USB C DP alt mode is enabled, we will determine max lane count supported based on current mode. Signed-off-by: Wenjing Liu <wenjing.liu@amd.com> Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4404b47852
commit
8ccf0e2076
@ -682,7 +682,7 @@ static bool is_same_edid(struct dc_edid *old_edid, struct dc_edid *new_edid)
|
||||
new_edid->raw_edid, new_edid->length) == 0);
|
||||
}
|
||||
|
||||
static bool wait_for_alt_mode(struct dc_link *link)
|
||||
static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
|
||||
{
|
||||
/**
|
||||
* something is terribly wrong if time out is > 200ms. (5Hz)
|
||||
@ -836,7 +836,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
|
||||
/* wa HPD high coming too early*/
|
||||
if (link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
|
||||
/* if alt mode times out, return false */
|
||||
if (!wait_for_alt_mode(link))
|
||||
if (!wait_for_entering_dp_alt_mode(link))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1710,19 +1710,10 @@ bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
|
||||
|
||||
static struct dc_link_settings get_max_link_cap(struct dc_link *link)
|
||||
{
|
||||
/* Set Default link settings */
|
||||
struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
|
||||
LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
|
||||
struct dc_link_settings max_link_cap = {0};
|
||||
|
||||
/* Higher link settings based on feature supported */
|
||||
if (link->link_enc->features.flags.bits.IS_HBR2_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_HIGH2;
|
||||
|
||||
if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_HIGH3;
|
||||
|
||||
if (link->link_enc->funcs->get_max_link_cap)
|
||||
link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
|
||||
/* get max link encoder capability */
|
||||
link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
|
||||
|
||||
/* Lower link settings based on sink's link cap */
|
||||
if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
|
||||
|
@ -118,7 +118,8 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
|
||||
.enable_hpd = dce110_link_encoder_enable_hpd,
|
||||
.disable_hpd = dce110_link_encoder_disable_hpd,
|
||||
.is_dig_enabled = dce110_is_dig_enabled,
|
||||
.destroy = dce110_link_encoder_destroy
|
||||
.destroy = dce110_link_encoder_destroy,
|
||||
.get_max_link_cap = dce110_link_encoder_get_max_link_cap
|
||||
};
|
||||
|
||||
static enum bp_result link_transmitter_control(
|
||||
@ -1389,3 +1390,20 @@ void dce110_link_encoder_disable_hpd(struct link_encoder *enc)
|
||||
|
||||
set_reg_field_value(value, 0, DC_HPD_CONTROL, DC_HPD_EN);
|
||||
}
|
||||
|
||||
void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
/* Set Default link settings */
|
||||
struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
|
||||
LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
|
||||
|
||||
/* Higher link settings based on feature supported */
|
||||
if (enc->features.flags.bits.IS_HBR2_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_HIGH2;
|
||||
|
||||
if (enc->features.flags.bits.IS_HBR3_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_HIGH3;
|
||||
|
||||
*link_settings = max_link_cap;
|
||||
}
|
||||
|
@ -271,4 +271,7 @@ void dce110_psr_program_secondary_packet(struct link_encoder *enc,
|
||||
|
||||
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);
|
||||
|
||||
#endif /* __DC_LINK_ENCODER__DCE110_H__ */
|
||||
|
@ -90,7 +90,8 @@ static const struct link_encoder_funcs dcn10_lnk_enc_funcs = {
|
||||
.is_dig_enabled = dcn10_is_dig_enabled,
|
||||
.get_dig_frontend = dcn10_get_dig_frontend,
|
||||
.get_dig_mode = dcn10_get_dig_mode,
|
||||
.destroy = dcn10_link_encoder_destroy
|
||||
.destroy = dcn10_link_encoder_destroy,
|
||||
.get_max_link_cap = dcn10_link_encoder_get_max_link_cap,
|
||||
};
|
||||
|
||||
static enum bp_result link_transmitter_control(
|
||||
@ -1370,7 +1371,6 @@ void dcn10_link_encoder_disable_hpd(struct link_encoder *enc)
|
||||
DC_HPD_EN, 0);
|
||||
}
|
||||
|
||||
|
||||
#define AUX_REG(reg)\
|
||||
(enc10->aux_regs->reg)
|
||||
|
||||
@ -1425,3 +1425,19 @@ enum signal_type dcn10_get_dig_mode(
|
||||
return SIGNAL_TYPE_NONE;
|
||||
}
|
||||
|
||||
void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
/* Set Default link settings */
|
||||
struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
|
||||
LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
|
||||
|
||||
/* Higher link settings based on feature supported */
|
||||
if (enc->features.flags.bits.IS_HBR2_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_HIGH2;
|
||||
|
||||
if (enc->features.flags.bits.IS_HBR3_CAPABLE)
|
||||
max_link_cap.link_rate = LINK_RATE_HIGH3;
|
||||
|
||||
*link_settings = max_link_cap;
|
||||
}
|
||||
|
@ -575,4 +575,7 @@ void dcn10_aux_initialize(struct dcn10_link_encoder *enc10);
|
||||
|
||||
enum signal_type dcn10_get_dig_mode(
|
||||
struct link_encoder *enc);
|
||||
|
||||
void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings);
|
||||
#endif /* __DC_LINK_ENCODER__DCN10_H__ */
|
||||
|
@ -49,6 +49,12 @@
|
||||
#define IND_REG(index) \
|
||||
(enc10->link_regs->index)
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#endif
|
||||
|
||||
static struct mpll_cfg dcn2_mpll_cfg[] = {
|
||||
// RBR
|
||||
@ -260,6 +266,38 @@ void dcn20_link_encoder_enable_dp_output(
|
||||
|
||||
}
|
||||
|
||||
void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t is_in_usb_c_dp4_mode = 0;
|
||||
|
||||
dcn10_link_encoder_get_max_link_cap(enc, link_settings);
|
||||
|
||||
/* in usb c dp2 mode, max lane count is 2 */
|
||||
if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
|
||||
if (!is_in_usb_c_dp4_mode)
|
||||
link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t dp_alt_mode_disable = 0;
|
||||
bool is_usb_c_alt_mode = false;
|
||||
|
||||
if (enc->features.flags.bits.DP_IS_USB_C) {
|
||||
/* if value == 1 alt mode is disabled, otherwise it is enabled */
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
|
||||
is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
|
||||
}
|
||||
|
||||
return is_usb_c_alt_mode;
|
||||
}
|
||||
|
||||
#define AUX_REG(reg)\
|
||||
(enc10->aux_regs->reg)
|
||||
|
||||
@ -311,28 +349,6 @@ void enc2_hw_init(struct link_encoder *enc)
|
||||
dcn10_aux_initialize(enc10);
|
||||
}
|
||||
|
||||
void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t value;
|
||||
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &value);
|
||||
|
||||
if (!value && link_settings->lane_count > LANE_COUNT_TWO)
|
||||
link_settings->lane_count = LANE_COUNT_TWO;
|
||||
}
|
||||
bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t value;
|
||||
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &value);
|
||||
|
||||
// if value == 1 alt mode is disabled, otherwise it is enabled
|
||||
return !value;
|
||||
}
|
||||
|
||||
static const struct link_encoder_funcs dcn20_link_enc_funcs = {
|
||||
.read_state = link_enc2_read_state,
|
||||
.validate_output_with_stream =
|
||||
|
@ -343,6 +343,10 @@ void dcn20_link_encoder_enable_dp_output(
|
||||
const struct dc_link_settings *link_settings,
|
||||
enum clock_source_id clock_source);
|
||||
|
||||
bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc);
|
||||
void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings);
|
||||
|
||||
void dcn20_link_encoder_construct(
|
||||
struct dcn20_link_encoder *enc20,
|
||||
const struct encoder_init_data *init_data,
|
||||
|
@ -203,29 +203,6 @@ static bool update_cfg_data(
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcn21_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t value;
|
||||
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &value);
|
||||
|
||||
if (!value && link_settings->lane_count > LANE_COUNT_TWO)
|
||||
link_settings->lane_count = LANE_COUNT_TWO;
|
||||
}
|
||||
|
||||
bool dcn21_link_encoder_is_in_alt_mode(struct link_encoder *enc)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
uint32_t value;
|
||||
|
||||
REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &value);
|
||||
|
||||
// if value == 1 alt mode is disabled, otherwise it is enabled
|
||||
return !value;
|
||||
}
|
||||
|
||||
bool dcn21_link_encoder_acquire_phy(struct link_encoder *enc)
|
||||
{
|
||||
struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
|
||||
@ -348,8 +325,8 @@ static const struct link_encoder_funcs dcn21_link_enc_funcs = {
|
||||
.fec_set_ready = enc2_fec_set_ready,
|
||||
.fec_is_active = enc2_fec_is_active,
|
||||
.get_dig_frontend = dcn10_get_dig_frontend,
|
||||
.is_in_alt_mode = dcn21_link_encoder_is_in_alt_mode,
|
||||
.get_max_link_cap = dcn21_link_encoder_get_max_link_cap,
|
||||
.is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
|
||||
.get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
|
||||
};
|
||||
|
||||
void dcn21_link_encoder_construct(
|
||||
|
@ -84,6 +84,14 @@ static void virtual_link_encoder_destroy(struct link_encoder **enc)
|
||||
*enc = NULL;
|
||||
}
|
||||
|
||||
static void virtual_link_encoder_get_max_link_cap(struct link_encoder *enc,
|
||||
struct dc_link_settings *link_settings)
|
||||
{
|
||||
/* Set Default link settings */
|
||||
struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
|
||||
LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
|
||||
*link_settings = max_link_cap;
|
||||
}
|
||||
|
||||
static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
|
||||
.validate_output_with_stream =
|
||||
@ -94,6 +102,7 @@ static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
|
||||
.enable_dp_output = virtual_link_encoder_enable_dp_output,
|
||||
.enable_dp_mst_output = virtual_link_encoder_enable_dp_mst_output,
|
||||
.disable_output = virtual_link_encoder_disable_output,
|
||||
.get_max_link_cap = virtual_link_encoder_get_max_link_cap,
|
||||
.dp_set_lane_settings = virtual_link_encoder_dp_set_lane_settings,
|
||||
.dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern,
|
||||
.update_mst_stream_allocation_table =
|
||||
|
Loading…
Reference in New Issue
Block a user