|
@@ -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. */
|
|
|
#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)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
uint32_t status;
|
|
|
-
|
|
|
- if (INTEL_INFO(dev)->gen < 7) {
|
|
|
- status = pipe == PIPE_A ?
|
|
|
- DE_PIPEA_VBLANK :
|
|
|
- DE_PIPEB_VBLANK;
|
|
|
+ int reg;
|
|
|
+
|
|
|
+ if (INTEL_INFO(dev)->gen >= 8) {
|
|
|
+ status = GEN8_PIPE_VBLANK;
|
|
|
+ reg = GEN8_DE_PIPE_ISR(pipe);
|
|
|
+ } else if (INTEL_INFO(dev)->gen >= 7) {
|
|
|
+ status = DE_PIPE_VBLANK_IVB(pipe);
|
|
|
+ reg = DEISR;
|
|
|
} else {
|
|
|
- switch (pipe) {
|
|
|
- default:
|
|
|
- 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;
|
|
|
- }
|
|
|
+ status = DE_PIPE_VBLANK(pipe);
|
|
|
+ reg = DEISR;
|
|
|
}
|
|
|
|
|
|
- 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,
|
|
@@ -702,7 +694,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
|
|
|
else
|
|
|
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
|
|
|
* of hsync, ie. it completely misses the active portion
|
|
@@ -2769,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev)
|
|
|
return;
|
|
|
|
|
|
if (HAS_PCH_IBX(dev)) {
|
|
|
- mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER |
|
|
|
- SDE_TRANSA_FIFO_UNDER | SDE_POISON;
|
|
|
+ mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
|
|
|
} 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));
|
|
|
}
|
|
@@ -2832,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
|
|
|
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
|
|
|
DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
|
|
|
DE_PLANEB_FLIP_DONE_IVB |
|
|
|
- DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB |
|
|
|
- DE_ERR_INT_IVB);
|
|
|
+ DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_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));
|
|
|
} else {
|
|
|
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
|
|
|
DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
|
|
|
DE_AUX_CHANNEL_A |
|
|
|
- DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
|
|
|
DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
|
|
|
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;
|
|
@@ -2961,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
|
|
|
struct drm_device *dev = dev_priv->dev;
|
|
|
uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
|
|
|
GEN8_PIPE_CDCLK_CRC_DONE |
|
|
|
- GEN8_PIPE_FIFO_UNDERRUN |
|
|
|
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;
|
|
|
dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
|
|
|
dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
|