diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 17d8fcb1b6f7..d554169ac592 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -567,8 +567,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
567 | 567 | ||
568 | vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; | 568 | vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; |
569 | } else { | 569 | } else { |
570 | enum transcoder cpu_transcoder = | 570 | enum transcoder cpu_transcoder = (enum transcoder) pipe; |
571 | intel_pipe_to_cpu_transcoder(dev_priv, pipe); | ||
572 | u32 htotal; | 571 | u32 htotal; |
573 | 572 | ||
574 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; | 573 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; |
@@ -619,33 +618,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | |||
619 | 618 | ||
620 | /* raw reads, only for fast reads of display block, no need for forcewake etc. */ | 619 | /* raw reads, only for fast reads of display block, no need for forcewake etc. */ |
621 | #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) | 620 | #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) |
622 | #define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__)) | ||
623 | 621 | ||
624 | static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) | 622 | static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) |
625 | { | 623 | { |
626 | struct drm_i915_private *dev_priv = dev->dev_private; | 624 | struct drm_i915_private *dev_priv = dev->dev_private; |
627 | uint32_t status; | 625 | uint32_t status; |
628 | 626 | int reg; | |
629 | if (INTEL_INFO(dev)->gen < 7) { | 627 | |
630 | status = pipe == PIPE_A ? | 628 | if (INTEL_INFO(dev)->gen >= 8) { |
631 | DE_PIPEA_VBLANK : | 629 | status = GEN8_PIPE_VBLANK; |
632 | DE_PIPEB_VBLANK; | 630 | reg = GEN8_DE_PIPE_ISR(pipe); |
631 | } else if (INTEL_INFO(dev)->gen >= 7) { | ||
632 | status = DE_PIPE_VBLANK_IVB(pipe); | ||
633 | reg = DEISR; | ||
633 | } else { | 634 | } else { |
634 | switch (pipe) { | 635 | status = DE_PIPE_VBLANK(pipe); |
635 | default: | 636 | reg = DEISR; |
636 | case PIPE_A: | ||
637 | status = DE_PIPEA_VBLANK_IVB; | ||
638 | break; | ||
639 | case PIPE_B: | ||
640 | status = DE_PIPEB_VBLANK_IVB; | ||
641 | break; | ||
642 | case PIPE_C: | ||
643 | status = DE_PIPEC_VBLANK_IVB; | ||
644 | break; | ||
645 | } | ||
646 | } | 637 | } |
647 | 638 | ||
648 | return __raw_i915_read32(dev_priv, DEISR) & status; | 639 | return __raw_i915_read32(dev_priv, reg) & status; |
649 | } | 640 | } |
650 | 641 | ||
651 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | 642 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, |
@@ -703,7 +694,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | |||
703 | else | 694 | else |
704 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; | 695 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; |
705 | 696 | ||
706 | if (HAS_PCH_SPLIT(dev)) { | 697 | if (HAS_DDI(dev)) { |
698 | /* | ||
699 | * On HSW HDMI outputs there seems to be a 2 line | ||
700 | * difference, whereas eDP has the normal 1 line | ||
701 | * difference that earlier platforms have. External | ||
702 | * DP is unknown. For now just check for the 2 line | ||
703 | * difference case on all output types on HSW+. | ||
704 | * | ||
705 | * This might misinterpret the scanline counter being | ||
706 | * one line too far along on eDP, but that's less | ||
707 | * dangerous than the alternative since that would lead | ||
708 | * the vblank timestamp code astray when it sees a | ||
709 | * scanline count before vblank_start during a vblank | ||
710 | * interrupt. | ||
711 | */ | ||
712 | in_vbl = ilk_pipe_in_vblank_locked(dev, pipe); | ||
713 | if ((in_vbl && (position == vbl_start - 2 || | ||
714 | position == vbl_start - 1)) || | ||
715 | (!in_vbl && (position == vbl_end - 2 || | ||
716 | position == vbl_end - 1))) | ||
717 | position = (position + 2) % vtotal; | ||
718 | } else if (HAS_PCH_SPLIT(dev)) { | ||
707 | /* | 719 | /* |
708 | * The scanline counter increments at the leading edge | 720 | * The scanline counter increments at the leading edge |
709 | * of hsync, ie. it completely misses the active portion | 721 | * of hsync, ie. it completely misses the active portion |
@@ -2770,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev) | |||
2770 | return; | 2782 | return; |
2771 | 2783 | ||
2772 | if (HAS_PCH_IBX(dev)) { | 2784 | if (HAS_PCH_IBX(dev)) { |
2773 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | | 2785 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; |
2774 | SDE_TRANSA_FIFO_UNDER | SDE_POISON; | ||
2775 | } else { | 2786 | } else { |
2776 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; | 2787 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; |
2777 | 2788 | ||
2778 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); | 2789 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); |
2779 | } | 2790 | } |
@@ -2833,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
2833 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | | 2844 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | |
2834 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | | 2845 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | |
2835 | DE_PLANEB_FLIP_DONE_IVB | | 2846 | DE_PLANEB_FLIP_DONE_IVB | |
2836 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | | 2847 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB); |
2837 | DE_ERR_INT_IVB); | ||
2838 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | | 2848 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | |
2839 | DE_PIPEA_VBLANK_IVB); | 2849 | DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB); |
2840 | 2850 | ||
2841 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); | 2851 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); |
2842 | } else { | 2852 | } else { |
2843 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 2853 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
2844 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | | 2854 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | |
2845 | DE_AUX_CHANNEL_A | | 2855 | DE_AUX_CHANNEL_A | |
2846 | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN | | ||
2847 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | | 2856 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | |
2848 | DE_POISON); | 2857 | DE_POISON); |
2849 | extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT; | 2858 | extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT | |
2859 | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN; | ||
2850 | } | 2860 | } |
2851 | 2861 | ||
2852 | dev_priv->irq_mask = ~display_mask; | 2862 | dev_priv->irq_mask = ~display_mask; |
@@ -2962,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) | |||
2962 | struct drm_device *dev = dev_priv->dev; | 2972 | struct drm_device *dev = dev_priv->dev; |
2963 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | | 2973 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | |
2964 | GEN8_PIPE_CDCLK_CRC_DONE | | 2974 | GEN8_PIPE_CDCLK_CRC_DONE | |
2965 | GEN8_PIPE_FIFO_UNDERRUN | | ||
2966 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | 2975 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
2967 | uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK; | 2976 | uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | |
2977 | GEN8_PIPE_FIFO_UNDERRUN; | ||
2968 | int pipe; | 2978 | int pipe; |
2969 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; | 2979 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; |
2970 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; | 2980 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; |