drm/amd/display: Add support for 1080p SubVP to reduce idle power
authorEthan Bitnun <ethan.bitnun@amd.com>
Mon, 14 Aug 2023 14:32:14 +0000 (10:32 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 30 Aug 2023 19:31:43 +0000 (15:31 -0400)
- Override the det to adjust microschedule timings allow for
  1080p configs with SubVP
- To lower unnecessary risk, we prevent multi 1080p configs
  from using SubVP, as multi 1080p already has low idle power.
- Count the number of streams to verify that we are in a
  SubVP config before overriding

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Ethan Bitnun <ethan.bitnun@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.h
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c

index 01fe2d2fd241726bbe3531d905483942c7eaadd5..dad1c85a1df3e4ceb64c45baa2cde06b59d762ea 100644 (file)
@@ -322,7 +322,7 @@ static bool is_subvp_high_refresh_candidate(struct dc_stream_state *stream)
         * then cause corruption.
         */
        if ((refresh_rate >= 120 && refresh_rate <= 175 &&
-                       stream->timing.v_addressable >= 1440 &&
+                       stream->timing.v_addressable >= 1080 &&
                        stream->timing.v_addressable <= 2160) &&
                        (dc->current_state->stream_count > 1 ||
                        (dc->current_state->stream_count == 1 && !stream->allow_freesync)))
index 103a2b54d025944172a09870df6475f86073c2a8..0c6ca3da66d918cba94f852b8ca67ac1b3de76e6 100644 (file)
@@ -38,7 +38,7 @@
 #define DCN3_2_MBLK_HEIGHT_4BPE 128
 #define DCN3_2_MBLK_HEIGHT_8BPE 64
 #define DCN3_2_DCFCLK_DS_INIT_KHZ 10000 // Choose 10Mhz for init DCFCLK DS freq
-#define SUBVP_HIGH_REFRESH_LIST_LEN 3
+#define SUBVP_HIGH_REFRESH_LIST_LEN 4
 #define DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ 1800
 #define DCN3_2_VMIN_DISPCLK_HZ 717000000
 
index 3ad2b48954e02924cce24d3680d6cdeece8ea3e0..f5705b3e6e4216d73c9024c9ac63b014d04dd781 100644 (file)
@@ -255,6 +255,51 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
        return psr_capable;
 }
 
+static void override_det_for_subvp(struct dc *dc, struct dc_state *context, uint8_t pipe_segments[])
+{
+       uint32_t i;
+       uint8_t fhd_count = 0;
+       uint8_t subvp_high_refresh_count = 0;
+       uint8_t stream_count = 0;
+
+       // Do not override if a stream has multiple planes
+       for (i = 0; i < context->stream_count; i++) {
+               if (context->stream_status[i].plane_count > 1) {
+                       return;
+               }
+               if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM) {
+                       stream_count++;
+               }
+       }
+
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream && pipe_ctx->plane_state && pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+                       if (dcn32_allow_subvp_high_refresh_rate(dc, context, pipe_ctx)) {
+
+                               if (pipe_ctx->stream->timing.v_addressable == 1080 && pipe_ctx->stream->timing.h_addressable == 1920) {
+                                       fhd_count++;
+                               }
+                               subvp_high_refresh_count++;
+                       }
+               }
+       }
+
+       if (stream_count == 2 && subvp_high_refresh_count == 2 && fhd_count == 1) {
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+                       if (pipe_ctx->stream && pipe_ctx->plane_state && pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+                               if (pipe_ctx->stream->timing.v_addressable == 1080 && pipe_ctx->stream->timing.h_addressable == 1920) {
+                                       if (pipe_segments[i] > 4)
+                                               pipe_segments[i] = 4;
+                               }
+                       }
+               }
+       }
+}
+
 /**
  * dcn32_determine_det_override(): Determine DET allocation for each pipe
  *
@@ -336,6 +381,7 @@ void dcn32_determine_det_override(struct dc *dc,
                        }
                }
 
+               override_det_for_subvp(dc, context, pipe_segments);
                for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
                        if (!context->res_ctx.pipe_ctx[i].stream)
                                continue;
index b3252db43ecb0edd249bef309b45223dac19da9b..96e3075e6dd00c5e310b8f8bbbdbd2b1880f9ead 100644 (file)
@@ -41,7 +41,8 @@ static const struct subvp_high_refresh_list subvp_high_refresh_list = {
                        .res = {
                                {.width = 3840, .height = 2160, },
                                {.width = 3440, .height = 1440, },
-                               {.width = 2560, .height = 1440, }},
+                               {.width = 2560, .height = 1440, },
+                               {.width = 1920, .height = 1080, }},
 };
 
 struct _vcs_dpi_ip_params_st dcn3_2_ip = {