drm/amd/display: Limit HW cursor size of >= 4k
authorAlvin Lee <Alvin.Lee2@amd.com>
Wed, 9 Nov 2022 14:27:45 +0000 (09:27 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 23 Nov 2022 14:47:13 +0000 (09:47 -0500)
[Description]
- For SubVP, we cannot support HW cursor if it's
  greater than 64 x 64 x 4 bytes in size
- However, on certain config changes (i.e. pixel format)
  we can exit SubVP (then change to HW cursor) then re-enter
  SubVP without changing back to SW cursor because there is
  no SetCursorAttributes call
- To workaround this issue, limit the HW cursor size to be
  less than 64 x 64 x 4 bytes whenever the stream is >= 4K
- Also ensure this W/A only affects DCN that supports SubVP

Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Brian Chang <Brian.Chang@amd.com>
Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c

index 38d71b5..20e534f 100644 (file)
@@ -332,9 +332,21 @@ bool dc_stream_set_cursor_attributes(
 
        dc = stream->ctx->dc;
 
-       if (dc->debug.allow_sw_cursor_fallback && attributes->height * attributes->width * 4 > 16384)
-               if (stream->mall_stream_config.type == SUBVP_MAIN)
+       /* SubVP is not compatible with HW cursor larger than 64 x 64 x 4.
+        * Therefore, if cursor is greater than 64 x 64 x 4, fallback to SW cursor in the following case:
+        * 1. For single display cases, if resolution is >= 5K and refresh rate < 120hz
+        * 2. For multi display cases, if resolution is >= 4K and refresh rate < 120hz
+        *
+        * [< 120hz is a requirement for SubVP configs]
+        */
+       if (dc->debug.allow_sw_cursor_fallback && attributes->height * attributes->width * 4 > 16384) {
+               if (dc->current_state->stream_count == 1 && stream->timing.v_addressable >= 2880 &&
+                               ((stream->timing.pix_clk_100hz * 100) / stream->timing.v_total / stream->timing.h_total) < 120)
                        return false;
+               else if (dc->current_state->stream_count > 1 && stream->timing.v_addressable >= 2160 &&
+                               ((stream->timing.pix_clk_100hz * 100) / stream->timing.v_total / stream->timing.h_total) < 120)
+                       return false;
+       }
 
        stream->cursor_attributes = *attributes;
 
index 0c13fe0..c40dcce 100644 (file)
@@ -723,7 +723,7 @@ static const struct dc_debug_options debug_defaults_drv = {
        /* Must match enable_single_display_2to1_odm_policy to support dynamic ODM transitions*/
        .enable_double_buffered_dsc_pg_support = true,
        .enable_dp_dig_pixel_rate_div_policy = 1,
-       .allow_sw_cursor_fallback = false,
+       .allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback"
        .alloc_extra_way_for_cursor = true,
        .min_prefetch_in_strobe_ns = 60000, // 60us
 };
index d17d0f2..06f1441 100644 (file)
@@ -721,7 +721,7 @@ static const struct dc_debug_options debug_defaults_drv = {
        /*must match enable_single_display_2to1_odm_policy to support dynamic ODM transitions*/
        .enable_double_buffered_dsc_pg_support = true,
        .enable_dp_dig_pixel_rate_div_policy = 1,
-       .allow_sw_cursor_fallback = false,
+       .allow_sw_cursor_fallback = false, // Linux can't do SW cursor "fallback"
        .alloc_extra_way_for_cursor = true,
        .min_prefetch_in_strobe_ns = 60000, // 60us
 };