diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/link/protocols')
8 files changed, 531 insertions, 223 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c index 0fa1228bc178..ecfd83299e75 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c @@ -412,6 +412,88 @@ int link_aux_transfer_raw(struct ddc_service *ddc, } } +uint32_t link_get_fixed_vs_pe_retimer_write_address(struct dc_link *link) +{ + uint32_t vendor_lttpr_write_address = 0xF004F; + uint8_t offset; + + switch (link->dpcd_caps.lttpr_caps.phy_repeater_cnt) { + case 0x80: // 1 lttpr repeater + offset = 1; + break; + case 0x40: // 2 lttpr repeaters + offset = 2; + break; + case 0x20: // 3 lttpr repeaters + offset = 3; + break; + case 0x10: // 4 lttpr repeaters + offset = 4; + break; + case 0x08: // 5 lttpr repeaters + offset = 5; + break; + case 0x04: // 6 lttpr repeaters + offset = 6; + break; + case 0x02: // 7 lttpr repeaters + offset = 7; + break; + case 0x01: // 8 lttpr repeaters + offset = 8; + break; + default: + offset = 0xFF; + } + + if (offset != 0xFF) { + vendor_lttpr_write_address += + ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + } + return vendor_lttpr_write_address; +} + +uint32_t link_get_fixed_vs_pe_retimer_read_address(struct dc_link *link) +{ + return link_get_fixed_vs_pe_retimer_write_address(link) + 4; +} + +bool link_configure_fixed_vs_pe_retimer(struct ddc_service *ddc, const uint8_t *data, uint32_t length) +{ + struct aux_payload write_payload = { + .i2c_over_aux = false, + .write = true, + .address = link_get_fixed_vs_pe_retimer_write_address(ddc->link), + .length = length, + .data = (uint8_t *) data, + .reply = NULL, + .mot = I2C_MOT_UNDEF, + .write_status_update = false, + .defer_delay = 0, + }; + + return link_aux_transfer_with_retries_no_mutex(ddc, + &write_payload); +} + +bool link_query_fixed_vs_pe_retimer(struct ddc_service *ddc, uint8_t *data, uint32_t length) +{ + struct aux_payload read_payload = { + .i2c_over_aux = false, + .write = false, + .address = link_get_fixed_vs_pe_retimer_read_address(ddc->link), + .length = length, + .data = data, + .reply = NULL, + .mot = I2C_MOT_UNDEF, + .write_status_update = false, + .defer_delay = 0, + }; + + return link_aux_transfer_with_retries_no_mutex(ddc, + &read_payload); +} + bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc, struct aux_payload *payload) { @@ -427,7 +509,7 @@ bool try_to_configure_aux_timeout(struct ddc_service *ddc, if ((ddc->link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && !ddc->link->dc->debug.disable_fixed_vs_aux_timeout_wa && - ASICREV_IS_YELLOW_CARP(ddc->ctx->asic_id.hw_internal_rev)) { + ddc->ctx->dce_version == DCN_VERSION_3_1) { /* Fixed VS workaround for AUX timeout */ const uint32_t fixed_vs_address = 0xF004F; const uint8_t fixed_vs_data[4] = {0x1, 0x22, 0x63, 0xc}; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h index 860ef15d7f1b..a3e25e55bed6 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.h @@ -72,6 +72,20 @@ bool link_query_ddc_data( bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc, struct aux_payload *payload); +bool link_configure_fixed_vs_pe_retimer( + struct ddc_service *ddc, + const uint8_t *data, + uint32_t length); + +bool link_query_fixed_vs_pe_retimer( + struct ddc_service *ddc, + uint8_t *data, + uint32_t length); + +uint32_t link_get_fixed_vs_pe_retimer_read_address(struct dc_link *link); +uint32_t link_get_fixed_vs_pe_retimer_write_address(struct dc_link *link); + + void write_scdc_data( struct ddc_service *ddc_service, uint32_t pix_clk, diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 3a5e80b57711..237e0ff955f3 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -906,7 +906,7 @@ bool link_decide_link_settings(struct dc_stream_state *stream, struct dc_link_settings *link_setting) { struct dc_link *link = stream->link; - uint32_t req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); + uint32_t req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing, dc_link_get_highest_encoding_format(link)); memset(link_setting, 0, sizeof(*link_setting)); @@ -939,7 +939,8 @@ bool link_decide_link_settings(struct dc_stream_state *stream, tmp_link_setting.link_rate = LINK_RATE_UNKNOWN; tmp_timing.flags.DSC = 0; - orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing); + orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing, + dc_link_get_highest_encoding_format(link)); edp_decide_link_settings(link, &tmp_link_setting, orig_req_bw); max_link_rate = tmp_link_setting.link_rate; } @@ -2008,6 +2009,16 @@ void detect_edp_sink_caps(struct dc_link *link) core_link_read_dpcd(link, DP_RECEIVER_ALPM_CAP, &link->dpcd_caps.alpm_caps.raw, sizeof(link->dpcd_caps.alpm_caps.raw)); + + /* + * Read REPLAY info + */ + core_link_read_dpcd(link, DP_SINK_PR_PIXEL_DEVIATION_PER_LINE, + &link->dpcd_caps.pr_info.pixel_deviation_per_line, + sizeof(link->dpcd_caps.pr_info.pixel_deviation_per_line)); + core_link_read_dpcd(link, DP_SINK_PR_MAX_NUMBER_OF_DEVIATION_LINE, + &link->dpcd_caps.pr_info.max_deviation_line, + sizeof(link->dpcd_caps.pr_info.max_deviation_line)); } bool dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap) @@ -2165,7 +2176,9 @@ static bool dp_verify_link_cap( link, &irq_data)) (*fail_count)++; - + } else if (status == LINK_TRAINING_LINK_LOSS) { + success = true; + (*fail_count)++; } else { (*fail_count)++; } @@ -2188,6 +2201,7 @@ bool dp_verify_link_cap_with_retries( int i = 0; bool success = false; int fail_count = 0; + struct dc_link_settings last_verified_link_cap = fail_safe_link_settings; dp_trace_detect_lt_init(link); @@ -2204,10 +2218,14 @@ bool dp_verify_link_cap_with_retries( if (!link_detect_connection_type(link, &type) || type == dc_connection_none) { link->verified_link_cap = fail_safe_link_settings; break; - } else if (dp_verify_link_cap(link, known_limit_link_setting, - &fail_count) && fail_count == 0) { - success = true; - break; + } else if (dp_verify_link_cap(link, known_limit_link_setting, &fail_count)) { + last_verified_link_cap = link->verified_link_cap; + if (fail_count == 0) { + success = true; + break; + } + } else { + link->verified_link_cap = last_verified_link_cap; } fsleep(10 * 1000); } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c index ef8739df91bc..e047bbeaa49a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c @@ -182,6 +182,68 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link) return false; } +static bool handle_hpd_irq_replay_sink(struct dc_link *link) +{ + union dpcd_replay_configuration replay_configuration; + /*AMD Replay version reuse DP_PSR_ERROR_STATUS for REPLAY_ERROR status.*/ + union psr_error_status replay_error_status; + + if (!link->replay_settings.replay_feature_enabled) + return false; + + dm_helpers_dp_read_dpcd( + link->ctx, + link, + DP_SINK_PR_REPLAY_STATUS, + &replay_configuration.raw, + sizeof(replay_configuration.raw)); + + dm_helpers_dp_read_dpcd( + link->ctx, + link, + DP_PSR_ERROR_STATUS, + &replay_error_status.raw, + sizeof(replay_error_status.raw)); + + link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR = + replay_error_status.bits.LINK_CRC_ERROR; + link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR = + replay_configuration.bits.DESYNC_ERROR_STATUS; + link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR = + replay_configuration.bits.STATE_TRANSITION_ERROR_STATUS; + + if (link->replay_settings.config.replay_error_status.bits.LINK_CRC_ERROR || + link->replay_settings.config.replay_error_status.bits.DESYNC_ERROR || + link->replay_settings.config.replay_error_status.bits.STATE_TRANSITION_ERROR) { + bool allow_active; + + /* Acknowledge and clear configuration bits */ + dm_helpers_dp_write_dpcd( + link->ctx, + link, + DP_SINK_PR_REPLAY_STATUS, + &replay_configuration.raw, + sizeof(replay_configuration.raw)); + + /* Acknowledge and clear error bits */ + dm_helpers_dp_write_dpcd( + link->ctx, + link, + DP_PSR_ERROR_STATUS,/*DpcdAddress_REPLAY_Error_Status*/ + &replay_error_status.raw, + sizeof(replay_error_status.raw)); + + /* Replay error, disable and re-enable Replay */ + if (link->replay_settings.replay_allow_active) { + allow_active = false; + edp_set_replay_allow_active(link, &allow_active, true, false, NULL); + allow_active = true; + edp_set_replay_allow_active(link, &allow_active, true, false, NULL); + } + } + return true; +} + void dp_handle_link_loss(struct dc_link *link) { struct pipe_ctx *pipes[MAX_PIPES]; @@ -360,6 +422,10 @@ bool dp_handle_hpd_rx_irq(struct dc_link *link, /* PSR-related error was detected and handled */ return true; + if (handle_hpd_irq_replay_sink(link)) + /* Replay-related error was detected and handled */ + return true; + /* If PSR-related error handled, Main link may be off, * so do not handle as a normal sink status change interrupt. */ diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index e011df4bdaf2..90339c2dfd84 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -1699,13 +1699,20 @@ bool perform_link_training_with_retries( } else if (do_fallback) { /* Try training at lower link bandwidth if doing fallback. */ uint32_t req_bw; uint32_t link_bw; + enum dc_link_encoding_format link_encoding = DC_LINK_ENCODING_UNSPECIFIED; decide_fallback_link_setting(link, &max_link_settings, &cur_link_settings, status); + + if (link_dp_get_encoding_format(&cur_link_settings) == DP_8b_10b_ENCODING) + link_encoding = DC_LINK_ENCODING_DP_8b_10b; + else if (link_dp_get_encoding_format(&cur_link_settings) == DP_128b_132b_ENCODING) + link_encoding = DC_LINK_ENCODING_DP_128b_132b; + /* Flag if reduced link bandwidth no longer meets stream requirements or fallen back to * minimum link bandwidth. */ - req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); + req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing, link_encoding); link_bw = dp_link_bandwidth_kbps(link, &cur_link_settings); is_link_bw_low = (req_bw > link_bw); is_link_bw_min = ((cur_link_settings.link_rate <= LINK_RATE_LOW) && diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c index 15faaf645b14..fd8f6f198146 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c @@ -36,6 +36,7 @@ #include "link_dpcd.h" #include "link_dp_phy.h" #include "link_dp_capability.h" +#include "link_ddc.h" #define DC_LOGGER \ link->ctx->logger @@ -46,42 +47,20 @@ void dp_fixed_vs_pe_read_lane_adjust( { const uint8_t vendor_lttpr_write_data_vs[3] = {0x0, 0x53, 0x63}; const uint8_t vendor_lttpr_write_data_pe[3] = {0x0, 0x54, 0x63}; - const uint8_t offset = dp_parse_lttpr_repeater_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); - uint32_t vendor_lttpr_write_address = 0xF004F; - uint32_t vendor_lttpr_read_address = 0xF0053; uint8_t dprx_vs = 0; uint8_t dprx_pe = 0; uint8_t lane; - if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - vendor_lttpr_read_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - } - /* W/A to read lane settings requested by DPRX */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_read_dpcd( - link, - vendor_lttpr_read_address, - &dprx_vs, - 1); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); - core_link_read_dpcd( - link, - vendor_lttpr_read_address, - &dprx_pe, - 1); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + + link_query_fixed_vs_pe_retimer(link->ddc, &dprx_vs, 1); + + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); + + link_query_fixed_vs_pe_retimer(link->ddc, &dprx_pe, 1); for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) { dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET = (dprx_vs >> (2 * lane)) & 0x3; @@ -95,19 +74,11 @@ void dp_fixed_vs_pe_set_retimer_lane_settings( const union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX], uint8_t lane_count) { - const uint8_t offset = dp_parse_lttpr_repeater_count( - link->dpcd_caps.lttpr_caps.phy_repeater_cnt); const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF}; - uint32_t vendor_lttpr_write_address = 0xF004F; uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; uint8_t lane = 0; - if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); - } - for (lane = 0; lane < lane_count; lane++) { vendor_lttpr_write_data_vs[3] |= dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET << (2 * lane); @@ -116,21 +87,14 @@ void dp_fixed_vs_pe_set_retimer_lane_settings( } /* Force LTTPR to output desired VS and PE */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_reset[0], sizeof(vendor_lttpr_write_data_reset)); + + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); } static enum link_training_result perform_fixed_vs_pe_nontransparent_training_sequence( @@ -236,7 +200,11 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( uint32_t pre_disable_intercept_delay_ms = 0; uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; - uint32_t vendor_lttpr_write_address = 0xF004F; + const uint8_t vendor_lttpr_write_data_4lane_1[4] = {0x1, 0x6E, 0xF2, 0x19}; + const uint8_t vendor_lttpr_write_data_4lane_2[4] = {0x1, 0x6B, 0xF2, 0x01}; + const uint8_t vendor_lttpr_write_data_4lane_3[4] = {0x1, 0x6D, 0xF2, 0x18}; + const uint8_t vendor_lttpr_write_data_4lane_4[4] = {0x1, 0x6C, 0xF2, 0x03}; + const uint8_t vendor_lttpr_write_data_4lane_5[4] = {0x1, 0x03, 0xF3, 0x06}; enum link_training_result status = LINK_TRAINING_SUCCESS; uint8_t lane = 0; union down_spread_ctrl downspread = {0}; @@ -244,10 +212,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( uint8_t toggle_rate; uint8_t rate; - if (link->local_sink) - pre_disable_intercept_delay_ms = - link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; - /* Only 8b/10b is supported */ ASSERT(link_dp_get_encoding_format(<_settings->link_settings) == DP_8b_10b_ENCODING); @@ -258,37 +222,27 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( } if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + if (offset == 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; /* Certain display and cable configuration require extra delay */ - if (offset > 2) - pre_disable_intercept_delay_ms = pre_disable_intercept_delay_ms * 2; + } else if (offset > 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa * 2; + } } /* Vendor specific: Reset lane settings */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_reset[0], sizeof(vendor_lttpr_write_data_reset)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* Vendor specific: Enable intercept */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_intercept_en[0], - sizeof(vendor_lttpr_write_data_intercept_en)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); + /* 1. set link rate, lane count and spread. */ @@ -339,6 +293,19 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( DP_DOWNSPREAD_CTRL, lt_settings->link_settings.link_spread); + if (lt_settings->link_settings.lane_count == LANE_COUNT_FOUR) { + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_1[0], sizeof(vendor_lttpr_write_data_4lane_1)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_2[0], sizeof(vendor_lttpr_write_data_4lane_2)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_3[0], sizeof(vendor_lttpr_write_data_4lane_3)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_4[0], sizeof(vendor_lttpr_write_data_4lane_4)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_5[0], sizeof(vendor_lttpr_write_data_4lane_5)); + } + /* 2. Perform link training */ /* Perform Clock Recovery Sequence */ @@ -351,7 +318,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; union lane_align_status_updated dpcd_lane_status_updated; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - enum dc_status dpcd_status = DC_OK; uint8_t i = 0; retries_cr = 0; @@ -386,18 +352,12 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( for (i = 0; i < max_vendor_dpcd_retries; i++) { if (pre_disable_intercept_delay_ms != 0) msleep(pre_disable_intercept_delay_ms); - dpcd_status = core_link_write_dpcd( - link, - vendor_lttpr_write_address, + if (link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_dis[0], - sizeof(vendor_lttpr_write_data_intercept_dis)); - - if (dpcd_status == DC_OK) + sizeof(vendor_lttpr_write_data_intercept_dis))) break; - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); } @@ -413,16 +373,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); dpcd_set_lane_settings( link, @@ -518,16 +472,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* 2. update DPCD*/ if (!retries_ch_eq) @@ -596,10 +544,14 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( const uint8_t vendor_lttpr_write_data_adicora_eq1[4] = {0x1, 0x55, 0x63, 0x2E}; const uint8_t vendor_lttpr_write_data_adicora_eq2[4] = {0x1, 0x55, 0x63, 0x01}; const uint8_t vendor_lttpr_write_data_adicora_eq3[4] = {0x1, 0x55, 0x63, 0x68}; + uint32_t pre_disable_intercept_delay_ms = 0; uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; - uint32_t pre_disable_intercept_delay_ms = 0; - uint32_t vendor_lttpr_write_address = 0xF004F; + const uint8_t vendor_lttpr_write_data_4lane_1[4] = {0x1, 0x6E, 0xF2, 0x19}; + const uint8_t vendor_lttpr_write_data_4lane_2[4] = {0x1, 0x6B, 0xF2, 0x01}; + const uint8_t vendor_lttpr_write_data_4lane_3[4] = {0x1, 0x6D, 0xF2, 0x18}; + const uint8_t vendor_lttpr_write_data_4lane_4[4] = {0x1, 0x6C, 0xF2, 0x03}; + const uint8_t vendor_lttpr_write_data_4lane_5[4] = {0x1, 0x03, 0xF3, 0x06}; enum link_training_result status = LINK_TRAINING_SUCCESS; uint8_t lane = 0; union down_spread_ctrl downspread = {0}; @@ -607,10 +559,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( uint8_t toggle_rate; uint8_t rate; - if (link->local_sink) - pre_disable_intercept_delay_ms = - link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; - /* Only 8b/10b is supported */ ASSERT(link_dp_get_encoding_format(<_settings->link_settings) == DP_8b_10b_ENCODING); @@ -621,37 +569,26 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( } if (offset != 0xFF) { - vendor_lttpr_write_address += - ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + if (offset == 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; /* Certain display and cable configuration require extra delay */ - if (offset > 2) - pre_disable_intercept_delay_ms = pre_disable_intercept_delay_ms * 2; + } else if (offset > 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa * 2; + } } /* Vendor specific: Reset lane settings */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_reset[0], - sizeof(vendor_lttpr_write_data_reset)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_reset[0], sizeof(vendor_lttpr_write_data_reset)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* Vendor specific: Enable intercept */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_intercept_en[0], - sizeof(vendor_lttpr_write_data_intercept_en)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); /* 1. set link rate, lane count and spread. */ @@ -702,6 +639,19 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( DP_DOWNSPREAD_CTRL, lt_settings->link_settings.link_spread); + if (lt_settings->link_settings.lane_count == LANE_COUNT_FOUR) { + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_1[0], sizeof(vendor_lttpr_write_data_4lane_1)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_2[0], sizeof(vendor_lttpr_write_data_4lane_2)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_3[0], sizeof(vendor_lttpr_write_data_4lane_3)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_4[0], sizeof(vendor_lttpr_write_data_4lane_4)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_4lane_5[0], sizeof(vendor_lttpr_write_data_4lane_5)); + } + /* 2. Perform link training */ /* Perform Clock Recovery Sequence */ @@ -714,7 +664,6 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX]; union lane_align_status_updated dpcd_lane_status_updated; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - enum dc_status dpcd_status = DC_OK; uint8_t i = 0; retries_cr = 0; @@ -749,18 +698,12 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( for (i = 0; i < max_vendor_dpcd_retries; i++) { if (pre_disable_intercept_delay_ms != 0) msleep(pre_disable_intercept_delay_ms); - dpcd_status = core_link_write_dpcd( - link, - vendor_lttpr_write_address, + if (link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_dis[0], - sizeof(vendor_lttpr_write_data_intercept_dis)); - - if (dpcd_status == DC_OK) + sizeof(vendor_lttpr_write_data_intercept_dis))) break; - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_intercept_en[0], sizeof(vendor_lttpr_write_data_intercept_en)); } @@ -776,16 +719,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); dpcd_set_lane_settings( link, @@ -858,17 +795,14 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0}; - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_adicora_eq1[0], sizeof(vendor_lttpr_write_data_adicora_eq1)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, + link_configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_write_data_adicora_eq2[0], sizeof(vendor_lttpr_write_data_adicora_eq2)); + /* Note: also check that TPS4 is a supported feature*/ tr_pattern = lt_settings->pattern_for_eq; @@ -892,16 +826,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( } /* Vendor specific: Update VS and PE to DPRX requested value */ - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_vs[0], - sizeof(vendor_lttpr_write_data_vs)); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_pe[0], - sizeof(vendor_lttpr_write_data_pe)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_vs[0], sizeof(vendor_lttpr_write_data_vs)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_pe[0], sizeof(vendor_lttpr_write_data_pe)); /* 2. update DPCD*/ if (!retries_ch_eq) { @@ -914,11 +842,10 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( lt_settings, tr_pattern, 0); - core_link_write_dpcd( - link, - vendor_lttpr_write_address, - &vendor_lttpr_write_data_adicora_eq3[0], - sizeof(vendor_lttpr_write_data_adicora_eq3)); + link_configure_fixed_vs_pe_retimer(link->ddc, + &vendor_lttpr_write_data_adicora_eq3[0], + sizeof(vendor_lttpr_write_data_adicora_eq3)); + } else dpcd_set_lane_settings(link, lt_settings, 0); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 2039a345f23a..98e715aa6d8e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -34,9 +34,13 @@ #include "dm_helpers.h" #include "dal_asic_id.h" #include "dce/dmub_psr.h" +#include "dc/dc_dmub_srv.h" +#include "dce/dmub_replay.h" #include "abm.h" #define DC_LOGGER_INIT(logger) +#define DP_SINK_PR_ENABLE_AND_CONFIGURATION 0x37B + /* Travis */ static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT"; /* Nutmeg */ @@ -46,43 +50,42 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode) { union dpcd_edp_config edp_config_set; bool panel_mode_edp = false; + enum dc_status result; memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config)); - if (panel_mode != DP_PANEL_MODE_DEFAULT) { + switch (panel_mode) { + case DP_PANEL_MODE_EDP: + case DP_PANEL_MODE_SPECIAL: + panel_mode_edp = true; + break; - switch (panel_mode) { - case DP_PANEL_MODE_EDP: - case DP_PANEL_MODE_SPECIAL: - panel_mode_edp = true; - break; + default: + break; + } - default: - break; - } + /*set edp panel mode in receiver*/ + result = core_link_read_dpcd( + link, + DP_EDP_CONFIGURATION_SET, + &edp_config_set.raw, + sizeof(edp_config_set.raw)); - /*set edp panel mode in receiver*/ - core_link_read_dpcd( + if (result == DC_OK && + edp_config_set.bits.PANEL_MODE_EDP + != panel_mode_edp) { + + edp_config_set.bits.PANEL_MODE_EDP = + panel_mode_edp; + result = core_link_write_dpcd( link, DP_EDP_CONFIGURATION_SET, &edp_config_set.raw, sizeof(edp_config_set.raw)); - if (edp_config_set.bits.PANEL_MODE_EDP - != panel_mode_edp) { - enum dc_status result; - - edp_config_set.bits.PANEL_MODE_EDP = - panel_mode_edp; - result = core_link_write_dpcd( - link, - DP_EDP_CONFIGURATION_SET, - &edp_config_set.raw, - sizeof(edp_config_set.raw)); - - ASSERT(result == DC_OK); - } + ASSERT(result == DC_OK); } + link->panel_mode = panel_mode; DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d " "eDP panel mode enabled: %d \n", @@ -164,6 +167,7 @@ bool edp_set_backlight_level_nits(struct dc_link *link, *(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits; *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms; + link->backlight_settings.backlight_millinits = backlight_millinits; if (!link->dpcd_caps.panel_luminance_control) { if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, @@ -251,10 +255,20 @@ static bool read_default_bl_aux(struct dc_link *link, uint32_t *backlight_millin link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)) return false; - if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, - (uint8_t *) backlight_millinits, - sizeof(uint32_t))) - return false; + if (!link->dpcd_caps.panel_luminance_control) { + if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, + (uint8_t *)backlight_millinits, + sizeof(uint32_t))) + return false; + } else { + //setting to 0 as a precaution, since target_luminance_value is 3 bytes + memset(backlight_millinits, 0, sizeof(uint32_t)); + + if (!core_link_read_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, + (uint8_t *)backlight_millinits, + sizeof(struct target_luminance_value))) + return false; + } return true; } @@ -276,6 +290,16 @@ bool set_default_brightness_aux(struct dc_link *link) return false; } +bool set_cached_brightness_aux(struct dc_link *link) +{ + if (link->backlight_settings.backlight_millinits) + return edp_set_backlight_level_nits(link, true, + link->backlight_settings.backlight_millinits, 0); + else + return set_default_brightness_aux(link); + return false; +} + bool edp_is_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timing *crtc_timing) { @@ -309,7 +333,7 @@ bool edp_is_ilr_optimization_required(struct dc_link *link, core_link_read_dpcd(link, DP_LANE_COUNT_SET, &lane_count_set.raw, sizeof(lane_count_set)); - req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing); + req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing, dc_link_get_highest_encoding_format(link)); if (!crtc_timing->flags.DSC) edp_decide_link_settings(link, &link_setting, req_bw); @@ -807,6 +831,167 @@ bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_ return true; } +bool edp_set_replay_allow_active(struct dc_link *link, const bool *allow_active, + bool wait, bool force_static, const unsigned int *power_opts) +{ + struct dc *dc = link->ctx->dc; + struct dmub_replay *replay = dc->res_pool->replay; + unsigned int panel_inst; + + if (replay == NULL && force_static) + return false; + + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + + /* Set power optimization flag */ + if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts) { + if (link->replay_settings.replay_feature_enabled && replay->funcs->replay_set_power_opt) { + replay->funcs->replay_set_power_opt(replay, *power_opts, panel_inst); + link->replay_settings.replay_power_opt_active = *power_opts; + } + } + + /* Activate or deactivate Replay */ + if (allow_active && link->replay_settings.replay_allow_active != *allow_active) { + // TODO: Handle mux change case if force_static is set + // If force_static is set, just change the replay_allow_active state directly + if (replay != NULL && link->replay_settings.replay_feature_enabled) + replay->funcs->replay_enable(replay, *allow_active, wait, panel_inst); + link->replay_settings.replay_allow_active = *allow_active; + } + + return true; +} + +bool edp_get_replay_state(const struct dc_link *link, uint64_t *state) +{ + struct dc *dc = link->ctx->dc; + struct dmub_replay *replay = dc->res_pool->replay; + unsigned int panel_inst; + enum replay_state pr_state = REPLAY_STATE_0; + + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + + if (replay != NULL && link->replay_settings.replay_feature_enabled) + replay->funcs->replay_get_state(replay, &pr_state, panel_inst); + *state = pr_state; + + return true; +} + +bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream) +{ + /* To-do: Setup Replay */ + struct dc *dc = link->ctx->dc; + struct dmub_replay *replay = dc->res_pool->replay; + int i; + unsigned int panel_inst; + struct replay_context replay_context = { 0 }; + unsigned int lineTimeInNs = 0; + + + union replay_enable_and_configuration replay_config; + + union dpcd_alpm_configuration alpm_config; + + replay_context.controllerId = CONTROLLER_ID_UNDEFINED; + + if (!link) + return false; + + if (!replay) + return false; + + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + + replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel; + replay_context.digbe_inst = link->link_enc->transmitter; + replay_context.digfe_inst = link->link_enc->preferred_engine; + + for (i = 0; i < MAX_PIPES; i++) { + if (dc->current_state->res_ctx.pipe_ctx[i].stream + == stream) { + /* dmcu -1 for all controller id values, + * therefore +1 here + */ + replay_context.controllerId = + dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst + 1; + break; + } + } + + lineTimeInNs = + ((stream->timing.h_total * 1000000) / + (stream->timing.pix_clk_100hz / 10)) + 1; + + replay_context.line_time_in_ns = lineTimeInNs; + + if (replay) + link->replay_settings.replay_feature_enabled = + replay->funcs->replay_copy_settings(replay, link, &replay_context, panel_inst); + if (link->replay_settings.replay_feature_enabled) { + + replay_config.bits.FREESYNC_PANEL_REPLAY_MODE = 1; + replay_config.bits.TIMING_DESYNC_ERROR_VERIFICATION = + link->replay_settings.config.replay_timing_sync_supported; + replay_config.bits.STATE_TRANSITION_ERROR_DETECTION = 1; + dm_helpers_dp_write_dpcd(link->ctx, link, + DP_SINK_PR_ENABLE_AND_CONFIGURATION, + (uint8_t *)&(replay_config.raw), sizeof(uint8_t)); + + memset(&alpm_config, 0, sizeof(alpm_config)); + alpm_config.bits.ENABLE = 1; + dm_helpers_dp_write_dpcd( + link->ctx, + link, + DP_RECEIVER_ALPM_CONFIG, + &alpm_config.raw, + sizeof(alpm_config.raw)); + } + return true; +} + +bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal) +{ + struct dc *dc = link->ctx->dc; + struct dmub_replay *replay = dc->res_pool->replay; + unsigned int panel_inst; + + if (!replay) + return false; + + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + + if (coasting_vtotal && link->replay_settings.coasting_vtotal != coasting_vtotal) { + replay->funcs->replay_set_coasting_vtotal(replay, coasting_vtotal, panel_inst); + link->replay_settings.coasting_vtotal = coasting_vtotal; + } + + return true; +} + +bool edp_replay_residency(const struct dc_link *link, + unsigned int *residency, const bool is_start, const bool is_alpm) +{ + struct dc *dc = link->ctx->dc; + struct dmub_replay *replay = dc->res_pool->replay; + unsigned int panel_inst; + + if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) + return false; + + if (replay != NULL && link->replay_settings.replay_feature_enabled) + replay->funcs->replay_residency(replay, panel_inst, residency, is_start, is_alpm); + else + *residency = 0; + + return true; +} + static struct abm *get_abm_from_stream_res(const struct dc_link *link) { int i; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h index 28f552080558..0a5bbda8c739 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h @@ -30,6 +30,7 @@ enum dp_panel_mode dp_get_panel_mode(struct dc_link *link); void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode); bool set_default_brightness_aux(struct dc_link *link); +bool set_cached_brightness_aux(struct dc_link *link); void edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd); int edp_get_backlight_level(const struct dc_link *link); bool edp_get_backlight_level_nits(struct dc_link *link, @@ -52,6 +53,14 @@ bool edp_setup_psr(struct dc_link *link, bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su); void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency); +bool edp_set_replay_allow_active(struct dc_link *dc_link, const bool *enable, + bool wait, bool force_static, const unsigned int *power_opts); +bool edp_setup_replay(struct dc_link *link, + const struct dc_stream_state *stream); +bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal); +bool edp_replay_residency(const struct dc_link *link, + unsigned int *residency, const bool is_start, const bool is_alpm); +bool edp_get_replay_state(const struct dc_link *link, uint64_t *state); bool edp_wait_for_t12(struct dc_link *link); bool edp_is_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timing *crtc_timing); |