mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-03 17:04:50 -04:00
drm/amd/display: Update cursor limits based on SW cursor fallback limits
[Why&How] For determining the cursor size limit, use the same checks that are used for determining SW cursor fallback instead of only using SubVP Reviewed-by: Aric Cyr <aric.cyr@amd.com> Acked-by: Tom Chung <chiahsuan.chung@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>
This commit is contained in:
@@ -5472,15 +5472,15 @@ bool dc_abm_save_restore(
|
||||
void dc_query_current_properties(struct dc *dc, struct dc_current_properties *properties)
|
||||
{
|
||||
unsigned int i;
|
||||
bool subvp_in_use = false;
|
||||
bool subvp_sw_cursor_req = false;
|
||||
|
||||
for (i = 0; i < dc->current_state->stream_count; i++) {
|
||||
if (dc->current_state->streams[i]->mall_stream_config.type != SUBVP_NONE) {
|
||||
subvp_in_use = true;
|
||||
if (check_subvp_sw_cursor_fallback_req(dc, dc->current_state->streams[i])) {
|
||||
subvp_sw_cursor_req = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
properties->cursor_size_limit = subvp_in_use ? 64 : dc->caps.max_cursor_size;
|
||||
properties->cursor_size_limit = subvp_sw_cursor_req ? 64 : dc->caps.max_cursor_size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1341,6 +1341,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;
|
||||
}
|
||||
|
||||
bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
|
||||
@@ -5121,3 +5147,16 @@ 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 >= 2160 &&
|
||||
((stream->timing.pix_clk_100hz * 100) / stream->timing.v_total / stream->timing.h_total) < 120)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -288,32 +288,6 @@ static void program_cursor_attributes(
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
|
||||
*/
|
||||
@@ -347,13 +321,7 @@ bool dc_stream_set_cursor_attributes(
|
||||
* 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 && attributes->height * attributes->width * 4 > 16384) {
|
||||
if (!dc->debug.disable_subvp_high_refresh && is_subvp_high_refresh_candidate(stream))
|
||||
return false;
|
||||
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)
|
||||
if (check_subvp_sw_cursor_fallback_req(dc, stream))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -604,4 +604,7 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy(
|
||||
enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
|
||||
bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream);
|
||||
|
||||
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
|
||||
|
||||
Reference in New Issue
Block a user