@@ -263,6 +263,14 @@ uint32_t dp_link_bandwidth_kbps(
263263 return link_rate_per_lane_kbps * link_settings -> lane_count / 10000 * total_data_bw_efficiency_x10000 ;
264264}
265265
266+ static uint32_t dp_get_timing_bandwidth_kbps (
267+ const struct dc_crtc_timing * timing ,
268+ const struct dc_link * link )
269+ {
270+ return dc_bandwidth_in_kbps_from_timing (timing ,
271+ dc_link_get_highest_encoding_format (link ));
272+ }
273+
266274static bool dp_validate_mode_timing (
267275 struct dc_link * link ,
268276 const struct dc_crtc_timing * timing )
@@ -411,13 +419,88 @@ bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const un
411419 for (uint8_t i = 0 ; i < num_dpias ; ++ i ) {
412420 int dp_overhead = 0 ;
413421
414- dp_overhead = link_dp_dpia_get_dp_overhead_in_dp_tunneling (dpia_link [i ]);
422+ dp_overhead = link_dpia_get_dp_mst_overhead (dpia_link [i ]);
415423 bw_needed [i ] += dp_overhead ;
416424 }
417425
418426 return dpia_validate_usb4_bw (dpia_link , bw_needed , num_dpias );
419427}
420428
429+ static const struct dc_tunnel_settings * get_dp_tunnel_settings (const struct dc_state * context ,
430+ const struct dc_stream_state * stream )
431+ {
432+ int i ;
433+ const struct dc_tunnel_settings * dp_tunnel_settings = NULL ;
434+
435+ for (i = 0 ; i < MAX_PIPES ; i ++ ) {
436+ if (context -> res_ctx .pipe_ctx [i ].stream && (context -> res_ctx .pipe_ctx [i ].stream == stream )) {
437+ dp_tunnel_settings = & context -> res_ctx .pipe_ctx [i ].link_config .dp_tunnel_settings ;
438+ break ;
439+ }
440+ }
441+
442+ return dp_tunnel_settings ;
443+ }
444+
445+ /*
446+ * Calculates the DP tunneling bandwidth required for the stream timing
447+ * and aggregates the stream bandwidth for the respective DP tunneling link
448+ *
449+ * return: dc_status
450+ */
451+ enum dc_status link_validate_dp_tunnel_bandwidth (const struct dc * dc , const struct dc_state * new_ctx )
452+ {
453+ struct dc_validation_dpia_set dpia_link_sets [MAX_DPIA_NUM ] = { 0 };
454+ uint8_t link_count = 0 ;
455+ enum dc_status result = DC_OK ;
456+
457+ for (uint8_t i = 0 ; (i < MAX_PIPES && i < new_ctx -> stream_count ); i ++ ) {
458+ const struct dc_stream_state * stream = new_ctx -> streams [i ];
459+ const struct dc_link * link ;
460+ const struct dc_tunnel_settings * dp_tunnel_settings ;
461+ uint32_t timing_bw ;
462+
463+ if (stream == NULL )
464+ continue ;
465+
466+ link = stream -> link ;
467+
468+ if (!(link && (stream -> signal == SIGNAL_TYPE_DISPLAY_PORT
469+ || stream -> signal == SIGNAL_TYPE_DISPLAY_PORT_MST )
470+ && link -> hpd_status ))
471+ continue ;
472+
473+ dp_tunnel_settings = get_dp_tunnel_settings (new_ctx , stream );
474+
475+ if ((dp_tunnel_settings == NULL ) || (dp_tunnel_settings -> should_use_dp_bw_allocation == false))
476+ continue ;
477+
478+ timing_bw = dp_get_timing_bandwidth_kbps (& stream -> timing , link );
479+
480+ for (uint8_t j = 0 ; j < MAX_DPIA_NUM ; j ++ ) {
481+ bool is_new_slot = false;
482+
483+ if (dpia_link_sets [j ].link == NULL ) {
484+ is_new_slot = true;
485+ link_count ++ ;
486+ dpia_link_sets [j ].required_bw = 0 ;
487+ dpia_link_sets [j ].link = link ;
488+ }
489+
490+ if (is_new_slot || (dpia_link_sets [j ].link == link )) {
491+ dpia_link_sets [j ].tunnel_settings = dp_tunnel_settings ;
492+ dpia_link_sets [j ].required_bw += timing_bw ;
493+ break ;
494+ }
495+ }
496+ }
497+
498+ if (link_count && link_dpia_validate_dp_tunnel_bandwidth (dpia_link_sets , link_count ) == false)
499+ result = DC_FAIL_DP_TUNNEL_BW_VALIDATE ;
500+
501+ return result ;
502+ }
503+
421504struct dp_audio_layout_config {
422505 uint8_t layouts_per_sample_denom ;
423506 uint8_t symbols_per_layout ;
0 commit comments