aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHamza Mahfooz <hamza.mahfooz@amd.com>2022-07-21 12:55:34 -0400
committerAlex Deucher <alexander.deucher@amd.com>2022-08-16 18:17:31 -0400
commit8350bb59e63d0909b0d65af2d9710026e0f902ce (patch)
tree73abd1f92e86e8d4268f08736492a1a7e1ffe3a6
parentdrm/dp_mst: add passthrough_aux to struct drm_dp_mst_port (diff)
downloadlinux-dev-8350bb59e63d0909b0d65af2d9710026e0f902ce.tar.xz
linux-dev-8350bb59e63d0909b0d65af2d9710026e0f902ce.zip
drm/amd/display: consider DSC pass-through during mode validation
Add a mode validation routine for DSC pass-through. Both the link from source to hub, and the link from hub to monitor are checked, according to the current link training result and full pbn returned by enum path resource sideband message. Pick up the minimum value as the bandwidth bottleneck for the end to end link bandwidth constraint, and check if the maximum DSC decompression bandwidth can fit. v2: squash in DSC CONFIG_DRM_AMD_DC_DCN compilation fix (Hamza) Co-authored-by: Fangzhi Zuo <Jerry.Zuo@amd.com> Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c84
1 files changed, 78 insertions, 6 deletions
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 2e74ccf7df5b..ce6929224a6e 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
@@ -36,6 +36,7 @@
#include "dm_helpers.h"
#include "dc_link_ddc.h"
+#include "dc_link_dp.h"
#include "ddc_service_types.h"
#include "dpcd_defs.h"
@@ -1386,19 +1387,90 @@ clean_exit:
return (ret == 0);
}
-#endif
+static unsigned int kbps_from_pbn(unsigned int pbn)
+{
+ unsigned int kbps = pbn;
+
+ kbps *= (1000000 / PEAK_FACTOR_X1000);
+ kbps *= 8;
+ kbps *= 54;
+ kbps /= 64;
+
+ return kbps;
+}
+
+static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
+ struct dc_dsc_bw_range *bw_range)
+{
+ struct dc_dsc_policy dsc_policy = {0};
+
+ dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy);
+ dc_dsc_compute_bandwidth_range(stream->sink->ctx->dc->res_pool->dscs[0],
+ stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
+ dsc_policy.min_target_bpp * 16,
+ dsc_policy.max_target_bpp * 16,
+ &stream->sink->dsc_caps.dsc_dec_caps,
+ &stream->timing, bw_range);
+
+ return bw_range->max_target_bpp_x16 && bw_range->min_target_bpp_x16;
+}
+#endif /* CONFIG_DRM_AMD_DC_DCN */
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;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+ struct dc_link_settings cur_link_settings;
+ unsigned int end_to_end_bw_in_kbps = 0;
+ unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
+ unsigned int max_compressed_bw_in_kbps = 0;
+ struct dc_dsc_bw_range bw_range = {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 if the mode could be supported if DSC pass-through is supported
+ * AND check if there enough bandwidth available to support the mode
+ * with DSC enabled.
+ */
+ if (is_dsc_common_config_possible(stream, &bw_range) &&
+ aconnector->port->passthrough_aux) {
+ mutex_lock(&aconnector->mst_mgr.lock);
+
+ cur_link_settings = stream->link->verified_link_cap;
+
+ upper_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
+ &cur_link_settings
+ );
+ down_link_bw_in_kbps = kbps_from_pbn(aconnector->port->full_pbn);
+
+ /* pick the bottleneck */
+ end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps,
+ down_link_bw_in_kbps);
+
+ mutex_unlock(&aconnector->mst_mgr.lock);
+
+ /*
+ * use the maximum dsc compression bandwidth as the required
+ * bandwidth for the mode
+ */
+ max_compressed_bw_in_kbps = bw_range.min_kbps;
+
+ if (end_to_end_bw_in_kbps < max_compressed_bw_in_kbps) {
+ DRM_DEBUG_DRIVER("Mode does not fit into DSC pass-through bandwidth validation\n");
+ return DC_FAIL_BANDWIDTH_VALIDATE;
+ }
+ } else {
+#endif
+ /* 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;
+#if defined(CONFIG_DRM_AMD_DC_DCN)
+ }
+#endif
/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
switch (stream->timing.pixel_encoding) {