diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 107 |
1 files changed, 76 insertions, 31 deletions
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 509f265663d2..a7553b6d59c2 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 @@ -3,6 +3,7 @@ #include "dc.h" #include "dc_link_dp.h" #include "dm_helpers.h" +#include "opp.h" #include "inc/core_types.h" #include "link_hwss.h" @@ -38,7 +39,7 @@ static bool decide_fallback_link_setting( struct dc_link_settings initial_link_settings, struct dc_link_settings *current_link_setting, enum link_training_result training_result); -static struct dc_link_settings get_common_supported_link_settings ( +static struct dc_link_settings get_common_supported_link_settings( struct dc_link_settings link_setting_a, struct dc_link_settings link_setting_b); @@ -93,8 +94,8 @@ static void dpcd_set_link_settings( uint8_t rate = (uint8_t) (lt_settings->link_settings.link_rate); - union down_spread_ctrl downspread = {{0}}; - union lane_count_set lane_count_set = {{0}}; + union down_spread_ctrl downspread = { {0} }; + union lane_count_set lane_count_set = { {0} }; uint8_t link_set_buffer[2]; downspread.raw = (uint8_t) @@ -164,11 +165,11 @@ static void dpcd_set_lt_pattern_and_lane_settings( const struct link_training_settings *lt_settings, enum hw_dp_training_pattern pattern) { - union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}}; + union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = { { {0} } }; const uint32_t dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET; uint8_t dpcd_lt_buffer[5] = {0}; - union dpcd_training_pattern dpcd_pattern = {{0}}; + union dpcd_training_pattern dpcd_pattern = { {0} }; uint32_t lane; uint32_t size_in_bytes; bool edp_workaround = false; /* TODO link_prop.INTERNAL */ @@ -232,7 +233,7 @@ static void dpcd_set_lt_pattern_and_lane_settings( link, DP_TRAINING_PATTERN_SET, &dpcd_pattern.raw, - sizeof(dpcd_pattern.raw) ); + sizeof(dpcd_pattern.raw)); core_link_write_dpcd( link, @@ -246,7 +247,7 @@ static void dpcd_set_lt_pattern_and_lane_settings( link, dpcd_base_lt_offset, dpcd_lt_buffer, - size_in_bytes + sizeof(dpcd_pattern.raw) ); + size_in_bytes + sizeof(dpcd_pattern.raw)); link->cur_lane_setting = lt_settings->lane_settings[0]; } @@ -428,8 +429,8 @@ static void get_lane_status_and_drive_settings( struct link_training_settings *req_settings) { uint8_t dpcd_buf[6] = {0}; - union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {{{0}}}; - struct link_training_settings request_settings = {{0}}; + union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } }; + struct link_training_settings request_settings = { {0} }; uint32_t lane; memset(req_settings, '\0', sizeof(struct link_training_settings)); @@ -651,7 +652,7 @@ static bool perform_post_lt_adj_req_sequence( if (req_drv_setting_changed) { update_drive_settings( - lt_settings,req_settings); + lt_settings, req_settings); dc_link_dp_set_drive_settings(link, lt_settings); @@ -724,8 +725,8 @@ static enum link_training_result perform_channel_equalization_sequence( enum hw_dp_training_pattern hw_tr_pattern; uint32_t retries_ch_eq; enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; - union lane_align_status_updated dpcd_lane_status_updated = {{0}}; - union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}}; + union lane_align_status_updated dpcd_lane_status_updated = { {0} }; + union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } }; hw_tr_pattern = get_supported_tp(link); @@ -952,7 +953,10 @@ enum link_training_result dc_link_dp_perform_link_training( * LINK_SPREAD_05_DOWNSPREAD_30KHZ : * LINK_SPREAD_DISABLED; */ - lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ; + if (link->dp_ss_off) + lt_settings.link_settings.link_spread = LINK_SPREAD_DISABLED; + else + lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ; /* 1. set link rate, lane count and spread*/ dpcd_set_link_settings(link, <_settings); @@ -1027,6 +1031,9 @@ enum link_training_result dc_link_dp_perform_link_training( lt_settings.lane_settings[0].VOLTAGE_SWING, lt_settings.lane_settings[0].PRE_EMPHASIS); + if (status != LINK_TRAINING_SUCCESS) + link->ctx->dc->debug_data.ltFailCount++; + return status; } @@ -1082,9 +1089,10 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link) return max_link_cap; } -bool dp_hbr_verify_link_cap( +bool dp_verify_link_cap( struct dc_link *link, - struct dc_link_settings *known_limit_link_setting) + struct dc_link_settings *known_limit_link_setting, + int *fail_count) { struct dc_link_settings max_link_cap = {0}; struct dc_link_settings cur_link_setting = {0}; @@ -1097,6 +1105,11 @@ bool dp_hbr_verify_link_cap( enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL; enum link_training_result status; + if (link->dc->debug.skip_detection_link_training) { + link->verified_link_cap = *known_limit_link_setting; + return true; + } + success = false; skip_link_training = false; @@ -1151,6 +1164,8 @@ bool dp_hbr_verify_link_cap( skip_video_pattern); if (status == LINK_TRAINING_SUCCESS) success = true; + else + (*fail_count)++; } if (success) @@ -1182,7 +1197,7 @@ bool dp_hbr_verify_link_cap( return success; } -static struct dc_link_settings get_common_supported_link_settings ( +static struct dc_link_settings get_common_supported_link_settings( struct dc_link_settings link_setting_a, struct dc_link_settings link_setting_b) { @@ -1428,6 +1443,7 @@ static uint32_t bandwidth_in_kbps_from_link_settings( uint32_t lane_count = link_setting->lane_count; uint32_t kbps = link_rate_in_kbps; + kbps *= lane_count; kbps *= 8; /* 8 bits per byte*/ @@ -1445,9 +1461,9 @@ bool dp_validate_mode_timing( const struct dc_link_settings *link_setting; /*always DP fail safe mode*/ - if (timing->pix_clk_khz == (uint32_t)25175 && - timing->h_addressable == (uint32_t)640 && - timing->v_addressable == (uint32_t)480) + if (timing->pix_clk_khz == (uint32_t) 25175 && + timing->h_addressable == (uint32_t) 640 && + timing->v_addressable == (uint32_t) 480) return true; /* We always use verified link settings */ @@ -1771,12 +1787,10 @@ static void dp_test_send_link_training(struct dc_link *link) dp_retrain_link_dp_test(link, &link_settings, false); } -/* TODO hbr2 compliance eye output is unstable +/* TODO Raven hbr2 compliance eye output is unstable * (toggling on and off) with debugger break * This caueses intermittent PHY automation failure * Need to look into the root cause */ -static uint8_t force_tps4_for_cp2520 = 1; - static void dp_test_send_phy_test_pattern(struct dc_link *link) { union phy_test_pattern dpcd_test_pattern; @@ -1836,13 +1850,13 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) break; case PHY_TEST_PATTERN_CP2520_1: /* CP2520 pattern is unstable, temporarily use TPS4 instead */ - test_pattern = (force_tps4_for_cp2520 == 1) ? + test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ? DP_TEST_PATTERN_TRAINING_PATTERN4 : DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; break; case PHY_TEST_PATTERN_CP2520_2: /* CP2520 pattern is unstable, temporarily use TPS4 instead */ - test_pattern = (force_tps4_for_cp2520 == 1) ? + test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ? DP_TEST_PATTERN_TRAINING_PATTERN4 : DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE; break; @@ -1995,12 +2009,16 @@ static void handle_automated_test(struct dc_link *link) sizeof(test_response)); } -bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data) +bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss) { - union hpd_irq_data hpd_irq_dpcd_data = {{{{0}}}}; + union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } }; union device_service_irq device_service_clear = { { 0 } }; - enum dc_status result = DDC_RESULT_UNKNOWN; + enum dc_status result; + bool status = false; + + if (out_link_loss) + *out_link_loss = false; /* For use cases related to down stream connection status change, * PSR and device auto test, refer to function handle_sst_hpd_irq * in DAL2.1*/ @@ -2075,6 +2093,8 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd true, LINK_TRAINING_ATTEMPTS); status = false; + if (out_link_loss) + *out_link_loss = true; } if (link->type == dc_connection_active_dongle && @@ -2261,6 +2281,11 @@ static void get_active_converter_info( link->dpcd_caps.branch_hw_revision = dp_hw_fw_revision.ieee_hw_rev; + + memmove( + link->dpcd_caps.branch_fw_revision, + dp_hw_fw_revision.ieee_fw_rev, + sizeof(dp_hw_fw_revision.ieee_fw_rev)); } } @@ -2316,6 +2341,7 @@ static bool retrieve_link_cap(struct dc_link *link) enum dc_status status = DC_ERROR_UNEXPECTED; uint32_t read_dpcd_retry_cnt = 3; int i; + struct dp_sink_hw_fw_revision dp_hw_fw_revision; memset(dpcd_data, '\0', sizeof(dpcd_data)); memset(&down_strm_port_count, @@ -2407,6 +2433,25 @@ static bool retrieve_link_cap(struct dc_link *link) (sink_id.ieee_oui[1] << 8) + (sink_id.ieee_oui[2]); + memmove( + link->dpcd_caps.sink_dev_id_str, + sink_id.ieee_device_id, + sizeof(sink_id.ieee_device_id)); + + core_link_read_dpcd( + link, + DP_SINK_HW_REVISION_START, + (uint8_t *)&dp_hw_fw_revision, + sizeof(dp_hw_fw_revision)); + + link->dpcd_caps.sink_hw_revision = + dp_hw_fw_revision.ieee_hw_rev; + + memmove( + link->dpcd_caps.sink_fw_revision, + dp_hw_fw_revision.ieee_fw_rev, + sizeof(dp_hw_fw_revision.ieee_fw_rev)); + /* Connectivity log: detection */ CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: "); @@ -2511,8 +2556,8 @@ static void set_crtc_test_pattern(struct dc_link *link, pipe_ctx->stream->bit_depth_params = params; pipe_ctx->stream_res.opp->funcs-> opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, ¶ms); - - pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, + if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) + pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, controller_test_pattern, color_depth); } break; @@ -2524,8 +2569,8 @@ static void set_crtc_test_pattern(struct dc_link *link, pipe_ctx->stream->bit_depth_params = params; pipe_ctx->stream_res.opp->funcs-> opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, ¶ms); - - pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, + if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) + pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, color_depth); } |