With all the pieces for UHBR SST LT implemented, we can now enable LT fallback switching between SST UHBR and non-UHBR link rates.
Testing with an Asus DP2.1 monitor confirms it follows the specs [1]. > ./kms_dp_linktrain_fallback --run-subtest dp-fallback Mode 3840x2160@160 on output DP-3 Current link rate: 1000000, Current lane count: 4 Current link rate: 810000, Current lane count: 4 Current link rate: 1000000, Current lane count: 2 Current link rate: 540000, Current lane count: 4 Current link rate: 810000, Current lane count: 2 Current link rate: 1000000, Current lane count: 1 Current link rate: 540000, Current lane count: 2 Current link rate: 270000, Current lane count: 4 Current link rate: 810000, Current lane count: 1 Current link rate: 162000, Current lane count: 4 Current link rate: 540000, Current lane count: 1 Current link rate: 270000, Current lane count: 2 Current link rate: 162000, Current lane count: 2 Current link rate: 270000, Current lane count: 1 Current link rate: 162000, Current lane count: 1 Testing by intentionally hacking the LT code to send incorrect training patterns to cause LT failures seems to confirm that this approach is working: 128b/132b Link Training failed at link rate = 1000000, lane count = 4 128b/132b Link Training failed at link rate = 1000000, lane count = 4 Link Training failed at link rate = 810000, lane count = 4 128b/132b Link Training failed at link rate = 1000000, lane count = 2 Link Training failed at link rate = 540000, lane count = 4 Link Training failed at link rate = 810000, lane count = 2 128b/132b Link Training failed at link rate = 1000000, lane count = 1 Link Training failed at link rate = 540000, lane count = 2 Link Training failed at link rate = 270000, lane count = 4 Link Training failed at link rate = 810000, lane count = 1 Link Training failed at link rate = 162000, lane count = 4 Link Training failed at link rate = 540000, lane count = 1 Link Training failed at link rate = 270000, lane count = 2 Link Training failed at link rate = 162000, lane count = 2 Link Training failed at link rate = 270000, lane count = 1 Link Training passed at link rate = 162000, lane count = 1 [1]: DP2.1 Specs - Table 3-31: DPTX Fallback Mandates v2: Modify commit message Cc: Imre Deak <imre.d...@intel.com> Cc: Jani Nikula <jani.nik...@intel.com> Signed-off-by: Charlton Lin <charlton....@intel.com> Signed-off-by: Khaled Almahallawy <khaled.almahall...@intel.com> --- .../drm/i915/display/intel_dp_link_training.c | 72 +------------------ 1 file changed, 1 insertion(+), 71 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 6fc76c424f46..26db4c49deec 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1220,76 +1220,6 @@ static bool reduce_link_params_in_bw_order(struct intel_dp *intel_dp, return true; } -static int reduce_link_rate(struct intel_dp *intel_dp, int current_rate) -{ - int rate_index; - int new_rate; - - if (intel_dp->link.force_rate) - return -1; - - rate_index = intel_dp_rate_index(intel_dp->common_rates, - intel_dp->num_common_rates, - current_rate); - - if (rate_index <= 0) - return -1; - - new_rate = intel_dp_common_rate(intel_dp, rate_index - 1); - - /* TODO: Make switching from UHBR to non-UHBR rates work. */ - if (drm_dp_is_uhbr_rate(current_rate) != drm_dp_is_uhbr_rate(new_rate)) - return -1; - - return new_rate; -} - -static int reduce_lane_count(struct intel_dp *intel_dp, int current_lane_count) -{ - if (intel_dp->link.force_lane_count) - return -1; - - if (current_lane_count == 1) - return -1; - - return current_lane_count >> 1; -} - -static bool reduce_link_params_in_rate_lane_order(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - int *new_link_rate, int *new_lane_count) -{ - int link_rate; - int lane_count; - - lane_count = crtc_state->lane_count; - link_rate = reduce_link_rate(intel_dp, crtc_state->port_clock); - if (link_rate < 0) { - lane_count = reduce_lane_count(intel_dp, crtc_state->lane_count); - link_rate = intel_dp_max_common_rate(intel_dp); - } - - if (lane_count < 0) - return false; - - *new_link_rate = link_rate; - *new_lane_count = lane_count; - - return true; -} - -static bool reduce_link_params(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, - int *new_link_rate, int *new_lane_count) -{ - /* TODO: Use the same fallback logic on SST as on MST. */ - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) - return reduce_link_params_in_bw_order(intel_dp, crtc_state, - new_link_rate, new_lane_count); - else - return reduce_link_params_in_rate_lane_order(intel_dp, crtc_state, - new_link_rate, new_lane_count); -} - static int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -1303,7 +1233,7 @@ static int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, return 0; } - if (!reduce_link_params(intel_dp, crtc_state, &new_link_rate, &new_lane_count)) + if (!reduce_link_params_in_bw_order(intel_dp, crtc_state, &new_link_rate, &new_lane_count)) return -1; if (intel_dp_is_edp(intel_dp) && -- 2.43.0