aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c149
1 files changed, 66 insertions, 83 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 15d6269027e7..da3edf891c21 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -85,21 +85,11 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
85 } 85 }
86} 86}
87 87
88static inline u32
89i915_pipestat(int pipe)
90{
91 if (pipe == 0)
92 return PIPEASTAT;
93 if (pipe == 1)
94 return PIPEBSTAT;
95 BUG();
96}
97
98void 88void
99i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) 89i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
100{ 90{
101 if ((dev_priv->pipestat[pipe] & mask) != mask) { 91 if ((dev_priv->pipestat[pipe] & mask) != mask) {
102 u32 reg = i915_pipestat(pipe); 92 u32 reg = PIPESTAT(pipe);
103 93
104 dev_priv->pipestat[pipe] |= mask; 94 dev_priv->pipestat[pipe] |= mask;
105 /* Enable the interrupt, clear any pending status */ 95 /* Enable the interrupt, clear any pending status */
@@ -112,7 +102,7 @@ void
112i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) 102i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
113{ 103{
114 if ((dev_priv->pipestat[pipe] & mask) != 0) { 104 if ((dev_priv->pipestat[pipe] & mask) != 0) {
115 u32 reg = i915_pipestat(pipe); 105 u32 reg = PIPESTAT(pipe);
116 106
117 dev_priv->pipestat[pipe] &= ~mask; 107 dev_priv->pipestat[pipe] &= ~mask;
118 I915_WRITE(reg, dev_priv->pipestat[pipe]); 108 I915_WRITE(reg, dev_priv->pipestat[pipe]);
@@ -171,12 +161,12 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
171 161
172 if (!i915_pipe_enabled(dev, pipe)) { 162 if (!i915_pipe_enabled(dev, pipe)) {
173 DRM_DEBUG_DRIVER("trying to get vblank count for disabled " 163 DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
174 "pipe %d\n", pipe); 164 "pipe %c\n", pipe_name(pipe));
175 return 0; 165 return 0;
176 } 166 }
177 167
178 high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; 168 high_frame = PIPEFRAME(pipe);
179 low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; 169 low_frame = PIPEFRAMEPIXEL(pipe);
180 170
181 /* 171 /*
182 * High & low register fields aren't synchronized, so make sure 172 * High & low register fields aren't synchronized, so make sure
@@ -197,11 +187,11 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
197u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) 187u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
198{ 188{
199 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 189 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
200 int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; 190 int reg = PIPE_FRMCOUNT_GM45(pipe);
201 191
202 if (!i915_pipe_enabled(dev, pipe)) { 192 if (!i915_pipe_enabled(dev, pipe)) {
203 DRM_DEBUG_DRIVER("trying to get vblank count for disabled " 193 DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
204 "pipe %d\n", pipe); 194 "pipe %c\n", pipe_name(pipe));
205 return 0; 195 return 0;
206 } 196 }
207 197
@@ -219,7 +209,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
219 209
220 if (!i915_pipe_enabled(dev, pipe)) { 210 if (!i915_pipe_enabled(dev, pipe)) {
221 DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " 211 DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
222 "pipe %d\n", pipe); 212 "pipe %c\n", pipe_name(pipe));
223 return 0; 213 return 0;
224 } 214 }
225 215
@@ -417,6 +407,7 @@ static void pch_irq_handler(struct drm_device *dev)
417{ 407{
418 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 408 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
419 u32 pch_iir; 409 u32 pch_iir;
410 int pipe;
420 411
421 pch_iir = I915_READ(SDEIIR); 412 pch_iir = I915_READ(SDEIIR);
422 413
@@ -437,13 +428,11 @@ static void pch_irq_handler(struct drm_device *dev)
437 if (pch_iir & SDE_POISON) 428 if (pch_iir & SDE_POISON)
438 DRM_ERROR("PCH poison interrupt\n"); 429 DRM_ERROR("PCH poison interrupt\n");
439 430
440 if (pch_iir & SDE_FDI_MASK) { 431 if (pch_iir & SDE_FDI_MASK)
441 u32 fdia, fdib; 432 for_each_pipe(pipe)
442 433 DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n",
443 fdia = I915_READ(FDI_RXA_IIR); 434 pipe_name(pipe),
444 fdib = I915_READ(FDI_RXB_IIR); 435 I915_READ(FDI_RX_IIR(pipe)));
445 DRM_DEBUG_DRIVER("PCH FDI RX interrupt; FDI RXA IIR: 0x%08x, FDI RXB IIR: 0x%08x\n", fdia, fdib);
446 }
447 436
448 if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) 437 if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE))
449 DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n"); 438 DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n");
@@ -770,7 +759,7 @@ static void i915_capture_error_state(struct drm_device *dev)
770 struct drm_i915_gem_object *obj; 759 struct drm_i915_gem_object *obj;
771 struct drm_i915_error_state *error; 760 struct drm_i915_error_state *error;
772 unsigned long flags; 761 unsigned long flags;
773 int i; 762 int i, pipe;
774 763
775 spin_lock_irqsave(&dev_priv->error_lock, flags); 764 spin_lock_irqsave(&dev_priv->error_lock, flags);
776 error = dev_priv->first_error; 765 error = dev_priv->first_error;
@@ -778,6 +767,7 @@ static void i915_capture_error_state(struct drm_device *dev)
778 if (error) 767 if (error)
779 return; 768 return;
780 769
770 /* Account for pipe specific data like PIPE*STAT */
781 error = kmalloc(sizeof(*error), GFP_ATOMIC); 771 error = kmalloc(sizeof(*error), GFP_ATOMIC);
782 if (!error) { 772 if (!error) {
783 DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); 773 DRM_DEBUG_DRIVER("out of memory, not capturing error state\n");
@@ -790,8 +780,8 @@ static void i915_capture_error_state(struct drm_device *dev)
790 error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]); 780 error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]);
791 error->eir = I915_READ(EIR); 781 error->eir = I915_READ(EIR);
792 error->pgtbl_er = I915_READ(PGTBL_ER); 782 error->pgtbl_er = I915_READ(PGTBL_ER);
793 error->pipeastat = I915_READ(PIPEASTAT); 783 for_each_pipe(pipe)
794 error->pipebstat = I915_READ(PIPEBSTAT); 784 error->pipestat[pipe] = I915_READ(PIPESTAT(pipe));
795 error->instpm = I915_READ(INSTPM); 785 error->instpm = I915_READ(INSTPM);
796 error->error = 0; 786 error->error = 0;
797 if (INTEL_INFO(dev)->gen >= 6) { 787 if (INTEL_INFO(dev)->gen >= 6) {
@@ -912,6 +902,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
912{ 902{
913 struct drm_i915_private *dev_priv = dev->dev_private; 903 struct drm_i915_private *dev_priv = dev->dev_private;
914 u32 eir = I915_READ(EIR); 904 u32 eir = I915_READ(EIR);
905 int pipe;
915 906
916 if (!eir) 907 if (!eir)
917 return; 908 return;
@@ -960,14 +951,10 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
960 } 951 }
961 952
962 if (eir & I915_ERROR_MEMORY_REFRESH) { 953 if (eir & I915_ERROR_MEMORY_REFRESH) {
963 u32 pipea_stats = I915_READ(PIPEASTAT); 954 printk(KERN_ERR "memory refresh error:\n");
964 u32 pipeb_stats = I915_READ(PIPEBSTAT); 955 for_each_pipe(pipe)
965 956 printk(KERN_ERR "pipe %c stat: 0x%08x\n",
966 printk(KERN_ERR "memory refresh error\n"); 957 pipe_name(pipe), I915_READ(PIPESTAT(pipe)));
967 printk(KERN_ERR "PIPEASTAT: 0x%08x\n",
968 pipea_stats);
969 printk(KERN_ERR "PIPEBSTAT: 0x%08x\n",
970 pipeb_stats);
971 /* pipestat has already been acked */ 958 /* pipestat has already been acked */
972 } 959 }
973 if (eir & I915_ERROR_INSTRUCTION) { 960 if (eir & I915_ERROR_INSTRUCTION) {
@@ -1081,10 +1068,10 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
1081 /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ 1068 /* Potential stall - if we see that the flip has happened, assume a missed interrupt */
1082 obj = work->pending_flip_obj; 1069 obj = work->pending_flip_obj;
1083 if (INTEL_INFO(dev)->gen >= 4) { 1070 if (INTEL_INFO(dev)->gen >= 4) {
1084 int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; 1071 int dspsurf = DSPSURF(intel_crtc->plane);
1085 stall_detected = I915_READ(dspsurf) == obj->gtt_offset; 1072 stall_detected = I915_READ(dspsurf) == obj->gtt_offset;
1086 } else { 1073 } else {
1087 int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; 1074 int dspaddr = DSPADDR(intel_crtc->plane);
1088 stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + 1075 stall_detected = I915_READ(dspaddr) == (obj->gtt_offset +
1089 crtc->y * crtc->fb->pitch + 1076 crtc->y * crtc->fb->pitch +
1090 crtc->x * crtc->fb->bits_per_pixel/8); 1077 crtc->x * crtc->fb->bits_per_pixel/8);
@@ -1104,12 +1091,13 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1104 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 1091 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1105 struct drm_i915_master_private *master_priv; 1092 struct drm_i915_master_private *master_priv;
1106 u32 iir, new_iir; 1093 u32 iir, new_iir;
1107 u32 pipea_stats, pipeb_stats; 1094 u32 pipe_stats[I915_MAX_PIPES];
1108 u32 vblank_status; 1095 u32 vblank_status;
1109 int vblank = 0; 1096 int vblank = 0;
1110 unsigned long irqflags; 1097 unsigned long irqflags;
1111 int irq_received; 1098 int irq_received;
1112 int ret = IRQ_NONE; 1099 int ret = IRQ_NONE, pipe;
1100 bool blc_event = false;
1113 1101
1114 atomic_inc(&dev_priv->irq_received); 1102 atomic_inc(&dev_priv->irq_received);
1115 1103
@@ -1132,27 +1120,23 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1132 * interrupts (for non-MSI). 1120 * interrupts (for non-MSI).
1133 */ 1121 */
1134 spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 1122 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
1135 pipea_stats = I915_READ(PIPEASTAT);
1136 pipeb_stats = I915_READ(PIPEBSTAT);
1137
1138 if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) 1123 if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
1139 i915_handle_error(dev, false); 1124 i915_handle_error(dev, false);
1140 1125
1141 /* 1126 for_each_pipe(pipe) {
1142 * Clear the PIPE(A|B)STAT regs before the IIR 1127 int reg = PIPESTAT(pipe);
1143 */ 1128 pipe_stats[pipe] = I915_READ(reg);
1144 if (pipea_stats & 0x8000ffff) { 1129
1145 if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS) 1130 /*
1146 DRM_DEBUG_DRIVER("pipe a underrun\n"); 1131 * Clear the PIPE*STAT regs before the IIR
1147 I915_WRITE(PIPEASTAT, pipea_stats); 1132 */
1148 irq_received = 1; 1133 if (pipe_stats[pipe] & 0x8000ffff) {
1149 } 1134 if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
1150 1135 DRM_DEBUG_DRIVER("pipe %c underrun\n",
1151 if (pipeb_stats & 0x8000ffff) { 1136 pipe_name(pipe));
1152 if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS) 1137 I915_WRITE(reg, pipe_stats[pipe]);
1153 DRM_DEBUG_DRIVER("pipe b underrun\n"); 1138 irq_received = 1;
1154 I915_WRITE(PIPEBSTAT, pipeb_stats); 1139 }
1155 irq_received = 1;
1156 } 1140 }
1157 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 1141 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
1158 1142
@@ -1203,27 +1187,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1203 intel_finish_page_flip_plane(dev, 1); 1187 intel_finish_page_flip_plane(dev, 1);
1204 } 1188 }
1205 1189
1206 if (pipea_stats & vblank_status && 1190 for_each_pipe(pipe) {
1207 drm_handle_vblank(dev, 0)) { 1191 if (pipe_stats[pipe] & vblank_status &&
1208 vblank++; 1192 drm_handle_vblank(dev, pipe)) {
1209 if (!dev_priv->flip_pending_is_done) { 1193 vblank++;
1210 i915_pageflip_stall_check(dev, 0); 1194 if (!dev_priv->flip_pending_is_done) {
1211 intel_finish_page_flip(dev, 0); 1195 i915_pageflip_stall_check(dev, pipe);
1196 intel_finish_page_flip(dev, pipe);
1197 }
1212 } 1198 }
1213 }
1214 1199
1215 if (pipeb_stats & vblank_status && 1200 if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
1216 drm_handle_vblank(dev, 1)) { 1201 blc_event = true;
1217 vblank++;
1218 if (!dev_priv->flip_pending_is_done) {
1219 i915_pageflip_stall_check(dev, 1);
1220 intel_finish_page_flip(dev, 1);
1221 }
1222 } 1202 }
1223 1203
1224 if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || 1204
1225 (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || 1205 if (blc_event || (iir & I915_ASLE_INTERRUPT))
1226 (iir & I915_ASLE_INTERRUPT))
1227 intel_opregion_asle_intr(dev); 1206 intel_opregion_asle_intr(dev);
1228 1207
1229 /* With MSI, interrupts are only generated when iir 1208 /* With MSI, interrupts are only generated when iir
@@ -1634,6 +1613,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1634 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; 1613 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
1635 u32 render_irqs; 1614 u32 render_irqs;
1636 u32 hotplug_mask; 1615 u32 hotplug_mask;
1616 int pipe;
1637 1617
1638 dev_priv->irq_mask = ~display_mask; 1618 dev_priv->irq_mask = ~display_mask;
1639 1619
@@ -1668,8 +1648,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1668 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | 1648 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
1669 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; 1649 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
1670 hotplug_mask |= SDE_AUX_MASK | SDE_FDI_MASK | SDE_TRANS_MASK; 1650 hotplug_mask |= SDE_AUX_MASK | SDE_FDI_MASK | SDE_TRANS_MASK;
1671 I915_WRITE(FDI_RXA_IMR, 0); 1651 for_each_pipe(pipe)
1672 I915_WRITE(FDI_RXB_IMR, 0); 1652 I915_WRITE(FDI_RX_IMR(pipe), 0);
1673 } 1653 }
1674 1654
1675 dev_priv->pch_irq_mask = ~hotplug_mask; 1655 dev_priv->pch_irq_mask = ~hotplug_mask;
@@ -1692,6 +1672,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1692void i915_driver_irq_preinstall(struct drm_device * dev) 1672void i915_driver_irq_preinstall(struct drm_device * dev)
1693{ 1673{
1694 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 1674 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1675 int pipe;
1695 1676
1696 atomic_set(&dev_priv->irq_received, 0); 1677 atomic_set(&dev_priv->irq_received, 0);
1697 atomic_set(&dev_priv->vblank_enabled, 0); 1678 atomic_set(&dev_priv->vblank_enabled, 0);
@@ -1711,8 +1692,8 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1711 } 1692 }
1712 1693
1713 I915_WRITE(HWSTAM, 0xeffe); 1694 I915_WRITE(HWSTAM, 0xeffe);
1714 I915_WRITE(PIPEASTAT, 0); 1695 for_each_pipe(pipe)
1715 I915_WRITE(PIPEBSTAT, 0); 1696 I915_WRITE(PIPESTAT(pipe), 0);
1716 I915_WRITE(IMR, 0xffffffff); 1697 I915_WRITE(IMR, 0xffffffff);
1717 I915_WRITE(IER, 0x0); 1698 I915_WRITE(IER, 0x0);
1718 POSTING_READ(IER); 1699 POSTING_READ(IER);
@@ -1824,6 +1805,7 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
1824void i915_driver_irq_uninstall(struct drm_device * dev) 1805void i915_driver_irq_uninstall(struct drm_device * dev)
1825{ 1806{
1826 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 1807 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1808 int pipe;
1827 1809
1828 if (!dev_priv) 1810 if (!dev_priv)
1829 return; 1811 return;
@@ -1841,12 +1823,13 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
1841 } 1823 }
1842 1824
1843 I915_WRITE(HWSTAM, 0xffffffff); 1825 I915_WRITE(HWSTAM, 0xffffffff);
1844 I915_WRITE(PIPEASTAT, 0); 1826 for_each_pipe(pipe)
1845 I915_WRITE(PIPEBSTAT, 0); 1827 I915_WRITE(PIPESTAT(pipe), 0);
1846 I915_WRITE(IMR, 0xffffffff); 1828 I915_WRITE(IMR, 0xffffffff);
1847 I915_WRITE(IER, 0x0); 1829 I915_WRITE(IER, 0x0);
1848 1830
1849 I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); 1831 for_each_pipe(pipe)
1850 I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); 1832 I915_WRITE(PIPESTAT(pipe),
1833 I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
1851 I915_WRITE(IIR, I915_READ(IIR)); 1834 I915_WRITE(IIR, I915_READ(IIR));
1852} 1835}