@@ -243,16 +243,34 @@ bool dc_link_perform_frl_training(struct dc_link *link,
243243bool dc_link_perform_frl_training_with_retries (struct dc_link * link ,
244244 const struct link_resource * link_res )
245245{
246+ uint8_t min_rate ;
246247 bool success ;
247248 int i ;
248249
250+ /*
251+ * We will attempt the highest rate first, then fall back to a lower rate
252+ * Ideally, the sink would respond with a lower rate request, but my
253+ * Samsung S95B just doesn't. So we do this here instead.
254+ */
255+
256+ min_rate = link -> cur_link_settings .frl_rate ;
257+ link -> cur_link_settings .frl_rate = link -> local_sink -> edid_caps .frl_caps .max_rate ;
258+ link -> cur_link_settings .lane_count = link -> cur_link_settings .frl_rate <= 2 ? 3 : 4 ;
259+
249260 for (i = 0 ; i < FRL_TRAINING_RETRIES ; ++ i ) {
250261 success = dc_link_perform_frl_training (link , link_res );
251262
252263 if (success )
253264 break ;
254265
255- DC_LOG_HW_LINK_TRAINING ("FRL: Training attempt %d failed!" );
266+ if (link -> cur_link_settings .frl_rate > min_rate ) {
267+ link -> cur_link_settings .frl_rate -- ;
268+ link -> cur_link_settings .lane_count =
269+ link -> cur_link_settings .frl_rate <= 2 ? 3 : 4 ;
270+ }
271+
272+ DC_LOG_HW_LINK_TRAINING ("FRL: Training attempt %d failed! Will attempt rate %d next" ,
273+ i , link -> cur_link_settings .frl_rate );
256274 }
257275
258276 return success ;
@@ -567,7 +585,7 @@ bool hdmi_decide_link_settings(
567585 pipe_ctx -> link_config .dp_link_settings .frl_rate = frl_rate ;
568586 pipe_ctx -> link_config .dp_link_settings .lane_count = cfg .lanes ;
569587
570- pr_info ("HDMI FRL: Rate %d Supported. Borrowed: %d , Margin: %d ppm\n" ,
588+ DC_LOG_HW_LINK_TRAINING ("HDMI FRL: Rate %d Supported. Borrowed: %llu , Margin: %d ppm\n" ,
571589 frl_rate , res .tb_borrowed , res .margin_ppm );
572590 return true;
573591 }
0 commit comments