Commit 2a636e24 authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915: Implement async flip for ivb/hsw



Add support for async flips on ivb/hsw. Unlike bdw+ we don't need
any workarounds to disable async flips. Apart from that the only
real difference from the bdw implementation is the location of the
flip_done interrupt bits.

Cc: Karthik B S <karthik.b.s@intel.com>
Cc: Vandita Kulkarni <vandita.kulkarni@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210111163711.12913-10-ville.syrjala@linux.intel.com


Reviewed-by: default avatarKarthik B S <karthik.b.s@intel.com>
parent cda195f1
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -539,6 +539,26 @@ bdw_primary_disable_flip_done(struct intel_plane *plane)
	spin_unlock_irq(&i915->irq_lock);
}

static void
ivb_primary_enable_flip_done(struct intel_plane *plane)
{
	struct drm_i915_private *i915 = to_i915(plane->base.dev);

	spin_lock_irq(&i915->irq_lock);
	ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
	spin_unlock_irq(&i915->irq_lock);
}

static void
ivb_primary_disable_flip_done(struct intel_plane *plane)
{
	struct drm_i915_private *i915 = to_i915(plane->base.dev);

	spin_lock_irq(&i915->irq_lock);
	ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
	spin_unlock_irq(&i915->irq_lock);
}

static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
				    enum pipe *pipe)
{
@@ -757,6 +777,10 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
		plane->async_flip = g4x_primary_async_flip;
		plane->enable_flip_done = bdw_primary_enable_flip_done;
		plane->disable_flip_done = bdw_primary_disable_flip_done;
	} else if (IS_HASWELL(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
		plane->async_flip = g4x_primary_async_flip;
		plane->enable_flip_done = ivb_primary_enable_flip_done;
		plane->disable_flip_done = ivb_primary_disable_flip_done;
	}

	if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
+2 −1
Original line number Diff line number Diff line
@@ -1319,7 +1319,8 @@ static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_pr

static bool has_async_flips(struct drm_i915_private *i915)
{
	return INTEL_GEN(i915) >= 9 || IS_BROADWELL(i915);
	return INTEL_GEN(i915) >= 9 || IS_BROADWELL(i915) ||
		IS_HASWELL(i915) || IS_IVYBRIDGE(i915);
}

static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
+6 −0
Original line number Diff line number Diff line
@@ -2104,6 +2104,9 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
	for_each_pipe(dev_priv, pipe) {
		if (de_iir & DE_PIPE_VBLANK_IVB(pipe))
			intel_handle_vblank(dev_priv, pipe);

		if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe))
			flip_done_handler(dev_priv, pipe);
	}

	/* check event from PCH */
@@ -3587,6 +3590,9 @@ static void ilk_irq_postinstall(struct drm_i915_private *dev_priv)
				DE_PCH_EVENT_IVB | DE_AUX_CHANNEL_A_IVB);
		extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
			      DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB |
			      DE_PLANE_FLIP_DONE_IVB(PLANE_C) |
			      DE_PLANE_FLIP_DONE_IVB(PLANE_B) |
			      DE_PLANE_FLIP_DONE_IVB(PLANE_A) |
			      DE_DP_A_HOTPLUG_IVB);
	} else {
		display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |