mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-13 23:45:26 -04:00
drm/amd/display: Fix subvp+drr logic errors
[Why] There is some logic error where the wrong variable was used to check for OTG_MASTER and DPP_PIPE. [How] Add booleans to confirm that the expected pipes were found before validating schedulability. Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com> Reviewed-by: Samson Tam <samson.tam@amd.com> Reviewed-by: Chaitanya Dhere <chaitanya.dhere@amd.com> Signed-off-by: Alvin Lee <alvin.lee2@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -806,6 +806,8 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)
|
||||
int16_t drr_stretched_vblank_us = 0;
|
||||
int16_t max_vblank_mallregion = 0;
|
||||
struct dc_stream_state *phantom_stream;
|
||||
bool subvp_found = false;
|
||||
bool drr_found = false;
|
||||
|
||||
// Find SubVP pipe
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
@@ -818,8 +820,10 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)
|
||||
continue;
|
||||
|
||||
// Find the SubVP pipe
|
||||
if (dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_MAIN)
|
||||
if (dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_MAIN) {
|
||||
subvp_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the DRR pipe
|
||||
@@ -827,33 +831,37 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)
|
||||
drr_pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
// We check for master pipe only
|
||||
if (!resource_is_pipe_type(pipe, OTG_MASTER) ||
|
||||
!resource_is_pipe_type(pipe, DPP_PIPE))
|
||||
if (!resource_is_pipe_type(drr_pipe, OTG_MASTER) ||
|
||||
!resource_is_pipe_type(drr_pipe, DPP_PIPE))
|
||||
continue;
|
||||
|
||||
if (dc_state_get_pipe_subvp_type(context, drr_pipe) == SUBVP_NONE && drr_pipe->stream->ignore_msa_timing_param &&
|
||||
(drr_pipe->stream->allow_freesync || drr_pipe->stream->vrr_active_variable || drr_pipe->stream->vrr_active_fixed))
|
||||
(drr_pipe->stream->allow_freesync || drr_pipe->stream->vrr_active_variable || drr_pipe->stream->vrr_active_fixed)) {
|
||||
drr_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
phantom_stream = dc_state_get_paired_subvp_stream(context, pipe->stream);
|
||||
main_timing = &pipe->stream->timing;
|
||||
phantom_timing = &phantom_stream->timing;
|
||||
drr_timing = &drr_pipe->stream->timing;
|
||||
prefetch_us = (phantom_timing->v_total - phantom_timing->v_front_porch) * phantom_timing->h_total /
|
||||
(double)(phantom_timing->pix_clk_100hz * 100) * 1000000 +
|
||||
dc->caps.subvp_prefetch_end_to_mall_start_us;
|
||||
subvp_active_us = main_timing->v_addressable * main_timing->h_total /
|
||||
(double)(main_timing->pix_clk_100hz * 100) * 1000000;
|
||||
drr_frame_us = drr_timing->v_total * drr_timing->h_total /
|
||||
(double)(drr_timing->pix_clk_100hz * 100) * 1000000;
|
||||
// P-State allow width and FW delays already included phantom_timing->v_addressable
|
||||
mall_region_us = phantom_timing->v_addressable * phantom_timing->h_total /
|
||||
(double)(phantom_timing->pix_clk_100hz * 100) * 1000000;
|
||||
stretched_drr_us = drr_frame_us + mall_region_us + SUBVP_DRR_MARGIN_US;
|
||||
drr_stretched_vblank_us = (drr_timing->v_total - drr_timing->v_addressable) * drr_timing->h_total /
|
||||
(double)(drr_timing->pix_clk_100hz * 100) * 1000000 + (stretched_drr_us - drr_frame_us);
|
||||
max_vblank_mallregion = drr_stretched_vblank_us > mall_region_us ? drr_stretched_vblank_us : mall_region_us;
|
||||
if (subvp_found && drr_found) {
|
||||
phantom_stream = dc_state_get_paired_subvp_stream(context, pipe->stream);
|
||||
main_timing = &pipe->stream->timing;
|
||||
phantom_timing = &phantom_stream->timing;
|
||||
drr_timing = &drr_pipe->stream->timing;
|
||||
prefetch_us = (phantom_timing->v_total - phantom_timing->v_front_porch) * phantom_timing->h_total /
|
||||
(double)(phantom_timing->pix_clk_100hz * 100) * 1000000 +
|
||||
dc->caps.subvp_prefetch_end_to_mall_start_us;
|
||||
subvp_active_us = main_timing->v_addressable * main_timing->h_total /
|
||||
(double)(main_timing->pix_clk_100hz * 100) * 1000000;
|
||||
drr_frame_us = drr_timing->v_total * drr_timing->h_total /
|
||||
(double)(drr_timing->pix_clk_100hz * 100) * 1000000;
|
||||
// P-State allow width and FW delays already included phantom_timing->v_addressable
|
||||
mall_region_us = phantom_timing->v_addressable * phantom_timing->h_total /
|
||||
(double)(phantom_timing->pix_clk_100hz * 100) * 1000000;
|
||||
stretched_drr_us = drr_frame_us + mall_region_us + SUBVP_DRR_MARGIN_US;
|
||||
drr_stretched_vblank_us = (drr_timing->v_total - drr_timing->v_addressable) * drr_timing->h_total /
|
||||
(double)(drr_timing->pix_clk_100hz * 100) * 1000000 + (stretched_drr_us - drr_frame_us);
|
||||
max_vblank_mallregion = drr_stretched_vblank_us > mall_region_us ? drr_stretched_vblank_us : mall_region_us;
|
||||
}
|
||||
|
||||
/* We consider SubVP + DRR schedulable if the stretched frame duration of the DRR display (i.e. the
|
||||
* highest refresh rate + margin that can support UCLK P-State switch) passes the static analysis
|
||||
|
||||
Reference in New Issue
Block a user