Commit 8c44515b authored by Aurabindo Pillai's avatar Aurabindo Pillai Committed by Alex Deucher
Browse files

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: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f822406c
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -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);