Commit 21821272 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2014-03-17' of git://anongit.freedesktop.org/drm-intel into drm-fixes

Two 3.14 specific fixes, two cc: stable.

* tag 'drm-intel-fixes-2014-03-17' of git://anongit.freedesktop.org/drm-intel:
  drm/i915: Don't enable display error interrupts from the start
  drm/i915: Fix scanline counter fixup on BDW
  drm/i915: Add a workaround for HSW scanline counter weirdness
  drm/i915: Fix PSR programming
parents dcb99fd9 5c673b60
...@@ -618,33 +618,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) ...@@ -618,33 +618,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
/* raw reads, only for fast reads of display block, no need for forcewake etc. */ /* raw reads, only for fast reads of display block, no need for forcewake etc. */
#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))
static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t status; uint32_t status;
int reg;
if (INTEL_INFO(dev)->gen < 7) {
status = pipe == PIPE_A ? if (INTEL_INFO(dev)->gen >= 8) {
DE_PIPEA_VBLANK : status = GEN8_PIPE_VBLANK;
DE_PIPEB_VBLANK; reg = GEN8_DE_PIPE_ISR(pipe);
} else if (INTEL_INFO(dev)->gen >= 7) {
status = DE_PIPE_VBLANK_IVB(pipe);
reg = DEISR;
} else { } else {
switch (pipe) { status = DE_PIPE_VBLANK(pipe);
default: reg = DEISR;
case PIPE_A:
status = DE_PIPEA_VBLANK_IVB;
break;
case PIPE_B:
status = DE_PIPEB_VBLANK_IVB;
break;
case PIPE_C:
status = DE_PIPEC_VBLANK_IVB;
break;
}
} }
return __raw_i915_read32(dev_priv, DEISR) & status; return __raw_i915_read32(dev_priv, reg) & status;
} }
static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
...@@ -702,7 +694,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, ...@@ -702,7 +694,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
else else
position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
if (HAS_PCH_SPLIT(dev)) { if (HAS_DDI(dev)) {
/*
* On HSW HDMI outputs there seems to be a 2 line
* difference, whereas eDP has the normal 1 line
* difference that earlier platforms have. External
* DP is unknown. For now just check for the 2 line
* difference case on all output types on HSW+.
*
* This might misinterpret the scanline counter being
* one line too far along on eDP, but that's less
* dangerous than the alternative since that would lead
* the vblank timestamp code astray when it sees a
* scanline count before vblank_start during a vblank
* interrupt.
*/
in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
if ((in_vbl && (position == vbl_start - 2 ||
position == vbl_start - 1)) ||
(!in_vbl && (position == vbl_end - 2 ||
position == vbl_end - 1)))
position = (position + 2) % vtotal;
} else if (HAS_PCH_SPLIT(dev)) {
/* /*
* The scanline counter increments at the leading edge * The scanline counter increments at the leading edge
* of hsync, ie. it completely misses the active portion * of hsync, ie. it completely misses the active portion
...@@ -2769,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev) ...@@ -2769,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev)
return; return;
if (HAS_PCH_IBX(dev)) { if (HAS_PCH_IBX(dev)) {
mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
SDE_TRANSA_FIFO_UNDER | SDE_POISON;
} else { } else {
mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
I915_WRITE(SERR_INT, I915_READ(SERR_INT)); I915_WRITE(SERR_INT, I915_READ(SERR_INT));
} }
...@@ -2832,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev) ...@@ -2832,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
DE_PLANEB_FLIP_DONE_IVB | DE_PLANEB_FLIP_DONE_IVB |
DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
DE_ERR_INT_IVB);
extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
DE_PIPEA_VBLANK_IVB); DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);
I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
} else { } else {
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
DE_AUX_CHANNEL_A | DE_AUX_CHANNEL_A |
DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
DE_POISON); DE_POISON);
extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT; extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
} }
dev_priv->irq_mask = ~display_mask; dev_priv->irq_mask = ~display_mask;
...@@ -2961,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) ...@@ -2961,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
GEN8_PIPE_CDCLK_CRC_DONE | GEN8_PIPE_CDCLK_CRC_DONE |
GEN8_PIPE_FIFO_UNDERRUN |
GEN8_DE_PIPE_IRQ_FAULT_ERRORS; GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK; uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
GEN8_PIPE_FIFO_UNDERRUN;
int pipe; int pipe;
dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
......
...@@ -1639,7 +1639,7 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) ...@@ -1639,7 +1639,7 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp)
val |= EDP_PSR_LINK_DISABLE; val |= EDP_PSR_LINK_DISABLE;
I915_WRITE(EDP_PSR_CTL(dev), val | I915_WRITE(EDP_PSR_CTL(dev), val |
IS_BROADWELL(dev) ? 0 : link_entry_time | (IS_BROADWELL(dev) ? 0 : link_entry_time) |
max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT |
idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT |
EDP_PSR_ENABLE); EDP_PSR_ENABLE);
......
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