summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_atomic_plane.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_atomic_plane.c')
-rw-r--r--drivers/gpu/drm/i915/intel_atomic_plane.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 4325cb0a04f5..8e6dc159f64d 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -107,13 +107,17 @@ intel_plane_destroy_state(struct drm_plane *plane,
drm_atomic_helper_plane_destroy_state(plane, state);
}
-int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
+int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
+ struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *old_plane_state,
struct intel_plane_state *intel_state)
{
struct drm_plane *plane = intel_state->base.plane;
struct drm_i915_private *dev_priv = to_i915(plane->dev);
struct drm_plane_state *state = &intel_state->base;
struct intel_plane *intel_plane = to_intel_plane(plane);
+ const struct drm_display_mode *adjusted_mode =
+ &crtc_state->base.adjusted_mode;
int ret;
/*
@@ -122,7 +126,7 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
* anything driver-specific we need to test in that case, so
* just return success.
*/
- if (!intel_state->base.crtc && !plane->state->crtc)
+ if (!intel_state->base.crtc && !old_plane_state->base.crtc)
return 0;
/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
@@ -173,22 +177,40 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
+ /*
+ * Y-tiling is not supported in IF-ID Interlace mode in
+ * GEN9 and above.
+ */
+ if (state->fb && INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
+ adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+ if (state->fb->modifier == I915_FORMAT_MOD_Y_TILED ||
+ state->fb->modifier == I915_FORMAT_MOD_Yf_TILED) {
+ DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
+ return -EINVAL;
+ }
+ }
+
/* FIXME pre-g4x don't work like this */
if (intel_state->base.visible)
crtc_state->active_planes |= BIT(intel_plane->id);
else
crtc_state->active_planes &= ~BIT(intel_plane->id);
- return intel_plane_atomic_calc_changes(&crtc_state->base, state);
+ return intel_plane_atomic_calc_changes(old_crtc_state,
+ &crtc_state->base,
+ old_plane_state,
+ state);
}
static int intel_plane_atomic_check(struct drm_plane *plane,
- struct drm_plane_state *state)
+ struct drm_plane_state *new_plane_state)
{
- struct drm_crtc *crtc = state->crtc;
- struct drm_crtc_state *drm_crtc_state;
-
- crtc = crtc ? crtc : plane->state->crtc;
+ struct drm_atomic_state *state = new_plane_state->state;
+ const struct drm_plane_state *old_plane_state =
+ drm_atomic_get_old_plane_state(state, plane);
+ struct drm_crtc *crtc = new_plane_state->crtc ?: old_plane_state->crtc;
+ const struct drm_crtc_state *old_crtc_state;
+ struct drm_crtc_state *new_crtc_state;
/*
* Both crtc and plane->crtc could be NULL if we're updating a
@@ -199,29 +221,33 @@ static int intel_plane_atomic_check(struct drm_plane *plane,
if (!crtc)
return 0;
- drm_crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
- if (WARN_ON(!drm_crtc_state))
- return -EINVAL;
+ old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
+ new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
- return intel_plane_atomic_check_with_state(to_intel_crtc_state(drm_crtc_state),
- to_intel_plane_state(state));
+ return intel_plane_atomic_check_with_state(to_intel_crtc_state(old_crtc_state),
+ to_intel_crtc_state(new_crtc_state),
+ to_intel_plane_state(old_plane_state),
+ to_intel_plane_state(new_plane_state));
}
static void intel_plane_atomic_update(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
+ struct intel_atomic_state *state = to_intel_atomic_state(old_state->state);
struct intel_plane *intel_plane = to_intel_plane(plane);
- struct intel_plane_state *intel_state =
- to_intel_plane_state(plane->state);
- struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc;
+ const struct intel_plane_state *new_plane_state =
+ intel_atomic_get_new_plane_state(state, intel_plane);
+ struct drm_crtc *crtc = new_plane_state->base.crtc ?: old_state->crtc;
+
+ if (new_plane_state->base.visible) {
+ const struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, to_intel_crtc(crtc));
- if (intel_state->base.visible) {
trace_intel_update_plane(plane,
to_intel_crtc(crtc));
intel_plane->update_plane(intel_plane,
- to_intel_crtc_state(crtc->state),
- intel_state);
+ new_crtc_state, new_plane_state);
} else {
trace_intel_disable_plane(plane,
to_intel_crtc(crtc));