drm/amd/display: add workaround for 4k video underflow
authorEric Yang <Eric.Yang2@amd.com>
Mon, 17 Dec 2018 23:28:59 +0000 (18:28 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 14 Jan 2019 20:41:47 +0000 (15:41 -0500)
[Why]
On DCN1, there is an issue where on high BW config on single channel
systems, underflow will be observed if DCC is disabled. This issue
can be observed on several use cases. For this particular case,
it is observed when playing 4k video on 4k desktop with video downscaled
to a certain size.

[How]
Block MPO for this particular case, this will prevent extra BW consumed
from downscaling, working around the underflow.

Signed-off-by: Eric Yang <Eric.Yang2@amd.com>
Reviewed-by: Yongqiang Sun <yongqiang.sun@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c

index 3e6a6025419a8348e41ce207f3616dedb10309f6..ea0628bebe0da00cf2c8188e4ef518d0975477a0 100644 (file)
@@ -1131,6 +1131,56 @@ static enum dc_status dcn10_validate_plane(const struct dc_plane_state *plane_st
        return DC_OK;
 }
 
+static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *context)
+{
+       int i, j;
+       bool video_down_scaled = false;
+       bool video_large = false;
+       bool desktop_large = false;
+       bool dcc_disabled = false;
+
+       for (i = 0; i < context->stream_count; i++) {
+               if (context->stream_status[i].plane_count == 0)
+                       continue;
+
+               if (context->stream_status[i].plane_count > 2)
+                       return false;
+
+               for (j = 0; j < context->stream_status[i].plane_count; j++) {
+                       struct dc_plane_state *plane =
+                               context->stream_status[i].plane_states[j];
+
+
+                       if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+
+                               if (plane->src_rect.width > plane->dst_rect.width ||
+                                               plane->src_rect.height > plane->dst_rect.height)
+                                       video_down_scaled = true;
+
+                               if (plane->src_rect.width >= 3840)
+                                       video_large = true;
+
+                       } else {
+                               if (plane->src_rect.width >= 3840)
+                                       desktop_large = true;
+                               if (!plane->dcc.enable)
+                                       dcc_disabled = true;
+                       }
+               }
+       }
+
+       /*
+        * Workaround: On DCN10 there is UMC issue that causes underflow when
+        * playing 4k video on 4k desktop with video downscaled and single channel
+        * memory
+        */
+       if (video_large && desktop_large && video_down_scaled && dcc_disabled &&
+                       dc->dcn_soc->number_of_channels == 1)
+               return DC_FAIL_SURFACE_VALIDATE;
+
+       return DC_OK;
+}
+
 static enum dc_status dcn10_get_default_swizzle_mode(struct dc_plane_state *plane_state)
 {
        enum dc_status result = DC_OK;
@@ -1159,6 +1209,7 @@ static const struct resource_funcs dcn10_res_pool_funcs = {
        .validate_bandwidth = dcn_validate_bandwidth,
        .acquire_idle_pipe_for_layer = dcn10_acquire_idle_pipe_for_layer,
        .validate_plane = dcn10_validate_plane,
+       .validate_global = dcn10_validate_global,
        .add_stream_to_ctx = dcn10_add_stream_to_ctx,
        .get_default_swizzle_mode = dcn10_get_default_swizzle_mode
 };