Commit 3001e6d1 authored by Ethan Bitnun's avatar Ethan Bitnun Committed by Alex Deucher
Browse files

drm/amd/display: Add support for 1080p SubVP to reduce idle power



- 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: default avatarAlvin Lee <alvin.lee2@amd.com>
Acked-by: default avatarHamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: default avatarEthan Bitnun <ethan.bitnun@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c4b9dc53
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)))
+1 −1
Original line number Diff line number Diff line
@@ -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

+46 −0
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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 = {