drm/amd/display: clip plane rects in DM before passing into DC

[Why]
DC global validation can fail when userspace requests to draw large
plane without performing the clipping themselves.

This is observed in the IGT kms_plane panning tests for 4K displays
where they draw an 8K plane without any clipping while expecting only
the top 4K to be drawn.

[How]
DRM already has helpers to take care of the clipping necessary and to
mark whether a plane is visible or not, so make use of these helpers
in DM before passing the plane to DC.

Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Aurabindo Pillai 2020-06-04 15:54:39 -04:00 committed by Alex Deucher
parent f822406cb1
commit 8c44515be1

View File

@ -5693,6 +5693,17 @@ static void dm_plane_helper_cleanup_fb(struct drm_plane *plane,
amdgpu_bo_unref(&rbo);
}
static int dm_plane_helper_check_state(struct drm_plane_state *state,
struct drm_crtc_state *new_crtc_state)
{
int max_downscale = 0;
int max_upscale = INT_MAX;
/* TODO: These should be checked against DC plane caps */
return drm_atomic_helper_check_plane_state(
state, new_crtc_state, max_downscale, max_upscale, true, true);
}
static int dm_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
@ -5700,6 +5711,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
struct dc *dc = adev->dm.dc;
struct dm_plane_state *dm_plane_state;
struct dc_scaling_info scaling_info;
struct drm_crtc_state *new_crtc_state;
int ret;
dm_plane_state = to_dm_plane_state(state);
@ -5707,6 +5719,15 @@ static int dm_plane_atomic_check(struct drm_plane *plane,
if (!dm_plane_state->dc_state)
return 0;
new_crtc_state =
drm_atomic_get_new_crtc_state(state->state, state->crtc);
if (!new_crtc_state)
return -EINVAL;
ret = dm_plane_helper_check_state(state, new_crtc_state);
if (ret)
return ret;
ret = fill_dc_scaling_info(state, &scaling_info);
if (ret)
return ret;
@ -8223,6 +8244,10 @@ static int dm_update_plane_state(struct dc *dc,
if (!needs_reset)
return 0;
ret = dm_plane_helper_check_state(new_plane_state, new_crtc_state);
if (ret)
return ret;
WARN_ON(dm_new_plane_state->dc_state);
dc_new_plane_state = dc_create_plane_state(dc);