diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 76 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc_link.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h | 2 |
9 files changed, 59 insertions, 50 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index f020b3b67f0d..02742cca4d84 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -690,7 +690,6 @@ static bool detect_dp(struct dc_link *link, if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) { sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT; - dpcd_set_source_specific_data(link); if (!detect_dp_sink_caps(link)) return false; if (is_mst_supported(link)) { @@ -855,6 +854,7 @@ static bool dc_link_detect_helper(struct dc_link *link, bool same_dpcd = true; enum dc_connection_type new_connection_type = dc_connection_none; bool perform_dp_seamless_boot = false; + const uint32_t post_oui_delay = 30; // 30ms DC_LOGGER_INIT(link->ctx->logger); @@ -867,6 +867,7 @@ static bool dc_link_detect_helper(struct dc_link *link, // need to re-write OUI and brightness in resume case if (link->connector_signal == SIGNAL_TYPE_EDP) { dpcd_set_source_specific_data(link); + msleep(post_oui_delay); dc_link_set_default_brightness_aux(link); //TODO: use cached } @@ -922,8 +923,6 @@ static bool dc_link_detect_helper(struct dc_link *link, case SIGNAL_TYPE_EDP: { read_current_link_settings_on_detect(link); - dpcd_set_source_specific_data(link); - detect_edp_sink_caps(link); read_current_link_settings_on_detect(link); sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX; @@ -1633,6 +1632,7 @@ static enum dc_status enable_link_dp(struct dc_state *state, int i; bool apply_seamless_boot_optimization = false; uint32_t bl_oled_enable_delay = 50; // in ms + const uint32_t post_oui_delay = 30; // 30ms // check for seamless boot for (i = 0; i < state->stream_count; i++) { @@ -1659,6 +1659,8 @@ static enum dc_status enable_link_dp(struct dc_state *state, // during mode switch we do DP_SET_POWER off then on, and OUI is lost dpcd_set_source_specific_data(link); + if (link->dpcd_sink_ext_caps.raw != 0) + msleep(post_oui_delay); skip_video_pattern = true; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index be8f265976b0..b984eecca58b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -655,16 +655,17 @@ bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, } -uint32_t dc_link_aux_configure_timeout(struct ddc_service *ddc, +bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc, uint32_t timeout) { - uint32_t prev_timeout = 0; + bool result = false; struct ddc *ddc_pin = ddc->ddc_pin; - if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) - prev_timeout = - ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout); - return prev_timeout; + if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) { + ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout); + result = true; + } + return result; } /*test only function*/ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 4054df1cd1a5..3d969f83b3cc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -247,7 +247,7 @@ static uint8_t dc_dp_initialize_scrambling_data_symbols( static inline bool is_repeater(struct dc_link *link, uint32_t offset) { - return (!link->is_lttpr_mode_transparent && offset != 0); + return (link->lttpr_non_transparent_mode && offset != 0); } static void dpcd_set_lt_pattern_and_lane_settings( @@ -1040,7 +1040,7 @@ static enum link_training_result perform_clock_recovery_sequence( /* 3. wait receiver to lock-on*/ wait_time_microsec = lt_settings->cr_pattern_time; - if (!link->is_lttpr_mode_transparent) + if (link->lttpr_non_transparent_mode) wait_time_microsec = TRAINING_AUX_RD_INTERVAL; wait_for_training_aux_rd_interval( @@ -1274,7 +1274,7 @@ static void configure_lttpr_mode(struct dc_link *link) link->dpcd_caps.lttpr_caps.mode = repeater_mode; } - if (!link->is_lttpr_mode_transparent) { + if (link->lttpr_non_transparent_mode) { DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__); @@ -1479,7 +1479,7 @@ enum link_training_result dc_link_dp_perform_link_training( <_settings); /* Configure lttpr mode */ - if (!link->is_lttpr_mode_transparent) + if (link->lttpr_non_transparent_mode) configure_lttpr_mode(link); if (link->ctx->dc->work_arounds.lt_early_cr_pattern) @@ -1495,7 +1495,7 @@ enum link_training_result dc_link_dp_perform_link_training( dp_set_fec_ready(link, fec_enable); - if (!link->is_lttpr_mode_transparent) { + if (link->lttpr_non_transparent_mode) { /* 2. perform link training (set link training done * to false is done as well) @@ -1762,7 +1762,7 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link) * account for lttpr repeaters cap * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3). */ - if (!link->is_lttpr_mode_transparent) { + if (link->lttpr_non_transparent_mode) { if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count) max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count; @@ -1920,7 +1920,7 @@ bool dp_verify_link_cap( max_link_cap = get_max_link_cap(link); /* Grant extended timeout request */ - if (!link->is_lttpr_mode_transparent && link->dpcd_caps.lttpr_caps.max_ext_timeout > 0) { + if (link->lttpr_non_transparent_mode && link->dpcd_caps.lttpr_caps.max_ext_timeout > 0) { uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80; core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant)); @@ -3253,17 +3253,8 @@ static bool retrieve_link_cap(struct dc_link *link) uint32_t read_dpcd_retry_cnt = 3; int i; struct dp_sink_hw_fw_revision dp_hw_fw_revision; - - /* Set default timeout to 3.2ms and read LTTPR capabilities */ - bool ext_timeout_support = link->dc->caps.extended_aux_timeout_support && - !link->dc->config.disable_extended_timeout_support; - - link->is_lttpr_mode_transparent = true; - - if (ext_timeout_support) { - dc_link_aux_configure_timeout(link->ddc, - LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD); - } + bool is_lttpr_present = false; + const uint32_t post_oui_delay = 30; // 30ms memset(dpcd_data, '\0', sizeof(dpcd_data)); memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data)); @@ -3272,6 +3263,13 @@ static bool retrieve_link_cap(struct dc_link *link) memset(&edp_config_cap, '\0', sizeof(union edp_configuration_cap)); + /* if extended timeout is supported in hardware, + * default to LTTPR timeout (3.2ms) first as a W/A for DP link layer + * CTS 4.2.1.1 regression introduced by CTS specs requirement update. + */ + dc_link_aux_try_to_configure_timeout(link->ddc, + LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD); + status = core_link_read_dpcd(link, DP_SET_POWER, &dpcd_power_state, sizeof(dpcd_power_state)); @@ -3283,6 +3281,12 @@ static bool retrieve_link_cap(struct dc_link *link) if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) udelay(1000); + dpcd_set_source_specific_data(link); + /* Sink may need to configure internals based on vendor, so allow some + * time before proceeding with possibly vendor specific transactions + */ + msleep(post_oui_delay); + for (i = 0; i < read_dpcd_retry_cnt; i++) { status = core_link_read_dpcd( link, @@ -3298,8 +3302,14 @@ static bool retrieve_link_cap(struct dc_link *link) return false; } - if (ext_timeout_support) { - + if (link->dc->caps.extended_aux_timeout_support && + link->dc->config.allow_lttpr_non_transparent_mode) { + /* By reading LTTPR capability, RX assumes that we will enable + * LTTPR non transparent if LTTPR is present. + * Therefore, only query LTTPR capability when both LTTPR + * extended aux timeout and + * non transparent mode is supported by hardware + */ status = core_link_read_dpcd( link, DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV, @@ -3330,20 +3340,21 @@ static bool retrieve_link_cap(struct dc_link *link) lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; - if (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0 && + is_lttpr_present = (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0 && link->dpcd_caps.lttpr_caps.max_lane_count > 0 && link->dpcd_caps.lttpr_caps.max_lane_count <= 4 && - link->dpcd_caps.lttpr_caps.revision.raw >= 0x14) { - link->is_lttpr_mode_transparent = false; - } else { - /*No lttpr reset timeout to its default value*/ - link->is_lttpr_mode_transparent = true; - dc_link_aux_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); - } - - CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: "); + link->dpcd_caps.lttpr_caps.revision.raw >= 0x14); + if (is_lttpr_present) + CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: "); } + /* decide lttpr non transparent mode */ + link->lttpr_non_transparent_mode = is_lttpr_present; + + if (!is_lttpr_present) + dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); + + { union training_aux_rd_interval aux_rd_interval; @@ -4282,7 +4293,6 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) void dpcd_set_source_specific_data(struct dc_link *link) { - const uint32_t post_oui_delay = 30; // 30ms uint8_t dspc = 0; enum dc_status ret; @@ -4323,10 +4333,6 @@ void dpcd_set_source_specific_data(struct dc_link *link) link->dc->vendor_signature.data.raw, sizeof(link->dc->vendor_signature.data.raw)); } - - // Sink may need to configure internals based on vendor, so allow some - // time before proceeding with possibly vendor specific transactions - msleep(post_oui_delay); } bool dc_link_set_backlight_level_nits(struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 93e28231a9d0..1b3474aa380d 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -283,7 +283,7 @@ void dp_set_hw_lane_settings( { struct link_encoder *encoder = link->link_enc; - if (!link->is_lttpr_mode_transparent && !is_immediate_downstream(link, offset)) + if (link->lttpr_non_transparent_mode && !is_immediate_downstream(link, offset)) return; /* call Encoder to set lane settings */ diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 83de4c2e045e..ceba626bda2f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -283,7 +283,7 @@ struct dc_config { bool edp_not_connected; bool force_enum_edp; bool forced_clocks; - bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well + bool allow_lttpr_non_transparent_mode; bool multi_mon_pp_mclk_switch; bool disable_dmcu; bool enable_4to1MPC; diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 79aca1bb9f1d..e002ef706e1d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -100,7 +100,7 @@ struct dc_link { bool link_state_valid; bool aux_access_disabled; bool sync_lt_in_progress; - bool is_lttpr_mode_transparent; + bool lttpr_non_transparent_mode; /* caps is the same as reported_link_cap. link_traing use * reported_link_cap. Will clean up. TODO diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 7a038eef8902..61b337267a72 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1806,7 +1806,7 @@ static bool dcn21_resource_construct( dc->caps.max_slave_planes = 1; dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; - dc->caps.extended_aux_timeout_support = false; + dc->caps.extended_aux_timeout_support = true; dc->caps.dmcub_support = true; dc->caps.is_apu = true; diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h index de2d160114db..b324e13f3f78 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h @@ -105,7 +105,7 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, struct aux_payload *payload); -uint32_t dc_link_aux_configure_timeout(struct ddc_service *ddc, +bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc, uint32_t timeout); void dal_ddc_service_write_scdc_data( diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h index e94e5fbf2aa2..b970a32177af 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h @@ -28,7 +28,7 @@ #define LINK_TRAINING_ATTEMPTS 4 #define LINK_TRAINING_RETRY_DELAY 50 /* ms */ -#define LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD 3200 /*us*/ +#define LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD 3200 /*us*/ #define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/ struct dc_link; |