Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a5c4d7bc authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

drm/i915: Disable/enable planes as the first/last thing during modeset on ILK+



We already do this for HSW, but doing it makes sense for everything else
as well. Extend it for ILK/SNB/IVB since that's where the new watermark
code is used.

Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77297


[danvet: Resolve conflict since I've plucked this out of the middle of
Ville's series.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent be6a6f8e
Loading
Loading
Loading
Loading
+46 −63
Original line number Diff line number Diff line
@@ -3636,6 +3636,46 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
		hsw_enable_ips(intel_crtc);
}

static void ilk_crtc_enable_planes(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	int pipe = intel_crtc->pipe;
	int plane = intel_crtc->plane;

	intel_enable_primary_hw_plane(dev_priv, plane, pipe);
	intel_enable_planes(crtc);
	intel_crtc_update_cursor(crtc, true);

	hsw_enable_ips(intel_crtc);

	mutex_lock(&dev->struct_mutex);
	intel_update_fbc(dev);
	mutex_unlock(&dev->struct_mutex);
}

static void ilk_crtc_disable_planes(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	int pipe = intel_crtc->pipe;
	int plane = intel_crtc->plane;

	intel_crtc_wait_for_pending_flips(crtc);
	drm_vblank_off(dev, pipe);

	if (dev_priv->fbc.plane == plane)
		intel_disable_fbc(dev);

	hsw_disable_ips(intel_crtc);

	intel_crtc_update_cursor(crtc, false);
	intel_disable_planes(crtc);
	intel_disable_primary_hw_plane(dev_priv, plane, pipe);
}

static void ironlake_crtc_enable(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
@@ -3643,7 +3683,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	struct intel_encoder *encoder;
	int pipe = intel_crtc->pipe;
	int plane = intel_crtc->plane;

	WARN_ON(!crtc->enabled);

@@ -3679,23 +3718,18 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)

	intel_update_watermarks(crtc);
	intel_enable_pipe(intel_crtc);
	intel_enable_primary_hw_plane(dev_priv, plane, pipe);
	intel_enable_planes(crtc);
	intel_crtc_update_cursor(crtc, true);

	if (intel_crtc->config.has_pch_encoder)
		ironlake_pch_enable(crtc);

	mutex_lock(&dev->struct_mutex);
	intel_update_fbc(dev);
	mutex_unlock(&dev->struct_mutex);

	for_each_encoder_on_crtc(dev, crtc, encoder)
		encoder->enable(encoder);

	if (HAS_PCH_CPT(dev))
		cpt_verify_modeset(dev, intel_crtc->pipe);

	ilk_crtc_enable_planes(crtc);

	/*
	 * There seems to be a race in PCH platform hw (at least on some
	 * outputs) where an enabled pipe still completes any pageflip right
@@ -3713,47 +3747,6 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
	return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
}

static void haswell_crtc_enable_planes(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	int pipe = intel_crtc->pipe;
	int plane = intel_crtc->plane;

	intel_enable_primary_hw_plane(dev_priv, plane, pipe);
	intel_enable_planes(crtc);
	intel_crtc_update_cursor(crtc, true);

	hsw_enable_ips(intel_crtc);

	mutex_lock(&dev->struct_mutex);
	intel_update_fbc(dev);
	mutex_unlock(&dev->struct_mutex);
}

static void haswell_crtc_disable_planes(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	int pipe = intel_crtc->pipe;
	int plane = intel_crtc->plane;

	intel_crtc_wait_for_pending_flips(crtc);
	drm_vblank_off(dev, pipe);

	/* FBC must be disabled before disabling the plane on HSW. */
	if (dev_priv->fbc.plane == plane)
		intel_disable_fbc(dev);

	hsw_disable_ips(intel_crtc);

	intel_crtc_update_cursor(crtc, false);
	intel_disable_planes(crtc);
	intel_disable_primary_hw_plane(dev_priv, plane, pipe);
}

/*
 * This implements the workaround described in the "notes" section of the mode
 * set sequence documentation. When going from no pipes or single pipe to
@@ -3836,7 +3829,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
	/* If we change the relative order between pipe/planes enabling, we need
	 * to change the workaround. */
	haswell_mode_set_planes_workaround(intel_crtc);
	haswell_crtc_enable_planes(crtc);
	ilk_crtc_enable_planes(crtc);
}

static void ironlake_pfit_disable(struct intel_crtc *crtc)
@@ -3861,26 +3854,16 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
	struct intel_encoder *encoder;
	int pipe = intel_crtc->pipe;
	int plane = intel_crtc->plane;
	u32 reg, temp;


	if (!intel_crtc->active)
		return;

	ilk_crtc_disable_planes(crtc);

	for_each_encoder_on_crtc(dev, crtc, encoder)
		encoder->disable(encoder);

	intel_crtc_wait_for_pending_flips(crtc);
	drm_vblank_off(dev, pipe);

	if (dev_priv->fbc.plane == plane)
		intel_disable_fbc(dev);

	intel_crtc_update_cursor(crtc, false);
	intel_disable_planes(crtc);
	intel_disable_primary_hw_plane(dev_priv, plane, pipe);

	if (intel_crtc->config.has_pch_encoder)
		intel_set_pch_fifo_underrun_reporting(dev, pipe, false);

@@ -3939,7 +3922,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
	if (!intel_crtc->active)
		return;

	haswell_crtc_disable_planes(crtc);
	ilk_crtc_disable_planes(crtc);

	for_each_encoder_on_crtc(dev, crtc, encoder) {
		intel_opregion_notify_encoder(encoder, false);