summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/amdgpu_dm
diff options
context:
space:
mode:
authorhersen wu <hersenxs.wu@amd.com>2022-05-29 12:12:32 -0400
committerAlex Deucher <alexander.deucher@amd.com>2022-06-21 18:17:23 -0400
commitf04d275d94e164d24516c32437c988a323018f63 (patch)
treeb140d57f1e5060356316ecf285b8dcab081bf54e /drivers/gpu/drm/amd/display/amdgpu_dm
parentec457f8378901d673b841e81d289b0165286db7f (diff)
downloadlinux-f04d275d94e164d24516c32437c988a323018f63.tar.bz2
drm/amd/display: add mst port output bw check
[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. Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Reviewed-by: Jerry Zuo <Jerry.Zuo@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: hersen wu <hersenxs.wu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c8
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h3
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c36
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h4
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 9039c2fbabe2..b3ab2a3ea29c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7260,7 +7260,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",
@@ -7560,7 +7564,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 2e351204cc2d..547fc1547977 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 26f733b2faa0..f3ce37664143 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 @@ clean_exit:
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