[PATCH 02/21] drm/amd/display: Add support for 1080p SubVP to reduce idle power

Hamza Mahfooz hamza.mahfooz at amd.com
Wed Aug 23 15:58:04 UTC 2023


From: Ethan Bitnun <ethan.bitnun at amd.com>

- 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 at amd.com>
Acked-by: Hamza Mahfooz <hamza.mahfooz at amd.com>
Signed-off-by: Ethan Bitnun <ethan.bitnun at amd.com>
---
 .../gpu/drm/amd/display/dc/core/dc_stream.c   |  2 +-
 .../drm/amd/display/dc/dcn32/dcn32_resource.h |  2 +-
 .../display/dc/dcn32/dcn32_resource_helpers.c | 46 +++++++++++++++++++
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c  |  3 +-
 4 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 01fe2d2fd241..dad1c85a1df3 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -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)))
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
index 103a2b54d025..0c6ca3da66d9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.h
@@ -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
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
index 3ad2b48954e0..f5705b3e6e42 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
@@ -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;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index b3252db43ecb..96e3075e6dd0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -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 = {
-- 
2.41.0



More information about the amd-gfx mailing list