Commit 10c59c51 authored by Imre Deak's avatar Imre Deak Committed by Daniel Vetter

drm/i915: vlv: fix mapping of pipestat enable to status bits

At least on VLV we can't get at the pipestat status bits by simply right
shifting the corresponding enable bits. The mapping between enable and
status bits for the sprite0,1 flip done and the PSR events don't follow
this rule, so we need to map them separately.

The PSR enable for pipe A is DPFLIPSTAT[22], but I haven't added support
for this, since there is no user of it atm. Until support is added WARN
if someone tries to enable PSR interrupts, or tries to enable the same
(1 << 6) bit on pipe B, which MBZ.

v2:
- inline the status->enable mask mapping (Ville)
- fix bogus use of status bits in enable mask (Ville)
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 755e9019
...@@ -515,13 +515,39 @@ __i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, ...@@ -515,13 +515,39 @@ __i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
POSTING_READ(reg); POSTING_READ(reg);
} }
static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
{
u32 enable_mask = status_mask << 16;
/*
* On pipe A we don't support the PSR interrupt yet, on pipe B the
* same bit MBZ.
*/
if (WARN_ON_ONCE(status_mask & PIPE_A_PSR_STATUS_VLV))
return 0;
enable_mask &= ~(PIPE_FIFO_UNDERRUN_STATUS |
SPRITE0_FLIP_DONE_INT_EN_VLV |
SPRITE1_FLIP_DONE_INT_EN_VLV);
if (status_mask & SPRITE0_FLIP_DONE_INT_STATUS_VLV)
enable_mask |= SPRITE0_FLIP_DONE_INT_EN_VLV;
if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV)
enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV;
return enable_mask;
}
void void
i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
u32 status_mask) u32 status_mask)
{ {
u32 enable_mask; u32 enable_mask;
enable_mask = status_mask << 16; if (IS_VALLEYVIEW(dev_priv->dev))
enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev,
status_mask);
else
enable_mask = status_mask << 16;
__i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask); __i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask);
} }
...@@ -531,7 +557,11 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, ...@@ -531,7 +557,11 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
{ {
u32 enable_mask; u32 enable_mask;
enable_mask = status_mask << 16; if (IS_VALLEYVIEW(dev_priv->dev))
enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev,
status_mask);
else
enable_mask = status_mask << 16;
__i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask); __i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask);
} }
......
...@@ -3254,6 +3254,7 @@ ...@@ -3254,6 +3254,7 @@
#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22) #define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21) #define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20) #define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
#define PIPE_B_PSR_INTERRUPT_ENABLE_VLV (1UL<<19)
#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */ #define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */ #define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) #define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
...@@ -3270,8 +3271,10 @@ ...@@ -3270,8 +3271,10 @@
#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) #define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
#define PIPE_DPST_EVENT_STATUS (1UL<<7) #define PIPE_DPST_EVENT_STATUS (1UL<<7)
#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) #define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
#define PIPE_A_PSR_STATUS_VLV (1UL<<6)
#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) #define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4) #define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
#define PIPE_B_PSR_STATUS_VLV (1UL<<3)
#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */ #define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ #define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) #define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
......
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