Commit 6ede6b06 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Implement async flips for vlv/chv

Add support for async flips on vlv/chv. Unlike all the other
platforms vlv/chv do not use the async flip bit in DSPCNTR and
instead we select between async vs. sync flips based on the
surface address register. The normal DSPSURF generates sync
flips DSPADDR_VLV generates async flips. And as usual the
interrupt bits are different from the other platforms.

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-12-ville.syrjala@linux.intel.comReviewed-by: default avatarKarthik B S <karthik.b.s@intel.com>
parent 4bb18054
...@@ -517,6 +517,23 @@ g4x_primary_async_flip(struct intel_plane *plane, ...@@ -517,6 +517,23 @@ g4x_primary_async_flip(struct intel_plane *plane,
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
} }
static void
vlv_primary_async_flip(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state,
bool async_flip)
{
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
u32 dspaddr_offset = plane_state->color_plane[0].offset;
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
intel_de_write_fw(dev_priv, DSPADDR_VLV(i9xx_plane),
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
static void static void
bdw_primary_enable_flip_done(struct intel_plane *plane) bdw_primary_enable_flip_done(struct intel_plane *plane)
{ {
...@@ -579,6 +596,28 @@ ilk_primary_disable_flip_done(struct intel_plane *plane) ...@@ -579,6 +596,28 @@ ilk_primary_disable_flip_done(struct intel_plane *plane)
spin_unlock_irq(&i915->irq_lock); spin_unlock_irq(&i915->irq_lock);
} }
static void
vlv_primary_enable_flip_done(struct intel_plane *plane)
{
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
i915_enable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
spin_unlock_irq(&i915->irq_lock);
}
static void
vlv_primary_disable_flip_done(struct intel_plane *plane)
{
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
i915_disable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
spin_unlock_irq(&i915->irq_lock);
}
static bool i9xx_plane_get_hw_state(struct intel_plane *plane, static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
enum pipe *pipe) enum pipe *pipe)
{ {
...@@ -792,16 +831,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) ...@@ -792,16 +831,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
plane->get_hw_state = i9xx_plane_get_hw_state; plane->get_hw_state = i9xx_plane_get_hw_state;
plane->check_plane = i9xx_plane_check; plane->check_plane = i9xx_plane_check;
if (IS_BROADWELL(dev_priv)) { if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
plane->async_flip = vlv_primary_async_flip;
plane->enable_flip_done = vlv_primary_enable_flip_done;
plane->disable_flip_done = vlv_primary_disable_flip_done;
} else if (IS_BROADWELL(dev_priv)) {
plane->need_async_flip_disable_wa = true; plane->need_async_flip_disable_wa = true;
plane->async_flip = g4x_primary_async_flip; plane->async_flip = g4x_primary_async_flip;
plane->enable_flip_done = bdw_primary_enable_flip_done; plane->enable_flip_done = bdw_primary_enable_flip_done;
plane->disable_flip_done = bdw_primary_disable_flip_done; plane->disable_flip_done = bdw_primary_disable_flip_done;
} else if (IS_HASWELL(dev_priv) || IS_IVYBRIDGE(dev_priv)) { } else if (INTEL_GEN(dev_priv) >= 7) {
plane->async_flip = g4x_primary_async_flip; plane->async_flip = g4x_primary_async_flip;
plane->enable_flip_done = ivb_primary_enable_flip_done; plane->enable_flip_done = ivb_primary_enable_flip_done;
plane->disable_flip_done = ivb_primary_disable_flip_done; plane->disable_flip_done = ivb_primary_disable_flip_done;
} else if (IS_GEN_RANGE(dev_priv, 5, 6)) { } else if (INTEL_GEN(dev_priv) >= 5) {
plane->async_flip = g4x_primary_async_flip; plane->async_flip = g4x_primary_async_flip;
plane->enable_flip_done = ilk_primary_enable_flip_done; plane->enable_flip_done = ilk_primary_enable_flip_done;
plane->disable_flip_done = ilk_primary_disable_flip_done; plane->disable_flip_done = ilk_primary_disable_flip_done;
......
...@@ -1319,9 +1319,7 @@ static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_pr ...@@ -1319,9 +1319,7 @@ static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_pr
static bool has_async_flips(struct drm_i915_private *i915) static bool has_async_flips(struct drm_i915_private *i915)
{ {
return INTEL_GEN(i915) >= 9 || IS_BROADWELL(i915) || return INTEL_GEN(i915) >= 5;
IS_HASWELL(i915) || IS_IVYBRIDGE(i915) ||
IS_GEN_RANGE(i915, 5, 6);
} }
static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
......
...@@ -1540,6 +1540,9 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, ...@@ -1540,6 +1540,9 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
intel_handle_vblank(dev_priv, pipe); intel_handle_vblank(dev_priv, pipe);
if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV)
flip_done_handler(dev_priv, pipe);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev_priv, pipe); i9xx_pipe_crc_irq_handler(dev_priv, pipe);
......
...@@ -6578,6 +6578,7 @@ enum { ...@@ -6578,6 +6578,7 @@ enum {
#define TGL_CURSOR_D_OFFSET 0x73080 #define TGL_CURSOR_D_OFFSET 0x73080
/* Display A control */ /* Display A control */
#define _DSPAADDR_VLV 0x7017C /* vlv/chv */
#define _DSPACNTR 0x70180 #define _DSPACNTR 0x70180
#define DISPLAY_PLANE_ENABLE (1 << 31) #define DISPLAY_PLANE_ENABLE (1 << 31)
#define DISPLAY_PLANE_DISABLE 0 #define DISPLAY_PLANE_DISABLE 0
...@@ -6626,6 +6627,7 @@ enum { ...@@ -6626,6 +6627,7 @@ enum {
#define _DSPASURFLIVE 0x701AC #define _DSPASURFLIVE 0x701AC
#define _DSPAGAMC 0x701E0 #define _DSPAGAMC 0x701E0
#define DSPADDR_VLV(plane) _MMIO_PIPE2(plane, _DSPAADDR_VLV)
#define DSPCNTR(plane) _MMIO_PIPE2(plane, _DSPACNTR) #define DSPCNTR(plane) _MMIO_PIPE2(plane, _DSPACNTR)
#define DSPADDR(plane) _MMIO_PIPE2(plane, _DSPAADDR) #define DSPADDR(plane) _MMIO_PIPE2(plane, _DSPAADDR)
#define DSPSTRIDE(plane) _MMIO_PIPE2(plane, _DSPASTRIDE) #define DSPSTRIDE(plane) _MMIO_PIPE2(plane, _DSPASTRIDE)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment