Commit ddd5298c authored by Alvin Lee's avatar Alvin Lee Committed by Alex Deucher

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: default avatarAric Cyr <aric.cyr@amd.com>
Acked-by: default avatarTom Chung <chiahsuan.chung@amd.com>
Signed-off-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c7c19779
...@@ -5472,15 +5472,15 @@ bool dc_abm_save_restore( ...@@ -5472,15 +5472,15 @@ bool dc_abm_save_restore(
void dc_query_current_properties(struct dc *dc, struct dc_current_properties *properties) void dc_query_current_properties(struct dc *dc, struct dc_current_properties *properties)
{ {
unsigned int i; unsigned int i;
bool subvp_in_use = false; bool subvp_sw_cursor_req = false;
for (i = 0; i < dc->current_state->stream_count; i++) { for (i = 0; i < dc->current_state->stream_count; i++) {
if (dc->current_state->streams[i]->mall_stream_config.type != SUBVP_NONE) { if (check_subvp_sw_cursor_fallback_req(dc, dc->current_state->streams[i])) {
subvp_in_use = true; subvp_sw_cursor_req = true;
break; 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) ...@@ -1341,6 +1341,32 @@ static void calculate_inits_and_viewports(struct pipe_ctx *pipe_ctx)
data->viewport_c.y += src.y / vpc_div; 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) bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
{ {
const struct dc_plane_state *plane_state = pipe_ctx->plane_state; 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, ...@@ -5121,3 +5147,16 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
return DC_OK; 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( ...@@ -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 * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
*/ */
...@@ -347,13 +321,7 @@ bool dc_stream_set_cursor_attributes( ...@@ -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 * 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.allow_sw_cursor_fallback && attributes->height * attributes->width * 4 > 16384) {
if (!dc->debug.disable_subvp_high_refresh && is_subvp_high_refresh_candidate(stream)) if (check_subvp_sw_cursor_fallback_req(dc, 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)
return false; return false;
} }
......
...@@ -604,4 +604,7 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy( ...@@ -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, enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
struct dc_state *context, struct dc_state *context,
struct pipe_ctx *pipe_ctx); 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_ */ #endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment