diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 223 |
1 files changed, 122 insertions, 101 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d1dedc02f15..d554169ac592 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -62,7 +62,7 @@ static const u32 hpd_mask_i915[] = { | |||
62 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_EN | 62 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_EN |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static const u32 hpd_status_gen4[] = { | 65 | static const u32 hpd_status_g4x[] = { |
66 | [HPD_CRT] = CRT_HOTPLUG_INT_STATUS, | 66 | [HPD_CRT] = CRT_HOTPLUG_INT_STATUS, |
67 | [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X, | 67 | [HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X, |
68 | [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X, | 68 | [HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X, |
@@ -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; |
@@ -600,7 +599,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
600 | * Cook up a vblank counter by also checking the pixel | 599 | * Cook up a vblank counter by also checking the pixel |
601 | * counter against vblank start. | 600 | * counter against vblank start. |
602 | */ | 601 | */ |
603 | return ((high1 << 8) | low) + (pixel >= vbl_start); | 602 | return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff; |
604 | } | 603 | } |
605 | 604 | ||
606 | static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | 605 | static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) |
@@ -619,63 +618,30 @@ 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 intel_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 | int reg; | 626 | int reg; |
629 | 627 | ||
630 | if (IS_VALLEYVIEW(dev)) { | 628 | if (INTEL_INFO(dev)->gen >= 8) { |
631 | status = pipe == PIPE_A ? | 629 | status = GEN8_PIPE_VBLANK; |
632 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT : | 630 | reg = GEN8_DE_PIPE_ISR(pipe); |
633 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | 631 | } else if (INTEL_INFO(dev)->gen >= 7) { |
634 | 632 | status = DE_PIPE_VBLANK_IVB(pipe); | |
635 | reg = VLV_ISR; | ||
636 | } else if (IS_GEN2(dev)) { | ||
637 | status = pipe == PIPE_A ? | ||
638 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT : | ||
639 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | ||
640 | |||
641 | reg = ISR; | ||
642 | } else if (INTEL_INFO(dev)->gen < 5) { | ||
643 | status = pipe == PIPE_A ? | ||
644 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT : | ||
645 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; | ||
646 | |||
647 | reg = ISR; | ||
648 | } else if (INTEL_INFO(dev)->gen < 7) { | ||
649 | status = pipe == PIPE_A ? | ||
650 | DE_PIPEA_VBLANK : | ||
651 | DE_PIPEB_VBLANK; | ||
652 | |||
653 | reg = DEISR; | 633 | reg = DEISR; |
654 | } else { | 634 | } else { |
655 | switch (pipe) { | 635 | status = DE_PIPE_VBLANK(pipe); |
656 | default: | ||
657 | case PIPE_A: | ||
658 | status = DE_PIPEA_VBLANK_IVB; | ||
659 | break; | ||
660 | case PIPE_B: | ||
661 | status = DE_PIPEB_VBLANK_IVB; | ||
662 | break; | ||
663 | case PIPE_C: | ||
664 | status = DE_PIPEC_VBLANK_IVB; | ||
665 | break; | ||
666 | } | ||
667 | |||
668 | reg = DEISR; | 636 | reg = DEISR; |
669 | } | 637 | } |
670 | 638 | ||
671 | if (IS_GEN2(dev)) | 639 | return __raw_i915_read32(dev_priv, reg) & status; |
672 | return __raw_i915_read16(dev_priv, reg) & status; | ||
673 | else | ||
674 | return __raw_i915_read32(dev_priv, reg) & status; | ||
675 | } | 640 | } |
676 | 641 | ||
677 | 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, |
678 | int *vpos, int *hpos, ktime_t *stime, ktime_t *etime) | 643 | unsigned int flags, int *vpos, int *hpos, |
644 | ktime_t *stime, ktime_t *etime) | ||
679 | { | 645 | { |
680 | struct drm_i915_private *dev_priv = dev->dev_private; | 646 | struct drm_i915_private *dev_priv = dev->dev_private; |
681 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | 647 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
@@ -698,6 +664,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | |||
698 | vbl_start = mode->crtc_vblank_start; | 664 | vbl_start = mode->crtc_vblank_start; |
699 | vbl_end = mode->crtc_vblank_end; | 665 | vbl_end = mode->crtc_vblank_end; |
700 | 666 | ||
667 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { | ||
668 | vbl_start = DIV_ROUND_UP(vbl_start, 2); | ||
669 | vbl_end /= 2; | ||
670 | vtotal /= 2; | ||
671 | } | ||
672 | |||
701 | ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; | 673 | ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; |
702 | 674 | ||
703 | /* | 675 | /* |
@@ -722,17 +694,63 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | |||
722 | else | 694 | else |
723 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; | 695 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; |
724 | 696 | ||
725 | /* | 697 | if (HAS_DDI(dev)) { |
726 | * The scanline counter increments at the leading edge | 698 | /* |
727 | * of hsync, ie. it completely misses the active portion | 699 | * On HSW HDMI outputs there seems to be a 2 line |
728 | * of the line. Fix up the counter at both edges of vblank | 700 | * difference, whereas eDP has the normal 1 line |
729 | * to get a more accurate picture whether we're in vblank | 701 | * difference that earlier platforms have. External |
730 | * or not. | 702 | * DP is unknown. For now just check for the 2 line |
731 | */ | 703 | * difference case on all output types on HSW+. |
732 | in_vbl = intel_pipe_in_vblank_locked(dev, pipe); | 704 | * |
733 | if ((in_vbl && position == vbl_start - 1) || | 705 | * This might misinterpret the scanline counter being |
734 | (!in_vbl && position == vbl_end - 1)) | 706 | * one line too far along on eDP, but that's less |
735 | position = (position + 1) % vtotal; | 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)) { | ||
719 | /* | ||
720 | * The scanline counter increments at the leading edge | ||
721 | * of hsync, ie. it completely misses the active portion | ||
722 | * of the line. Fix up the counter at both edges of vblank | ||
723 | * to get a more accurate picture whether we're in vblank | ||
724 | * or not. | ||
725 | */ | ||
726 | in_vbl = ilk_pipe_in_vblank_locked(dev, pipe); | ||
727 | if ((in_vbl && position == vbl_start - 1) || | ||
728 | (!in_vbl && position == vbl_end - 1)) | ||
729 | position = (position + 1) % vtotal; | ||
730 | } else { | ||
731 | /* | ||
732 | * ISR vblank status bits don't work the way we'd want | ||
733 | * them to work on non-PCH platforms (for | ||
734 | * ilk_pipe_in_vblank_locked()), and there doesn't | ||
735 | * appear any other way to determine if we're currently | ||
736 | * in vblank. | ||
737 | * | ||
738 | * Instead let's assume that we're already in vblank if | ||
739 | * we got called from the vblank interrupt and the | ||
740 | * scanline counter value indicates that we're on the | ||
741 | * line just prior to vblank start. This should result | ||
742 | * in the correct answer, unless the vblank interrupt | ||
743 | * delivery really got delayed for almost exactly one | ||
744 | * full frame/field. | ||
745 | */ | ||
746 | if (flags & DRM_CALLED_FROM_VBLIRQ && | ||
747 | position == vbl_start - 1) { | ||
748 | position = (position + 1) % vtotal; | ||
749 | |||
750 | /* Signal this correction as "applied". */ | ||
751 | ret |= 0x8; | ||
752 | } | ||
753 | } | ||
736 | } else { | 754 | } else { |
737 | /* Have access to pixelcount since start of frame. | 755 | /* Have access to pixelcount since start of frame. |
738 | * We can split this into vertical and horizontal | 756 | * We can split this into vertical and horizontal |
@@ -809,7 +827,8 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, | |||
809 | /* Helper routine in DRM core does all the work: */ | 827 | /* Helper routine in DRM core does all the work: */ |
810 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, | 828 | return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, |
811 | vblank_time, flags, | 829 | vblank_time, flags, |
812 | crtc); | 830 | crtc, |
831 | &to_intel_crtc(crtc)->config.adjusted_mode); | ||
813 | } | 832 | } |
814 | 833 | ||
815 | static bool intel_hpd_irq_event(struct drm_device *dev, | 834 | static bool intel_hpd_irq_event(struct drm_device *dev, |
@@ -1015,10 +1034,8 @@ static void gen6_pm_rps_work(struct work_struct *work) | |||
1015 | /* sysfs frequency interfaces may have snuck in while servicing the | 1034 | /* sysfs frequency interfaces may have snuck in while servicing the |
1016 | * interrupt | 1035 | * interrupt |
1017 | */ | 1036 | */ |
1018 | if (new_delay < (int)dev_priv->rps.min_delay) | 1037 | new_delay = clamp_t(int, new_delay, |
1019 | new_delay = dev_priv->rps.min_delay; | 1038 | dev_priv->rps.min_delay, dev_priv->rps.max_delay); |
1020 | if (new_delay > (int)dev_priv->rps.max_delay) | ||
1021 | new_delay = dev_priv->rps.max_delay; | ||
1022 | dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_delay; | 1039 | dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_delay; |
1023 | 1040 | ||
1024 | if (IS_VALLEYVIEW(dev_priv->dev)) | 1041 | if (IS_VALLEYVIEW(dev_priv->dev)) |
@@ -1235,9 +1252,10 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, | |||
1235 | spin_lock(&dev_priv->irq_lock); | 1252 | spin_lock(&dev_priv->irq_lock); |
1236 | for (i = 1; i < HPD_NUM_PINS; i++) { | 1253 | for (i = 1; i < HPD_NUM_PINS; i++) { |
1237 | 1254 | ||
1238 | WARN(((hpd[i] & hotplug_trigger) && | 1255 | WARN_ONCE(hpd[i] & hotplug_trigger && |
1239 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED), | 1256 | dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED, |
1240 | "Received HPD interrupt although disabled\n"); | 1257 | "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", |
1258 | hotplug_trigger, i, hpd[i]); | ||
1241 | 1259 | ||
1242 | if (!(hpd[i] & hotplug_trigger) || | 1260 | if (!(hpd[i] & hotplug_trigger) || |
1243 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) | 1261 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) |
@@ -1474,6 +1492,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) | |||
1474 | 1492 | ||
1475 | intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); | 1493 | intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); |
1476 | 1494 | ||
1495 | if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X) | ||
1496 | dp_aux_irq_handler(dev); | ||
1497 | |||
1477 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); | 1498 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
1478 | I915_READ(PORT_HOTPLUG_STAT); | 1499 | I915_READ(PORT_HOTPLUG_STAT); |
1479 | } | 1500 | } |
@@ -1993,7 +2014,7 @@ static void i915_error_work_func(struct work_struct *work) | |||
1993 | kobject_uevent_env(&dev->primary->kdev->kobj, | 2014 | kobject_uevent_env(&dev->primary->kdev->kobj, |
1994 | KOBJ_CHANGE, reset_done_event); | 2015 | KOBJ_CHANGE, reset_done_event); |
1995 | } else { | 2016 | } else { |
1996 | atomic_set(&error->reset_counter, I915_WEDGED); | 2017 | atomic_set_mask(I915_WEDGED, &error->reset_counter); |
1997 | } | 2018 | } |
1998 | 2019 | ||
1999 | /* | 2020 | /* |
@@ -2713,6 +2734,8 @@ static void gen8_irq_preinstall(struct drm_device *dev) | |||
2713 | #undef GEN8_IRQ_INIT_NDX | 2734 | #undef GEN8_IRQ_INIT_NDX |
2714 | 2735 | ||
2715 | POSTING_READ(GEN8_PCU_IIR); | 2736 | POSTING_READ(GEN8_PCU_IIR); |
2737 | |||
2738 | ibx_irq_preinstall(dev); | ||
2716 | } | 2739 | } |
2717 | 2740 | ||
2718 | static void ibx_hpd_irq_setup(struct drm_device *dev) | 2741 | static void ibx_hpd_irq_setup(struct drm_device *dev) |
@@ -2759,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev) | |||
2759 | return; | 2782 | return; |
2760 | 2783 | ||
2761 | if (HAS_PCH_IBX(dev)) { | 2784 | if (HAS_PCH_IBX(dev)) { |
2762 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | | 2785 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; |
2763 | SDE_TRANSA_FIFO_UNDER | SDE_POISON; | ||
2764 | } else { | 2786 | } else { |
2765 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; | 2787 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; |
2766 | 2788 | ||
2767 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); | 2789 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); |
2768 | } | 2790 | } |
@@ -2822,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
2822 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | | 2844 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | |
2823 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | | 2845 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | |
2824 | DE_PLANEB_FLIP_DONE_IVB | | 2846 | DE_PLANEB_FLIP_DONE_IVB | |
2825 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | | 2847 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB); |
2826 | DE_ERR_INT_IVB); | ||
2827 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | | 2848 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | |
2828 | DE_PIPEA_VBLANK_IVB); | 2849 | DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB); |
2829 | 2850 | ||
2830 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); | 2851 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); |
2831 | } else { | 2852 | } else { |
2832 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 2853 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
2833 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | | 2854 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | |
2834 | DE_AUX_CHANNEL_A | | 2855 | DE_AUX_CHANNEL_A | |
2835 | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN | | ||
2836 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | | 2856 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | |
2837 | DE_POISON); | 2857 | DE_POISON); |
2838 | 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; | ||
2839 | } | 2860 | } |
2840 | 2861 | ||
2841 | dev_priv->irq_mask = ~display_mask; | 2862 | dev_priv->irq_mask = ~display_mask; |
@@ -2951,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) | |||
2951 | struct drm_device *dev = dev_priv->dev; | 2972 | struct drm_device *dev = dev_priv->dev; |
2952 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | | 2973 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | |
2953 | GEN8_PIPE_CDCLK_CRC_DONE | | 2974 | GEN8_PIPE_CDCLK_CRC_DONE | |
2954 | GEN8_PIPE_FIFO_UNDERRUN | | ||
2955 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | 2975 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
2956 | 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; | ||
2957 | int pipe; | 2978 | int pipe; |
2958 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; | 2979 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; |
2959 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; | 2980 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; |
@@ -3138,10 +3159,10 @@ static int i8xx_irq_postinstall(struct drm_device *dev) | |||
3138 | * Returns true when a page flip has completed. | 3159 | * Returns true when a page flip has completed. |
3139 | */ | 3160 | */ |
3140 | static bool i8xx_handle_vblank(struct drm_device *dev, | 3161 | static bool i8xx_handle_vblank(struct drm_device *dev, |
3141 | int pipe, u16 iir) | 3162 | int plane, int pipe, u32 iir) |
3142 | { | 3163 | { |
3143 | drm_i915_private_t *dev_priv = dev->dev_private; | 3164 | drm_i915_private_t *dev_priv = dev->dev_private; |
3144 | u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(pipe); | 3165 | u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane); |
3145 | 3166 | ||
3146 | if (!drm_handle_vblank(dev, pipe)) | 3167 | if (!drm_handle_vblank(dev, pipe)) |
3147 | return false; | 3168 | return false; |
@@ -3149,7 +3170,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev, | |||
3149 | if ((iir & flip_pending) == 0) | 3170 | if ((iir & flip_pending) == 0) |
3150 | return false; | 3171 | return false; |
3151 | 3172 | ||
3152 | intel_prepare_page_flip(dev, pipe); | 3173 | intel_prepare_page_flip(dev, plane); |
3153 | 3174 | ||
3154 | /* We detect FlipDone by looking for the change in PendingFlip from '1' | 3175 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
3155 | * to '0' on the following vblank, i.e. IIR has the Pendingflip | 3176 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
@@ -3218,9 +3239,13 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) | |||
3218 | notify_ring(dev, &dev_priv->ring[RCS]); | 3239 | notify_ring(dev, &dev_priv->ring[RCS]); |
3219 | 3240 | ||
3220 | for_each_pipe(pipe) { | 3241 | for_each_pipe(pipe) { |
3242 | int plane = pipe; | ||
3243 | if (HAS_FBC(dev)) | ||
3244 | plane = !plane; | ||
3245 | |||
3221 | if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS && | 3246 | if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS && |
3222 | i8xx_handle_vblank(dev, pipe, iir)) | 3247 | i8xx_handle_vblank(dev, plane, pipe, iir)) |
3223 | flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(pipe); | 3248 | flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane); |
3224 | 3249 | ||
3225 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) | 3250 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
3226 | i9xx_pipe_crc_irq_handler(dev, pipe); | 3251 | i9xx_pipe_crc_irq_handler(dev, pipe); |
@@ -3416,7 +3441,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) | |||
3416 | 3441 | ||
3417 | for_each_pipe(pipe) { | 3442 | for_each_pipe(pipe) { |
3418 | int plane = pipe; | 3443 | int plane = pipe; |
3419 | if (IS_MOBILE(dev)) | 3444 | if (HAS_FBC(dev)) |
3420 | plane = !plane; | 3445 | plane = !plane; |
3421 | 3446 | ||
3422 | if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS && | 3447 | if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS && |
@@ -3653,7 +3678,11 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) | |||
3653 | hotplug_status); | 3678 | hotplug_status); |
3654 | 3679 | ||
3655 | intel_hpd_irq_handler(dev, hotplug_trigger, | 3680 | intel_hpd_irq_handler(dev, hotplug_trigger, |
3656 | IS_G4X(dev) ? hpd_status_gen4 : hpd_status_i915); | 3681 | IS_G4X(dev) ? hpd_status_g4x : hpd_status_i915); |
3682 | |||
3683 | if (IS_G4X(dev) && | ||
3684 | (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X)) | ||
3685 | dp_aux_irq_handler(dev); | ||
3657 | 3686 | ||
3658 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); | 3687 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
3659 | I915_READ(PORT_HOTPLUG_STAT); | 3688 | I915_READ(PORT_HOTPLUG_STAT); |
@@ -3891,8 +3920,8 @@ void hsw_pc8_disable_interrupts(struct drm_device *dev) | |||
3891 | dev_priv->pc8.regsave.gtier = I915_READ(GTIER); | 3920 | dev_priv->pc8.regsave.gtier = I915_READ(GTIER); |
3892 | dev_priv->pc8.regsave.gen6_pmimr = I915_READ(GEN6_PMIMR); | 3921 | dev_priv->pc8.regsave.gen6_pmimr = I915_READ(GEN6_PMIMR); |
3893 | 3922 | ||
3894 | ironlake_disable_display_irq(dev_priv, ~DE_PCH_EVENT_IVB); | 3923 | ironlake_disable_display_irq(dev_priv, 0xffffffff); |
3895 | ibx_disable_display_interrupt(dev_priv, ~SDE_HOTPLUG_MASK_CPT); | 3924 | ibx_disable_display_interrupt(dev_priv, 0xffffffff); |
3896 | ilk_disable_gt_irq(dev_priv, 0xffffffff); | 3925 | ilk_disable_gt_irq(dev_priv, 0xffffffff); |
3897 | snb_disable_pm_irq(dev_priv, 0xffffffff); | 3926 | snb_disable_pm_irq(dev_priv, 0xffffffff); |
3898 | 3927 | ||
@@ -3906,34 +3935,26 @@ void hsw_pc8_restore_interrupts(struct drm_device *dev) | |||
3906 | { | 3935 | { |
3907 | struct drm_i915_private *dev_priv = dev->dev_private; | 3936 | struct drm_i915_private *dev_priv = dev->dev_private; |
3908 | unsigned long irqflags; | 3937 | unsigned long irqflags; |
3909 | uint32_t val, expected; | 3938 | uint32_t val; |
3910 | 3939 | ||
3911 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3940 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3912 | 3941 | ||
3913 | val = I915_READ(DEIMR); | 3942 | val = I915_READ(DEIMR); |
3914 | expected = ~DE_PCH_EVENT_IVB; | 3943 | WARN(val != 0xffffffff, "DEIMR is 0x%08x\n", val); |
3915 | WARN(val != expected, "DEIMR is 0x%08x, not 0x%08x\n", val, expected); | ||
3916 | 3944 | ||
3917 | val = I915_READ(SDEIMR) & ~SDE_HOTPLUG_MASK_CPT; | 3945 | val = I915_READ(SDEIMR); |
3918 | expected = ~SDE_HOTPLUG_MASK_CPT; | 3946 | WARN(val != 0xffffffff, "SDEIMR is 0x%08x\n", val); |
3919 | WARN(val != expected, "SDEIMR non-HPD bits are 0x%08x, not 0x%08x\n", | ||
3920 | val, expected); | ||
3921 | 3947 | ||
3922 | val = I915_READ(GTIMR); | 3948 | val = I915_READ(GTIMR); |
3923 | expected = 0xffffffff; | 3949 | WARN(val != 0xffffffff, "GTIMR is 0x%08x\n", val); |
3924 | WARN(val != expected, "GTIMR is 0x%08x, not 0x%08x\n", val, expected); | ||
3925 | 3950 | ||
3926 | val = I915_READ(GEN6_PMIMR); | 3951 | val = I915_READ(GEN6_PMIMR); |
3927 | expected = 0xffffffff; | 3952 | WARN(val != 0xffffffff, "GEN6_PMIMR is 0x%08x\n", val); |
3928 | WARN(val != expected, "GEN6_PMIMR is 0x%08x, not 0x%08x\n", val, | ||
3929 | expected); | ||
3930 | 3953 | ||
3931 | dev_priv->pc8.irqs_disabled = false; | 3954 | dev_priv->pc8.irqs_disabled = false; |
3932 | 3955 | ||
3933 | ironlake_enable_display_irq(dev_priv, ~dev_priv->pc8.regsave.deimr); | 3956 | ironlake_enable_display_irq(dev_priv, ~dev_priv->pc8.regsave.deimr); |
3934 | ibx_enable_display_interrupt(dev_priv, | 3957 | ibx_enable_display_interrupt(dev_priv, ~dev_priv->pc8.regsave.sdeimr); |
3935 | ~dev_priv->pc8.regsave.sdeimr & | ||
3936 | ~SDE_HOTPLUG_MASK_CPT); | ||
3937 | ilk_enable_gt_irq(dev_priv, ~dev_priv->pc8.regsave.gtimr); | 3958 | ilk_enable_gt_irq(dev_priv, ~dev_priv->pc8.regsave.gtimr); |
3938 | snb_enable_pm_irq(dev_priv, ~dev_priv->pc8.regsave.gen6_pmimr); | 3959 | snb_enable_pm_irq(dev_priv, ~dev_priv->pc8.regsave.gen6_pmimr); |
3939 | I915_WRITE(GTIER, dev_priv->pc8.regsave.gtier); | 3960 | I915_WRITE(GTIER, dev_priv->pc8.regsave.gtier); |