Commit 6f231633 authored by Ryan Seto's avatar Ryan Seto Committed by Alex Deucher
Browse files

Revert "drm/amd/display: Refactor SubVP cursor limiting logic"



This reverts commit 19e743f0 ("drm/amd/display: Refactor SubVP cursor limiting logic")

Reason for revert: Corruption

Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Signed-off-by: default avatarRyan Seto <ryanseto@amd.com>
Signed-off-by: default avatarRay Wu <ray.wu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 2f2c9708
Loading
Loading
Loading
Loading
+10 −42
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@
#include "dc_state.h"
#include "dc_state_priv.h"
#include "dc_plane_priv.h"
#include "dc_stream_priv.h"

#include "gpio_service_interface.h"
#include "clk_mgr.h"
@@ -2887,7 +2886,7 @@ static enum surface_update_type check_update_surfaces_for_stream(
	int i;
	enum surface_update_type overall_type = UPDATE_TYPE_FAST;

	if (dc->idle_optimizations_allowed || dc_can_clear_cursor_limit(dc))
	if (dc->idle_optimizations_allowed)
		overall_type = UPDATE_TYPE_FULL;

	if (stream_status == NULL || stream_status->plane_count != surface_count)
@@ -3291,7 +3290,7 @@ static void copy_stream_update_to_stream(struct dc *dc,
		if (dsc_validate_context) {
			stream->timing.dsc_cfg = *update->dsc_config;
			stream->timing.flags.DSC = enable_dsc;
			if (dc->res_pool->funcs->validate_bandwidth(dc, dsc_validate_context, true) != DC_OK) {
			if (!dc->res_pool->funcs->validate_bandwidth(dc, dsc_validate_context, true)) {
				stream->timing.dsc_cfg = old_dsc_cfg;
				stream->timing.flags.DSC = old_dsc_enabled;
				update->dsc_config = NULL;
@@ -4609,7 +4608,7 @@ static struct dc_state *create_minimal_transition_state(struct dc *dc,

	backup_and_set_minimal_pipe_split_policy(dc, base_context, policy);
	/* commit minimal state */
	if (dc->res_pool->funcs->validate_bandwidth(dc, minimal_transition_context, false) == DC_OK) {
	if (dc->res_pool->funcs->validate_bandwidth(dc, minimal_transition_context, false)) {
		/* prevent underflow and corruption when reconfiguring pipes */
		force_vsync_flip_in_minimal_transition_context(minimal_transition_context);
	} else {
@@ -5129,7 +5128,7 @@ static bool update_planes_and_stream_v1(struct dc *dc,
	copy_stream_update_to_stream(dc, context, stream, stream_update);

	if (update_type >= UPDATE_TYPE_FULL) {
		if (dc->res_pool->funcs->validate_bandwidth(dc, context, false) != DC_OK) {
		if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) {
			DC_ERROR("Mode validation failed for stream update!\n");
			dc_state_release(context);
			return false;
@@ -6273,22 +6272,15 @@ bool dc_abm_save_restore(
void dc_query_current_properties(struct dc *dc, struct dc_current_properties *properties)
{
	unsigned int i;
	unsigned int max_cursor_size = dc->caps.max_cursor_size;
	unsigned int stream_cursor_size;
	bool subvp_sw_cursor_req = false;

	if (dc->debug.allow_sw_cursor_fallback && dc->res_pool->funcs->get_max_hw_cursor_size) {
	for (i = 0; i < dc->current_state->stream_count; i++) {
			stream_cursor_size = dc->res_pool->funcs->get_max_hw_cursor_size(dc,
					dc->current_state,
					dc->current_state->streams[i]);

			if (stream_cursor_size < max_cursor_size) {
				max_cursor_size = stream_cursor_size;
			}
		if (check_subvp_sw_cursor_fallback_req(dc, dc->current_state->streams[i]) && !dc->current_state->streams[i]->hw_cursor_req) {
			subvp_sw_cursor_req = true;
			break;
		}
	}

	properties->cursor_size_limit = max_cursor_size;
	properties->cursor_size_limit = subvp_sw_cursor_req ? 64 : dc->caps.max_cursor_size;
}

/**
@@ -6354,27 +6346,3 @@ unsigned int dc_get_det_buffer_size_from_state(const struct dc_state *context)
	else
		return 0;
}

bool dc_is_cursor_limit_pending(struct dc *dc)
{
	uint32_t i;

	for (i = 0; i < dc->current_state->stream_count; i++) {
		if (dc_stream_is_cursor_limit_pending(dc, dc->current_state->streams[i]))
			return true;
	}

	return false;
}

bool dc_can_clear_cursor_limit(struct dc *dc)
{
	uint32_t i;

	for (i = 0; i < dc->current_state->stream_count; i++) {
		if (dc_state_can_clear_stream_cursor_subvp_limit(dc->current_state->streams[i], dc->current_state))
			return true;
	}

	return false;
}
+0 −2
Original line number Diff line number Diff line
@@ -266,8 +266,6 @@ char *dc_status_to_str(enum dc_status status)
		return "Fail dp payload allocation";
	case DC_FAIL_DP_LINK_BANDWIDTH:
		return "Insufficient DP link bandwidth";
	case DC_FAIL_HW_CURSOR_SUPPORT:
		return "HW Cursor not supported";
	case DC_ERROR_UNEXPECTED:
		return "Unexpected error";
	}
+42 −6
Original line number Diff line number Diff line
@@ -1342,6 +1342,32 @@ static void calculate_inits_and_viewports(struct pipe_ctx *pipe_ctx)
	data->viewport_c.y += src.y / vpc_div;
}

static bool is_subvp_high_refresh_candidate(struct dc_stream_state *stream)
{
	uint32_t refresh_rate;
	struct dc *dc = stream->ctx->dc;

	refresh_rate = (stream->timing.pix_clk_100hz * (uint64_t)100 +
		stream->timing.v_total * stream->timing.h_total - (uint64_t)1);
	refresh_rate = div_u64(refresh_rate, stream->timing.v_total);
	refresh_rate = div_u64(refresh_rate, stream->timing.h_total);

	/* If there's any stream that fits the SubVP high refresh criteria,
	 * we must return true. This is because cursor updates are asynchronous
	 * with full updates, so we could transition into a SubVP config and
	 * remain in HW cursor mode if there's no cursor update which will
	 * then cause corruption.
	 */
	if ((refresh_rate >= 120 && refresh_rate <= 175 &&
			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)))
		return true;

	return false;
}

static enum controller_dp_test_pattern convert_dp_to_controller_test_pattern(
				enum dp_test_pattern test_pattern)
{
@@ -4233,11 +4259,6 @@ enum dc_status dc_validate_with_context(struct dc *dc,
		}
	}

	/* clear subvp cursor limitations */
	for (i = 0; i < context->stream_count; i++) {
		dc_state_set_stream_subvp_cursor_limit(context->streams[i], context, false);
	}

	res = dc_validate_global_state(dc, context, fast_validate);

	/* calculate pixel rate divider after deciding pxiel clock & odm combine  */
@@ -4364,7 +4385,8 @@ enum dc_status dc_validate_global_state(
	result = resource_build_scaling_params_for_context(dc, new_ctx);

	if (result == DC_OK)
		result = dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate);
		if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate))
			result = DC_FAIL_BANDWIDTH_VALIDATE;

	return result;
}
@@ -5516,6 +5538,20 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
	return DC_OK;
}

bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream)
{
	if (!dc->debug.disable_subvp_high_refresh && is_subvp_high_refresh_candidate(stream))
		return true;
	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 true;
	else if (dc->current_state->stream_count > 1 && stream->timing.v_addressable >= 1080 &&
			((stream->timing.pix_clk_100hz * 100) / stream->timing.v_total / stream->timing.h_total) < 120)
		return true;

	return false;
}

struct dscl_prog_data *resource_get_dscl_prog_data(struct pipe_ctx *pipe_ctx)
{
	return &pipe_ctx->plane_res.scl_data.dscl_prog_data;
+0 −96
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
 * Authors: AMD
 *
 */
#include "dc_types.h"
#include "core_types.h"
#include "core_status.h"
#include "dc_state.h"
@@ -813,12 +812,8 @@ enum dc_status dc_state_add_phantom_stream(const struct dc *dc,
	if (phantom_stream_status) {
		phantom_stream_status->mall_stream_config.type = SUBVP_PHANTOM;
		phantom_stream_status->mall_stream_config.paired_stream = main_stream;
		phantom_stream_status->mall_stream_config.subvp_limit_cursor_size = false;
		phantom_stream_status->mall_stream_config.cursor_size_limit_subvp = false;
	}

	dc_state_set_stream_subvp_cursor_limit(main_stream, state, true);

	return res;
}

@@ -982,94 +977,3 @@ bool dc_state_is_fams2_in_use(

	return is_fams2_in_use;
}

void dc_state_set_stream_subvp_cursor_limit(const struct dc_stream_state *stream,
		struct dc_state *state,
		bool limit)
{
	struct dc_stream_status *stream_status;

	stream_status = dc_state_get_stream_status(state, stream);

	if (stream_status) {
		stream_status->mall_stream_config.subvp_limit_cursor_size = limit;
	}
}

bool dc_state_get_stream_subvp_cursor_limit(const struct dc_stream_state *stream,
		struct dc_state *state)
{
	bool limit = false;

	struct dc_stream_status *stream_status;

	stream_status = dc_state_get_stream_status(state, stream);

	if (stream_status) {
		limit = stream_status->mall_stream_config.subvp_limit_cursor_size;
	}

	return limit;
}

void dc_state_set_stream_cursor_subvp_limit(const struct dc_stream_state *stream,
		struct dc_state *state,
		bool limit)
{
	struct dc_stream_status *stream_status;

	stream_status = dc_state_get_stream_status(state, stream);

	if (stream_status) {
		stream_status->mall_stream_config.cursor_size_limit_subvp = limit;
	}
}

bool dc_state_get_stream_cursor_subvp_limit(const struct dc_stream_state *stream,
		struct dc_state *state)
{
	bool limit = false;

	struct dc_stream_status *stream_status;

	stream_status = dc_state_get_stream_status(state, stream);

	if (stream_status) {
		limit = stream_status->mall_stream_config.cursor_size_limit_subvp;
	}

	return limit;
}

bool dc_state_can_clear_stream_cursor_subvp_limit(const struct dc_stream_state *stream,
		struct dc_state *state)
{
	bool can_clear_limit = false;

	struct dc_stream_status *stream_status;

	stream_status = dc_state_get_stream_status(state, stream);

	if (stream_status) {
		can_clear_limit = dc_state_get_stream_cursor_subvp_limit(stream, state) &&
				(stream_status->mall_stream_config.type == SUBVP_PHANTOM ||
				stream->hw_cursor_req ||
				!stream_status->mall_stream_config.subvp_limit_cursor_size ||
				!stream->cursor_position.enable ||
				dc_stream_check_cursor_attributes(stream, state, &stream->cursor_attributes));
	}

	return can_clear_limit;
}

bool dc_state_is_subvp_in_use(struct dc_state *state)
{
	uint32_t i;

	for (i = 0; i < state->stream_count; i++) {
		if (dc_state_get_stream_subvp_type(state, state->streams[i]) != SUBVP_NONE)
			return true;
	}

	return false;
}
+15 −55
Original line number Diff line number Diff line
@@ -265,16 +265,13 @@ void program_cursor_attributes(
}

/*
 * dc_stream_check_cursor_attributes() - Check validitity of cursor attributes and surface address
 * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
 */
bool dc_stream_check_cursor_attributes(
	const struct dc_stream_state *stream,
	struct dc_state *state,
bool dc_stream_set_cursor_attributes(
	struct dc_stream_state *stream,
	const struct dc_cursor_attributes *attributes)
{
	const struct dc *dc;

	unsigned int max_cursor_size;
	struct dc  *dc;

	if (NULL == stream) {
		dm_error("DC: dc_stream is NULL!\n");
@@ -292,36 +289,22 @@ bool dc_stream_check_cursor_attributes(

	dc = stream->ctx->dc;

	/* SubVP is not compatible with HW cursor larger than what can fit in cursor SRAM.
	 * Therefore, if cursor is greater than this, fallback to SW cursor.
	/* 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. If the config is a candidate for SubVP high refresh (both single an dual display configs)
	 * 2. If not subvp high refresh, for single display cases, if resolution is >= 5K and refresh rate < 120hz
	 * 3. If not subvp high refresh, for multi display cases, if resolution is >= 4K and refresh rate < 120hz
	 */
	if (dc->debug.allow_sw_cursor_fallback && dc->res_pool->funcs->get_max_hw_cursor_size) {
		max_cursor_size = dc->res_pool->funcs->get_max_hw_cursor_size(dc, state, stream);
		max_cursor_size = max_cursor_size * max_cursor_size * 4;

		if (attributes->height * attributes->width * 4 > max_cursor_size) {
	if (dc->debug.allow_sw_cursor_fallback &&
		attributes->height * attributes->width * 4 > 16384 &&
		!stream->hw_cursor_req) {
		if (check_subvp_sw_cursor_fallback_req(dc, stream))
			return false;
	}
	}

	return true;
}

/*
 * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
 */
bool dc_stream_set_cursor_attributes(
	struct dc_stream_state *stream,
	const struct dc_cursor_attributes *attributes)
{
	bool result = false;

	if (dc_stream_check_cursor_attributes(stream, stream->ctx->dc->current_state, attributes)) {
	stream->cursor_attributes = *attributes;
		result = true;
	}

	return result;
	return true;
}

bool dc_stream_program_cursor_attributes(
@@ -1126,26 +1109,3 @@ unsigned int dc_stream_get_max_flickerless_instant_vtotal_increase(struct dc_str

	return dc_stream_get_max_flickerless_instant_vtotal_delta(stream, is_gaming, false);
}

bool dc_stream_is_cursor_limit_pending(struct dc *dc, struct dc_stream_state *stream)
{
	bool is_limit_pending = false;

	if (dc->current_state)
		is_limit_pending = dc_state_get_stream_cursor_subvp_limit(stream, dc->current_state);

	return is_limit_pending;
}

bool dc_stream_can_clear_cursor_limit(struct dc *dc, struct dc_stream_state *stream)
{
	bool can_clear_limit = false;

	if (dc->current_state)
		can_clear_limit = dc_state_get_stream_cursor_subvp_limit(stream, dc->current_state) &&
				(stream->hw_cursor_req ||
				!stream->cursor_position.enable ||
				dc_stream_check_cursor_attributes(stream, dc->current_state, &stream->cursor_attributes));

	return can_clear_limit;
}
Loading