From: hersen wu <[email protected]>

[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 <[email protected]>
Acked-by: Rodrigo Siqueira <[email protected]>
Signed-off-by: hersen wu <[email protected]>
---
 .../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

Reply via email to