From: hersen wu <hersenxs.wu@xxxxxxx> [Why] when connect one 4k@144hz dp to dsc mst hub, 4k@144hz mode is in valid mode list. but some mst hub port output bandwidth does not support 4k@144hz. [How] add mst port output bandwidth checks, include full_pbn, branch max throughput mps. Reviewed-by: Jerry Zuo <Jerry.Zuo@xxxxxxx> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@xxxxxxx> Signed-off-by: hersen wu <hersenxs.wu@xxxxxxx> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +++-- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 +- .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 36 +++++++++++++++++++ .../display/amdgpu_dm/amdgpu_dm_mst_types.h | 4 +++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c2fc32dac712..ea91149ec3e6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -7259,7 +7259,11 @@ create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector, break; } - dc_result = dc_validate_stream(adev->dm.dc, stream); + if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) + dc_result = dm_dp_mst_is_port_support_mode(aconnector, stream); + + if (dc_result == DC_OK) + dc_result = dc_validate_stream(adev->dm.dc, stream); if (dc_result != DC_OK) { DRM_DEBUG_KMS("Mode %dx%d (clk %d) failed DC validation with error %d (%s)\n", @@ -7559,7 +7563,7 @@ static void dm_encoder_helper_disable(struct drm_encoder *encoder) } -static int convert_dc_color_depth_into_bpc (enum dc_color_depth display_color_depth) +int convert_dc_color_depth_into_bpc(enum dc_color_depth display_color_depth) { switch (display_color_depth) { case COLOR_DEPTH_666: diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index cbd2e8f2ae50..8241a3795762 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -583,7 +583,6 @@ struct amdgpu_dm_connector { struct drm_dp_mst_port *port; struct amdgpu_dm_connector *mst_port; struct drm_dp_aux *dsc_aux; - /* TODO see if we can merge with ddc_bus or make a dm_connector */ struct amdgpu_i2c_adapter *i2c; @@ -747,4 +746,6 @@ int dm_atomic_get_state(struct drm_atomic_state *state, struct amdgpu_dm_connector * amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state, struct drm_crtc *crtc); + +int convert_dc_color_depth_into_bpc(enum dc_color_depth display_color_depth); #endif /* __AMDGPU_DM_H__ */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index d005bb6a2956..ee5d6fa34a6b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -1353,4 +1353,40 @@ bool pre_validate_dsc(struct drm_atomic_state *state, return (ret == 0); } + #endif + +enum dc_status dm_dp_mst_is_port_support_mode( + struct amdgpu_dm_connector *aconnector, + struct dc_stream_state *stream) +{ + int bpp, pbn, branch_max_throughput_mps = 0; + + /* check if mode could be supported within fUll_pbn */ + bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; + pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); + if (pbn > aconnector->port->full_pbn) + return DC_FAIL_BANDWIDTH_VALIDATE; + + /* check is mst dsc output bandwidth branch_overall_throughput_0_mps */ + switch (stream->timing.pixel_encoding) { + case PIXEL_ENCODING_RGB: + case PIXEL_ENCODING_YCBCR444: + branch_max_throughput_mps = + aconnector->dc_sink->dsc_caps.dsc_dec_caps.branch_overall_throughput_0_mps; + break; + case PIXEL_ENCODING_YCBCR422: + case PIXEL_ENCODING_YCBCR420: + branch_max_throughput_mps = + aconnector->dc_sink->dsc_caps.dsc_dec_caps.branch_overall_throughput_1_mps; + break; + default: + break; + } + + if (branch_max_throughput_mps != 0 && + ((stream->timing.pix_clk_100hz / 10) > branch_max_throughput_mps * 1000)) + return DC_FAIL_BANDWIDTH_VALIDATE; + + return DC_OK; +} diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 2e13027d9b88..b92a7c5671aa 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -63,4 +63,8 @@ bool pre_validate_dsc(struct drm_atomic_state *state, struct dm_atomic_state **dm_state_ptr, struct dsc_mst_fairness_vars *vars); +enum dc_status dm_dp_mst_is_port_support_mode( + struct amdgpu_dm_connector *aconnector, + struct dc_stream_state *stream); + #endif -- 2.25.1