Rev 4560 | Rev 5354 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4560 | Rev 5060 | ||
---|---|---|---|
Line 78... | Line 78... | ||
78 | [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS, |
78 | [HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS, |
79 | [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS, |
79 | [HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS, |
80 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS |
80 | [HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS |
81 | }; |
81 | }; |
Line -... | Line 82... | ||
- | 82 | ||
- | 83 | /* IIR can theoretically queue up two events. Be paranoid. */ |
|
- | 84 | #define GEN8_IRQ_RESET_NDX(type, which) do { \ |
|
- | 85 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ |
|
- | 86 | POSTING_READ(GEN8_##type##_IMR(which)); \ |
|
- | 87 | I915_WRITE(GEN8_##type##_IER(which), 0); \ |
|
- | 88 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ |
|
- | 89 | POSTING_READ(GEN8_##type##_IIR(which)); \ |
|
- | 90 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ |
|
- | 91 | POSTING_READ(GEN8_##type##_IIR(which)); \ |
|
- | 92 | } while (0) |
|
- | 93 | ||
- | 94 | #define GEN5_IRQ_RESET(type) do { \ |
|
- | 95 | I915_WRITE(type##IMR, 0xffffffff); \ |
|
- | 96 | POSTING_READ(type##IMR); \ |
|
- | 97 | I915_WRITE(type##IER, 0); \ |
|
- | 98 | I915_WRITE(type##IIR, 0xffffffff); \ |
|
- | 99 | POSTING_READ(type##IIR); \ |
|
- | 100 | I915_WRITE(type##IIR, 0xffffffff); \ |
|
- | 101 | POSTING_READ(type##IIR); \ |
|
- | 102 | } while (0) |
|
- | 103 | ||
- | 104 | /* |
|
- | 105 | * We should clear IMR at preinstall/uninstall, and just check at postinstall. |
|
- | 106 | */ |
|
- | 107 | #define GEN5_ASSERT_IIR_IS_ZERO(reg) do { \ |
|
- | 108 | u32 val = I915_READ(reg); \ |
|
- | 109 | if (val) { \ |
|
- | 110 | WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", \ |
|
- | 111 | (reg), val); \ |
|
- | 112 | I915_WRITE((reg), 0xffffffff); \ |
|
- | 113 | POSTING_READ(reg); \ |
|
- | 114 | I915_WRITE((reg), 0xffffffff); \ |
|
- | 115 | POSTING_READ(reg); \ |
|
- | 116 | } \ |
|
- | 117 | } while (0) |
|
- | 118 | ||
- | 119 | #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \ |
|
- | 120 | GEN5_ASSERT_IIR_IS_ZERO(GEN8_##type##_IIR(which)); \ |
|
- | 121 | I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \ |
|
- | 122 | I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \ |
|
- | 123 | POSTING_READ(GEN8_##type##_IER(which)); \ |
|
- | 124 | } while (0) |
|
- | 125 | ||
- | 126 | #define GEN5_IRQ_INIT(type, imr_val, ier_val) do { \ |
|
- | 127 | GEN5_ASSERT_IIR_IS_ZERO(type##IIR); \ |
|
- | 128 | I915_WRITE(type##IMR, (imr_val)); \ |
|
- | 129 | I915_WRITE(type##IER, (ier_val)); \ |
|
- | 130 | POSTING_READ(type##IER); \ |
|
Line 82... | Line 131... | ||
82 | 131 | } while (0) |
|
83 | 132 | ||
Line 92... | Line 141... | ||
92 | 141 | ||
93 | 142 | ||
94 | 143 | ||
95 | /* For display hotplug interrupt */ |
144 | /* For display hotplug interrupt */ |
96 | static void |
145 | static void |
Line 97... | Line 146... | ||
97 | ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
146 | ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask) |
98 | { |
- | |
99 | assert_spin_locked(&dev_priv->irq_lock); |
- | |
100 | 147 | { |
|
101 | if (dev_priv->pc8.irqs_disabled) { |
- | |
Line 102... | Line 148... | ||
102 | WARN(1, "IRQs disabled\n"); |
148 | assert_spin_locked(&dev_priv->irq_lock); |
103 | dev_priv->pc8.regsave.deimr &= ~mask; |
149 | |
104 | return; |
150 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) |
105 | } |
151 | return; |
106 | 152 | ||
107 | if ((dev_priv->irq_mask & mask) != 0) { |
153 | if ((dev_priv->irq_mask & mask) != 0) { |
Line 108... | Line 154... | ||
108 | dev_priv->irq_mask &= ~mask; |
154 | dev_priv->irq_mask &= ~mask; |
109 | I915_WRITE(DEIMR, dev_priv->irq_mask); |
155 | I915_WRITE(DEIMR, dev_priv->irq_mask); |
110 | POSTING_READ(DEIMR); |
156 | POSTING_READ(DEIMR); |
111 | } |
157 | } |
Line 112... | Line 158... | ||
112 | } |
158 | } |
113 | - | ||
114 | static void |
- | |
115 | ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
159 | |
116 | { |
- | |
Line 117... | Line 160... | ||
117 | assert_spin_locked(&dev_priv->irq_lock); |
160 | static void |
118 | 161 | ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask) |
|
119 | if (dev_priv->pc8.irqs_disabled) { |
162 | { |
120 | WARN(1, "IRQs disabled\n"); |
163 | assert_spin_locked(&dev_priv->irq_lock); |
Line 139... | Line 182... | ||
139 | uint32_t interrupt_mask, |
182 | uint32_t interrupt_mask, |
140 | uint32_t enabled_irq_mask) |
183 | uint32_t enabled_irq_mask) |
141 | { |
184 | { |
142 | assert_spin_locked(&dev_priv->irq_lock); |
185 | assert_spin_locked(&dev_priv->irq_lock); |
Line 143... | Line 186... | ||
143 | 186 | ||
144 | if (dev_priv->pc8.irqs_disabled) { |
- | |
145 | WARN(1, "IRQs disabled\n"); |
- | |
146 | dev_priv->pc8.regsave.gtimr &= ~interrupt_mask; |
- | |
147 | dev_priv->pc8.regsave.gtimr |= (~enabled_irq_mask & |
- | |
148 | interrupt_mask); |
187 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) |
149 | return; |
- | |
Line 150... | Line 188... | ||
150 | } |
188 | return; |
151 | 189 | ||
152 | dev_priv->gt_irq_mask &= ~interrupt_mask; |
190 | dev_priv->gt_irq_mask &= ~interrupt_mask; |
153 | dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask); |
191 | dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask); |
154 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
192 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
Line 155... | Line 193... | ||
155 | POSTING_READ(GTIMR); |
193 | POSTING_READ(GTIMR); |
156 | } |
194 | } |
157 | 195 | ||
158 | void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
196 | void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
Line 159... | Line 197... | ||
159 | { |
197 | { |
160 | ilk_update_gt_irq(dev_priv, mask, mask); |
198 | ilk_update_gt_irq(dev_priv, mask, mask); |
161 | } |
199 | } |
162 | 200 | ||
Line 163... | Line 201... | ||
163 | void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
201 | void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
Line 177... | Line 215... | ||
177 | { |
215 | { |
178 | uint32_t new_val; |
216 | uint32_t new_val; |
Line 179... | Line 217... | ||
179 | 217 | ||
Line 180... | Line 218... | ||
180 | assert_spin_locked(&dev_priv->irq_lock); |
218 | assert_spin_locked(&dev_priv->irq_lock); |
181 | - | ||
182 | if (dev_priv->pc8.irqs_disabled) { |
- | |
183 | WARN(1, "IRQs disabled\n"); |
- | |
184 | dev_priv->pc8.regsave.gen6_pmimr &= ~interrupt_mask; |
- | |
185 | dev_priv->pc8.regsave.gen6_pmimr |= (~enabled_irq_mask & |
219 | |
186 | interrupt_mask); |
- | |
Line 187... | Line 220... | ||
187 | return; |
220 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) |
188 | } |
221 | return; |
189 | 222 | ||
Line 196... | Line 229... | ||
196 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask); |
229 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask); |
197 | POSTING_READ(GEN6_PMIMR); |
230 | POSTING_READ(GEN6_PMIMR); |
198 | } |
231 | } |
199 | } |
232 | } |
Line 200... | Line 233... | ||
200 | 233 | ||
201 | void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
234 | void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
202 | { |
235 | { |
203 | snb_update_pm_irq(dev_priv, mask, mask); |
236 | snb_update_pm_irq(dev_priv, mask, mask); |
Line 204... | Line 237... | ||
204 | } |
237 | } |
205 | 238 | ||
206 | void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
239 | void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
207 | { |
240 | { |
Line 208... | Line 241... | ||
208 | snb_update_pm_irq(dev_priv, mask, 0); |
241 | snb_update_pm_irq(dev_priv, mask, 0); |
Line 224... | Line 257... | ||
224 | } |
257 | } |
Line 225... | Line 258... | ||
225 | 258 | ||
226 | return true; |
259 | return true; |
Line -... | Line 260... | ||
- | 260 | } |
|
- | 261 | ||
- | 262 | /** |
|
- | 263 | * bdw_update_pm_irq - update GT interrupt 2 |
|
- | 264 | * @dev_priv: driver private |
|
- | 265 | * @interrupt_mask: mask of interrupt bits to update |
|
- | 266 | * @enabled_irq_mask: mask of interrupt bits to enable |
|
- | 267 | * |
|
- | 268 | * Copied from the snb function, updated with relevant register offsets |
|
- | 269 | */ |
|
- | 270 | static void bdw_update_pm_irq(struct drm_i915_private *dev_priv, |
|
- | 271 | uint32_t interrupt_mask, |
|
- | 272 | uint32_t enabled_irq_mask) |
|
- | 273 | { |
|
- | 274 | uint32_t new_val; |
|
- | 275 | ||
- | 276 | assert_spin_locked(&dev_priv->irq_lock); |
|
- | 277 | ||
- | 278 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) |
|
- | 279 | return; |
|
- | 280 | ||
- | 281 | new_val = dev_priv->pm_irq_mask; |
|
- | 282 | new_val &= ~interrupt_mask; |
|
- | 283 | new_val |= (~enabled_irq_mask & interrupt_mask); |
|
- | 284 | ||
- | 285 | if (new_val != dev_priv->pm_irq_mask) { |
|
- | 286 | dev_priv->pm_irq_mask = new_val; |
|
- | 287 | I915_WRITE(GEN8_GT_IMR(2), dev_priv->pm_irq_mask); |
|
- | 288 | POSTING_READ(GEN8_GT_IMR(2)); |
|
- | 289 | } |
|
- | 290 | } |
|
- | 291 | ||
- | 292 | void gen8_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
|
- | 293 | { |
|
- | 294 | bdw_update_pm_irq(dev_priv, mask, mask); |
|
- | 295 | } |
|
- | 296 | ||
- | 297 | void gen8_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) |
|
- | 298 | { |
|
- | 299 | bdw_update_pm_irq(dev_priv, mask, 0); |
|
227 | } |
300 | } |
228 | 301 | ||
229 | static bool cpt_can_enable_serr_int(struct drm_device *dev) |
302 | static bool cpt_can_enable_serr_int(struct drm_device *dev) |
230 | { |
303 | { |
231 | struct drm_i915_private *dev_priv = dev->dev_private; |
304 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 242... | Line 315... | ||
242 | } |
315 | } |
Line 243... | Line 316... | ||
243 | 316 | ||
244 | return true; |
317 | return true; |
Line -... | Line 318... | ||
- | 318 | } |
|
- | 319 | ||
- | 320 | void i9xx_check_fifo_underruns(struct drm_device *dev) |
|
- | 321 | { |
|
- | 322 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 323 | struct intel_crtc *crtc; |
|
- | 324 | unsigned long flags; |
|
- | 325 | ||
- | 326 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
|
- | 327 | ||
- | 328 | for_each_intel_crtc(dev, crtc) { |
|
- | 329 | u32 reg = PIPESTAT(crtc->pipe); |
|
- | 330 | u32 pipestat; |
|
- | 331 | ||
- | 332 | if (crtc->cpu_fifo_underrun_disabled) |
|
- | 333 | continue; |
|
- | 334 | ||
- | 335 | pipestat = I915_READ(reg) & 0xffff0000; |
|
- | 336 | if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0) |
|
- | 337 | continue; |
|
- | 338 | ||
- | 339 | I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); |
|
- | 340 | POSTING_READ(reg); |
|
- | 341 | ||
- | 342 | DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe)); |
|
- | 343 | } |
|
- | 344 | ||
- | 345 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
|
- | 346 | } |
|
- | 347 | ||
- | 348 | static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, |
|
- | 349 | enum pipe pipe, |
|
- | 350 | bool enable, bool old) |
|
- | 351 | { |
|
- | 352 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 353 | u32 reg = PIPESTAT(pipe); |
|
- | 354 | u32 pipestat = I915_READ(reg) & 0xffff0000; |
|
- | 355 | ||
- | 356 | assert_spin_locked(&dev_priv->irq_lock); |
|
- | 357 | ||
- | 358 | if (enable) { |
|
- | 359 | I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); |
|
- | 360 | POSTING_READ(reg); |
|
- | 361 | } else { |
|
- | 362 | if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS) |
|
- | 363 | DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); |
|
- | 364 | } |
|
245 | } |
365 | } |
246 | 366 | ||
247 | static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, |
367 | static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, |
248 | enum pipe pipe, bool enable) |
368 | enum pipe pipe, bool enable) |
249 | { |
369 | { |
Line 256... | Line 376... | ||
256 | else |
376 | else |
257 | ironlake_disable_display_irq(dev_priv, bit); |
377 | ironlake_disable_display_irq(dev_priv, bit); |
258 | } |
378 | } |
Line 259... | Line 379... | ||
259 | 379 | ||
260 | static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, |
380 | static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, |
- | 381 | enum pipe pipe, |
|
261 | enum pipe pipe, bool enable) |
382 | bool enable, bool old) |
262 | { |
383 | { |
263 | struct drm_i915_private *dev_priv = dev->dev_private; |
384 | struct drm_i915_private *dev_priv = dev->dev_private; |
264 | if (enable) { |
385 | if (enable) { |
Line 265... | Line 386... | ||
265 | I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); |
386 | I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); |
266 | 387 | ||
Line 267... | Line 388... | ||
267 | if (!ivb_can_enable_err_int(dev)) |
388 | if (!ivb_can_enable_err_int(dev)) |
268 | return; |
389 | return; |
269 | - | ||
270 | ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); |
- | |
271 | } else { |
- | |
272 | bool was_enabled = !(I915_READ(DEIMR) & DE_ERR_INT_IVB); |
390 | |
Line 273... | Line 391... | ||
273 | 391 | ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); |
|
274 | /* Change the state _after_ we've read out the current one. */ |
392 | } else { |
275 | ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); |
393 | ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); |
276 | 394 | ||
277 | if (!was_enabled && |
395 | if (old && |
278 | (I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe))) { |
396 | I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { |
279 | DRM_DEBUG_KMS("uncleared fifo underrun on pipe %c\n", |
397 | DRM_ERROR("uncleared fifo underrun on pipe %c\n", |
Line 311... | Line 429... | ||
311 | sdeimr &= ~interrupt_mask; |
429 | sdeimr &= ~interrupt_mask; |
312 | sdeimr |= (~enabled_irq_mask & interrupt_mask); |
430 | sdeimr |= (~enabled_irq_mask & interrupt_mask); |
Line 313... | Line 431... | ||
313 | 431 | ||
Line 314... | Line 432... | ||
314 | assert_spin_locked(&dev_priv->irq_lock); |
432 | assert_spin_locked(&dev_priv->irq_lock); |
315 | - | ||
316 | if (dev_priv->pc8.irqs_disabled && |
- | |
317 | (interrupt_mask & SDE_HOTPLUG_MASK_CPT)) { |
- | |
318 | WARN(1, "IRQs disabled\n"); |
- | |
319 | dev_priv->pc8.regsave.sdeimr &= ~interrupt_mask; |
- | |
320 | dev_priv->pc8.regsave.sdeimr |= (~enabled_irq_mask & |
433 | |
321 | interrupt_mask); |
- | |
Line 322... | Line 434... | ||
322 | return; |
434 | if (WARN_ON(!intel_irqs_enabled(dev_priv))) |
323 | } |
435 | return; |
324 | 436 | ||
325 | I915_WRITE(SDEIMR, sdeimr); |
437 | I915_WRITE(SDEIMR, sdeimr); |
Line 344... | Line 456... | ||
344 | ibx_disable_display_interrupt(dev_priv, bit); |
456 | ibx_disable_display_interrupt(dev_priv, bit); |
345 | } |
457 | } |
Line 346... | Line 458... | ||
346 | 458 | ||
347 | static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, |
459 | static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, |
348 | enum transcoder pch_transcoder, |
460 | enum transcoder pch_transcoder, |
349 | bool enable) |
461 | bool enable, bool old) |
350 | { |
462 | { |
Line 351... | Line 463... | ||
351 | struct drm_i915_private *dev_priv = dev->dev_private; |
463 | struct drm_i915_private *dev_priv = dev->dev_private; |
352 | 464 | ||
Line 357... | Line 469... | ||
357 | if (!cpt_can_enable_serr_int(dev)) |
469 | if (!cpt_can_enable_serr_int(dev)) |
358 | return; |
470 | return; |
Line 359... | Line 471... | ||
359 | 471 | ||
360 | ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); |
472 | ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); |
361 | } else { |
- | |
362 | uint32_t tmp = I915_READ(SERR_INT); |
- | |
363 | bool was_enabled = !(I915_READ(SDEIMR) & SDE_ERROR_CPT); |
- | |
364 | - | ||
365 | /* Change the state _after_ we've read out the current one. */ |
473 | } else { |
Line 366... | Line 474... | ||
366 | ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); |
474 | ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); |
367 | 475 | ||
368 | if (!was_enabled && |
476 | if (old && I915_READ(SERR_INT) & |
369 | (tmp & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder))) { |
477 | SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { |
370 | DRM_DEBUG_KMS("uncleared pch fifo underrun on pch transcoder %c\n", |
478 | DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n", |
371 | transcoder_name(pch_transcoder)); |
479 | transcoder_name(pch_transcoder)); |
372 | } |
480 | } |
Line 385... | Line 493... | ||
385 | * the other pipes, due to the fact that there's just one interrupt mask/enable |
493 | * the other pipes, due to the fact that there's just one interrupt mask/enable |
386 | * bit for all the pipes. |
494 | * bit for all the pipes. |
387 | * |
495 | * |
388 | * Returns the previous state of underrun reporting. |
496 | * Returns the previous state of underrun reporting. |
389 | */ |
497 | */ |
390 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, |
498 | static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, |
391 | enum pipe pipe, bool enable) |
499 | enum pipe pipe, bool enable) |
392 | { |
500 | { |
393 | struct drm_i915_private *dev_priv = dev->dev_private; |
501 | struct drm_i915_private *dev_priv = dev->dev_private; |
394 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
502 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
395 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
503 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
396 | unsigned long flags; |
- | |
397 | bool ret; |
504 | bool old; |
Line 398... | Line 505... | ||
398 | 505 | ||
399 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
- | |
400 | - | ||
401 | ret = !intel_crtc->cpu_fifo_underrun_disabled; |
- | |
402 | - | ||
403 | if (enable == ret) |
- | |
Line -... | Line 506... | ||
- | 506 | assert_spin_locked(&dev_priv->irq_lock); |
|
404 | goto done; |
507 | |
Line -... | Line 508... | ||
- | 508 | old = !intel_crtc->cpu_fifo_underrun_disabled; |
|
- | 509 | intel_crtc->cpu_fifo_underrun_disabled = !enable; |
|
405 | 510 | ||
406 | intel_crtc->cpu_fifo_underrun_disabled = !enable; |
511 | if (INTEL_INFO(dev)->gen < 5 || IS_VALLEYVIEW(dev)) |
407 | 512 | i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); |
|
408 | if (IS_GEN5(dev) || IS_GEN6(dev)) |
513 | else if (IS_GEN5(dev) || IS_GEN6(dev)) |
409 | ironlake_set_fifo_underrun_reporting(dev, pipe, enable); |
514 | ironlake_set_fifo_underrun_reporting(dev, pipe, enable); |
410 | else if (IS_GEN7(dev)) |
515 | else if (IS_GEN7(dev)) |
Line -... | Line 516... | ||
- | 516 | ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old); |
|
- | 517 | else if (IS_GEN8(dev)) |
|
- | 518 | broadwell_set_fifo_underrun_reporting(dev, pipe, enable); |
|
- | 519 | ||
- | 520 | return old; |
|
- | 521 | } |
|
- | 522 | ||
- | 523 | bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, |
|
411 | ivybridge_set_fifo_underrun_reporting(dev, pipe, enable); |
524 | enum pipe pipe, bool enable) |
- | 525 | { |
|
- | 526 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 527 | unsigned long flags; |
|
412 | else if (IS_GEN8(dev)) |
528 | bool ret; |
- | 529 | ||
413 | broadwell_set_fifo_underrun_reporting(dev, pipe, enable); |
530 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
414 | 531 | ret = __intel_set_cpu_fifo_underrun_reporting(dev, pipe, enable); |
|
Line -... | Line 532... | ||
- | 532 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
|
- | 533 | ||
- | 534 | return ret; |
|
- | 535 | } |
|
- | 536 | ||
- | 537 | static bool __cpu_fifo_underrun_reporting_enabled(struct drm_device *dev, |
|
- | 538 | enum pipe pipe) |
|
- | 539 | { |
|
- | 540 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 541 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
|
415 | done: |
542 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
416 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
543 | |
417 | return ret; |
544 | return !intel_crtc->cpu_fifo_underrun_disabled; |
418 | } |
545 | } |
419 | 546 | ||
Line 437... | Line 564... | ||
437 | { |
564 | { |
438 | struct drm_i915_private *dev_priv = dev->dev_private; |
565 | struct drm_i915_private *dev_priv = dev->dev_private; |
439 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; |
566 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder]; |
440 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
567 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
441 | unsigned long flags; |
568 | unsigned long flags; |
442 | bool ret; |
569 | bool old; |
Line 443... | Line 570... | ||
443 | 570 | ||
444 | /* |
571 | /* |
445 | * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT |
572 | * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT |
446 | * has only one pch transcoder A that all pipes can use. To avoid racy |
573 | * has only one pch transcoder A that all pipes can use. To avoid racy |
Line 450... | Line 577... | ||
450 | * crtc on LPT won't cause issues. |
577 | * crtc on LPT won't cause issues. |
451 | */ |
578 | */ |
Line 452... | Line 579... | ||
452 | 579 | ||
Line 453... | Line 580... | ||
453 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
580 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
454 | - | ||
455 | ret = !intel_crtc->pch_fifo_underrun_disabled; |
- | |
456 | - | ||
457 | if (enable == ret) |
- | |
458 | goto done; |
581 | |
Line 459... | Line 582... | ||
459 | 582 | old = !intel_crtc->pch_fifo_underrun_disabled; |
|
460 | intel_crtc->pch_fifo_underrun_disabled = !enable; |
583 | intel_crtc->pch_fifo_underrun_disabled = !enable; |
461 | 584 | ||
462 | if (HAS_PCH_IBX(dev)) |
585 | if (HAS_PCH_IBX(dev)) |
Line 463... | Line -... | ||
463 | ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable); |
- | |
464 | else |
586 | ibx_set_fifo_underrun_reporting(dev, pch_transcoder, enable); |
465 | cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable); |
587 | else |
466 | 588 | cpt_set_fifo_underrun_reporting(dev, pch_transcoder, enable, old); |
|
Line 467... | Line 589... | ||
467 | done: |
589 | |
468 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
590 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
- | 591 | return old; |
|
469 | return ret; |
592 | } |
470 | } |
593 | |
471 | 594 | ||
Line 472... | Line 595... | ||
472 | 595 | static void |
|
Line -... | Line 596... | ||
- | 596 | __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
|
- | 597 | u32 enable_mask, u32 status_mask) |
|
- | 598 | { |
|
473 | void |
599 | u32 reg = PIPESTAT(pipe); |
474 | i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask) |
600 | u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; |
Line -... | Line 601... | ||
- | 601 | ||
- | 602 | assert_spin_locked(&dev_priv->irq_lock); |
|
- | 603 | ||
- | 604 | if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || |
|
- | 605 | status_mask & ~PIPESTAT_INT_STATUS_MASK, |
|
475 | { |
606 | "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", |
476 | u32 reg = PIPESTAT(pipe); |
607 | pipe_name(pipe), enable_mask, status_mask)) |
477 | u32 pipestat = I915_READ(reg) & 0x7fff0000; |
608 | return; |
478 | 609 | ||
479 | assert_spin_locked(&dev_priv->irq_lock); |
610 | if ((pipestat & enable_mask) == enable_mask) |
Line 480... | Line 611... | ||
480 | 611 | return; |
|
481 | if ((pipestat & mask) == mask) |
612 | |
- | 613 | dev_priv->pipestat_irq_mask[pipe] |= status_mask; |
|
482 | return; |
614 | |
483 | 615 | /* Enable the interrupt, clear any pending status */ |
|
484 | /* Enable the interrupt, clear any pending status */ |
616 | pipestat |= enable_mask | status_mask; |
Line 485... | Line 617... | ||
485 | pipestat |= mask | (mask >> 16); |
617 | I915_WRITE(reg, pipestat); |
Line -... | Line 618... | ||
- | 618 | POSTING_READ(reg); |
|
- | 619 | } |
|
- | 620 | ||
486 | I915_WRITE(reg, pipestat); |
621 | static void |
487 | POSTING_READ(reg); |
622 | __i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
Line -... | Line 623... | ||
- | 623 | u32 enable_mask, u32 status_mask) |
|
- | 624 | { |
|
- | 625 | u32 reg = PIPESTAT(pipe); |
|
- | 626 | u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; |
|
- | 627 | ||
488 | } |
628 | assert_spin_locked(&dev_priv->irq_lock); |
489 | 629 | ||
490 | void |
630 | if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || |
491 | i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask) |
631 | status_mask & ~PIPESTAT_INT_STATUS_MASK, |
Line -... | Line 632... | ||
- | 632 | "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", |
|
- | 633 | pipe_name(pipe), enable_mask, status_mask)) |
|
- | 634 | return; |
|
- | 635 | ||
- | 636 | if ((pipestat & enable_mask) == 0) |
|
- | 637 | return; |
|
- | 638 | ||
- | 639 | dev_priv->pipestat_irq_mask[pipe] &= ~status_mask; |
|
- | 640 | ||
- | 641 | pipestat &= ~enable_mask; |
|
- | 642 | I915_WRITE(reg, pipestat); |
|
- | 643 | POSTING_READ(reg); |
|
- | 644 | } |
|
- | 645 | ||
- | 646 | static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask) |
|
- | 647 | { |
|
- | 648 | u32 enable_mask = status_mask << 16; |
|
- | 649 | ||
- | 650 | /* |
|
- | 651 | * On pipe A we don't support the PSR interrupt yet, |
|
- | 652 | * on pipe B and C the same bit MBZ. |
|
- | 653 | */ |
|
- | 654 | if (WARN_ON_ONCE(status_mask & PIPE_A_PSR_STATUS_VLV)) |
|
- | 655 | return 0; |
|
- | 656 | /* |
|
- | 657 | * On pipe B and C we don't support the PSR interrupt yet, on pipe |
|
- | 658 | * A the same bit is for perf counters which we don't use either. |
|
- | 659 | */ |
|
- | 660 | if (WARN_ON_ONCE(status_mask & PIPE_B_PSR_STATUS_VLV)) |
|
- | 661 | return 0; |
|
- | 662 | ||
- | 663 | enable_mask &= ~(PIPE_FIFO_UNDERRUN_STATUS | |
|
- | 664 | SPRITE0_FLIP_DONE_INT_EN_VLV | |
|
- | 665 | SPRITE1_FLIP_DONE_INT_EN_VLV); |
|
- | 666 | if (status_mask & SPRITE0_FLIP_DONE_INT_STATUS_VLV) |
|
- | 667 | enable_mask |= SPRITE0_FLIP_DONE_INT_EN_VLV; |
|
- | 668 | if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV) |
|
- | 669 | enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV; |
|
- | 670 | ||
- | 671 | return enable_mask; |
|
- | 672 | } |
|
- | 673 | ||
- | 674 | void |
|
- | 675 | i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
|
- | 676 | u32 status_mask) |
|
- | 677 | { |
|
- | 678 | u32 enable_mask; |
|
- | 679 | ||
- | 680 | if (IS_VALLEYVIEW(dev_priv->dev)) |
|
- | 681 | enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev, |
|
- | 682 | status_mask); |
|
- | 683 | else |
|
- | 684 | enable_mask = status_mask << 16; |
|
- | 685 | __i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask); |
|
- | 686 | } |
|
- | 687 | ||
492 | { |
688 | void |
493 | u32 reg = PIPESTAT(pipe); |
689 | i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
494 | u32 pipestat = I915_READ(reg) & 0x7fff0000; |
690 | u32 status_mask) |
495 | 691 | { |
|
496 | assert_spin_locked(&dev_priv->irq_lock); |
692 | u32 enable_mask; |
497 | 693 | ||
498 | if ((pipestat & mask) == 0) |
694 | if (IS_VALLEYVIEW(dev_priv->dev)) |
Line 499... | Line 695... | ||
499 | return; |
695 | enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev, |
500 | 696 | status_mask); |
|
Line 501... | Line 697... | ||
501 | pipestat &= ~mask; |
697 | else |
Line 502... | Line 698... | ||
502 | I915_WRITE(reg, pipestat); |
698 | enable_mask = status_mask << 16; |
503 | POSTING_READ(reg); |
699 | __i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask); |
504 | } |
700 | } |
505 | 701 | ||
Line 506... | Line 702... | ||
506 | /** |
702 | /** |
507 | * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion |
703 | * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion |
Line 508... | Line 704... | ||
508 | */ |
704 | */ |
Line 534... | Line 730... | ||
534 | * before reading such registers if unsure. |
730 | * before reading such registers if unsure. |
535 | */ |
731 | */ |
536 | static int |
732 | static int |
537 | i915_pipe_enabled(struct drm_device *dev, int pipe) |
733 | i915_pipe_enabled(struct drm_device *dev, int pipe) |
538 | { |
734 | { |
539 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
735 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 540... | Line 736... | ||
540 | 736 | ||
541 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
737 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
542 | /* Locking is horribly broken here, but whatever. */ |
738 | /* Locking is horribly broken here, but whatever. */ |
543 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
739 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
Line 547... | Line 743... | ||
547 | } else { |
743 | } else { |
548 | return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE; |
744 | return I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE; |
549 | } |
745 | } |
550 | } |
746 | } |
Line -... | Line 747... | ||
- | 747 | ||
- | 748 | /* |
|
- | 749 | * This timing diagram depicts the video signal in and |
|
- | 750 | * around the vertical blanking period. |
|
- | 751 | * |
|
- | 752 | * Assumptions about the fictitious mode used in this example: |
|
- | 753 | * vblank_start >= 3 |
|
- | 754 | * vsync_start = vblank_start + 1 |
|
- | 755 | * vsync_end = vblank_start + 2 |
|
- | 756 | * vtotal = vblank_start + 3 |
|
- | 757 | * |
|
- | 758 | * start of vblank: |
|
- | 759 | * latch double buffered registers |
|
- | 760 | * increment frame counter (ctg+) |
|
- | 761 | * generate start of vblank interrupt (gen4+) |
|
- | 762 | * | |
|
- | 763 | * | frame start: |
|
- | 764 | * | generate frame start interrupt (aka. vblank interrupt) (gmch) |
|
- | 765 | * | may be shifted forward 1-3 extra lines via PIPECONF |
|
- | 766 | * | | |
|
- | 767 | * | | start of vsync: |
|
- | 768 | * | | generate vsync interrupt |
|
- | 769 | * | | | |
|
- | 770 | * ___xxxx___ ___xxxx___ ___xxxx___ ___xxxx___ ___xxxx___ ___xxxx |
|
- | 771 | * . \hs/ . \hs/ \hs/ \hs/ . \hs/ |
|
- | 772 | * ----va---> <-----------------vb--------------------> <--------va------------- |
|
- | 773 | * | | <----vs-----> | |
|
- | 774 | * -vbs-----> <---vbs+1---> <---vbs+2---> <-----0-----> <-----1-----> <-----2--- (scanline counter gen2) |
|
- | 775 | * -vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2---> <-----0--- (scanline counter gen3+) |
|
- | 776 | * -vbs-2---> <---vbs-2---> <---vbs-1---> <---vbs-----> <---vbs+1---> <---vbs+2- (scanline counter hsw+ hdmi) |
|
- | 777 | * | | | |
|
- | 778 | * last visible pixel first visible pixel |
|
- | 779 | * | increment frame counter (gen3/4) |
|
- | 780 | * pixel counter = vblank_start * htotal pixel counter = 0 (gen3/4) |
|
- | 781 | * |
|
- | 782 | * x = horizontal active |
|
- | 783 | * _ = horizontal blanking |
|
- | 784 | * hs = horizontal sync |
|
- | 785 | * va = vertical active |
|
- | 786 | * vb = vertical blanking |
|
- | 787 | * vs = vertical sync |
|
- | 788 | * vbs = vblank_start (number) |
|
- | 789 | * |
|
- | 790 | * Summary: |
|
- | 791 | * - most events happen at the start of horizontal sync |
|
- | 792 | * - frame start happens at the start of horizontal blank, 1-4 lines |
|
- | 793 | * (depending on PIPECONF settings) after the start of vblank |
|
- | 794 | * - gen3/4 pixel and frame counter are synchronized with the start |
|
- | 795 | * of horizontal active on the first line of vertical active |
|
- | 796 | */ |
|
551 | 797 | ||
552 | static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe) |
798 | static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe) |
553 | { |
799 | { |
554 | /* Gen2 doesn't have a hardware frame counter */ |
800 | /* Gen2 doesn't have a hardware frame counter */ |
555 | return 0; |
801 | return 0; |
Line 558... | Line 804... | ||
558 | /* Called from drm generic code, passed a 'crtc', which |
804 | /* Called from drm generic code, passed a 'crtc', which |
559 | * we use as a pipe index |
805 | * we use as a pipe index |
560 | */ |
806 | */ |
561 | static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) |
807 | static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) |
562 | { |
808 | { |
563 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
809 | struct drm_i915_private *dev_priv = dev->dev_private; |
564 | unsigned long high_frame; |
810 | unsigned long high_frame; |
565 | unsigned long low_frame; |
811 | unsigned long low_frame; |
566 | u32 high1, high2, low, pixel, vbl_start; |
812 | u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal; |
Line 567... | Line 813... | ||
567 | 813 | ||
568 | if (!i915_pipe_enabled(dev, pipe)) { |
814 | if (!i915_pipe_enabled(dev, pipe)) { |
569 | DRM_DEBUG_DRIVER("trying to get vblank count for disabled " |
815 | DRM_DEBUG_DRIVER("trying to get vblank count for disabled " |
570 | "pipe %c\n", pipe_name(pipe)); |
816 | "pipe %c\n", pipe_name(pipe)); |
Line 575... | Line 821... | ||
575 | struct intel_crtc *intel_crtc = |
821 | struct intel_crtc *intel_crtc = |
576 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
822 | to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
577 | const struct drm_display_mode *mode = |
823 | const struct drm_display_mode *mode = |
578 | &intel_crtc->config.adjusted_mode; |
824 | &intel_crtc->config.adjusted_mode; |
Line -... | Line 825... | ||
- | 825 | ||
- | 826 | htotal = mode->crtc_htotal; |
|
579 | 827 | hsync_start = mode->crtc_hsync_start; |
|
- | 828 | vbl_start = mode->crtc_vblank_start; |
|
- | 829 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
|
580 | vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; |
830 | vbl_start = DIV_ROUND_UP(vbl_start, 2); |
581 | } else { |
831 | } else { |
582 | enum transcoder cpu_transcoder = |
- | |
583 | intel_pipe_to_cpu_transcoder(dev_priv, pipe); |
- | |
Line 584... | Line 832... | ||
584 | u32 htotal; |
832 | enum transcoder cpu_transcoder = (enum transcoder) pipe; |
- | 833 | ||
585 | 834 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; |
|
- | 835 | hsync_start = (I915_READ(HSYNC(cpu_transcoder)) & 0x1fff) + 1; |
|
- | 836 | vbl_start = (I915_READ(VBLANK(cpu_transcoder)) & 0x1fff) + 1; |
|
- | 837 | if ((I915_READ(PIPECONF(cpu_transcoder)) & |
|
- | 838 | PIPECONF_INTERLACE_MASK) != PIPECONF_PROGRESSIVE) |
|
Line -... | Line 839... | ||
- | 839 | vbl_start = DIV_ROUND_UP(vbl_start, 2); |
|
586 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; |
840 | } |
587 | vbl_start = (I915_READ(VBLANK(cpu_transcoder)) & 0x1fff) + 1; |
841 | |
- | 842 | /* Convert to pixel count */ |
|
- | 843 | vbl_start *= htotal; |
|
Line 588... | Line 844... | ||
588 | 844 | ||
589 | vbl_start *= htotal; |
845 | /* Start of vblank event occurs at start of hsync */ |
Line 590... | Line 846... | ||
590 | } |
846 | vbl_start -= htotal - hsync_start; |
Line 615... | Line 871... | ||
615 | return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff; |
871 | return (((high1 << 8) | low) + (pixel >= vbl_start)) & 0xffffff; |
616 | } |
872 | } |
Line 617... | Line 873... | ||
617 | 873 | ||
618 | static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) |
874 | static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) |
619 | { |
875 | { |
620 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
876 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 621... | Line 877... | ||
621 | int reg = PIPE_FRMCOUNT_GM45(pipe); |
877 | int reg = PIPE_FRMCOUNT_GM45(pipe); |
622 | 878 | ||
623 | if (!i915_pipe_enabled(dev, pipe)) { |
879 | if (!i915_pipe_enabled(dev, pipe)) { |
Line 629... | Line 885... | ||
629 | return I915_READ(reg); |
885 | return I915_READ(reg); |
630 | } |
886 | } |
Line 631... | Line 887... | ||
631 | 887 | ||
632 | /* raw reads, only for fast reads of display block, no need for forcewake etc. */ |
888 | /* raw reads, only for fast reads of display block, no need for forcewake etc. */ |
633 | #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) |
- | |
Line 634... | Line 889... | ||
634 | #define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__)) |
889 | #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) |
635 | 890 | ||
- | 891 | static int __intel_get_crtc_scanline(struct intel_crtc *crtc) |
|
636 | static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) |
892 | { |
- | 893 | struct drm_device *dev = crtc->base.dev; |
|
- | 894 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
637 | { |
895 | const struct drm_display_mode *mode = &crtc->config.adjusted_mode; |
Line 638... | Line -... | ||
638 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
639 | uint32_t status; |
896 | enum pipe pipe = crtc->pipe; |
640 | 897 | int position, vtotal; |
|
641 | if (INTEL_INFO(dev)->gen < 7) { |
898 | |
642 | status = pipe == PIPE_A ? |
899 | vtotal = mode->crtc_vtotal; |
643 | DE_PIPEA_VBLANK : |
900 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
644 | DE_PIPEB_VBLANK; |
- | |
645 | } else { |
- | |
646 | switch (pipe) { |
- | |
647 | default: |
- | |
648 | case PIPE_A: |
- | |
649 | status = DE_PIPEA_VBLANK_IVB; |
901 | vtotal /= 2; |
650 | break; |
902 | |
651 | case PIPE_B: |
- | |
652 | status = DE_PIPEB_VBLANK_IVB; |
903 | if (IS_GEN2(dev)) |
653 | break; |
- | |
654 | case PIPE_C: |
- | |
655 | status = DE_PIPEC_VBLANK_IVB; |
- | |
Line -... | Line 904... | ||
- | 904 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN2; |
|
- | 905 | else |
|
- | 906 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; |
|
- | 907 | ||
656 | break; |
908 | /* |
657 | } |
909 | * See update_scanline_offset() for the details on the |
Line 658... | Line 910... | ||
658 | } |
910 | * scanline_offset adjustment. |
659 | 911 | */ |
|
660 | return __raw_i915_read32(dev_priv, DEISR) & status; |
912 | return (position + crtc->scanline_offset) % vtotal; |
Line 667... | Line 919... | ||
667 | struct drm_i915_private *dev_priv = dev->dev_private; |
919 | struct drm_i915_private *dev_priv = dev->dev_private; |
668 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
920 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
669 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
921 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
670 | const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; |
922 | const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; |
671 | int position; |
923 | int position; |
672 | int vbl_start, vbl_end, htotal, vtotal; |
924 | int vbl_start, vbl_end, hsync_start, htotal, vtotal; |
673 | bool in_vbl = true; |
925 | bool in_vbl = true; |
674 | int ret = 0; |
926 | int ret = 0; |
675 | unsigned long irqflags; |
927 | unsigned long irqflags; |
Line 676... | Line 928... | ||
676 | 928 | ||
Line 679... | Line 931... | ||
679 | "pipe %c\n", pipe_name(pipe)); |
931 | "pipe %c\n", pipe_name(pipe)); |
680 | return 0; |
932 | return 0; |
681 | } |
933 | } |
Line 682... | Line 934... | ||
682 | 934 | ||
- | 935 | htotal = mode->crtc_htotal; |
|
683 | htotal = mode->crtc_htotal; |
936 | hsync_start = mode->crtc_hsync_start; |
684 | vtotal = mode->crtc_vtotal; |
937 | vtotal = mode->crtc_vtotal; |
685 | vbl_start = mode->crtc_vblank_start; |
938 | vbl_start = mode->crtc_vblank_start; |
Line 686... | Line 939... | ||
686 | vbl_end = mode->crtc_vblank_end; |
939 | vbl_end = mode->crtc_vblank_end; |
Line 705... | Line 958... | ||
705 | 958 | ||
706 | if (IS_GEN2(dev) || IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { |
959 | if (IS_GEN2(dev) || IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) { |
707 | /* No obvious pixelcount register. Only query vertical |
960 | /* No obvious pixelcount register. Only query vertical |
708 | * scanout position from Display scan line register. |
961 | * scanout position from Display scan line register. |
709 | */ |
- | |
710 | if (IS_GEN2(dev)) |
- | |
711 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN2; |
- | |
712 | else |
- | |
713 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; |
- | |
714 | - | ||
715 | if (HAS_PCH_SPLIT(dev)) { |
- | |
716 | /* |
- | |
717 | * The scanline counter increments at the leading edge |
- | |
718 | * of hsync, ie. it completely misses the active portion |
- | |
719 | * of the line. Fix up the counter at both edges of vblank |
- | |
720 | * to get a more accurate picture whether we're in vblank |
- | |
721 | * or not. |
- | |
722 | */ |
- | |
723 | in_vbl = ilk_pipe_in_vblank_locked(dev, pipe); |
- | |
724 | if ((in_vbl && position == vbl_start - 1) || |
- | |
725 | (!in_vbl && position == vbl_end - 1)) |
962 | */ |
726 | position = (position + 1) % vtotal; |
- | |
727 | } else { |
- | |
728 | /* |
- | |
729 | * ISR vblank status bits don't work the way we'd want |
- | |
730 | * them to work on non-PCH platforms (for |
- | |
731 | * ilk_pipe_in_vblank_locked()), and there doesn't |
- | |
732 | * appear any other way to determine if we're currently |
- | |
733 | * in vblank. |
- | |
734 | * |
- | |
735 | * Instead let's assume that we're already in vblank if |
- | |
736 | * we got called from the vblank interrupt and the |
- | |
737 | * scanline counter value indicates that we're on the |
- | |
738 | * line just prior to vblank start. This should result |
- | |
739 | * in the correct answer, unless the vblank interrupt |
- | |
740 | * delivery really got delayed for almost exactly one |
- | |
741 | * full frame/field. |
- | |
742 | */ |
- | |
743 | if (flags & DRM_CALLED_FROM_VBLIRQ && |
- | |
744 | position == vbl_start - 1) { |
- | |
745 | position = (position + 1) % vtotal; |
- | |
746 | - | ||
747 | /* Signal this correction as "applied". */ |
- | |
748 | ret |= 0x8; |
- | |
749 | } |
- | |
750 | } |
963 | position = __intel_get_crtc_scanline(intel_crtc); |
751 | } else { |
964 | } else { |
752 | /* Have access to pixelcount since start of frame. |
965 | /* Have access to pixelcount since start of frame. |
753 | * We can split this into vertical and horizontal |
966 | * We can split this into vertical and horizontal |
754 | * scanout position. |
967 | * scanout position. |
Line 757... | Line 970... | ||
757 | 970 | ||
758 | /* convert to pixel counts */ |
971 | /* convert to pixel counts */ |
759 | vbl_start *= htotal; |
972 | vbl_start *= htotal; |
760 | vbl_end *= htotal; |
973 | vbl_end *= htotal; |
- | 974 | vtotal *= htotal; |
|
- | 975 | ||
- | 976 | /* |
|
- | 977 | * In interlaced modes, the pixel counter counts all pixels, |
|
- | 978 | * so one field will have htotal more pixels. In order to avoid |
|
- | 979 | * the reported position from jumping backwards when the pixel |
|
- | 980 | * counter is beyond the length of the shorter field, just |
|
- | 981 | * clamp the position the length of the shorter field. This |
|
- | 982 | * matches how the scanline counter based position works since |
|
- | 983 | * the scanline counter doesn't count the two half lines. |
|
- | 984 | */ |
|
- | 985 | if (position >= vtotal) |
|
- | 986 | position = vtotal - 1; |
|
- | 987 | ||
- | 988 | /* |
|
- | 989 | * Start of vblank interrupt is triggered at start of hsync, |
|
- | 990 | * just prior to the first active line of vblank. However we |
|
- | 991 | * consider lines to start at the leading edge of horizontal |
|
- | 992 | * active. So, should we get here before we've crossed into |
|
- | 993 | * the horizontal active of the first line in vblank, we would |
|
- | 994 | * not set the DRM_SCANOUTPOS_INVBL flag. In order to fix that, |
|
- | 995 | * always add htotal-hsync_start to the current pixel position. |
|
- | 996 | */ |
|
761 | vtotal *= htotal; |
997 | position = (position + htotal - hsync_start) % vtotal; |
Line 762... | Line 998... | ||
762 | } |
998 | } |
Line 792... | Line 1028... | ||
792 | ret |= DRM_SCANOUTPOS_INVBL; |
1028 | ret |= DRM_SCANOUTPOS_INVBL; |
Line 793... | Line 1029... | ||
793 | 1029 | ||
794 | return ret; |
1030 | return ret; |
Line -... | Line 1031... | ||
- | 1031 | } |
|
- | 1032 | ||
- | 1033 | int intel_get_crtc_scanline(struct intel_crtc *crtc) |
|
- | 1034 | { |
|
- | 1035 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; |
|
- | 1036 | unsigned long irqflags; |
|
- | 1037 | int position; |
|
- | 1038 | ||
- | 1039 | spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); |
|
- | 1040 | position = __intel_get_crtc_scanline(crtc); |
|
- | 1041 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
|
- | 1042 | ||
- | 1043 | return position; |
|
795 | } |
1044 | } |
796 | 1045 | ||
797 | static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, |
1046 | static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, |
798 | int *max_error, |
1047 | int *max_error, |
799 | struct timeval *vblank_time, |
1048 | struct timeval *vblank_time, |
Line 837... | Line 1086... | ||
837 | if (old_status == connector->status) |
1086 | if (old_status == connector->status) |
838 | return false; |
1087 | return false; |
Line 839... | Line 1088... | ||
839 | 1088 | ||
840 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", |
1089 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", |
841 | connector->base.id, |
1090 | connector->base.id, |
842 | drm_get_connector_name(connector), |
1091 | connector->name, |
843 | drm_get_connector_status_name(old_status), |
1092 | drm_get_connector_status_name(old_status), |
Line 844... | Line 1093... | ||
844 | drm_get_connector_status_name(connector->status)); |
1093 | drm_get_connector_status_name(connector->status)); |
845 | 1094 | ||
Line 851... | Line 1100... | ||
851 | */ |
1100 | */ |
852 | #define I915_REENABLE_HOTPLUG_DELAY (2*60*1000) |
1101 | #define I915_REENABLE_HOTPLUG_DELAY (2*60*1000) |
Line 853... | Line 1102... | ||
853 | 1102 | ||
854 | static void i915_hotplug_work_func(struct work_struct *work) |
1103 | static void i915_hotplug_work_func(struct work_struct *work) |
855 | { |
1104 | { |
856 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, |
1105 | struct drm_i915_private *dev_priv = |
857 | hotplug_work); |
1106 | container_of(work, struct drm_i915_private, hotplug_work); |
858 | struct drm_device *dev = dev_priv->dev; |
1107 | struct drm_device *dev = dev_priv->dev; |
859 | struct drm_mode_config *mode_config = &dev->mode_config; |
1108 | struct drm_mode_config *mode_config = &dev->mode_config; |
860 | struct intel_connector *intel_connector; |
1109 | struct intel_connector *intel_connector; |
861 | struct intel_encoder *intel_encoder; |
1110 | struct intel_encoder *intel_encoder; |
862 | struct drm_connector *connector; |
1111 | struct drm_connector *connector; |
863 | unsigned long irqflags; |
1112 | unsigned long irqflags; |
864 | bool hpd_disabled = false; |
1113 | bool hpd_disabled = false; |
865 | bool changed = false; |
1114 | bool changed = false; |
Line 866... | Line -... | ||
866 | u32 hpd_event_bits; |
- | |
867 | - | ||
868 | /* HPD irq before everything is fully set up. */ |
- | |
869 | if (!dev_priv->enable_hotplug_processing) |
- | |
870 | return; |
1115 | u32 hpd_event_bits; |
871 | 1116 | ||
Line 872... | Line 1117... | ||
872 | mutex_lock(&mode_config->mutex); |
1117 | mutex_lock(&mode_config->mutex); |
Line 873... | Line 1118... | ||
873 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); |
1118 | DRM_DEBUG_KMS("running encoder hotplug functions\n"); |
874 | 1119 | ||
875 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1120 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
876 | 1121 | ||
- | 1122 | hpd_event_bits = dev_priv->hpd_event_bits; |
|
- | 1123 | dev_priv->hpd_event_bits = 0; |
|
877 | hpd_event_bits = dev_priv->hpd_event_bits; |
1124 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
878 | dev_priv->hpd_event_bits = 0; |
1125 | intel_connector = to_intel_connector(connector); |
879 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
1126 | if (!intel_connector->encoder) |
880 | intel_connector = to_intel_connector(connector); |
1127 | continue; |
881 | intel_encoder = intel_connector->encoder; |
1128 | intel_encoder = intel_connector->encoder; |
882 | if (intel_encoder->hpd_pin > HPD_NONE && |
1129 | if (intel_encoder->hpd_pin > HPD_NONE && |
883 | dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_MARK_DISABLED && |
1130 | dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_MARK_DISABLED && |
884 | connector->polled == DRM_CONNECTOR_POLL_HPD) { |
1131 | connector->polled == DRM_CONNECTOR_POLL_HPD) { |
885 | DRM_INFO("HPD interrupt storm detected on connector %s: " |
1132 | DRM_INFO("HPD interrupt storm detected on connector %s: " |
886 | "switching from hotplug detection to polling\n", |
1133 | "switching from hotplug detection to polling\n", |
887 | drm_get_connector_name(connector)); |
1134 | connector->name); |
888 | dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark = HPD_DISABLED; |
1135 | dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark = HPD_DISABLED; |
889 | connector->polled = DRM_CONNECTOR_POLL_CONNECT |
1136 | connector->polled = DRM_CONNECTOR_POLL_CONNECT |
890 | | DRM_CONNECTOR_POLL_DISCONNECT; |
1137 | | DRM_CONNECTOR_POLL_DISCONNECT; |
891 | hpd_disabled = true; |
1138 | hpd_disabled = true; |
892 | } |
1139 | } |
893 | if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { |
1140 | if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { |
894 | DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n", |
1141 | DRM_DEBUG_KMS("Connector %s (pin %i) received hotplug event.\n", |
895 | drm_get_connector_name(connector), intel_encoder->hpd_pin); |
1142 | connector->name, intel_encoder->hpd_pin); |
896 | } |
1143 | } |
897 | } |
- | |
898 | /* if there were no outputs to poll, poll was disabled, |
- | |
899 | * therefore make sure it's enabled when disabling HPD on |
- | |
900 | * some connectors */ |
- | |
901 | if (hpd_disabled) { |
- | |
Line 902... | Line 1144... | ||
902 | drm_kms_helper_poll_enable(dev); |
1144 | } |
Line 903... | Line 1145... | ||
903 | mod_timer(&dev_priv->hotplug_reenable_timer, |
1145 | /* if there were no outputs to poll, poll was disabled, |
904 | GetTimerTicks() + msecs_to_jiffies(I915_REENABLE_HOTPLUG_DELAY)); |
1146 | * therefore make sure it's enabled when disabling HPD on |
- | 1147 | * some connectors */ |
|
- | 1148 | ||
905 | } |
1149 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
906 | 1150 | ||
907 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1151 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
908 | 1152 | intel_connector = to_intel_connector(connector); |
|
909 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
1153 | if (!intel_connector->encoder) |
910 | intel_connector = to_intel_connector(connector); |
1154 | continue; |
911 | intel_encoder = intel_connector->encoder; |
1155 | intel_encoder = intel_connector->encoder; |
912 | if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { |
1156 | if (hpd_event_bits & (1 << intel_encoder->hpd_pin)) { |
913 | if (intel_encoder->hot_plug) |
1157 | if (intel_encoder->hot_plug) |
Line 914... | Line -... | ||
914 | intel_encoder->hot_plug(intel_encoder); |
- | |
915 | if (intel_hpd_irq_event(dev, connector)) |
- | |
916 | changed = true; |
1158 | intel_encoder->hot_plug(intel_encoder); |
Line 917... | Line 1159... | ||
917 | } |
1159 | if (intel_hpd_irq_event(dev, connector)) |
918 | } |
1160 | changed = true; |
919 | mutex_unlock(&mode_config->mutex); |
1161 | } |
920 | 1162 | } |
|
921 | if (changed) |
1163 | mutex_unlock(&mode_config->mutex); |
Line 922... | Line 1164... | ||
922 | drm_kms_helper_hotplug_event(dev); |
1164 | |
Line 960... | Line 1202... | ||
960 | 1202 | ||
961 | return; |
1203 | return; |
Line 962... | Line 1204... | ||
962 | } |
1204 | } |
963 | 1205 | ||
964 | static void notify_ring(struct drm_device *dev, |
1206 | static void notify_ring(struct drm_device *dev, |
965 | struct intel_ring_buffer *ring) |
1207 | struct intel_engine_cs *ring) |
966 | { |
1208 | { |
Line 967... | Line 1209... | ||
967 | if (ring->obj == NULL) |
1209 | if (!intel_ring_initialized(ring)) |
Line 968... | Line 1210... | ||
968 | return; |
1210 | return; |
969 | 1211 | ||
Line -... | Line 1212... | ||
- | 1212 | trace_i915_gem_request_complete(ring); |
|
- | 1213 | ||
- | 1214 | wake_up_all(&ring->irq_queue); |
|
- | 1215 | } |
|
- | 1216 | ||
- | 1217 | static u32 vlv_c0_residency(struct drm_i915_private *dev_priv, |
|
- | 1218 | struct intel_rps_ei *rps_ei) |
|
- | 1219 | { |
|
- | 1220 | u32 cz_ts, cz_freq_khz; |
|
- | 1221 | u32 render_count, media_count; |
|
- | 1222 | u32 elapsed_render, elapsed_media, elapsed_time; |
|
- | 1223 | u32 residency = 0; |
|
- | 1224 | ||
- | 1225 | cz_ts = vlv_punit_read(dev_priv, PUNIT_REG_CZ_TIMESTAMP); |
|
- | 1226 | cz_freq_khz = DIV_ROUND_CLOSEST(dev_priv->mem_freq * 1000, 4); |
|
- | 1227 | ||
- | 1228 | render_count = I915_READ(VLV_RENDER_C0_COUNT_REG); |
|
- | 1229 | media_count = I915_READ(VLV_MEDIA_C0_COUNT_REG); |
|
- | 1230 | ||
- | 1231 | if (rps_ei->cz_clock == 0) { |
|
- | 1232 | rps_ei->cz_clock = cz_ts; |
|
- | 1233 | rps_ei->render_c0 = render_count; |
|
- | 1234 | rps_ei->media_c0 = media_count; |
|
- | 1235 | ||
- | 1236 | return dev_priv->rps.cur_freq; |
|
- | 1237 | } |
|
- | 1238 | ||
- | 1239 | elapsed_time = cz_ts - rps_ei->cz_clock; |
|
- | 1240 | rps_ei->cz_clock = cz_ts; |
|
- | 1241 | ||
- | 1242 | elapsed_render = render_count - rps_ei->render_c0; |
|
- | 1243 | rps_ei->render_c0 = render_count; |
|
- | 1244 | ||
- | 1245 | elapsed_media = media_count - rps_ei->media_c0; |
|
- | 1246 | rps_ei->media_c0 = media_count; |
|
- | 1247 | ||
- | 1248 | /* Convert all the counters into common unit of milli sec */ |
|
- | 1249 | elapsed_time /= VLV_CZ_CLOCK_TO_MILLI_SEC; |
|
- | 1250 | elapsed_render /= cz_freq_khz; |
|
- | 1251 | elapsed_media /= cz_freq_khz; |
|
- | 1252 | ||
- | 1253 | /* |
|
- | 1254 | * Calculate overall C0 residency percentage |
|
- | 1255 | * only if elapsed time is non zero |
|
- | 1256 | */ |
|
- | 1257 | if (elapsed_time) { |
|
- | 1258 | residency = |
|
- | 1259 | ((max(elapsed_render, elapsed_media) * 100) |
|
- | 1260 | / elapsed_time); |
|
- | 1261 | } |
|
- | 1262 | ||
- | 1263 | return residency; |
|
- | 1264 | } |
|
- | 1265 | ||
- | 1266 | /** |
|
- | 1267 | * vlv_calc_delay_from_C0_counters - Increase/Decrease freq based on GPU |
|
- | 1268 | * busy-ness calculated from C0 counters of render & media power wells |
|
- | 1269 | * @dev_priv: DRM device private |
|
- | 1270 | * |
|
- | 1271 | */ |
|
- | 1272 | static u32 vlv_calc_delay_from_C0_counters(struct drm_i915_private *dev_priv) |
|
- | 1273 | { |
|
- | 1274 | u32 residency_C0_up = 0, residency_C0_down = 0; |
|
- | 1275 | u8 new_delay, adj; |
|
- | 1276 | ||
- | 1277 | dev_priv->rps.ei_interrupt_count++; |
|
- | 1278 | ||
- | 1279 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); |
|
- | 1280 | ||
- | 1281 | ||
- | 1282 | if (dev_priv->rps.up_ei.cz_clock == 0) { |
|
- | 1283 | vlv_c0_residency(dev_priv, &dev_priv->rps.up_ei); |
|
- | 1284 | vlv_c0_residency(dev_priv, &dev_priv->rps.down_ei); |
|
- | 1285 | return dev_priv->rps.cur_freq; |
|
- | 1286 | } |
|
- | 1287 | ||
- | 1288 | ||
- | 1289 | /* |
|
- | 1290 | * To down throttle, C0 residency should be less than down threshold |
|
- | 1291 | * for continous EI intervals. So calculate down EI counters |
|
- | 1292 | * once in VLV_INT_COUNT_FOR_DOWN_EI |
|
- | 1293 | */ |
|
- | 1294 | if (dev_priv->rps.ei_interrupt_count == VLV_INT_COUNT_FOR_DOWN_EI) { |
|
- | 1295 | ||
- | 1296 | dev_priv->rps.ei_interrupt_count = 0; |
|
- | 1297 | ||
- | 1298 | residency_C0_down = vlv_c0_residency(dev_priv, |
|
- | 1299 | &dev_priv->rps.down_ei); |
|
- | 1300 | } else { |
|
- | 1301 | residency_C0_up = vlv_c0_residency(dev_priv, |
|
- | 1302 | &dev_priv->rps.up_ei); |
|
- | 1303 | } |
|
- | 1304 | ||
- | 1305 | new_delay = dev_priv->rps.cur_freq; |
|
- | 1306 | ||
- | 1307 | adj = dev_priv->rps.last_adj; |
|
- | 1308 | /* C0 residency is greater than UP threshold. Increase Frequency */ |
|
- | 1309 | if (residency_C0_up >= VLV_RP_UP_EI_THRESHOLD) { |
|
- | 1310 | if (adj > 0) |
|
- | 1311 | adj *= 2; |
|
- | 1312 | else |
|
- | 1313 | adj = 1; |
|
- | 1314 | ||
- | 1315 | if (dev_priv->rps.cur_freq < dev_priv->rps.max_freq_softlimit) |
|
- | 1316 | new_delay = dev_priv->rps.cur_freq + adj; |
|
- | 1317 | ||
- | 1318 | /* |
|
- | 1319 | * For better performance, jump directly |
|
- | 1320 | * to RPe if we're below it. |
|
- | 1321 | */ |
|
- | 1322 | if (new_delay < dev_priv->rps.efficient_freq) |
|
- | 1323 | new_delay = dev_priv->rps.efficient_freq; |
|
- | 1324 | ||
- | 1325 | } else if (!dev_priv->rps.ei_interrupt_count && |
|
- | 1326 | (residency_C0_down < VLV_RP_DOWN_EI_THRESHOLD)) { |
|
- | 1327 | if (adj < 0) |
|
- | 1328 | adj *= 2; |
|
- | 1329 | else |
|
- | 1330 | adj = -1; |
|
- | 1331 | /* |
|
- | 1332 | * This means, C0 residency is less than down threshold over |
|
- | 1333 | * a period of VLV_INT_COUNT_FOR_DOWN_EI. So, reduce the freq |
|
- | 1334 | */ |
|
- | 1335 | if (dev_priv->rps.cur_freq > dev_priv->rps.min_freq_softlimit) |
|
- | 1336 | new_delay = dev_priv->rps.cur_freq + adj; |
|
970 | trace_i915_gem_request_complete(ring); |
1337 | } |
971 | 1338 | ||
972 | wake_up_all(&ring->irq_queue); |
1339 | return new_delay; |
973 | } |
1340 | } |
974 | 1341 | ||
975 | static void gen6_pm_rps_work(struct work_struct *work) |
1342 | static void gen6_pm_rps_work(struct work_struct *work) |
Line 976... | Line 1343... | ||
976 | { |
1343 | { |
977 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, |
1344 | struct drm_i915_private *dev_priv = |
978 | rps.work); |
1345 | container_of(work, struct drm_i915_private, rps.work); |
- | 1346 | u32 pm_iir; |
|
- | 1347 | int new_delay, adj; |
|
- | 1348 | ||
979 | u32 pm_iir; |
1349 | spin_lock_irq(&dev_priv->irq_lock); |
980 | int new_delay, adj; |
1350 | pm_iir = dev_priv->rps.pm_iir; |
- | 1351 | dev_priv->rps.pm_iir = 0; |
|
981 | 1352 | if (INTEL_INFO(dev_priv->dev)->gen >= 8) |
|
Line 982... | Line 1353... | ||
982 | spin_lock_irq(&dev_priv->irq_lock); |
1353 | gen8_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
983 | pm_iir = dev_priv->rps.pm_iir; |
1354 | else { |
Line 984... | Line 1355... | ||
984 | dev_priv->rps.pm_iir = 0; |
1355 | /* Make sure not to corrupt PMIMR state used by ringbuffer */ |
985 | /* Make sure not to corrupt PMIMR state used by ringbuffer code */ |
1356 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
Line 986... | Line 1357... | ||
986 | snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); |
1357 | } |
Line 987... | Line 1358... | ||
987 | spin_unlock_irq(&dev_priv->irq_lock); |
1358 | spin_unlock_irq(&dev_priv->irq_lock); |
988 | 1359 | ||
989 | /* Make sure we didn't queue anything we're not going to process. */ |
1360 | /* Make sure we didn't queue anything we're not going to process. */ |
990 | WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS); |
1361 | WARN_ON(pm_iir & ~dev_priv->pm_rps_events); |
991 | 1362 | ||
- | 1363 | if ((pm_iir & dev_priv->pm_rps_events) == 0) |
|
- | 1364 | return; |
|
992 | if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0) |
1365 | |
993 | return; |
1366 | mutex_lock(&dev_priv->rps.hw_lock); |
Line 994... | Line 1367... | ||
994 | 1367 | ||
995 | mutex_lock(&dev_priv->rps.hw_lock); |
1368 | adj = dev_priv->rps.last_adj; |
996 | 1369 | if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { |
|
997 | adj = dev_priv->rps.last_adj; |
1370 | if (adj > 0) |
998 | if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { |
1371 | adj *= 2; |
999 | if (adj > 0) |
1372 | else { |
1000 | adj *= 2; |
1373 | /* CHV needs even encode values */ |
1001 | else |
1374 | adj = IS_CHERRYVIEW(dev_priv->dev) ? 2 : 1; |
1002 | adj = 1; |
1375 | } |
1003 | new_delay = dev_priv->rps.cur_delay + adj; |
1376 | new_delay = dev_priv->rps.cur_freq + adj; |
1004 | 1377 | ||
1005 | /* |
1378 | /* |
- | 1379 | * For better performance, jump directly |
|
- | 1380 | * to RPe if we're below it. |
|
1006 | * For better performance, jump directly |
1381 | */ |
1007 | * to RPe if we're below it. |
1382 | if (new_delay < dev_priv->rps.efficient_freq) |
1008 | */ |
1383 | new_delay = dev_priv->rps.efficient_freq; |
1009 | if (new_delay < dev_priv->rps.rpe_delay) |
1384 | } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) { |
- | 1385 | if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq) |
|
- | 1386 | new_delay = dev_priv->rps.efficient_freq; |
|
1010 | new_delay = dev_priv->rps.rpe_delay; |
1387 | else |
1011 | } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) { |
1388 | new_delay = dev_priv->rps.min_freq_softlimit; |
1012 | if (dev_priv->rps.cur_delay > dev_priv->rps.rpe_delay) |
1389 | adj = 0; |
1013 | new_delay = dev_priv->rps.rpe_delay; |
1390 | } else if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) { |
1014 | else |
1391 | new_delay = vlv_calc_delay_from_C0_counters(dev_priv); |
Line 1015... | Line 1392... | ||
1015 | new_delay = dev_priv->rps.min_delay; |
1392 | } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) { |
1016 | adj = 0; |
1393 | if (adj < 0) |
1017 | } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) { |
1394 | adj *= 2; |
1018 | if (adj < 0) |
1395 | else { |
- | 1396 | /* CHV needs even encode values */ |
|
1019 | adj *= 2; |
1397 | adj = IS_CHERRYVIEW(dev_priv->dev) ? -2 : -1; |
- | 1398 | } |
|
1020 | else |
1399 | new_delay = dev_priv->rps.cur_freq + adj; |
Line 1021... | Line 1400... | ||
1021 | adj = -1; |
1400 | } else { /* unknown event */ |
1022 | new_delay = dev_priv->rps.cur_delay + adj; |
1401 | new_delay = dev_priv->rps.cur_freq; |
1023 | } else { /* unknown event */ |
1402 | } |
1024 | new_delay = dev_priv->rps.cur_delay; |
1403 | |
Line 1049... | Line 1428... | ||
1049 | * this event, userspace should try to remap the bad rows since statistically |
1428 | * this event, userspace should try to remap the bad rows since statistically |
1050 | * it is likely the same row is more likely to go bad again. |
1429 | * it is likely the same row is more likely to go bad again. |
1051 | */ |
1430 | */ |
1052 | static void ivybridge_parity_work(struct work_struct *work) |
1431 | static void ivybridge_parity_work(struct work_struct *work) |
1053 | { |
1432 | { |
1054 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, |
1433 | struct drm_i915_private *dev_priv = |
1055 | l3_parity.error_work); |
1434 | container_of(work, struct drm_i915_private, l3_parity.error_work); |
1056 | u32 error_status, row, bank, subbank; |
1435 | u32 error_status, row, bank, subbank; |
1057 | char *parity_event[6]; |
1436 | char *parity_event[6]; |
1058 | uint32_t misccpctl; |
1437 | uint32_t misccpctl; |
1059 | unsigned long flags; |
1438 | unsigned long flags; |
1060 | uint8_t slice = 0; |
1439 | uint8_t slice = 0; |
Line 1100... | Line 1479... | ||
1100 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); |
1479 | I915_WRITE(GEN7_MISCCPCTL, misccpctl); |
Line 1101... | Line 1480... | ||
1101 | 1480 | ||
1102 | out: |
1481 | out: |
1103 | WARN_ON(dev_priv->l3_parity.which_slice); |
1482 | WARN_ON(dev_priv->l3_parity.which_slice); |
1104 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
1483 | spin_lock_irqsave(&dev_priv->irq_lock, flags); |
1105 | ilk_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv->dev)); |
1484 | gen5_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv->dev)); |
Line 1106... | Line 1485... | ||
1106 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
1485 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
1107 | 1486 | ||
Line 1108... | Line 1487... | ||
1108 | mutex_unlock(&dev_priv->dev->struct_mutex); |
1487 | mutex_unlock(&dev_priv->dev->struct_mutex); |
1109 | } |
1488 | } |
1110 | 1489 | ||
Line 1111... | Line 1490... | ||
1111 | static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir) |
1490 | static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir) |
1112 | { |
1491 | { |
Line 1113... | Line 1492... | ||
1113 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1492 | struct drm_i915_private *dev_priv = dev->dev_private; |
1114 | 1493 | ||
1115 | if (!HAS_L3_DPF(dev)) |
1494 | if (!HAS_L3_DPF(dev)) |
Line 1116... | Line 1495... | ||
1116 | return; |
1495 | return; |
1117 | 1496 | ||
1118 | spin_lock(&dev_priv->irq_lock); |
1497 | spin_lock(&dev_priv->irq_lock); |
Line 1154... | Line 1533... | ||
1154 | notify_ring(dev, &dev_priv->ring[BCS]); |
1533 | notify_ring(dev, &dev_priv->ring[BCS]); |
Line 1155... | Line 1534... | ||
1155 | 1534 | ||
1156 | if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | |
1535 | if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | |
1157 | GT_BSD_CS_ERROR_INTERRUPT | |
1536 | GT_BSD_CS_ERROR_INTERRUPT | |
1158 | GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) { |
1537 | GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) { |
1159 | DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); |
1538 | i915_handle_error(dev, false, "GT error interrupt 0x%08x", |
1160 | i915_handle_error(dev, false); |
1539 | gt_iir); |
Line 1161... | Line 1540... | ||
1161 | } |
1540 | } |
1162 | 1541 | ||
1163 | if (gt_iir & GT_PARITY_ERROR(dev)) |
1542 | if (gt_iir & GT_PARITY_ERROR(dev)) |
Line -... | Line 1543... | ||
- | 1543 | ivybridge_parity_error_irq_handler(dev, gt_iir); |
|
- | 1544 | } |
|
- | 1545 | ||
- | 1546 | static void gen8_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) |
|
- | 1547 | { |
|
- | 1548 | if ((pm_iir & dev_priv->pm_rps_events) == 0) |
|
- | 1549 | return; |
|
- | 1550 | ||
- | 1551 | spin_lock(&dev_priv->irq_lock); |
|
- | 1552 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; |
|
- | 1553 | gen8_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); |
|
- | 1554 | spin_unlock(&dev_priv->irq_lock); |
|
- | 1555 | ||
1164 | ivybridge_parity_error_irq_handler(dev, gt_iir); |
1556 | queue_work(dev_priv->wq, &dev_priv->rps.work); |
1165 | } |
1557 | } |
1166 | 1558 | ||
1167 | static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, |
1559 | static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, |
1168 | struct drm_i915_private *dev_priv, |
1560 | struct drm_i915_private *dev_priv, |
Line 1173... | Line 1565... | ||
1173 | irqreturn_t ret = IRQ_NONE; |
1565 | irqreturn_t ret = IRQ_NONE; |
Line 1174... | Line 1566... | ||
1174 | 1566 | ||
1175 | if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) { |
1567 | if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) { |
1176 | tmp = I915_READ(GEN8_GT_IIR(0)); |
1568 | tmp = I915_READ(GEN8_GT_IIR(0)); |
- | 1569 | if (tmp) { |
|
1177 | if (tmp) { |
1570 | I915_WRITE(GEN8_GT_IIR(0), tmp); |
1178 | ret = IRQ_HANDLED; |
1571 | ret = IRQ_HANDLED; |
1179 | rcs = tmp >> GEN8_RCS_IRQ_SHIFT; |
1572 | rcs = tmp >> GEN8_RCS_IRQ_SHIFT; |
1180 | bcs = tmp >> GEN8_BCS_IRQ_SHIFT; |
1573 | bcs = tmp >> GEN8_BCS_IRQ_SHIFT; |
1181 | if (rcs & GT_RENDER_USER_INTERRUPT) |
1574 | if (rcs & GT_RENDER_USER_INTERRUPT) |
1182 | notify_ring(dev, &dev_priv->ring[RCS]); |
1575 | notify_ring(dev, &dev_priv->ring[RCS]); |
1183 | if (bcs & GT_RENDER_USER_INTERRUPT) |
1576 | if (bcs & GT_RENDER_USER_INTERRUPT) |
1184 | notify_ring(dev, &dev_priv->ring[BCS]); |
- | |
1185 | I915_WRITE(GEN8_GT_IIR(0), tmp); |
1577 | notify_ring(dev, &dev_priv->ring[BCS]); |
1186 | } else |
1578 | } else |
1187 | DRM_ERROR("The master control interrupt lied (GT0)!\n"); |
1579 | DRM_ERROR("The master control interrupt lied (GT0)!\n"); |
Line 1188... | Line 1580... | ||
1188 | } |
1580 | } |
1189 | 1581 | ||
1190 | if (master_ctl & GEN8_GT_VCS1_IRQ) { |
1582 | if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) { |
- | 1583 | tmp = I915_READ(GEN8_GT_IIR(1)); |
|
1191 | tmp = I915_READ(GEN8_GT_IIR(1)); |
1584 | if (tmp) { |
1192 | if (tmp) { |
1585 | I915_WRITE(GEN8_GT_IIR(1), tmp); |
1193 | ret = IRQ_HANDLED; |
1586 | ret = IRQ_HANDLED; |
1194 | vcs = tmp >> GEN8_VCS1_IRQ_SHIFT; |
1587 | vcs = tmp >> GEN8_VCS1_IRQ_SHIFT; |
1195 | if (vcs & GT_RENDER_USER_INTERRUPT) |
1588 | if (vcs & GT_RENDER_USER_INTERRUPT) |
- | 1589 | notify_ring(dev, &dev_priv->ring[VCS]); |
|
- | 1590 | vcs = tmp >> GEN8_VCS2_IRQ_SHIFT; |
|
1196 | notify_ring(dev, &dev_priv->ring[VCS]); |
1591 | if (vcs & GT_RENDER_USER_INTERRUPT) |
1197 | I915_WRITE(GEN8_GT_IIR(1), tmp); |
1592 | notify_ring(dev, &dev_priv->ring[VCS2]); |
1198 | } else |
1593 | } else |
Line -... | Line 1594... | ||
- | 1594 | DRM_ERROR("The master control interrupt lied (GT1)!\n"); |
|
- | 1595 | } |
|
- | 1596 | ||
- | 1597 | if (master_ctl & GEN8_GT_PM_IRQ) { |
|
- | 1598 | tmp = I915_READ(GEN8_GT_IIR(2)); |
|
- | 1599 | if (tmp & dev_priv->pm_rps_events) { |
|
- | 1600 | I915_WRITE(GEN8_GT_IIR(2), |
|
- | 1601 | tmp & dev_priv->pm_rps_events); |
|
- | 1602 | ret = IRQ_HANDLED; |
|
- | 1603 | gen8_rps_irq_handler(dev_priv, tmp); |
|
- | 1604 | } else |
|
1199 | DRM_ERROR("The master control interrupt lied (GT1)!\n"); |
1605 | DRM_ERROR("The master control interrupt lied (PM)!\n"); |
1200 | } |
1606 | } |
1201 | 1607 | ||
- | 1608 | if (master_ctl & GEN8_GT_VECS_IRQ) { |
|
1202 | if (master_ctl & GEN8_GT_VECS_IRQ) { |
1609 | tmp = I915_READ(GEN8_GT_IIR(3)); |
1203 | tmp = I915_READ(GEN8_GT_IIR(3)); |
1610 | if (tmp) { |
1204 | if (tmp) { |
1611 | I915_WRITE(GEN8_GT_IIR(3), tmp); |
1205 | ret = IRQ_HANDLED; |
1612 | ret = IRQ_HANDLED; |
1206 | vcs = tmp >> GEN8_VECS_IRQ_SHIFT; |
- | |
1207 | if (vcs & GT_RENDER_USER_INTERRUPT) |
1613 | vcs = tmp >> GEN8_VECS_IRQ_SHIFT; |
1208 | notify_ring(dev, &dev_priv->ring[VECS]); |
1614 | if (vcs & GT_RENDER_USER_INTERRUPT) |
1209 | I915_WRITE(GEN8_GT_IIR(3), tmp); |
1615 | notify_ring(dev, &dev_priv->ring[VECS]); |
Line 1210... | Line 1616... | ||
1210 | } else |
1616 | } else |
1211 | DRM_ERROR("The master control interrupt lied (GT3)!\n"); |
1617 | DRM_ERROR("The master control interrupt lied (GT3)!\n"); |
Line 1212... | Line 1618... | ||
1212 | } |
1618 | } |
1213 | 1619 | ||
Line -... | Line 1620... | ||
- | 1620 | return ret; |
|
- | 1621 | } |
|
- | 1622 | ||
- | 1623 | #define HPD_STORM_DETECT_PERIOD 1000 |
|
- | 1624 | #define HPD_STORM_THRESHOLD 5 |
|
- | 1625 | ||
- | 1626 | static int ilk_port_to_hotplug_shift(enum port port) |
|
- | 1627 | { |
|
- | 1628 | switch (port) { |
|
- | 1629 | case PORT_A: |
|
- | 1630 | case PORT_E: |
|
- | 1631 | default: |
|
- | 1632 | return -1; |
|
- | 1633 | case PORT_B: |
|
- | 1634 | return 0; |
|
- | 1635 | case PORT_C: |
|
- | 1636 | return 8; |
|
- | 1637 | case PORT_D: |
|
- | 1638 | return 16; |
|
- | 1639 | } |
|
- | 1640 | } |
|
- | 1641 | ||
- | 1642 | static int g4x_port_to_hotplug_shift(enum port port) |
|
- | 1643 | { |
|
- | 1644 | switch (port) { |
|
- | 1645 | case PORT_A: |
|
- | 1646 | case PORT_E: |
|
- | 1647 | default: |
|
- | 1648 | return -1; |
|
- | 1649 | case PORT_B: |
|
- | 1650 | return 17; |
|
- | 1651 | case PORT_C: |
|
- | 1652 | return 19; |
|
- | 1653 | case PORT_D: |
|
- | 1654 | return 21; |
|
- | 1655 | } |
|
- | 1656 | } |
|
- | 1657 | ||
- | 1658 | static inline enum port get_port_from_pin(enum hpd_pin pin) |
|
- | 1659 | { |
|
- | 1660 | switch (pin) { |
|
- | 1661 | case HPD_PORT_B: |
|
- | 1662 | return PORT_B; |
|
- | 1663 | case HPD_PORT_C: |
|
- | 1664 | return PORT_C; |
|
- | 1665 | case HPD_PORT_D: |
|
1214 | return ret; |
1666 | return PORT_D; |
1215 | } |
1667 | default: |
- | 1668 | return PORT_A; /* no hpd */ |
|
1216 | 1669 | } |
|
1217 | #define HPD_STORM_DETECT_PERIOD 1000 |
1670 | } |
1218 | #define HPD_STORM_THRESHOLD 5 |
1671 | |
1219 | 1672 | static inline void intel_hpd_irq_handler(struct drm_device *dev, |
|
- | 1673 | u32 hotplug_trigger, |
|
1220 | static inline void intel_hpd_irq_handler(struct drm_device *dev, |
1674 | u32 dig_hotplug_reg, |
- | 1675 | const u32 *hpd) |
|
- | 1676 | { |
|
- | 1677 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
Line 1221... | Line 1678... | ||
1221 | u32 hotplug_trigger, |
1678 | int i; |
1222 | const u32 *hpd) |
1679 | enum port port; |
Line -... | Line 1680... | ||
- | 1680 | bool storm_detected = false; |
|
- | 1681 | bool queue_dig = false, queue_hp = false; |
|
- | 1682 | u32 dig_shift; |
|
1223 | { |
1683 | u32 dig_port_mask = 0; |
1224 | drm_i915_private_t *dev_priv = dev->dev_private; |
1684 | |
- | 1685 | if (!hotplug_trigger) |
|
- | 1686 | return; |
|
- | 1687 | ||
- | 1688 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x, dig 0x%08x\n", |
|
- | 1689 | hotplug_trigger, dig_hotplug_reg); |
|
- | 1690 | ||
Line -... | Line 1691... | ||
- | 1691 | spin_lock(&dev_priv->irq_lock); |
|
- | 1692 | for (i = 1; i < HPD_NUM_PINS; i++) { |
|
- | 1693 | if (!(hpd[i] & hotplug_trigger)) |
|
- | 1694 | continue; |
|
- | 1695 | ||
- | 1696 | port = get_port_from_pin(i); |
|
- | 1697 | if (port && dev_priv->hpd_irq_port[port]) { |
|
- | 1698 | bool long_hpd; |
|
- | 1699 | ||
- | 1700 | if (IS_G4X(dev)) { |
|
- | 1701 | dig_shift = g4x_port_to_hotplug_shift(port); |
|
- | 1702 | long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; |
|
- | 1703 | } else { |
|
- | 1704 | dig_shift = ilk_port_to_hotplug_shift(port); |
|
- | 1705 | long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; |
|
- | 1706 | } |
|
- | 1707 | ||
- | 1708 | DRM_DEBUG_DRIVER("digital hpd port %d %d\n", port, long_hpd); |
|
- | 1709 | /* for long HPD pulses we want to have the digital queue happen, |
|
- | 1710 | but we still want HPD storm detection to function. */ |
|
- | 1711 | if (long_hpd) { |
|
- | 1712 | dev_priv->long_hpd_port_mask |= (1 << port); |
|
- | 1713 | dig_port_mask |= hpd[i]; |
|
- | 1714 | } else { |
|
1225 | int i; |
1715 | /* for short HPD just trigger the digital queue */ |
1226 | bool storm_detected = false; |
1716 | dev_priv->short_hpd_port_mask |= (1 << port); |
- | 1717 | hotplug_trigger &= ~hpd[i]; |
|
- | 1718 | } |
|
- | 1719 | queue_dig = true; |
|
- | 1720 | } |
|
- | 1721 | } |
|
- | 1722 | ||
- | 1723 | for (i = 1; i < HPD_NUM_PINS; i++) { |
|
1227 | 1724 | if (hpd[i] & hotplug_trigger && |
|
1228 | if (!hotplug_trigger) |
1725 | dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED) { |
Line -... | Line 1726... | ||
- | 1726 | /* |
|
- | 1727 | * On GMCH platforms the interrupt mask bits only |
|
- | 1728 | * prevent irq generation, not the setting of the |
|
1229 | return; |
1729 | * hotplug bits itself. So only WARN about unexpected |
1230 | 1730 | * interrupts on saner platforms. |
|
1231 | spin_lock(&dev_priv->irq_lock); |
1731 | */ |
Line -... | Line 1732... | ||
- | 1732 | WARN_ONCE(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev), |
|
1232 | for (i = 1; i < HPD_NUM_PINS; i++) { |
1733 | "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", |
- | 1734 | hotplug_trigger, i, hpd[i]); |
|
- | 1735 | ||
- | 1736 | continue; |
|
1233 | 1737 | } |
|
1234 | WARN_ONCE(hpd[i] & hotplug_trigger && |
1738 | |
1235 | dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED, |
1739 | if (!(hpd[i] & hotplug_trigger) || |
1236 | "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", |
1740 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) |
1237 | hotplug_trigger, i, hpd[i]); |
1741 | continue; |
1238 | 1742 | ||
1239 | if (!(hpd[i] & hotplug_trigger) || |
1743 | if (!(dig_port_mask & hpd[i])) { |
1240 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) |
1744 | dev_priv->hpd_event_bits |= (1 << i); |
1241 | continue; |
1745 | queue_hp = true; |
Line 1267... | Line 1771... | ||
1267 | * Our hotplug handler can grab modeset locks (by calling down into the |
1771 | * Our hotplug handler can grab modeset locks (by calling down into the |
1268 | * fb helpers). Hence it must not be run on our own dev-priv->wq work |
1772 | * fb helpers). Hence it must not be run on our own dev-priv->wq work |
1269 | * queue for otherwise the flush_work in the pageflip code will |
1773 | * queue for otherwise the flush_work in the pageflip code will |
1270 | * deadlock. |
1774 | * deadlock. |
1271 | */ |
1775 | */ |
- | 1776 | if (queue_hp) |
|
1272 | schedule_work(&dev_priv->hotplug_work); |
1777 | schedule_work(&dev_priv->hotplug_work); |
1273 | } |
1778 | } |
Line 1274... | Line 1779... | ||
1274 | 1779 | ||
1275 | static void gmbus_irq_handler(struct drm_device *dev) |
1780 | static void gmbus_irq_handler(struct drm_device *dev) |
1276 | { |
1781 | { |
Line 1277... | Line 1782... | ||
1277 | struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1782 | struct drm_i915_private *dev_priv = dev->dev_private; |
1278 | 1783 | ||
Line 1279... | Line 1784... | ||
1279 | wake_up_all(&dev_priv->gmbus_wait_queue); |
1784 | wake_up_all(&dev_priv->gmbus_wait_queue); |
1280 | } |
1785 | } |
1281 | 1786 | ||
Line 1282... | Line 1787... | ||
1282 | static void dp_aux_irq_handler(struct drm_device *dev) |
1787 | static void dp_aux_irq_handler(struct drm_device *dev) |
1283 | { |
1788 | { |
Line 1284... | Line 1789... | ||
1284 | struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1789 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 1385... | Line 1890... | ||
1385 | /* The RPS events need forcewake, so we add them to a work queue and mask their |
1890 | /* The RPS events need forcewake, so we add them to a work queue and mask their |
1386 | * IMR bits until the work is done. Other interrupts can be processed without |
1891 | * IMR bits until the work is done. Other interrupts can be processed without |
1387 | * the work queue. */ |
1892 | * the work queue. */ |
1388 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) |
1893 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) |
1389 | { |
1894 | { |
1390 | if (pm_iir & GEN6_PM_RPS_EVENTS) { |
1895 | if (pm_iir & dev_priv->pm_rps_events) { |
1391 | spin_lock(&dev_priv->irq_lock); |
1896 | spin_lock(&dev_priv->irq_lock); |
1392 | dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; |
1897 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; |
1393 | snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS); |
1898 | gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); |
1394 | spin_unlock(&dev_priv->irq_lock); |
1899 | spin_unlock(&dev_priv->irq_lock); |
Line 1395... | Line 1900... | ||
1395 | 1900 | ||
1396 | queue_work(dev_priv->wq, &dev_priv->rps.work); |
1901 | queue_work(dev_priv->wq, &dev_priv->rps.work); |
Line 1397... | Line 1902... | ||
1397 | } |
1902 | } |
1398 | 1903 | ||
1399 | if (HAS_VEBOX(dev_priv->dev)) { |
1904 | if (HAS_VEBOX(dev_priv->dev)) { |
Line 1400... | Line 1905... | ||
1400 | if (pm_iir & PM_VEBOX_USER_INTERRUPT) |
1905 | if (pm_iir & PM_VEBOX_USER_INTERRUPT) |
- | 1906 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); |
|
1401 | notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); |
1907 | |
1402 | 1908 | if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { |
|
1403 | if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { |
1909 | i915_handle_error(dev_priv->dev, false, |
1404 | DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir); |
1910 | "VEBOX CS error interrupt 0x%08x", |
1405 | i915_handle_error(dev_priv->dev, false); |
1911 | pm_iir); |
Line 1406... | Line 1912... | ||
1406 | } |
1912 | } |
1407 | } |
1913 | } |
1408 | } |
- | |
1409 | 1914 | } |
|
1410 | static irqreturn_t valleyview_irq_handler(int irq, void *arg) |
1915 | |
1411 | { |
- | |
1412 | struct drm_device *dev = (struct drm_device *) arg; |
- | |
1413 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1916 | static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) |
1414 | u32 iir, gt_iir, pm_iir; |
- | |
Line 1415... | Line 1917... | ||
1415 | irqreturn_t ret = IRQ_NONE; |
1917 | { |
1416 | unsigned long irqflags; |
- | |
1417 | int pipe; |
1918 | struct drm_i915_private *dev_priv = dev->dev_private; |
1418 | u32 pipe_stats[I915_MAX_PIPES]; |
1919 | u32 pipe_stats[I915_MAX_PIPES] = { }; |
1419 | 1920 | int pipe; |
|
1420 | atomic_inc(&dev_priv->irq_received); |
- | |
Line -... | Line 1921... | ||
- | 1921 | ||
1421 | 1922 | spin_lock(&dev_priv->irq_lock); |
|
- | 1923 | for_each_pipe(pipe) { |
|
- | 1924 | int reg; |
|
- | 1925 | u32 mask, iir_bit = 0; |
|
- | 1926 | ||
- | 1927 | /* |
|
1422 | while (true) { |
1928 | * PIPESTAT bits get signalled even when the interrupt is |
- | 1929 | * disabled with the mask bits, and some of the status bits do |
|
- | 1930 | * not generate interrupts at all (like the underrun bit). Hence |
|
Line -... | Line 1931... | ||
- | 1931 | * we need to be careful that we only handle what we want to |
|
1423 | iir = I915_READ(VLV_IIR); |
1932 | * handle. |
- | 1933 | */ |
|
- | 1934 | mask = 0; |
|
- | 1935 | if (__cpu_fifo_underrun_reporting_enabled(dev, pipe)) |
|
- | 1936 | mask |= PIPE_FIFO_UNDERRUN_STATUS; |
|
- | 1937 | ||
- | 1938 | switch (pipe) { |
|
- | 1939 | case PIPE_A: |
|
- | 1940 | iir_bit = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT; |
|
- | 1941 | break; |
|
- | 1942 | case PIPE_B: |
|
- | 1943 | iir_bit = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; |
|
Line -... | Line 1944... | ||
- | 1944 | break; |
|
1424 | gt_iir = I915_READ(GTIIR); |
1945 | case PIPE_C: |
Line 1425... | Line -... | ||
1425 | pm_iir = I915_READ(GEN6_PMIIR); |
- | |
1426 | 1946 | iir_bit = I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; |
|
1427 | if (gt_iir == 0 && pm_iir == 0 && iir == 0) |
1947 | break; |
1428 | goto out; |
1948 | } |
Line 1429... | Line 1949... | ||
1429 | 1949 | if (iir & iir_bit) |
|
1430 | ret = IRQ_HANDLED; |
1950 | mask |= dev_priv->pipestat_irq_mask[pipe]; |
1431 | 1951 | ||
1432 | snb_gt_irq_handler(dev, dev_priv, gt_iir); |
- | |
1433 | 1952 | if (!mask) |
|
1434 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
- | |
1435 | for_each_pipe(pipe) { |
1953 | continue; |
1436 | int reg = PIPESTAT(pipe); |
1954 | |
1437 | pipe_stats[pipe] = I915_READ(reg); |
1955 | reg = PIPESTAT(pipe); |
1438 | - | ||
1439 | /* |
1956 | mask |= PIPESTAT_INT_ENABLE_MASK; |
Line 1440... | Line 1957... | ||
1440 | * Clear the PIPE*STAT regs before the IIR |
1957 | pipe_stats[pipe] = I915_READ(reg) & mask; |
1441 | */ |
1958 | |
1442 | if (pipe_stats[pipe] & 0x8000ffff) { |
1959 | /* |
Line 1443... | Line 1960... | ||
1443 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) |
1960 | * Clear the PIPE*STAT regs before the IIR |
1444 | DRM_DEBUG_DRIVER("pipe %c underrun\n", |
1961 | */ |
1445 | pipe_name(pipe)); |
1962 | if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS | |
1446 | I915_WRITE(reg, pipe_stats[pipe]); |
1963 | PIPESTAT_INT_STATUS_MASK)) |
Line 1447... | Line 1964... | ||
1447 | } |
1964 | I915_WRITE(reg, pipe_stats[pipe]); |
1448 | } |
1965 | } |
- | 1966 | spin_unlock(&dev_priv->irq_lock); |
|
- | 1967 | ||
- | 1968 | for_each_pipe(pipe) { |
|
- | 1969 | // if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) |
|
1449 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1970 | // drm_handle_vblank(dev, pipe); |
Line -... | Line 1971... | ||
- | 1971 | ||
- | 1972 | if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV) { |
|
- | 1973 | // intel_prepare_page_flip(dev, pipe); |
|
- | 1974 | // intel_finish_page_flip(dev, pipe); |
|
1450 | 1975 | } |
|
- | 1976 | ||
1451 | for_each_pipe(pipe) { |
1977 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
1452 | // if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) |
1978 | i9xx_pipe_crc_irq_handler(dev, pipe); |
1453 | // drm_handle_vblank(dev, pipe); |
- | |
Line -... | Line 1979... | ||
- | 1979 | ||
- | 1980 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && |
|
- | 1981 | intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) |
|
1454 | 1982 | DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); |
|
1455 | if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) { |
1983 | } |
- | 1984 | ||
- | 1985 | if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) |
|
Line -... | Line 1986... | ||
- | 1986 | gmbus_irq_handler(dev); |
|
1456 | // intel_prepare_page_flip(dev, pipe); |
1987 | } |
Line 1457... | Line 1988... | ||
1457 | // intel_finish_page_flip(dev, pipe); |
1988 | |
- | 1989 | static void i9xx_hpd_irq_handler(struct drm_device *dev) |
|
1458 | } |
1990 | { |
Line 1459... | Line 1991... | ||
1459 | 1991 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
1460 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
- | |
1461 | i9xx_pipe_crc_irq_handler(dev, pipe); |
1992 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
Line -... | Line 1993... | ||
- | 1993 | ||
1462 | } |
1994 | if (hotplug_status) { |
1463 | 1995 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
|
- | 1996 | /* |
|
- | 1997 | * Make sure hotplug status is cleared before we clear IIR, or else we |
|
Line -... | Line 1998... | ||
- | 1998 | * may miss hotplug events. |
|
- | 1999 | */ |
|
- | 2000 | POSTING_READ(PORT_HOTPLUG_STAT); |
|
- | 2001 | ||
- | 2002 | if (IS_G4X(dev)) { |
|
- | 2003 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X; |
|
- | 2004 | ||
1464 | /* Consume port. Then clear IIR or we'll miss events */ |
2005 | intel_hpd_irq_handler(dev, hotplug_trigger, 0, hpd_status_g4x); |
1465 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
2006 | } else { |
Line -... | Line 2007... | ||
- | 2007 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; |
|
- | 2008 | ||
1466 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
2009 | intel_hpd_irq_handler(dev, hotplug_trigger, 0, hpd_status_i915); |
- | 2010 | } |
|
- | 2011 | ||
- | 2012 | if ((IS_G4X(dev) || IS_VALLEYVIEW(dev)) && |
|
1467 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; |
2013 | hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X) |
- | 2014 | dp_aux_irq_handler(dev); |
|
- | 2015 | } |
|
- | 2016 | } |
|
- | 2017 | ||
- | 2018 | static irqreturn_t valleyview_irq_handler(int irq, void *arg) |
|
- | 2019 | { |
|
1468 | 2020 | struct drm_device *dev = arg; |
|
1469 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
2021 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line -... | Line 2022... | ||
- | 2022 | u32 iir, gt_iir, pm_iir; |
|
- | 2023 | irqreturn_t ret = IRQ_NONE; |
|
- | 2024 | ||
- | 2025 | while (true) { |
|
- | 2026 | /* Find, clear, then process each source of interrupt */ |
|
- | 2027 | ||
- | 2028 | gt_iir = I915_READ(GTIIR); |
|
- | 2029 | if (gt_iir) |
|
- | 2030 | I915_WRITE(GTIIR, gt_iir); |
|
- | 2031 | ||
- | 2032 | pm_iir = I915_READ(GEN6_PMIIR); |
|
- | 2033 | if (pm_iir) |
|
- | 2034 | I915_WRITE(GEN6_PMIIR, pm_iir); |
|
- | 2035 | ||
1470 | hotplug_status); |
2036 | iir = I915_READ(VLV_IIR); |
1471 | 2037 | if (iir) { |
|
1472 | intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); |
2038 | /* Consume port before clearing IIR or we'll miss events */ |
Line -... | Line 2039... | ||
- | 2039 | if (iir & I915_DISPLAY_PORT_INTERRUPT) |
|
- | 2040 | i9xx_hpd_irq_handler(dev); |
|
- | 2041 | I915_WRITE(VLV_IIR, iir); |
|
- | 2042 | } |
|
- | 2043 | ||
- | 2044 | if (gt_iir == 0 && pm_iir == 0 && iir == 0) |
|
- | 2045 | goto out; |
|
- | 2046 | ||
- | 2047 | ret = IRQ_HANDLED; |
|
- | 2048 | ||
- | 2049 | if (gt_iir) |
|
- | 2050 | snb_gt_irq_handler(dev, dev_priv, gt_iir); |
|
- | 2051 | if (pm_iir) |
|
- | 2052 | gen6_rps_irq_handler(dev_priv, pm_iir); |
|
- | 2053 | /* Call regardless, as some status bits might not be |
|
- | 2054 | * signalled in iir */ |
|
- | 2055 | valleyview_pipestat_irq_handler(dev, iir); |
|
- | 2056 | } |
|
- | 2057 | ||
- | 2058 | out: |
|
- | 2059 | return ret; |
|
- | 2060 | } |
|
- | 2061 | ||
- | 2062 | static irqreturn_t cherryview_irq_handler(int irq, void *arg) |
|
- | 2063 | { |
|
- | 2064 | struct drm_device *dev = arg; |
|
- | 2065 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2066 | u32 master_ctl, iir; |
|
- | 2067 | irqreturn_t ret = IRQ_NONE; |
|
- | 2068 | ||
- | 2069 | for (;;) { |
|
- | 2070 | master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; |
|
- | 2071 | iir = I915_READ(VLV_IIR); |
|
- | 2072 | ||
- | 2073 | if (master_ctl == 0 && iir == 0) |
|
- | 2074 | break; |
|
- | 2075 | ||
- | 2076 | ret = IRQ_HANDLED; |
|
- | 2077 | ||
- | 2078 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
|
1473 | 2079 | ||
1474 | if (hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X) |
2080 | /* Find, clear, then process each source of interrupt */ |
1475 | dp_aux_irq_handler(dev); |
2081 | |
1476 | 2082 | if (iir) { |
|
1477 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
2083 | /* Consume port before clearing IIR or we'll miss events */ |
- | 2084 | if (iir & I915_DISPLAY_PORT_INTERRUPT) |
|
- | 2085 | i9xx_hpd_irq_handler(dev); |
|
- | 2086 | I915_WRITE(VLV_IIR, iir); |
|
- | 2087 | } |
|
Line 1478... | Line 2088... | ||
1478 | I915_READ(PORT_HOTPLUG_STAT); |
2088 | |
Line 1479... | Line 2089... | ||
1479 | } |
2089 | gen8_gt_irq_handler(dev, dev_priv, master_ctl); |
1480 | 2090 | ||
1481 | if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) |
2091 | /* Call regardless, as some status bits might not be |
1482 | gmbus_irq_handler(dev); |
2092 | * signalled in iir */ |
Line 1536... | Line 2146... | ||
1536 | DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); |
2146 | DRM_DEBUG_DRIVER("PCH transcoder CRC error interrupt\n"); |
Line 1537... | Line 2147... | ||
1537 | 2147 | ||
1538 | if (pch_iir & SDE_TRANSA_FIFO_UNDER) |
2148 | if (pch_iir & SDE_TRANSA_FIFO_UNDER) |
1539 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, |
2149 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, |
1540 | false)) |
2150 | false)) |
Line 1541... | Line 2151... | ||
1541 | DRM_DEBUG_DRIVER("PCH transcoder A FIFO underrun\n"); |
2151 | DRM_ERROR("PCH transcoder A FIFO underrun\n"); |
1542 | 2152 | ||
1543 | if (pch_iir & SDE_TRANSB_FIFO_UNDER) |
2153 | if (pch_iir & SDE_TRANSB_FIFO_UNDER) |
1544 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, |
2154 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, |
1545 | false)) |
2155 | false)) |
Line 1546... | Line 2156... | ||
1546 | DRM_DEBUG_DRIVER("PCH transcoder B FIFO underrun\n"); |
2156 | DRM_ERROR("PCH transcoder B FIFO underrun\n"); |
1547 | } |
2157 | } |
1548 | 2158 | ||
Line 1557... | Line 2167... | ||
1557 | 2167 | ||
1558 | for_each_pipe(pipe) { |
2168 | for_each_pipe(pipe) { |
1559 | if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) { |
2169 | if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) { |
1560 | if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, |
2170 | if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, |
1561 | false)) |
2171 | false)) |
1562 | DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n", |
2172 | DRM_ERROR("Pipe %c FIFO underrun\n", |
1563 | pipe_name(pipe)); |
2173 | pipe_name(pipe)); |
Line 1564... | Line 2174... | ||
1564 | } |
2174 | } |
1565 | 2175 | ||
Line 1583... | Line 2193... | ||
1583 | DRM_ERROR("PCH poison interrupt\n"); |
2193 | DRM_ERROR("PCH poison interrupt\n"); |
Line 1584... | Line 2194... | ||
1584 | 2194 | ||
1585 | if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN) |
2195 | if (serr_int & SERR_INT_TRANS_A_FIFO_UNDERRUN) |
1586 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, |
2196 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, |
1587 | false)) |
2197 | false)) |
Line 1588... | Line 2198... | ||
1588 | DRM_DEBUG_DRIVER("PCH transcoder A FIFO underrun\n"); |
2198 | DRM_ERROR("PCH transcoder A FIFO underrun\n"); |
1589 | 2199 | ||
1590 | if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN) |
2200 | if (serr_int & SERR_INT_TRANS_B_FIFO_UNDERRUN) |
1591 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, |
2201 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_B, |
Line 1592... | Line 2202... | ||
1592 | false)) |
2202 | false)) |
1593 | DRM_DEBUG_DRIVER("PCH transcoder B FIFO underrun\n"); |
2203 | DRM_ERROR("PCH transcoder B FIFO underrun\n"); |
1594 | 2204 | ||
1595 | if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN) |
2205 | if (serr_int & SERR_INT_TRANS_C_FIFO_UNDERRUN) |
Line 1596... | Line 2206... | ||
1596 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_C, |
2206 | if (intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_C, |
1597 | false)) |
2207 | false)) |
Line 1598... | Line 2208... | ||
1598 | DRM_DEBUG_DRIVER("PCH transcoder C FIFO underrun\n"); |
2208 | DRM_ERROR("PCH transcoder C FIFO underrun\n"); |
1599 | 2209 | ||
1600 | I915_WRITE(SERR_INT, serr_int); |
2210 | I915_WRITE(SERR_INT, serr_int); |
1601 | } |
2211 | } |
1602 | 2212 | ||
- | 2213 | static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) |
|
Line -... | Line 2214... | ||
- | 2214 | { |
|
- | 2215 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2216 | int pipe; |
|
1603 | static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir) |
2217 | u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; |
Line 1604... | Line 2218... | ||
1604 | { |
2218 | u32 dig_hotplug_reg; |
1605 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2219 | |
1606 | int pipe; |
2220 | dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG); |
1607 | u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; |
2221 | I915_WRITE(PCH_PORT_HOTPLUG, dig_hotplug_reg); |
Line 1655... | Line 2269... | ||
1655 | // if (de_iir & DE_PIPE_VBLANK(pipe)) |
2269 | // if (de_iir & DE_PIPE_VBLANK(pipe)) |
1656 | // drm_handle_vblank(dev, pipe); |
2270 | // drm_handle_vblank(dev, pipe); |
Line 1657... | Line 2271... | ||
1657 | 2271 | ||
1658 | if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) |
2272 | if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) |
1659 | if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) |
2273 | if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) |
1660 | DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n", |
2274 | DRM_ERROR("Pipe %c FIFO underrun\n", |
Line 1661... | Line 2275... | ||
1661 | pipe_name(pipe)); |
2275 | pipe_name(pipe)); |
1662 | 2276 | ||
Line 1688... | Line 2302... | ||
1688 | } |
2302 | } |
Line 1689... | Line 2303... | ||
1689 | 2303 | ||
1690 | static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) |
2304 | static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir) |
1691 | { |
2305 | { |
1692 | struct drm_i915_private *dev_priv = dev->dev_private; |
2306 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 1693... | Line 2307... | ||
1693 | enum pipe i; |
2307 | enum pipe pipe; |
1694 | 2308 | ||
Line 1695... | Line 2309... | ||
1695 | if (de_iir & DE_ERR_INT_IVB) |
2309 | if (de_iir & DE_ERR_INT_IVB) |
1696 | ivb_err_int_handler(dev); |
2310 | ivb_err_int_handler(dev); |
Line 1697... | Line 2311... | ||
1697 | 2311 | ||
1698 | if (de_iir & DE_AUX_CHANNEL_A_IVB) |
2312 | if (de_iir & DE_AUX_CHANNEL_A_IVB) |
Line 1699... | Line 2313... | ||
1699 | dp_aux_irq_handler(dev); |
2313 | dp_aux_irq_handler(dev); |
1700 | 2314 | ||
1701 | if (de_iir & DE_GSE_IVB) |
2315 | if (de_iir & DE_GSE_IVB) |
Line 1702... | Line 2316... | ||
1702 | intel_opregion_asle_intr(dev); |
2316 | intel_opregion_asle_intr(dev); |
1703 | 2317 | ||
1704 | for_each_pipe(i) { |
2318 | for_each_pipe(pipe) { |
1705 | // if (de_iir & (DE_PIPE_VBLANK_IVB(i))) |
2319 | // if (de_iir & (DE_PIPE_VBLANK_IVB(pipe))) |
1706 | // drm_handle_vblank(dev, i); |
2320 | // drm_handle_vblank(dev, pipe); |
1707 | 2321 | ||
Line 1708... | Line 2322... | ||
1708 | /* plane/pipes map 1:1 on ilk+ */ |
2322 | /* plane/pipes map 1:1 on ilk+ */ |
1709 | if (de_iir & DE_PLANE_FLIP_DONE_IVB(i)) { |
2323 | if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe)) { |
Line 1721... | Line 2335... | ||
1721 | /* clear PCH hotplug event before clear CPU irq */ |
2335 | /* clear PCH hotplug event before clear CPU irq */ |
1722 | I915_WRITE(SDEIIR, pch_iir); |
2336 | I915_WRITE(SDEIIR, pch_iir); |
1723 | } |
2337 | } |
1724 | } |
2338 | } |
Line -... | Line 2339... | ||
- | 2339 | ||
- | 2340 | /* |
|
- | 2341 | * To handle irqs with the minimum potential races with fresh interrupts, we: |
|
- | 2342 | * 1 - Disable Master Interrupt Control. |
|
- | 2343 | * 2 - Find the source(s) of the interrupt. |
|
- | 2344 | * 3 - Clear the Interrupt Identity bits (IIR). |
|
- | 2345 | * 4 - Process the interrupt(s) that had bits set in the IIRs. |
|
- | 2346 | * 5 - Re-enable Master Interrupt Control. |
|
1725 | 2347 | */ |
|
1726 | static irqreturn_t ironlake_irq_handler(int irq, void *arg) |
2348 | static irqreturn_t ironlake_irq_handler(int irq, void *arg) |
1727 | { |
2349 | { |
1728 | struct drm_device *dev = (struct drm_device *) arg; |
2350 | struct drm_device *dev = arg; |
1729 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2351 | struct drm_i915_private *dev_priv = dev->dev_private; |
1730 | u32 de_iir, gt_iir, de_ier, sde_ier = 0; |
2352 | u32 de_iir, gt_iir, de_ier, sde_ier = 0; |
Line 1731... | Line -... | ||
1731 | irqreturn_t ret = IRQ_NONE; |
- | |
1732 | - | ||
1733 | atomic_inc(&dev_priv->irq_received); |
2353 | irqreturn_t ret = IRQ_NONE; |
1734 | 2354 | ||
1735 | /* We get interrupts on unclaimed registers, so check for this before we |
2355 | /* We get interrupts on unclaimed registers, so check for this before we |
Line 1736... | Line 2356... | ||
1736 | * do any I915_{READ,WRITE}. */ |
2356 | * do any I915_{READ,WRITE}. */ |
Line 1750... | Line 2370... | ||
1750 | sde_ier = I915_READ(SDEIER); |
2370 | sde_ier = I915_READ(SDEIER); |
1751 | I915_WRITE(SDEIER, 0); |
2371 | I915_WRITE(SDEIER, 0); |
1752 | POSTING_READ(SDEIER); |
2372 | POSTING_READ(SDEIER); |
1753 | } |
2373 | } |
Line -... | Line 2374... | ||
- | 2374 | ||
- | 2375 | /* Find, clear, then process each source of interrupt */ |
|
1754 | 2376 | ||
1755 | gt_iir = I915_READ(GTIIR); |
2377 | gt_iir = I915_READ(GTIIR); |
- | 2378 | if (gt_iir) { |
|
- | 2379 | I915_WRITE(GTIIR, gt_iir); |
|
1756 | if (gt_iir) { |
2380 | ret = IRQ_HANDLED; |
1757 | if (INTEL_INFO(dev)->gen >= 6) |
2381 | if (INTEL_INFO(dev)->gen >= 6) |
1758 | snb_gt_irq_handler(dev, dev_priv, gt_iir); |
2382 | snb_gt_irq_handler(dev, dev_priv, gt_iir); |
1759 | else |
2383 | else |
1760 | ilk_gt_irq_handler(dev, dev_priv, gt_iir); |
- | |
1761 | I915_WRITE(GTIIR, gt_iir); |
- | |
1762 | ret = IRQ_HANDLED; |
2384 | ilk_gt_irq_handler(dev, dev_priv, gt_iir); |
Line 1763... | Line 2385... | ||
1763 | } |
2385 | } |
1764 | 2386 | ||
- | 2387 | de_iir = I915_READ(DEIIR); |
|
- | 2388 | if (de_iir) { |
|
1765 | de_iir = I915_READ(DEIIR); |
2389 | I915_WRITE(DEIIR, de_iir); |
1766 | if (de_iir) { |
2390 | ret = IRQ_HANDLED; |
1767 | if (INTEL_INFO(dev)->gen >= 7) |
2391 | if (INTEL_INFO(dev)->gen >= 7) |
1768 | ivb_display_irq_handler(dev, de_iir); |
2392 | ivb_display_irq_handler(dev, de_iir); |
1769 | else |
- | |
1770 | ilk_display_irq_handler(dev, de_iir); |
- | |
1771 | I915_WRITE(DEIIR, de_iir); |
2393 | else |
Line 1772... | Line 2394... | ||
1772 | ret = IRQ_HANDLED; |
2394 | ilk_display_irq_handler(dev, de_iir); |
1773 | } |
2395 | } |
1774 | 2396 | ||
1775 | if (INTEL_INFO(dev)->gen >= 6) { |
- | |
1776 | u32 pm_iir = I915_READ(GEN6_PMIIR); |
2397 | if (INTEL_INFO(dev)->gen >= 6) { |
1777 | if (pm_iir) { |
2398 | u32 pm_iir = I915_READ(GEN6_PMIIR); |
- | 2399 | if (pm_iir) { |
|
1778 | gen6_rps_irq_handler(dev_priv, pm_iir); |
2400 | I915_WRITE(GEN6_PMIIR, pm_iir); |
1779 | I915_WRITE(GEN6_PMIIR, pm_iir); |
2401 | ret = IRQ_HANDLED; |
Line 1780... | Line 2402... | ||
1780 | ret = IRQ_HANDLED; |
2402 | gen6_rps_irq_handler(dev_priv, pm_iir); |
1781 | } |
2403 | } |
Line 1798... | Line 2420... | ||
1798 | u32 master_ctl; |
2420 | u32 master_ctl; |
1799 | irqreturn_t ret = IRQ_NONE; |
2421 | irqreturn_t ret = IRQ_NONE; |
1800 | uint32_t tmp = 0; |
2422 | uint32_t tmp = 0; |
1801 | enum pipe pipe; |
2423 | enum pipe pipe; |
Line 1802... | Line -... | ||
1802 | - | ||
1803 | atomic_inc(&dev_priv->irq_received); |
- | |
1804 | 2424 | ||
1805 | master_ctl = I915_READ(GEN8_MASTER_IRQ); |
2425 | master_ctl = I915_READ(GEN8_MASTER_IRQ); |
1806 | master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; |
2426 | master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; |
1807 | if (!master_ctl) |
2427 | if (!master_ctl) |
Line 1808... | Line 2428... | ||
1808 | return IRQ_NONE; |
2428 | return IRQ_NONE; |
1809 | 2429 | ||
Line -... | Line 2430... | ||
- | 2430 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
|
- | 2431 | POSTING_READ(GEN8_MASTER_IRQ); |
|
1810 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
2432 | |
Line 1811... | Line 2433... | ||
1811 | POSTING_READ(GEN8_MASTER_IRQ); |
2433 | /* Find, clear, then process each source of interrupt */ |
1812 | 2434 | ||
- | 2435 | ret = gen8_gt_irq_handler(dev, dev_priv, master_ctl); |
|
- | 2436 | ||
- | 2437 | if (master_ctl & GEN8_DE_MISC_IRQ) { |
|
1813 | ret = gen8_gt_irq_handler(dev, dev_priv, master_ctl); |
2438 | tmp = I915_READ(GEN8_DE_MISC_IIR); |
1814 | 2439 | if (tmp) { |
|
1815 | if (master_ctl & GEN8_DE_MISC_IRQ) { |
2440 | I915_WRITE(GEN8_DE_MISC_IIR, tmp); |
1816 | tmp = I915_READ(GEN8_DE_MISC_IIR); |
2441 | ret = IRQ_HANDLED; |
- | 2442 | if (tmp & GEN8_DE_MISC_GSE) |
|
1817 | if (tmp & GEN8_DE_MISC_GSE) |
2443 | intel_opregion_asle_intr(dev); |
1818 | intel_opregion_asle_intr(dev); |
2444 | else |
1819 | else if (tmp) |
- | |
1820 | DRM_ERROR("Unexpected DE Misc interrupt\n"); |
- | |
1821 | else |
- | |
1822 | DRM_ERROR("The master control interrupt lied (DE MISC)!\n"); |
- | |
1823 | - | ||
1824 | if (tmp) { |
2445 | DRM_ERROR("Unexpected DE Misc interrupt\n"); |
Line 1825... | Line 2446... | ||
1825 | I915_WRITE(GEN8_DE_MISC_IIR, tmp); |
2446 | } |
1826 | ret = IRQ_HANDLED; |
2447 | else |
- | 2448 | DRM_ERROR("The master control interrupt lied (DE MISC)!\n"); |
|
- | 2449 | } |
|
- | 2450 | ||
1827 | } |
2451 | if (master_ctl & GEN8_DE_PORT_IRQ) { |
1828 | } |
2452 | tmp = I915_READ(GEN8_DE_PORT_IIR); |
1829 | 2453 | if (tmp) { |
|
1830 | if (master_ctl & GEN8_DE_PORT_IRQ) { |
2454 | I915_WRITE(GEN8_DE_PORT_IIR, tmp); |
- | 2455 | ret = IRQ_HANDLED; |
|
1831 | tmp = I915_READ(GEN8_DE_PORT_IIR); |
2456 | if (tmp & GEN8_AUX_CHANNEL_A) |
1832 | if (tmp & GEN8_AUX_CHANNEL_A) |
2457 | dp_aux_irq_handler(dev); |
1833 | dp_aux_irq_handler(dev); |
- | |
1834 | else if (tmp) |
- | |
1835 | DRM_ERROR("Unexpected DE Port interrupt\n"); |
- | |
1836 | else |
- | |
1837 | DRM_ERROR("The master control interrupt lied (DE PORT)!\n"); |
- | |
1838 | 2458 | else |
|
Line 1839... | Line 2459... | ||
1839 | if (tmp) { |
2459 | DRM_ERROR("Unexpected DE Port interrupt\n"); |
1840 | I915_WRITE(GEN8_DE_PORT_IIR, tmp); |
2460 | } |
Line 1841... | Line 2461... | ||
1841 | ret = IRQ_HANDLED; |
2461 | else |
1842 | } |
2462 | DRM_ERROR("The master control interrupt lied (DE PORT)!\n"); |
Line 1843... | Line 2463... | ||
1843 | } |
2463 | } |
- | 2464 | ||
- | 2465 | for_each_pipe(pipe) { |
|
- | 2466 | uint32_t pipe_iir; |
|
1844 | 2467 | ||
1845 | for_each_pipe(pipe) { |
2468 | if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) |
Line 1846... | Line 2469... | ||
1846 | uint32_t pipe_iir; |
2469 | continue; |
1847 | 2470 | ||
1848 | if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) |
2471 | pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); |
1849 | continue; |
2472 | if (pipe_iir) { |
Line 1850... | Line 2473... | ||
1850 | 2473 | ret = IRQ_HANDLED; |
|
1851 | pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); |
2474 | I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir); |
Line 1852... | Line 2475... | ||
1852 | // if (pipe_iir & GEN8_PIPE_VBLANK) |
2475 | // if (pipe_iir & GEN8_PIPE_VBLANK) |
1853 | // drm_handle_vblank(dev, pipe); |
2476 | // intel_pipe_handle_vblank(dev, pipe); |
1854 | 2477 | ||
1855 | if (pipe_iir & GEN8_PIPE_FLIP_DONE) { |
2478 | if (pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE) { |
1856 | // intel_prepare_page_flip(dev, pipe); |
2479 | // intel_prepare_page_flip(dev, pipe); |
1857 | // intel_finish_page_flip_plane(dev, pipe); |
2480 | // intel_finish_page_flip_plane(dev, pipe); |
Line 1858... | Line 2481... | ||
1858 | } |
2481 | } |
1859 | 2482 | ||
1860 | if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE) |
2483 | if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE) |
1861 | hsw_pipe_crc_irq_handler(dev, pipe); |
2484 | hsw_pipe_crc_irq_handler(dev, pipe); |
1862 | 2485 | ||
1863 | if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) { |
- | |
1864 | if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, |
- | |
1865 | false)) |
- | |
1866 | DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n", |
- | |
1867 | pipe_name(pipe)); |
2486 | if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) { |
1868 | } |
2487 | if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, |
1869 | 2488 | false)) |
|
Line 1870... | Line 2489... | ||
1870 | if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) { |
2489 | DRM_ERROR("Pipe %c FIFO underrun\n", |
Line 1885... | Line 2504... | ||
1885 | * FIXME(BDW): Assume for now that the new interrupt handling |
2504 | * FIXME(BDW): Assume for now that the new interrupt handling |
1886 | * scheme also closed the SDE interrupt handling race we've seen |
2505 | * scheme also closed the SDE interrupt handling race we've seen |
1887 | * on older pch-split platforms. But this needs testing. |
2506 | * on older pch-split platforms. But this needs testing. |
1888 | */ |
2507 | */ |
1889 | u32 pch_iir = I915_READ(SDEIIR); |
2508 | u32 pch_iir = I915_READ(SDEIIR); |
1890 | - | ||
1891 | cpt_irq_handler(dev, pch_iir); |
- | |
1892 | - | ||
1893 | if (pch_iir) { |
2509 | if (pch_iir) { |
1894 | I915_WRITE(SDEIIR, pch_iir); |
2510 | I915_WRITE(SDEIIR, pch_iir); |
1895 | ret = IRQ_HANDLED; |
2511 | ret = IRQ_HANDLED; |
- | 2512 | cpt_irq_handler(dev, pch_iir); |
|
1896 | } |
2513 | } else |
- | 2514 | DRM_ERROR("The master control interrupt lied (SDE)!\n"); |
|
- | 2515 | ||
1897 | } |
2516 | } |
Line 1898... | Line 2517... | ||
1898 | 2517 | ||
1899 | I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); |
2518 | I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); |
Line 1903... | Line 2522... | ||
1903 | } |
2522 | } |
Line 1904... | Line 2523... | ||
1904 | 2523 | ||
1905 | static void i915_error_wake_up(struct drm_i915_private *dev_priv, |
2524 | static void i915_error_wake_up(struct drm_i915_private *dev_priv, |
1906 | bool reset_completed) |
2525 | bool reset_completed) |
1907 | { |
2526 | { |
1908 | struct intel_ring_buffer *ring; |
2527 | struct intel_engine_cs *ring; |
Line 1909... | Line 2528... | ||
1909 | int i; |
2528 | int i; |
1910 | 2529 | ||
1911 | /* |
2530 | /* |
Line 1937... | Line 2556... | ||
1937 | */ |
2556 | */ |
1938 | static void i915_error_work_func(struct work_struct *work) |
2557 | static void i915_error_work_func(struct work_struct *work) |
1939 | { |
2558 | { |
1940 | struct i915_gpu_error *error = container_of(work, struct i915_gpu_error, |
2559 | struct i915_gpu_error *error = container_of(work, struct i915_gpu_error, |
1941 | work); |
2560 | work); |
1942 | drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t, |
2561 | struct drm_i915_private *dev_priv = |
1943 | gpu_error); |
2562 | container_of(error, struct drm_i915_private, gpu_error); |
1944 | struct drm_device *dev = dev_priv->dev; |
2563 | struct drm_device *dev = dev_priv->dev; |
1945 | char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; |
2564 | char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; |
1946 | char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; |
2565 | char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; |
1947 | char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; |
2566 | char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; |
1948 | int ret; |
2567 | int ret; |
Line 2095... | Line 2714... | ||
2095 | * dump it to the syslog. Also call i915_capture_error_state() to make |
2714 | * dump it to the syslog. Also call i915_capture_error_state() to make |
2096 | * sure we get a record and make it available in debugfs. Fire a uevent |
2715 | * sure we get a record and make it available in debugfs. Fire a uevent |
2097 | * so userspace knows something bad happened (should trigger collection |
2716 | * so userspace knows something bad happened (should trigger collection |
2098 | * of a ring dump etc.). |
2717 | * of a ring dump etc.). |
2099 | */ |
2718 | */ |
2100 | void i915_handle_error(struct drm_device *dev, bool wedged) |
2719 | void i915_handle_error(struct drm_device *dev, bool wedged, |
- | 2720 | const char *fmt, ...) |
|
2101 | { |
2721 | { |
2102 | struct drm_i915_private *dev_priv = dev->dev_private; |
2722 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 2723 | va_list args; |
|
- | 2724 | char error_msg[80]; |
|
- | 2725 | ||
- | 2726 | va_start(args, fmt); |
|
- | 2727 | vscnprintf(error_msg, sizeof(error_msg), fmt, args); |
|
- | 2728 | va_end(args); |
|
Line 2103... | Line 2729... | ||
2103 | 2729 | ||
2104 | // i915_capture_error_state(dev); |
2730 | // i915_capture_error_state(dev); |
Line 2105... | Line 2731... | ||
2105 | i915_report_and_clear_eir(dev); |
2731 | i915_report_and_clear_eir(dev); |
Line 2134... | Line 2760... | ||
2134 | } |
2760 | } |
Line 2135... | Line 2761... | ||
2135 | 2761 | ||
2136 | #if 0 |
2762 | #if 0 |
2137 | static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe) |
2763 | static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe) |
2138 | { |
2764 | { |
2139 | drm_i915_private_t *dev_priv = dev->dev_private; |
2765 | struct drm_i915_private *dev_priv = dev->dev_private; |
2140 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
2766 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
2141 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2767 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2142 | struct drm_i915_gem_object *obj; |
2768 | struct drm_i915_gem_object *obj; |
2143 | struct intel_unpin_work *work; |
2769 | struct intel_unpin_work *work; |
Line 2166... | Line 2792... | ||
2166 | stall_detected = I915_HI_DISPBASE(I915_READ(dspsurf)) == |
2792 | stall_detected = I915_HI_DISPBASE(I915_READ(dspsurf)) == |
2167 | i915_gem_obj_ggtt_offset(obj); |
2793 | i915_gem_obj_ggtt_offset(obj); |
2168 | } else { |
2794 | } else { |
2169 | int dspaddr = DSPADDR(intel_crtc->plane); |
2795 | int dspaddr = DSPADDR(intel_crtc->plane); |
2170 | stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) + |
2796 | stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) + |
2171 | crtc->y * crtc->fb->pitches[0] + |
2797 | crtc->y * crtc->primary->fb->pitches[0] + |
2172 | crtc->x * crtc->fb->bits_per_pixel/8); |
2798 | crtc->x * crtc->primary->fb->bits_per_pixel/8); |
2173 | } |
2799 | } |
Line 2174... | Line 2800... | ||
2174 | 2800 | ||
Line 2175... | Line 2801... | ||
2175 | spin_unlock_irqrestore(&dev->event_lock, flags); |
2801 | spin_unlock_irqrestore(&dev->event_lock, flags); |
Line 2185... | Line 2811... | ||
2185 | /* Called from drm generic code, passed 'crtc' which |
2811 | /* Called from drm generic code, passed 'crtc' which |
2186 | * we use as a pipe index |
2812 | * we use as a pipe index |
2187 | */ |
2813 | */ |
2188 | static int i915_enable_vblank(struct drm_device *dev, int pipe) |
2814 | static int i915_enable_vblank(struct drm_device *dev, int pipe) |
2189 | { |
2815 | { |
2190 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2816 | struct drm_i915_private *dev_priv = dev->dev_private; |
2191 | unsigned long irqflags; |
2817 | unsigned long irqflags; |
Line 2192... | Line 2818... | ||
2192 | 2818 | ||
2193 | if (!i915_pipe_enabled(dev, pipe)) |
2819 | if (!i915_pipe_enabled(dev, pipe)) |
Line 2194... | Line 2820... | ||
2194 | return -EINVAL; |
2820 | return -EINVAL; |
2195 | 2821 | ||
2196 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2822 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2197 | if (INTEL_INFO(dev)->gen >= 4) |
2823 | if (INTEL_INFO(dev)->gen >= 4) |
2198 | i915_enable_pipestat(dev_priv, pipe, |
2824 | i915_enable_pipestat(dev_priv, pipe, |
2199 | PIPE_START_VBLANK_INTERRUPT_ENABLE); |
2825 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
2200 | else |
2826 | else |
2201 | i915_enable_pipestat(dev_priv, pipe, |
- | |
2202 | PIPE_VBLANK_INTERRUPT_ENABLE); |
- | |
2203 | - | ||
2204 | /* maintain vblank delivery even in deep C-states */ |
- | |
2205 | if (dev_priv->info->gen == 3) |
2827 | i915_enable_pipestat(dev_priv, pipe, |
Line 2206... | Line 2828... | ||
2206 | I915_WRITE(INSTPM, _MASKED_BIT_DISABLE(INSTPM_AGPBUSY_DIS)); |
2828 | PIPE_VBLANK_INTERRUPT_STATUS); |
2207 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2829 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
Line 2208... | Line 2830... | ||
2208 | 2830 | ||
2209 | return 0; |
2831 | return 0; |
2210 | } |
2832 | } |
2211 | 2833 | ||
2212 | static int ironlake_enable_vblank(struct drm_device *dev, int pipe) |
2834 | static int ironlake_enable_vblank(struct drm_device *dev, int pipe) |
2213 | { |
2835 | { |
Line 2214... | Line 2836... | ||
2214 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2836 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2226... | Line 2848... | ||
2226 | return 0; |
2848 | return 0; |
2227 | } |
2849 | } |
Line 2228... | Line 2850... | ||
2228 | 2850 | ||
2229 | static int valleyview_enable_vblank(struct drm_device *dev, int pipe) |
2851 | static int valleyview_enable_vblank(struct drm_device *dev, int pipe) |
2230 | { |
2852 | { |
2231 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2853 | struct drm_i915_private *dev_priv = dev->dev_private; |
2232 | unsigned long irqflags; |
- | |
Line 2233... | Line 2854... | ||
2233 | u32 imr; |
2854 | unsigned long irqflags; |
2234 | 2855 | ||
Line 2235... | Line 2856... | ||
2235 | if (!i915_pipe_enabled(dev, pipe)) |
2856 | if (!i915_pipe_enabled(dev, pipe)) |
2236 | return -EINVAL; |
- | |
2237 | - | ||
2238 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
- | |
2239 | imr = I915_READ(VLV_IMR); |
- | |
2240 | if (pipe == PIPE_A) |
- | |
2241 | imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; |
- | |
2242 | else |
2857 | return -EINVAL; |
2243 | imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
2858 | |
2244 | I915_WRITE(VLV_IMR, imr); |
2859 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
Line 2245... | Line 2860... | ||
2245 | i915_enable_pipestat(dev_priv, pipe, |
2860 | i915_enable_pipestat(dev_priv, pipe, |
2246 | PIPE_START_VBLANK_INTERRUPT_ENABLE); |
2861 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
Line 2268... | Line 2883... | ||
2268 | /* Called from drm generic code, passed 'crtc' which |
2883 | /* Called from drm generic code, passed 'crtc' which |
2269 | * we use as a pipe index |
2884 | * we use as a pipe index |
2270 | */ |
2885 | */ |
2271 | static void i915_disable_vblank(struct drm_device *dev, int pipe) |
2886 | static void i915_disable_vblank(struct drm_device *dev, int pipe) |
2272 | { |
2887 | { |
2273 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2888 | struct drm_i915_private *dev_priv = dev->dev_private; |
2274 | unsigned long irqflags; |
2889 | unsigned long irqflags; |
Line 2275... | Line 2890... | ||
2275 | 2890 | ||
2276 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
- | |
2277 | if (dev_priv->info->gen == 3) |
- | |
2278 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_DIS)); |
- | |
2279 | 2891 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
|
2280 | i915_disable_pipestat(dev_priv, pipe, |
2892 | i915_disable_pipestat(dev_priv, pipe, |
2281 | PIPE_VBLANK_INTERRUPT_ENABLE | |
2893 | PIPE_VBLANK_INTERRUPT_STATUS | |
2282 | PIPE_START_VBLANK_INTERRUPT_ENABLE); |
2894 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
2283 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2895 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
Line 2284... | Line 2896... | ||
2284 | } |
2896 | } |
2285 | 2897 | ||
2286 | static void ironlake_disable_vblank(struct drm_device *dev, int pipe) |
2898 | static void ironlake_disable_vblank(struct drm_device *dev, int pipe) |
2287 | { |
2899 | { |
2288 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2900 | struct drm_i915_private *dev_priv = dev->dev_private; |
2289 | unsigned long irqflags; |
2901 | unsigned long irqflags; |
Line 2290... | Line 2902... | ||
2290 | uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) : |
2902 | uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) : |
Line 2295... | Line 2907... | ||
2295 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2907 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2296 | } |
2908 | } |
Line 2297... | Line 2909... | ||
2297 | 2909 | ||
2298 | static void valleyview_disable_vblank(struct drm_device *dev, int pipe) |
2910 | static void valleyview_disable_vblank(struct drm_device *dev, int pipe) |
2299 | { |
2911 | { |
2300 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2912 | struct drm_i915_private *dev_priv = dev->dev_private; |
2301 | unsigned long irqflags; |
- | |
Line 2302... | Line 2913... | ||
2302 | u32 imr; |
2913 | unsigned long irqflags; |
2303 | 2914 | ||
2304 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2915 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2305 | i915_disable_pipestat(dev_priv, pipe, |
- | |
2306 | PIPE_START_VBLANK_INTERRUPT_ENABLE); |
- | |
2307 | imr = I915_READ(VLV_IMR); |
- | |
2308 | if (pipe == PIPE_A) |
- | |
2309 | imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT; |
- | |
2310 | else |
- | |
2311 | imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
2916 | i915_disable_pipestat(dev_priv, pipe, |
2312 | I915_WRITE(VLV_IMR, imr); |
2917 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
Line 2313... | Line 2918... | ||
2313 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2918 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2314 | } |
2919 | } |
Line 2327... | Line 2932... | ||
2327 | POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); |
2932 | POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); |
2328 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2933 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2329 | } |
2934 | } |
Line 2330... | Line 2935... | ||
2330 | 2935 | ||
2331 | static u32 |
2936 | static u32 |
2332 | ring_last_seqno(struct intel_ring_buffer *ring) |
2937 | ring_last_seqno(struct intel_engine_cs *ring) |
2333 | { |
2938 | { |
2334 | return list_entry(ring->request_list.prev, |
2939 | return list_entry(ring->request_list.prev, |
2335 | struct drm_i915_gem_request, list)->seqno; |
2940 | struct drm_i915_gem_request, list)->seqno; |
Line 2336... | Line 2941... | ||
2336 | } |
2941 | } |
2337 | 2942 | ||
2338 | static bool |
2943 | static bool |
2339 | ring_idle(struct intel_ring_buffer *ring, u32 seqno) |
2944 | ring_idle(struct intel_engine_cs *ring, u32 seqno) |
2340 | { |
2945 | { |
2341 | return (list_empty(&ring->request_list) || |
2946 | return (list_empty(&ring->request_list) || |
Line -... | Line 2947... | ||
- | 2947 | i915_seqno_passed(seqno, ring_last_seqno(ring))); |
|
- | 2948 | } |
|
- | 2949 | ||
- | 2950 | static bool |
|
- | 2951 | ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) |
|
- | 2952 | { |
|
- | 2953 | if (INTEL_INFO(dev)->gen >= 8) { |
|
- | 2954 | return (ipehr >> 23) == 0x1c; |
|
- | 2955 | } else { |
|
- | 2956 | ipehr &= ~MI_SEMAPHORE_SYNC_MASK; |
|
- | 2957 | return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | |
|
- | 2958 | MI_SEMAPHORE_REGISTER); |
|
- | 2959 | } |
|
- | 2960 | } |
|
- | 2961 | ||
- | 2962 | static struct intel_engine_cs * |
|
- | 2963 | semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr, u64 offset) |
|
- | 2964 | { |
|
- | 2965 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
|
- | 2966 | struct intel_engine_cs *signaller; |
|
- | 2967 | int i; |
|
- | 2968 | ||
- | 2969 | if (INTEL_INFO(dev_priv->dev)->gen >= 8) { |
|
- | 2970 | for_each_ring(signaller, dev_priv, i) { |
|
- | 2971 | if (ring == signaller) |
|
- | 2972 | continue; |
|
- | 2973 | ||
- | 2974 | if (offset == signaller->semaphore.signal_ggtt[ring->id]) |
|
- | 2975 | return signaller; |
|
- | 2976 | } |
|
- | 2977 | } else { |
|
- | 2978 | u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; |
|
- | 2979 | ||
- | 2980 | for_each_ring(signaller, dev_priv, i) { |
|
- | 2981 | if(ring == signaller) |
|
- | 2982 | continue; |
|
- | 2983 | ||
- | 2984 | if (sync_bits == signaller->semaphore.mbox.wait[ring->id]) |
|
- | 2985 | return signaller; |
|
- | 2986 | } |
|
- | 2987 | } |
|
- | 2988 | ||
- | 2989 | DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x, offset 0x%016llx\n", |
|
- | 2990 | ring->id, ipehr, offset); |
|
- | 2991 | ||
2342 | i915_seqno_passed(seqno, ring_last_seqno(ring))); |
2992 | return NULL; |
2343 | } |
2993 | } |
2344 | 2994 | ||
2345 | static struct intel_ring_buffer * |
2995 | static struct intel_engine_cs * |
2346 | semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno) |
2996 | semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) |
- | 2997 | { |
|
- | 2998 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
|
Line 2347... | Line 2999... | ||
2347 | { |
2999 | u32 cmd, ipehr, head; |
2348 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
3000 | u64 offset = 0; |
2349 | u32 cmd, ipehr, acthd, acthd_min; |
- | |
2350 | 3001 | int i, backwards; |
|
Line -... | Line 3002... | ||
- | 3002 | ||
2351 | ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); |
3003 | ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); |
2352 | if ((ipehr & ~(0x3 << 16)) != |
3004 | if (!ipehr_is_semaphore_wait(ring->dev, ipehr)) |
- | 3005 | return NULL; |
|
- | 3006 | ||
- | 3007 | /* |
|
- | 3008 | * HEAD is likely pointing to the dword after the actual command, |
|
2353 | (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER)) |
3009 | * so scan backwards until we find the MBOX. But limit it to just 3 |
2354 | return NULL; |
3010 | * or 4 dwords depending on the semaphore wait command size. |
- | 3011 | * Note that we don't care about ACTHD here since that might |
|
- | 3012 | * point at at batch, and semaphores are always emitted into the |
|
2355 | 3013 | * ringbuffer itself. |
|
- | 3014 | */ |
|
- | 3015 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
|
- | 3016 | backwards = (INTEL_INFO(ring->dev)->gen >= 8) ? 5 : 4; |
|
- | 3017 | ||
2356 | /* ACTHD is likely pointing to the dword after the actual command, |
3018 | for (i = backwards; i; --i) { |
- | 3019 | /* |
|
- | 3020 | * Be paranoid and presume the hw has gone off into the wild - |
|
- | 3021 | * our ring is smaller than what the hardware (and hence |
|
2357 | * so scan backwards until we find the MBOX. |
3022 | * HEAD_ADDR) allows. Also handles wrap-around. |
2358 | */ |
3023 | */ |
2359 | acthd = intel_ring_get_active_head(ring) & HEAD_ADDR; |
3024 | head &= ring->buffer->size - 1; |
Line 2360... | Line 3025... | ||
2360 | acthd_min = max((int)acthd - 3 * 4, 0); |
3025 | |
- | 3026 | /* This here seems to blow up */ |
|
- | 3027 | cmd = ioread32(ring->buffer->virtual_start + head); |
|
2361 | do { |
3028 | if (cmd == ipehr) |
2362 | cmd = ioread32(ring->virtual_start + acthd); |
3029 | break; |
2363 | if (cmd == ipehr) |
- | |
Line 2364... | Line 3030... | ||
2364 | break; |
3030 | |
- | 3031 | head -= 4; |
|
- | 3032 | } |
|
- | 3033 | ||
- | 3034 | if (!i) |
|
- | 3035 | return NULL; |
|
2365 | 3036 | ||
2366 | acthd -= 4; |
3037 | *seqno = ioread32(ring->buffer->virtual_start + head + 4) + 1; |
Line 2367... | Line 3038... | ||
2367 | if (acthd < acthd_min) |
3038 | if (INTEL_INFO(ring->dev)->gen >= 8) { |
2368 | return NULL; |
3039 | offset = ioread32(ring->buffer->virtual_start + head + 12); |
2369 | } while (1); |
3040 | offset <<= 32; |
2370 | 3041 | offset = ioread32(ring->buffer->virtual_start + head + 8); |
|
2371 | *seqno = ioread32(ring->virtual_start+acthd+4)+1; |
3042 | } |
Line 2372... | Line 3043... | ||
2372 | return &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3]; |
3043 | return semaphore_wait_to_signaller_ring(ring, ipehr, offset); |
Line 2373... | Line 3044... | ||
2373 | } |
3044 | } |
- | 3045 | ||
- | 3046 | static int semaphore_passed(struct intel_engine_cs *ring) |
|
- | 3047 | { |
|
- | 3048 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
|
2374 | 3049 | struct intel_engine_cs *signaller; |
|
2375 | static int semaphore_passed(struct intel_ring_buffer *ring) |
3050 | u32 seqno; |
Line -... | Line 3051... | ||
- | 3051 | ||
- | 3052 | ring->hangcheck.deadlock++; |
|
- | 3053 | ||
2376 | { |
3054 | signaller = semaphore_waits_for(ring, &seqno); |
2377 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
3055 | if (signaller == NULL) |
2378 | struct intel_ring_buffer *signaller; |
3056 | return -1; |
2379 | u32 seqno, ctl; |
3057 | |
Line 2380... | Line 3058... | ||
2380 | 3058 | /* Prevent pathological recursion due to driver bugs */ |
|
2381 | ring->hangcheck.deadlock = true; |
3059 | if (signaller->hangcheck.deadlock >= I915_NUM_RINGS) |
Line 2382... | Line 3060... | ||
2382 | 3060 | return -1; |
|
2383 | signaller = semaphore_waits_for(ring, &seqno); |
3061 | |
2384 | if (signaller == NULL || signaller->hangcheck.deadlock) |
3062 | if (i915_seqno_passed(signaller->get_seqno(signaller, false), seqno)) |
2385 | return -1; |
3063 | return 1; |
Line 2386... | Line 3064... | ||
2386 | 3064 | ||
2387 | /* cursory check for an unkickable deadlock */ |
3065 | /* cursory check for an unkickable deadlock */ |
2388 | ctl = I915_READ_CTL(signaller); |
3066 | if (I915_READ_CTL(signaller) & RING_WAIT_SEMAPHORE && |
Line 2389... | Line 3067... | ||
2389 | if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0) |
3067 | semaphore_passed(signaller) < 0) |
2390 | return -1; |
3068 | return -1; |
2391 | 3069 | ||
2392 | return i915_seqno_passed(signaller->get_seqno(signaller, false), seqno); |
3070 | return 0; |
2393 | } |
3071 | } |
2394 | 3072 | ||
Line -... | Line 3073... | ||
- | 3073 | static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) |
|
- | 3074 | { |
|
2395 | static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) |
3075 | struct intel_engine_cs *ring; |
2396 | { |
3076 | int i; |
- | 3077 | ||
- | 3078 | for_each_ring(ring, dev_priv, i) |
|
- | 3079 | ring->hangcheck.deadlock = 0; |
|
- | 3080 | } |
|
Line 2397... | Line 3081... | ||
2397 | struct intel_ring_buffer *ring; |
3081 | |
2398 | int i; |
3082 | static enum intel_ring_hangcheck_action |
Line 2399... | Line 3083... | ||
2399 | 3083 | ring_stuck(struct intel_engine_cs *ring, u64 acthd) |
|
Line 2419... | Line 3103... | ||
2419 | * and break the hang. This should work on |
3103 | * and break the hang. This should work on |
2420 | * all but the second generation chipsets. |
3104 | * all but the second generation chipsets. |
2421 | */ |
3105 | */ |
2422 | tmp = I915_READ_CTL(ring); |
3106 | tmp = I915_READ_CTL(ring); |
2423 | if (tmp & RING_WAIT) { |
3107 | if (tmp & RING_WAIT) { |
- | 3108 | i915_handle_error(dev, false, |
|
2424 | DRM_ERROR("Kicking stuck wait on %s\n", |
3109 | "Kicking stuck wait on %s", |
2425 | ring->name); |
3110 | ring->name); |
2426 | I915_WRITE_CTL(ring, tmp); |
3111 | I915_WRITE_CTL(ring, tmp); |
2427 | return HANGCHECK_KICK; |
3112 | return HANGCHECK_KICK; |
2428 | } |
3113 | } |
Line 2429... | Line 3114... | ||
2429 | 3114 | ||
2430 | if (INTEL_INFO(dev)->gen >= 6 && tmp & RING_WAIT_SEMAPHORE) { |
3115 | if (INTEL_INFO(dev)->gen >= 6 && tmp & RING_WAIT_SEMAPHORE) { |
2431 | switch (semaphore_passed(ring)) { |
3116 | switch (semaphore_passed(ring)) { |
2432 | default: |
3117 | default: |
2433 | return HANGCHECK_HUNG; |
3118 | return HANGCHECK_HUNG; |
- | 3119 | case 1: |
|
2434 | case 1: |
3120 | i915_handle_error(dev, false, |
2435 | DRM_ERROR("Kicking stuck semaphore on %s\n", |
3121 | "Kicking stuck semaphore on %s", |
2436 | ring->name); |
3122 | ring->name); |
2437 | I915_WRITE_CTL(ring, tmp); |
3123 | I915_WRITE_CTL(ring, tmp); |
2438 | return HANGCHECK_KICK; |
3124 | return HANGCHECK_KICK; |
2439 | case 0: |
3125 | case 0: |
Line 2453... | Line 3139... | ||
2453 | * we assume chip is wedged and try to fix it by resetting the chip. |
3139 | * we assume chip is wedged and try to fix it by resetting the chip. |
2454 | */ |
3140 | */ |
2455 | static void i915_hangcheck_elapsed(unsigned long data) |
3141 | static void i915_hangcheck_elapsed(unsigned long data) |
2456 | { |
3142 | { |
2457 | struct drm_device *dev = (struct drm_device *)data; |
3143 | struct drm_device *dev = (struct drm_device *)data; |
2458 | drm_i915_private_t *dev_priv = dev->dev_private; |
3144 | struct drm_i915_private *dev_priv = dev->dev_private; |
2459 | struct intel_ring_buffer *ring; |
3145 | struct intel_engine_cs *ring; |
2460 | int i; |
3146 | int i; |
2461 | int busy_count = 0, rings_hung = 0; |
3147 | int busy_count = 0, rings_hung = 0; |
2462 | bool stuck[I915_NUM_RINGS] = { 0 }; |
3148 | bool stuck[I915_NUM_RINGS] = { 0 }; |
2463 | #define BUSY 1 |
3149 | #define BUSY 1 |
2464 | #define KICK 5 |
3150 | #define KICK 5 |
2465 | #define HUNG 20 |
3151 | #define HUNG 20 |
2466 | #define FIRE 30 |
- | |
Line 2467... | Line 3152... | ||
2467 | 3152 | ||
2468 | if (!i915_enable_hangcheck) |
3153 | if (!i915.enable_hangcheck) |
Line 2469... | Line 3154... | ||
2469 | return; |
3154 | return; |
- | 3155 | ||
2470 | 3156 | for_each_ring(ring, dev_priv, i) { |
|
2471 | for_each_ring(ring, dev_priv, i) { |
3157 | u64 acthd; |
Line 2472... | Line 3158... | ||
2472 | u32 seqno, acthd; |
3158 | u32 seqno; |
Line 2473... | Line 3159... | ||
2473 | bool busy = true; |
3159 | bool busy = true; |
2474 | 3160 | ||
Line 2475... | Line 3161... | ||
2475 | semaphore_clear_deadlocks(dev_priv); |
3161 | semaphore_clear_deadlocks(dev_priv); |
2476 | 3162 | ||
- | 3163 | seqno = ring->get_seqno(ring, false); |
|
- | 3164 | acthd = intel_ring_get_active_head(ring); |
|
2477 | seqno = ring->get_seqno(ring, false); |
3165 | |
2478 | acthd = intel_ring_get_active_head(ring); |
3166 | if (ring->hangcheck.seqno == seqno) { |
2479 | 3167 | if (ring_idle(ring, seqno)) { |
|
2480 | if (ring->hangcheck.seqno == seqno) { |
3168 | ring->hangcheck.action = HANGCHECK_IDLE; |
2481 | if (ring_idle(ring, seqno)) { |
3169 | |
Line 2506... | Line 3194... | ||
2506 | acthd); |
3194 | acthd); |
Line 2507... | Line 3195... | ||
2507 | 3195 | ||
2508 | switch (ring->hangcheck.action) { |
3196 | switch (ring->hangcheck.action) { |
2509 | case HANGCHECK_IDLE: |
3197 | case HANGCHECK_IDLE: |
2510 | case HANGCHECK_WAIT: |
- | |
2511 | break; |
3198 | case HANGCHECK_WAIT: |
- | 3199 | case HANGCHECK_ACTIVE: |
|
- | 3200 | break; |
|
2512 | case HANGCHECK_ACTIVE: |
3201 | case HANGCHECK_ACTIVE_LOOP: |
2513 | ring->hangcheck.score += BUSY; |
3202 | ring->hangcheck.score += BUSY; |
2514 | break; |
3203 | break; |
2515 | case HANGCHECK_KICK: |
3204 | case HANGCHECK_KICK: |
2516 | ring->hangcheck.score += KICK; |
3205 | ring->hangcheck.score += KICK; |
Line 2527... | Line 3216... | ||
2527 | /* Gradually reduce the count so that we catch DoS |
3216 | /* Gradually reduce the count so that we catch DoS |
2528 | * attempts across multiple batches. |
3217 | * attempts across multiple batches. |
2529 | */ |
3218 | */ |
2530 | if (ring->hangcheck.score > 0) |
3219 | if (ring->hangcheck.score > 0) |
2531 | ring->hangcheck.score--; |
3220 | ring->hangcheck.score--; |
- | 3221 | ||
- | 3222 | ring->hangcheck.acthd = ring->hangcheck.max_acthd = 0; |
|
2532 | } |
3223 | } |
Line 2533... | Line 3224... | ||
2533 | 3224 | ||
2534 | ring->hangcheck.seqno = seqno; |
3225 | ring->hangcheck.seqno = seqno; |
2535 | ring->hangcheck.acthd = acthd; |
3226 | ring->hangcheck.acthd = acthd; |
2536 | busy_count += busy; |
3227 | busy_count += busy; |
Line 2537... | Line 3228... | ||
2537 | } |
3228 | } |
2538 | 3229 | ||
2539 | for_each_ring(ring, dev_priv, i) { |
3230 | for_each_ring(ring, dev_priv, i) { |
2540 | if (ring->hangcheck.score > FIRE) { |
3231 | if (ring->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { |
2541 | DRM_INFO("%s on %s\n", |
3232 | DRM_INFO("%s on %s\n", |
2542 | stuck[i] ? "stuck" : "no progress", |
3233 | stuck[i] ? "stuck" : "no progress", |
2543 | ring->name); |
3234 | ring->name); |
Line 2547... | Line 3238... | ||
2547 | 3238 | ||
2548 | // if (rings_hung) |
3239 | // if (rings_hung) |
Line 2549... | Line 3240... | ||
2549 | // return i915_handle_error(dev, true); |
3240 | // return i915_handle_error(dev, true); |
2550 | - | ||
2551 | } |
3241 | |
2552 | 3242 | } |
|
2553 | static void ibx_irq_preinstall(struct drm_device *dev) |
3243 | static void ibx_irq_reset(struct drm_device *dev) |
Line 2554... | Line 3244... | ||
2554 | { |
3244 | { |
2555 | struct drm_i915_private *dev_priv = dev->dev_private; |
3245 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2556... | Line 3246... | ||
2556 | 3246 | ||
- | 3247 | if (HAS_PCH_NOP(dev)) |
|
- | 3248 | return; |
|
2557 | if (HAS_PCH_NOP(dev)) |
3249 | |
- | 3250 | GEN5_IRQ_RESET(SDE); |
|
- | 3251 | ||
2558 | return; |
3252 | if (HAS_PCH_CPT(dev) || HAS_PCH_LPT(dev)) |
2559 | 3253 | I915_WRITE(SERR_INT, 0xffffffff); |
|
2560 | /* south display irq */ |
3254 | } |
2561 | I915_WRITE(SDEIMR, 0xffffffff); |
3255 | |
2562 | /* |
3256 | /* |
- | 3257 | * SDEIER is also touched by the interrupt handler to work around missed PCH |
|
- | 3258 | * interrupts. Hence we can't update it after the interrupt handler is enabled - |
|
2563 | * SDEIER is also touched by the interrupt handler to work around missed |
3259 | * instead we unconditionally enable all PCH interrupt sources here, but then |
- | 3260 | * only unmask them as needed with SDEIMR. |
|
- | 3261 | * |
|
- | 3262 | * This function needs to be called before interrupts are enabled. |
|
- | 3263 | */ |
|
- | 3264 | static void ibx_irq_pre_postinstall(struct drm_device *dev) |
|
- | 3265 | { |
|
- | 3266 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 3267 | ||
2564 | * PCH interrupts. Hence we can't update it after the interrupt handler |
3268 | if (HAS_PCH_NOP(dev)) |
2565 | * is enabled - instead we unconditionally enable all PCH interrupt |
3269 | return; |
2566 | * sources here, but then only unmask them as needed with SDEIMR. |
3270 | |
Line 2567... | Line 3271... | ||
2567 | */ |
3271 | WARN_ON(I915_READ(SDEIER) != 0); |
2568 | I915_WRITE(SDEIER, 0xffffffff); |
3272 | I915_WRITE(SDEIER, 0xffffffff); |
2569 | POSTING_READ(SDEIER); |
3273 | POSTING_READ(SDEIER); |
Line 2570... | Line -... | ||
2570 | } |
- | |
2571 | - | ||
2572 | static void gen5_gt_irq_preinstall(struct drm_device *dev) |
- | |
2573 | { |
3274 | } |
2574 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
2575 | 3275 | ||
2576 | /* and GT */ |
- | |
2577 | I915_WRITE(GTIMR, 0xffffffff); |
- | |
2578 | I915_WRITE(GTIER, 0x0); |
- | |
2579 | POSTING_READ(GTIER); |
3276 | static void gen5_gt_irq_reset(struct drm_device *dev) |
2580 | - | ||
2581 | if (INTEL_INFO(dev)->gen >= 6) { |
3277 | { |
Line 2582... | Line 3278... | ||
2582 | /* and PM */ |
3278 | struct drm_i915_private *dev_priv = dev->dev_private; |
2583 | I915_WRITE(GEN6_PMIMR, 0xffffffff); |
3279 | |
2584 | I915_WRITE(GEN6_PMIER, 0x0); |
3280 | GEN5_IRQ_RESET(GT); |
2585 | POSTING_READ(GEN6_PMIER); |
3281 | if (INTEL_INFO(dev)->gen >= 6) |
2586 | } |
3282 | GEN5_IRQ_RESET(GEN6_PM); |
2587 | } |
- | |
2588 | - | ||
Line 2589... | Line 3283... | ||
2589 | /* drm_dma.h hooks |
3283 | } |
Line 2590... | Line 3284... | ||
2590 | */ |
3284 | |
2591 | static void ironlake_irq_preinstall(struct drm_device *dev) |
3285 | /* drm_dma.h hooks |
2592 | { |
3286 | */ |
Line 2593... | Line 3287... | ||
2593 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3287 | static void ironlake_irq_reset(struct drm_device *dev) |
Line 2594... | Line 3288... | ||
2594 | 3288 | { |
|
2595 | atomic_set(&dev_priv->irq_received, 0); |
3289 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2596... | Line 3290... | ||
2596 | 3290 | ||
2597 | I915_WRITE(HWSTAM, 0xeffe); |
3291 | I915_WRITE(HWSTAM, 0xffffffff); |
2598 | 3292 | ||
2599 | I915_WRITE(DEIMR, 0xffffffff); |
3293 | GEN5_IRQ_RESET(DE); |
Line 2600... | Line -... | ||
2600 | I915_WRITE(DEIER, 0x0); |
- | |
2601 | POSTING_READ(DEIER); |
- | |
2602 | 3294 | if (IS_GEN7(dev)) |
|
2603 | gen5_gt_irq_preinstall(dev); |
3295 | I915_WRITE(GEN7_ERR_INT, 0xffffffff); |
2604 | 3296 | ||
2605 | ibx_irq_preinstall(dev); |
3297 | gen5_gt_irq_reset(dev); |
2606 | } |
3298 | |
Line 2607... | Line 3299... | ||
2607 | 3299 | ibx_irq_reset(dev); |
|
2608 | static void valleyview_irq_preinstall(struct drm_device *dev) |
3300 | } |
2609 | { |
3301 | |
Line 2610... | Line 3302... | ||
2610 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3302 | static void valleyview_irq_preinstall(struct drm_device *dev) |
Line 2611... | Line 3303... | ||
2611 | int pipe; |
3303 | { |
Line 2612... | Line 3304... | ||
2612 | 3304 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
2613 | atomic_set(&dev_priv->irq_received, 0); |
3305 | int pipe; |
Line 2634... | Line 3326... | ||
2634 | I915_WRITE(VLV_IMR, 0xffffffff); |
3326 | I915_WRITE(VLV_IMR, 0xffffffff); |
2635 | I915_WRITE(VLV_IER, 0x0); |
3327 | I915_WRITE(VLV_IER, 0x0); |
2636 | POSTING_READ(VLV_IER); |
3328 | POSTING_READ(VLV_IER); |
2637 | } |
3329 | } |
Line -... | Line 3330... | ||
- | 3330 | ||
- | 3331 | static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv) |
|
- | 3332 | { |
|
- | 3333 | GEN8_IRQ_RESET_NDX(GT, 0); |
|
- | 3334 | GEN8_IRQ_RESET_NDX(GT, 1); |
|
- | 3335 | GEN8_IRQ_RESET_NDX(GT, 2); |
|
- | 3336 | GEN8_IRQ_RESET_NDX(GT, 3); |
|
- | 3337 | } |
|
2638 | 3338 | ||
2639 | static void gen8_irq_preinstall(struct drm_device *dev) |
3339 | static void gen8_irq_reset(struct drm_device *dev) |
2640 | { |
3340 | { |
2641 | struct drm_i915_private *dev_priv = dev->dev_private; |
3341 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2642... | Line -... | ||
2642 | int pipe; |
- | |
2643 | - | ||
2644 | atomic_set(&dev_priv->irq_received, 0); |
3342 | int pipe; |
2645 | 3343 | ||
Line 2646... | Line -... | ||
2646 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
- | |
2647 | POSTING_READ(GEN8_MASTER_IRQ); |
3344 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
2648 | - | ||
2649 | /* IIR can theoretically queue up two events. Be paranoid */ |
- | |
2650 | #define GEN8_IRQ_INIT_NDX(type, which) do { \ |
- | |
2651 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ |
- | |
2652 | POSTING_READ(GEN8_##type##_IMR(which)); \ |
- | |
2653 | I915_WRITE(GEN8_##type##_IER(which), 0); \ |
- | |
2654 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ |
- | |
Line 2655... | Line 3345... | ||
2655 | POSTING_READ(GEN8_##type##_IIR(which)); \ |
3345 | POSTING_READ(GEN8_MASTER_IRQ); |
2656 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ |
3346 | |
2657 | } while (0) |
3347 | gen8_gt_irq_reset(dev_priv); |
2658 | 3348 | ||
2659 | #define GEN8_IRQ_INIT(type) do { \ |
- | |
2660 | I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \ |
- | |
2661 | POSTING_READ(GEN8_##type##_IMR); \ |
- | |
2662 | I915_WRITE(GEN8_##type##_IER, 0); \ |
- | |
Line 2663... | Line 3349... | ||
2663 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ |
3349 | for_each_pipe(pipe) |
2664 | POSTING_READ(GEN8_##type##_IIR); \ |
3350 | if (intel_display_power_enabled(dev_priv, |
2665 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ |
3351 | POWER_DOMAIN_PIPE(pipe))) |
2666 | } while (0) |
- | |
Line 2667... | Line 3352... | ||
2667 | 3352 | GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); |
|
- | 3353 | ||
- | 3354 | GEN5_IRQ_RESET(GEN8_DE_PORT_); |
|
- | 3355 | GEN5_IRQ_RESET(GEN8_DE_MISC_); |
|
- | 3356 | GEN5_IRQ_RESET(GEN8_PCU_); |
|
- | 3357 | ||
- | 3358 | ibx_irq_reset(dev); |
|
- | 3359 | } |
|
- | 3360 | ||
- | 3361 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) |
|
2668 | GEN8_IRQ_INIT_NDX(GT, 0); |
3362 | { |
- | 3363 | unsigned long irqflags; |
|
- | 3364 | ||
2669 | GEN8_IRQ_INIT_NDX(GT, 1); |
3365 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
Line -... | Line 3366... | ||
- | 3366 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B], |
|
- | 3367 | ~dev_priv->de_irq_mask[PIPE_B]); |
|
- | 3368 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C], |
|
2670 | GEN8_IRQ_INIT_NDX(GT, 2); |
3369 | ~dev_priv->de_irq_mask[PIPE_C]); |
- | 3370 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
|
2671 | GEN8_IRQ_INIT_NDX(GT, 3); |
3371 | } |
2672 | 3372 | ||
- | 3373 | static void cherryview_irq_preinstall(struct drm_device *dev) |
|
2673 | for_each_pipe(pipe) { |
3374 | { |
- | 3375 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
2674 | GEN8_IRQ_INIT_NDX(DE_PIPE, pipe); |
3376 | int pipe; |
Line 2675... | Line 3377... | ||
2675 | } |
3377 | |
Line -... | Line 3378... | ||
- | 3378 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
|
- | 3379 | POSTING_READ(GEN8_MASTER_IRQ); |
|
- | 3380 | ||
- | 3381 | gen8_gt_irq_reset(dev_priv); |
|
- | 3382 | ||
2676 | 3383 | GEN5_IRQ_RESET(GEN8_PCU_); |
|
- | 3384 | ||
- | 3385 | POSTING_READ(GEN8_PCU_IIR); |
|
- | 3386 | ||
- | 3387 | I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK_CHV); |
|
- | 3388 | ||
- | 3389 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
|
2677 | GEN8_IRQ_INIT(DE_PORT); |
3390 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
Line 2678... | Line 3391... | ||
2678 | GEN8_IRQ_INIT(DE_MISC); |
3391 | |
2679 | GEN8_IRQ_INIT(PCU); |
3392 | for_each_pipe(pipe) |
2680 | #undef GEN8_IRQ_INIT |
3393 | I915_WRITE(PIPESTAT(pipe), 0xffff); |
2681 | #undef GEN8_IRQ_INIT_NDX |
3394 | |
2682 | 3395 | I915_WRITE(VLV_IMR, 0xffffffff); |
|
2683 | POSTING_READ(GEN8_PCU_IIR); |
3396 | I915_WRITE(VLV_IER, 0x0); |
Line 2684... | Line 3397... | ||
2684 | 3397 | I915_WRITE(VLV_IIR, 0xffffffff); |
|
Line 2720... | Line 3433... | ||
2720 | I915_WRITE(PCH_PORT_HOTPLUG, hotplug); |
3433 | I915_WRITE(PCH_PORT_HOTPLUG, hotplug); |
2721 | } |
3434 | } |
Line 2722... | Line 3435... | ||
2722 | 3435 | ||
2723 | static void ibx_irq_postinstall(struct drm_device *dev) |
3436 | static void ibx_irq_postinstall(struct drm_device *dev) |
2724 | { |
3437 | { |
2725 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3438 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2726... | Line 3439... | ||
2726 | u32 mask; |
3439 | u32 mask; |
2727 | 3440 | ||
Line 2728... | Line 3441... | ||
2728 | if (HAS_PCH_NOP(dev)) |
3441 | if (HAS_PCH_NOP(dev)) |
2729 | return; |
3442 | return; |
2730 | - | ||
2731 | if (HAS_PCH_IBX(dev)) { |
3443 | |
2732 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | |
3444 | if (HAS_PCH_IBX(dev)) |
2733 | SDE_TRANSA_FIFO_UNDER | SDE_POISON; |
- | |
2734 | } else { |
- | |
2735 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; |
- | |
Line 2736... | Line 3445... | ||
2736 | 3445 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; |
|
2737 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); |
3446 | else |
2738 | } |
3447 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; |
Line 2739... | Line 3448... | ||
2739 | 3448 | ||
2740 | I915_WRITE(SDEIIR, I915_READ(SDEIIR)); |
3449 | GEN5_ASSERT_IIR_IS_ZERO(SDEIIR); |
Line 2761... | Line 3470... | ||
2761 | ILK_BSD_USER_INTERRUPT; |
3470 | ILK_BSD_USER_INTERRUPT; |
2762 | } else { |
3471 | } else { |
2763 | gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; |
3472 | gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; |
2764 | } |
3473 | } |
Line 2765... | Line -... | ||
2765 | - | ||
2766 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
3474 | |
2767 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask); |
- | |
2768 | I915_WRITE(GTIER, gt_irqs); |
- | |
Line 2769... | Line 3475... | ||
2769 | POSTING_READ(GTIER); |
3475 | GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); |
2770 | 3476 | ||
Line 2771... | Line 3477... | ||
2771 | if (INTEL_INFO(dev)->gen >= 6) { |
3477 | if (INTEL_INFO(dev)->gen >= 6) { |
2772 | pm_irqs |= GEN6_PM_RPS_EVENTS; |
3478 | pm_irqs |= dev_priv->pm_rps_events; |
Line 2773... | Line 3479... | ||
2773 | 3479 | ||
2774 | if (HAS_VEBOX(dev)) |
- | |
2775 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; |
3480 | if (HAS_VEBOX(dev)) |
2776 | - | ||
2777 | dev_priv->pm_irq_mask = 0xffffffff; |
- | |
2778 | I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); |
3481 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; |
2779 | I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask); |
3482 | |
Line 2780... | Line 3483... | ||
2780 | I915_WRITE(GEN6_PMIER, pm_irqs); |
3483 | dev_priv->pm_irq_mask = 0xffffffff; |
2781 | POSTING_READ(GEN6_PMIER); |
3484 | GEN5_IRQ_INIT(GEN6_PM, dev_priv->pm_irq_mask, pm_irqs); |
2782 | } |
3485 | } |
2783 | } |
3486 | } |
2784 | 3487 | ||
Line 2785... | Line 3488... | ||
2785 | static int ironlake_irq_postinstall(struct drm_device *dev) |
3488 | static int ironlake_irq_postinstall(struct drm_device *dev) |
2786 | { |
3489 | { |
2787 | unsigned long irqflags; |
3490 | unsigned long irqflags; |
2788 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3491 | struct drm_i915_private *dev_priv = dev->dev_private; |
2789 | u32 display_mask, extra_mask; |
3492 | u32 display_mask, extra_mask; |
2790 | - | ||
2791 | if (INTEL_INFO(dev)->gen >= 7) { |
3493 | |
2792 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | |
3494 | if (INTEL_INFO(dev)->gen >= 7) { |
2793 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | |
- | |
2794 | DE_PLANEB_FLIP_DONE_IVB | |
- | |
2795 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | |
3495 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | |
2796 | DE_ERR_INT_IVB); |
3496 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | |
2797 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | |
3497 | DE_PLANEB_FLIP_DONE_IVB | |
2798 | DE_PIPEA_VBLANK_IVB); |
3498 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB); |
2799 | - | ||
2800 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); |
3499 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | |
2801 | } else { |
3500 | DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB); |
2802 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
3501 | } else { |
- | 3502 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
|
2803 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | |
3503 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | |
Line 2804... | Line 3504... | ||
2804 | DE_AUX_CHANNEL_A | |
3504 | DE_AUX_CHANNEL_A | |
Line 2805... | Line -... | ||
2805 | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN | |
- | |
2806 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | |
3505 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | |
- | 3506 | DE_POISON); |
|
2807 | DE_POISON); |
3507 | extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT | |
- | 3508 | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN; |
|
2808 | extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT; |
3509 | } |
2809 | } |
- | |
Line 2810... | Line 3510... | ||
2810 | 3510 | ||
Line 2811... | Line 3511... | ||
2811 | dev_priv->irq_mask = ~display_mask; |
3511 | dev_priv->irq_mask = ~display_mask; |
Line 2832... | Line 3532... | ||
2832 | } |
3532 | } |
Line 2833... | Line 3533... | ||
2833 | 3533 | ||
2834 | return 0; |
3534 | return 0; |
Line -... | Line 3535... | ||
- | 3535 | } |
|
- | 3536 | ||
- | 3537 | static void valleyview_display_irqs_install(struct drm_i915_private *dev_priv) |
|
- | 3538 | { |
|
- | 3539 | u32 pipestat_mask; |
|
- | 3540 | u32 iir_mask; |
|
- | 3541 | ||
- | 3542 | pipestat_mask = PIPESTAT_INT_STATUS_MASK | |
|
- | 3543 | PIPE_FIFO_UNDERRUN_STATUS; |
|
- | 3544 | ||
- | 3545 | I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask); |
|
- | 3546 | I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask); |
|
- | 3547 | POSTING_READ(PIPESTAT(PIPE_A)); |
|
- | 3548 | ||
- | 3549 | pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | |
|
- | 3550 | PIPE_CRC_DONE_INTERRUPT_STATUS; |
|
- | 3551 | ||
- | 3552 | i915_enable_pipestat(dev_priv, PIPE_A, pipestat_mask | |
|
- | 3553 | PIPE_GMBUS_INTERRUPT_STATUS); |
|
- | 3554 | i915_enable_pipestat(dev_priv, PIPE_B, pipestat_mask); |
|
- | 3555 | ||
- | 3556 | iir_mask = I915_DISPLAY_PORT_INTERRUPT | |
|
- | 3557 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | |
|
- | 3558 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; |
|
- | 3559 | dev_priv->irq_mask &= ~iir_mask; |
|
- | 3560 | ||
- | 3561 | I915_WRITE(VLV_IIR, iir_mask); |
|
- | 3562 | I915_WRITE(VLV_IIR, iir_mask); |
|
- | 3563 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); |
|
- | 3564 | I915_WRITE(VLV_IER, ~dev_priv->irq_mask); |
|
- | 3565 | POSTING_READ(VLV_IER); |
|
- | 3566 | } |
|
- | 3567 | ||
- | 3568 | static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv) |
|
- | 3569 | { |
|
- | 3570 | u32 pipestat_mask; |
|
- | 3571 | u32 iir_mask; |
|
- | 3572 | ||
- | 3573 | iir_mask = I915_DISPLAY_PORT_INTERRUPT | |
|
- | 3574 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | |
|
- | 3575 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT; |
|
- | 3576 | ||
- | 3577 | dev_priv->irq_mask |= iir_mask; |
|
- | 3578 | I915_WRITE(VLV_IER, ~dev_priv->irq_mask); |
|
- | 3579 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); |
|
- | 3580 | I915_WRITE(VLV_IIR, iir_mask); |
|
- | 3581 | I915_WRITE(VLV_IIR, iir_mask); |
|
- | 3582 | POSTING_READ(VLV_IIR); |
|
- | 3583 | ||
- | 3584 | pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV | |
|
- | 3585 | PIPE_CRC_DONE_INTERRUPT_STATUS; |
|
- | 3586 | ||
- | 3587 | i915_disable_pipestat(dev_priv, PIPE_A, pipestat_mask | |
|
- | 3588 | PIPE_GMBUS_INTERRUPT_STATUS); |
|
- | 3589 | i915_disable_pipestat(dev_priv, PIPE_B, pipestat_mask); |
|
- | 3590 | ||
- | 3591 | pipestat_mask = PIPESTAT_INT_STATUS_MASK | |
|
- | 3592 | PIPE_FIFO_UNDERRUN_STATUS; |
|
- | 3593 | I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask); |
|
- | 3594 | I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask); |
|
- | 3595 | POSTING_READ(PIPESTAT(PIPE_A)); |
|
- | 3596 | } |
|
- | 3597 | ||
- | 3598 | void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) |
|
- | 3599 | { |
|
- | 3600 | assert_spin_locked(&dev_priv->irq_lock); |
|
- | 3601 | ||
- | 3602 | if (dev_priv->display_irqs_enabled) |
|
- | 3603 | return; |
|
- | 3604 | ||
- | 3605 | dev_priv->display_irqs_enabled = true; |
|
- | 3606 | ||
- | 3607 | if (dev_priv->dev->irq_enabled) |
|
- | 3608 | valleyview_display_irqs_install(dev_priv); |
|
- | 3609 | } |
|
- | 3610 | ||
- | 3611 | void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) |
|
- | 3612 | { |
|
- | 3613 | assert_spin_locked(&dev_priv->irq_lock); |
|
- | 3614 | ||
- | 3615 | if (!dev_priv->display_irqs_enabled) |
|
- | 3616 | return; |
|
- | 3617 | ||
- | 3618 | dev_priv->display_irqs_enabled = false; |
|
- | 3619 | ||
- | 3620 | if (dev_priv->dev->irq_enabled) |
|
- | 3621 | valleyview_display_irqs_uninstall(dev_priv); |
|
2835 | } |
3622 | } |
2836 | 3623 | ||
2837 | static int valleyview_irq_postinstall(struct drm_device *dev) |
3624 | static int valleyview_irq_postinstall(struct drm_device *dev) |
2838 | { |
- | |
2839 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | |
2840 | u32 enable_mask; |
- | |
2841 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV | |
3625 | { |
Line 2842... | Line -... | ||
2842 | PIPE_CRC_DONE_ENABLE; |
- | |
2843 | unsigned long irqflags; |
- | |
2844 | - | ||
2845 | enable_mask = I915_DISPLAY_PORT_INTERRUPT; |
- | |
2846 | enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | |
- | |
2847 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | |
- | |
2848 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | |
- | |
2849 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
- | |
2850 | - | ||
2851 | /* |
- | |
2852 | *Leave vblank interrupts masked initially. enable/disable will |
3626 | struct drm_i915_private *dev_priv = dev->dev_private; |
2853 | * toggle them based on usage. |
- | |
2854 | */ |
- | |
Line 2855... | Line 3627... | ||
2855 | dev_priv->irq_mask = (~enable_mask) | |
3627 | unsigned long irqflags; |
2856 | I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | |
3628 | |
Line 2857... | Line 3629... | ||
2857 | I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT; |
3629 | dev_priv->irq_mask = ~0; |
2858 | 3630 | ||
2859 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
3631 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
2860 | POSTING_READ(PORT_HOTPLUG_EN); |
- | |
2861 | - | ||
2862 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); |
3632 | POSTING_READ(PORT_HOTPLUG_EN); |
Line 2863... | Line 3633... | ||
2863 | I915_WRITE(VLV_IER, enable_mask); |
3633 | |
2864 | I915_WRITE(VLV_IIR, 0xffffffff); |
3634 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); |
2865 | I915_WRITE(PIPESTAT(0), 0xffff); |
3635 | I915_WRITE(VLV_IER, ~dev_priv->irq_mask); |
2866 | I915_WRITE(PIPESTAT(1), 0xffff); |
3636 | I915_WRITE(VLV_IIR, 0xffffffff); |
2867 | POSTING_READ(VLV_IER); |
- | |
2868 | 3637 | POSTING_READ(VLV_IER); |
|
2869 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3638 | |
Line 2870... | Line 3639... | ||
2870 | * just to make the assert_spin_locked check happy. */ |
3639 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
2871 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3640 | * just to make the assert_spin_locked check happy. */ |
Line 2903... | Line 3672... | ||
2903 | GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT, |
3672 | GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT, |
2904 | 0, |
3673 | 0, |
2905 | GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT |
3674 | GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT |
2906 | }; |
3675 | }; |
Line 2907... | Line 3676... | ||
2907 | 3676 | ||
2908 | for (i = 0; i < ARRAY_SIZE(gt_interrupts); i++) { |
- | |
2909 | u32 tmp = I915_READ(GEN8_GT_IIR(i)); |
- | |
2910 | if (tmp) |
- | |
2911 | DRM_ERROR("Interrupt (%d) should have been masked in pre-install 0x%08x\n", |
- | |
2912 | i, tmp); |
- | |
2913 | I915_WRITE(GEN8_GT_IMR(i), ~gt_interrupts[i]); |
3677 | for (i = 0; i < ARRAY_SIZE(gt_interrupts); i++) |
2914 | I915_WRITE(GEN8_GT_IER(i), gt_interrupts[i]); |
3678 | GEN8_IRQ_INIT_NDX(GT, i, ~gt_interrupts[i], gt_interrupts[i]); |
2915 | } |
3679 | |
2916 | POSTING_READ(GEN8_GT_IER(0)); |
3680 | dev_priv->pm_irq_mask = 0xffffffff; |
Line 2917... | Line 3681... | ||
2917 | } |
3681 | } |
2918 | 3682 | ||
2919 | static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) |
3683 | static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) |
2920 | { |
3684 | { |
2921 | struct drm_device *dev = dev_priv->dev; |
3685 | struct drm_device *dev = dev_priv->dev; |
2922 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | |
- | |
2923 | GEN8_PIPE_CDCLK_CRC_DONE | |
3686 | uint32_t de_pipe_masked = GEN8_PIPE_PRIMARY_FLIP_DONE | |
2924 | GEN8_PIPE_FIFO_UNDERRUN | |
3687 | GEN8_PIPE_CDCLK_CRC_DONE | |
- | 3688 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
|
2925 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
3689 | uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | |
2926 | uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK; |
3690 | GEN8_PIPE_FIFO_UNDERRUN; |
2927 | int pipe; |
3691 | int pipe; |
2928 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; |
3692 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; |
Line 2929... | Line 3693... | ||
2929 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; |
3693 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; |
2930 | dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked; |
3694 | dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked; |
2931 | 3695 | ||
2932 | for_each_pipe(pipe) { |
- | |
2933 | u32 tmp = I915_READ(GEN8_DE_PIPE_IIR(pipe)); |
3696 | for_each_pipe(pipe) |
2934 | if (tmp) |
3697 | if (intel_display_power_enabled(dev_priv, |
2935 | DRM_ERROR("Interrupt (%d) should have been masked in pre-install 0x%08x\n", |
3698 | POWER_DOMAIN_PIPE(pipe))) |
2936 | pipe, tmp); |
- | |
2937 | I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); |
- | |
Line 2938... | Line -... | ||
2938 | I915_WRITE(GEN8_DE_PIPE_IER(pipe), de_pipe_enables); |
- | |
2939 | } |
3699 | GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, |
2940 | POSTING_READ(GEN8_DE_PIPE_ISR(0)); |
- | |
2941 | 3700 | dev_priv->de_irq_mask[pipe], |
|
Line 2942... | Line 3701... | ||
2942 | I915_WRITE(GEN8_DE_PORT_IMR, ~GEN8_AUX_CHANNEL_A); |
3701 | de_pipe_enables); |
2943 | I915_WRITE(GEN8_DE_PORT_IER, GEN8_AUX_CHANNEL_A); |
3702 | |
2944 | POSTING_READ(GEN8_DE_PORT_IER); |
3703 | GEN5_IRQ_INIT(GEN8_DE_PORT_, ~GEN8_AUX_CHANNEL_A, GEN8_AUX_CHANNEL_A); |
Line -... | Line 3704... | ||
- | 3704 | } |
|
- | 3705 | ||
2945 | } |
3706 | static int gen8_irq_postinstall(struct drm_device *dev) |
2946 | 3707 | { |
|
Line 2947... | Line 3708... | ||
2947 | static int gen8_irq_postinstall(struct drm_device *dev) |
3708 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2957... | Line 3718... | ||
2957 | POSTING_READ(GEN8_MASTER_IRQ); |
3718 | POSTING_READ(GEN8_MASTER_IRQ); |
Line 2958... | Line 3719... | ||
2958 | 3719 | ||
2959 | return 0; |
3720 | return 0; |
Line 2960... | Line 3721... | ||
2960 | } |
3721 | } |
2961 | 3722 | ||
2962 | static void gen8_irq_uninstall(struct drm_device *dev) |
3723 | static int cherryview_irq_postinstall(struct drm_device *dev) |
- | 3724 | { |
|
- | 3725 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 3726 | u32 enable_mask = I915_DISPLAY_PORT_INTERRUPT | |
|
- | 3727 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | |
|
- | 3728 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | |
|
- | 3729 | I915_DISPLAY_PIPE_C_EVENT_INTERRUPT; |
|
- | 3730 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV | |
|
2963 | { |
3731 | PIPE_CRC_DONE_INTERRUPT_STATUS; |
Line -... | Line 3732... | ||
- | 3732 | unsigned long irqflags; |
|
- | 3733 | int pipe; |
|
2964 | struct drm_i915_private *dev_priv = dev->dev_private; |
3734 | |
2965 | int pipe; |
3735 | /* |
- | 3736 | * Leave vblank interrupts masked initially. enable/disable will |
|
Line -... | Line 3737... | ||
- | 3737 | * toggle them based on usage. |
|
2966 | 3738 | */ |
|
Line 2967... | Line 3739... | ||
2967 | if (!dev_priv) |
3739 | dev_priv->irq_mask = ~enable_mask; |
- | 3740 | ||
- | 3741 | for_each_pipe(pipe) |
|
- | 3742 | I915_WRITE(PIPESTAT(pipe), 0xffff); |
|
- | 3743 | ||
Line 2968... | Line -... | ||
2968 | return; |
- | |
2969 | 3744 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
|
2970 | atomic_set(&dev_priv->irq_received, 0); |
3745 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); |
2971 | 3746 | for_each_pipe(pipe) |
|
2972 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
- | |
Line 2973... | Line -... | ||
2973 | - | ||
2974 | #define GEN8_IRQ_FINI_NDX(type, which) do { \ |
- | |
2975 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ |
3747 | i915_enable_pipestat(dev_priv, pipe, pipestat_enable); |
2976 | I915_WRITE(GEN8_##type##_IER(which), 0); \ |
- | |
2977 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ |
- | |
Line 2978... | Line -... | ||
2978 | } while (0) |
- | |
2979 | - | ||
2980 | #define GEN8_IRQ_FINI(type) do { \ |
3748 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2981 | I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \ |
3749 | |
Line 2982... | Line 3750... | ||
2982 | I915_WRITE(GEN8_##type##_IER, 0); \ |
3750 | I915_WRITE(VLV_IIR, 0xffffffff); |
2983 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ |
- | |
2984 | } while (0) |
3751 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); |
Line 2985... | Line 3752... | ||
2985 | 3752 | I915_WRITE(VLV_IER, enable_mask); |
|
- | 3753 | ||
2986 | GEN8_IRQ_FINI_NDX(GT, 0); |
3754 | gen8_gt_irq_postinstall(dev_priv); |
2987 | GEN8_IRQ_FINI_NDX(GT, 1); |
- | |
2988 | GEN8_IRQ_FINI_NDX(GT, 2); |
- | |
2989 | GEN8_IRQ_FINI_NDX(GT, 3); |
- | |
Line -... | Line 3755... | ||
- | 3755 | ||
- | 3756 | I915_WRITE(GEN8_MASTER_IRQ, MASTER_INTERRUPT_ENABLE); |
|
- | 3757 | POSTING_READ(GEN8_MASTER_IRQ); |
|
2990 | 3758 | ||
2991 | for_each_pipe(pipe) { |
3759 | return 0; |
Line 2992... | Line 3760... | ||
2992 | GEN8_IRQ_FINI_NDX(DE_PIPE, pipe); |
3760 | } |
2993 | } |
3761 | |
2994 | 3762 | static void gen8_irq_uninstall(struct drm_device *dev) |
|
- | 3763 | { |
|
2995 | GEN8_IRQ_FINI(DE_PORT); |
3764 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 2996... | Line 3765... | ||
2996 | GEN8_IRQ_FINI(DE_MISC); |
3765 | |
2997 | GEN8_IRQ_FINI(PCU); |
3766 | if (!dev_priv) |
Line 2998... | Line 3767... | ||
2998 | #undef GEN8_IRQ_FINI |
3767 | return; |
Line 2999... | Line 3768... | ||
2999 | #undef GEN8_IRQ_FINI_NDX |
3768 | |
3000 | 3769 | gen8_irq_reset(dev); |
|
Line 3001... | Line 3770... | ||
3001 | POSTING_READ(GEN8_PCU_IIR); |
3770 | } |
3002 | } |
3771 | |
3003 | 3772 | static void valleyview_irq_uninstall(struct drm_device *dev) |
|
- | 3773 | { |
|
- | 3774 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
3004 | static void valleyview_irq_uninstall(struct drm_device *dev) |
3775 | unsigned long irqflags; |
3005 | { |
3776 | int pipe; |
- | 3777 | ||
- | 3778 | if (!dev_priv) |
|
- | 3779 | return; |
|
- | 3780 | ||
3006 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3781 | I915_WRITE(VLV_MASTER_IER, 0); |
3007 | int pipe; |
3782 | |
3008 | 3783 | for_each_pipe(pipe) |
|
3009 | if (!dev_priv) |
3784 | I915_WRITE(PIPESTAT(pipe), 0xffff); |
3010 | return; |
3785 | |
Line 3011... | Line 3786... | ||
3011 | 3786 | I915_WRITE(HWSTAM, 0xffffffff); |
|
3012 | del_timer_sync(&dev_priv->hotplug_reenable_timer); |
3787 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
3013 | 3788 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
|
- | 3789 | ||
Line 3014... | Line 3790... | ||
3014 | for_each_pipe(pipe) |
3790 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3015 | I915_WRITE(PIPESTAT(pipe), 0xffff); |
3791 | if (dev_priv->display_irqs_enabled) |
Line -... | Line 3792... | ||
- | 3792 | valleyview_display_irqs_uninstall(dev_priv); |
|
3016 | 3793 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
|
Line -... | Line 3794... | ||
- | 3794 | ||
- | 3795 | dev_priv->irq_mask = 0; |
|
3017 | I915_WRITE(HWSTAM, 0xffffffff); |
3796 | |
- | 3797 | I915_WRITE(VLV_IIR, 0xffffffff); |
|
- | 3798 | I915_WRITE(VLV_IMR, 0xffffffff); |
|
- | 3799 | I915_WRITE(VLV_IER, 0x0); |
|
- | 3800 | POSTING_READ(VLV_IER); |
|
- | 3801 | } |
|
Line -... | Line 3802... | ||
- | 3802 | ||
- | 3803 | static void cherryview_irq_uninstall(struct drm_device *dev) |
|
3018 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
3804 | { |
3019 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
3805 | struct drm_i915_private *dev_priv = dev->dev_private; |
3020 | for_each_pipe(pipe) |
3806 | int pipe; |
3021 | I915_WRITE(PIPESTAT(pipe), 0xffff); |
3807 | |
3022 | I915_WRITE(VLV_IIR, 0xffffffff); |
3808 | if (!dev_priv) |
- | 3809 | return; |
|
Line -... | Line 3810... | ||
- | 3810 | ||
3023 | I915_WRITE(VLV_IMR, 0xffffffff); |
3811 | I915_WRITE(GEN8_MASTER_IRQ, 0); |
3024 | I915_WRITE(VLV_IER, 0x0); |
3812 | POSTING_READ(GEN8_MASTER_IRQ); |
3025 | POSTING_READ(VLV_IER); |
3813 | |
Line -... | Line 3814... | ||
- | 3814 | #define GEN8_IRQ_FINI_NDX(type, which) \ |
|
- | 3815 | do { \ |
|
- | 3816 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ |
|
- | 3817 | I915_WRITE(GEN8_##type##_IER(which), 0); \ |
|
- | 3818 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ |
|
- | 3819 | POSTING_READ(GEN8_##type##_IIR(which)); \ |
|
- | 3820 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ |
|
- | 3821 | } while (0) |
|
- | 3822 | ||
- | 3823 | #define GEN8_IRQ_FINI(type) \ |
|
- | 3824 | do { \ |
|
- | 3825 | I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \ |
|
- | 3826 | I915_WRITE(GEN8_##type##_IER, 0); \ |
|
- | 3827 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ |
|
- | 3828 | POSTING_READ(GEN8_##type##_IIR); \ |
|
- | 3829 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ |
|
- | 3830 | } while (0) |
|
- | 3831 | ||
- | 3832 | GEN8_IRQ_FINI_NDX(GT, 0); |
|
- | 3833 | GEN8_IRQ_FINI_NDX(GT, 1); |
|
- | 3834 | GEN8_IRQ_FINI_NDX(GT, 2); |
|
3026 | } |
3835 | GEN8_IRQ_FINI_NDX(GT, 3); |
3027 | 3836 | ||
Line 3028... | Line -... | ||
3028 | static void ironlake_irq_uninstall(struct drm_device *dev) |
- | |
3029 | { |
3837 | GEN8_IRQ_FINI(PCU); |
3030 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | |
3031 | - | ||
3032 | if (!dev_priv) |
- | |
3033 | return; |
3838 | |
Line 3034... | Line 3839... | ||
3034 | 3839 | #undef GEN8_IRQ_FINI |
|
Line 3035... | Line 3840... | ||
3035 | del_timer_sync(&dev_priv->hotplug_reenable_timer); |
3840 | #undef GEN8_IRQ_FINI_NDX |
3036 | 3841 | ||
3037 | I915_WRITE(HWSTAM, 0xffffffff); |
3842 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
3038 | 3843 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
|
Line 3039... | Line -... | ||
3039 | I915_WRITE(DEIMR, 0xffffffff); |
- | |
3040 | I915_WRITE(DEIER, 0x0); |
- | |
3041 | I915_WRITE(DEIIR, I915_READ(DEIIR)); |
3844 | |
3042 | if (IS_GEN7(dev)) |
3845 | for_each_pipe(pipe) |
3043 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); |
3846 | I915_WRITE(PIPESTAT(pipe), 0xffff); |
3044 | 3847 | ||
3045 | I915_WRITE(GTIMR, 0xffffffff); |
3848 | I915_WRITE(VLV_IMR, 0xffffffff); |
3046 | I915_WRITE(GTIER, 0x0); |
3849 | I915_WRITE(VLV_IER, 0x0); |
Line 3047... | Line 3850... | ||
3047 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
3850 | I915_WRITE(VLV_IIR, 0xffffffff); |
3048 | 3851 | POSTING_READ(VLV_IIR); |
|
3049 | if (HAS_PCH_NOP(dev)) |
3852 | } |
3050 | return; |
3853 | |
Line 3051... | Line 3854... | ||
3051 | 3854 | static void ironlake_irq_uninstall(struct drm_device *dev) |
|
3052 | I915_WRITE(SDEIMR, 0xffffffff); |
3855 | { |
Line 3097... | Line 3900... | ||
3097 | POSTING_READ16(IER); |
3900 | POSTING_READ16(IER); |
Line 3098... | Line 3901... | ||
3098 | 3901 | ||
3099 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3902 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3100 | * just to make the assert_spin_locked check happy. */ |
3903 | * just to make the assert_spin_locked check happy. */ |
3101 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3904 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3102 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE); |
3905 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3103 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE); |
3906 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); |
Line 3104... | Line 3907... | ||
3104 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3907 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3105 | 3908 | ||
Line 3110... | Line 3913... | ||
3110 | * Returns true when a page flip has completed. |
3913 | * Returns true when a page flip has completed. |
3111 | */ |
3914 | */ |
3112 | static bool i8xx_handle_vblank(struct drm_device *dev, |
3915 | static bool i8xx_handle_vblank(struct drm_device *dev, |
3113 | int plane, int pipe, u32 iir) |
3916 | int plane, int pipe, u32 iir) |
3114 | { |
3917 | { |
3115 | drm_i915_private_t *dev_priv = dev->dev_private; |
3918 | struct drm_i915_private *dev_priv = dev->dev_private; |
3116 | u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane); |
3919 | u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane); |
Line 3117... | Line 3920... | ||
3117 | 3920 | ||
3118 | // if (!drm_handle_vblank(dev, pipe)) |
3921 | // if (!drm_handle_vblank(dev, pipe)) |
Line 3137... | Line 3940... | ||
3137 | return true; |
3940 | return true; |
3138 | } |
3941 | } |
Line 3139... | Line 3942... | ||
3139 | 3942 | ||
3140 | static irqreturn_t i8xx_irq_handler(int irq, void *arg) |
3943 | static irqreturn_t i8xx_irq_handler(int irq, void *arg) |
3141 | { |
3944 | { |
3142 | struct drm_device *dev = (struct drm_device *) arg; |
3945 | struct drm_device *dev = arg; |
3143 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
3946 | struct drm_i915_private *dev_priv = dev->dev_private; |
3144 | u16 iir, new_iir; |
3947 | u16 iir, new_iir; |
3145 | u32 pipe_stats[2]; |
3948 | u32 pipe_stats[2]; |
3146 | unsigned long irqflags; |
3949 | unsigned long irqflags; |
3147 | int pipe; |
3950 | int pipe; |
3148 | u16 flip_mask = |
3951 | u16 flip_mask = |
3149 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
3952 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
Line 3150... | Line -... | ||
3150 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
- | |
3151 | - | ||
3152 | atomic_inc(&dev_priv->irq_received); |
3953 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
3153 | 3954 | ||
3154 | iir = I915_READ16(IIR); |
3955 | iir = I915_READ16(IIR); |
Line 3155... | Line 3956... | ||
3155 | if (iir == 0) |
3956 | if (iir == 0) |
Line 3161... | Line 3962... | ||
3161 | * It doesn't set the bit in iir again, but it still produces |
3962 | * It doesn't set the bit in iir again, but it still produces |
3162 | * interrupts (for non-MSI). |
3963 | * interrupts (for non-MSI). |
3163 | */ |
3964 | */ |
3164 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3965 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3165 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3966 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3166 | i915_handle_error(dev, false); |
3967 | i915_handle_error(dev, false, |
- | 3968 | "Command parser error, iir 0x%08x", |
|
- | 3969 | iir); |
|
Line 3167... | Line 3970... | ||
3167 | 3970 | ||
3168 | for_each_pipe(pipe) { |
3971 | for_each_pipe(pipe) { |
3169 | int reg = PIPESTAT(pipe); |
3972 | int reg = PIPESTAT(pipe); |
Line 3170... | Line 3973... | ||
3170 | pipe_stats[pipe] = I915_READ(reg); |
3973 | pipe_stats[pipe] = I915_READ(reg); |
3171 | 3974 | ||
3172 | /* |
3975 | /* |
3173 | * Clear the PIPE*STAT regs before the IIR |
3976 | * Clear the PIPE*STAT regs before the IIR |
3174 | */ |
- | |
3175 | if (pipe_stats[pipe] & 0x8000ffff) { |
- | |
3176 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) |
- | |
3177 | DRM_DEBUG_DRIVER("pipe %c underrun\n", |
3977 | */ |
3178 | pipe_name(pipe)); |
3978 | if (pipe_stats[pipe] & 0x8000ffff) |
3179 | I915_WRITE(reg, pipe_stats[pipe]); |
- | |
3180 | } |
3979 | I915_WRITE(reg, pipe_stats[pipe]); |
Line 3181... | Line 3980... | ||
3181 | } |
3980 | } |
3182 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3981 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
Line 3198... | Line 3997... | ||
3198 | i8xx_handle_vblank(dev, plane, pipe, iir)) |
3997 | i8xx_handle_vblank(dev, plane, pipe, iir)) |
3199 | flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane); |
3998 | flip_mask &= ~DISPLAY_PLANE_FLIP_PENDING(plane); |
Line 3200... | Line 3999... | ||
3200 | 3999 | ||
3201 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
4000 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
- | 4001 | i9xx_pipe_crc_irq_handler(dev, pipe); |
|
- | 4002 | ||
- | 4003 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && |
|
- | 4004 | intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) |
|
3202 | i9xx_pipe_crc_irq_handler(dev, pipe); |
4005 | DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); |
Line 3203... | Line 4006... | ||
3203 | } |
4006 | } |
3204 | 4007 | ||
Line 3205... | Line 4008... | ||
3205 | iir = new_iir; |
4008 | iir = new_iir; |
3206 | } |
4009 | } |
Line 3207... | Line 4010... | ||
3207 | 4010 | ||
3208 | return IRQ_HANDLED; |
4011 | return IRQ_HANDLED; |
3209 | } |
4012 | } |
3210 | 4013 | ||
Line 3211... | Line 4014... | ||
3211 | static void i8xx_irq_uninstall(struct drm_device * dev) |
4014 | static void i8xx_irq_uninstall(struct drm_device * dev) |
3212 | { |
4015 | { |
3213 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4016 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 3225... | Line 4028... | ||
3225 | 4028 | ||
Line 3226... | Line 4029... | ||
3226 | #endif |
4029 | #endif |
3227 | 4030 | ||
3228 | static void i915_irq_preinstall(struct drm_device * dev) |
4031 | static void i915_irq_preinstall(struct drm_device * dev) |
3229 | { |
4032 | { |
Line 3230... | Line -... | ||
3230 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
- | |
3231 | int pipe; |
- | |
3232 | 4033 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
3233 | atomic_set(&dev_priv->irq_received, 0); |
4034 | int pipe; |
3234 | 4035 | ||
3235 | if (I915_HAS_HOTPLUG(dev)) { |
4036 | if (I915_HAS_HOTPLUG(dev)) { |
Line 3245... | Line 4046... | ||
3245 | POSTING_READ(IER); |
4046 | POSTING_READ(IER); |
3246 | } |
4047 | } |
Line 3247... | Line 4048... | ||
3247 | 4048 | ||
3248 | static int i915_irq_postinstall(struct drm_device *dev) |
4049 | static int i915_irq_postinstall(struct drm_device *dev) |
3249 | { |
4050 | { |
3250 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4051 | struct drm_i915_private *dev_priv = dev->dev_private; |
3251 | u32 enable_mask; |
4052 | u32 enable_mask; |
Line 3252... | Line 4053... | ||
3252 | unsigned long irqflags; |
4053 | unsigned long irqflags; |
Line 3286... | Line 4087... | ||
3286 | i915_enable_asle_pipestat(dev); |
4087 | i915_enable_asle_pipestat(dev); |
Line 3287... | Line 4088... | ||
3287 | 4088 | ||
3288 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
4089 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3289 | * just to make the assert_spin_locked check happy. */ |
4090 | * just to make the assert_spin_locked check happy. */ |
3290 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
4091 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3291 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE); |
4092 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3292 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE); |
4093 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); |
Line 3293... | Line 4094... | ||
3293 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
4094 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3294 | 4095 | ||
Line 3299... | Line 4100... | ||
3299 | * Returns true when a page flip has completed. |
4100 | * Returns true when a page flip has completed. |
3300 | */ |
4101 | */ |
3301 | static bool i915_handle_vblank(struct drm_device *dev, |
4102 | static bool i915_handle_vblank(struct drm_device *dev, |
3302 | int plane, int pipe, u32 iir) |
4103 | int plane, int pipe, u32 iir) |
3303 | { |
4104 | { |
3304 | drm_i915_private_t *dev_priv = dev->dev_private; |
4105 | struct drm_i915_private *dev_priv = dev->dev_private; |
3305 | u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane); |
4106 | u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane); |
Line 3306... | Line 4107... | ||
3306 | 4107 | ||
3307 | // if (!drm_handle_vblank(dev, pipe)) |
4108 | // if (!drm_handle_vblank(dev, pipe)) |
Line 3326... | Line 4127... | ||
3326 | return true; |
4127 | return true; |
3327 | } |
4128 | } |
Line 3328... | Line 4129... | ||
3328 | 4129 | ||
3329 | static irqreturn_t i915_irq_handler(int irq, void *arg) |
4130 | static irqreturn_t i915_irq_handler(int irq, void *arg) |
3330 | { |
4131 | { |
3331 | struct drm_device *dev = (struct drm_device *) arg; |
4132 | struct drm_device *dev = arg; |
3332 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4133 | struct drm_i915_private *dev_priv = dev->dev_private; |
3333 | u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; |
4134 | u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; |
3334 | unsigned long irqflags; |
4135 | unsigned long irqflags; |
3335 | u32 flip_mask = |
4136 | u32 flip_mask = |
3336 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
4137 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
3337 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
4138 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
Line 3338... | Line -... | ||
3338 | int pipe, ret = IRQ_NONE; |
- | |
3339 | - | ||
3340 | atomic_inc(&dev_priv->irq_received); |
4139 | int pipe, ret = IRQ_NONE; |
3341 | 4140 | ||
3342 | iir = I915_READ(IIR); |
4141 | iir = I915_READ(IIR); |
3343 | do { |
4142 | do { |
Line 3349... | Line 4148... | ||
3349 | * It doesn't set the bit in iir again, but it still produces |
4148 | * It doesn't set the bit in iir again, but it still produces |
3350 | * interrupts (for non-MSI). |
4149 | * interrupts (for non-MSI). |
3351 | */ |
4150 | */ |
3352 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
4151 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3353 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
4152 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3354 | i915_handle_error(dev, false); |
4153 | i915_handle_error(dev, false, |
- | 4154 | "Command parser error, iir 0x%08x", |
|
- | 4155 | iir); |
|
Line 3355... | Line 4156... | ||
3355 | 4156 | ||
3356 | for_each_pipe(pipe) { |
4157 | for_each_pipe(pipe) { |
3357 | int reg = PIPESTAT(pipe); |
4158 | int reg = PIPESTAT(pipe); |
Line 3358... | Line 4159... | ||
3358 | pipe_stats[pipe] = I915_READ(reg); |
4159 | pipe_stats[pipe] = I915_READ(reg); |
3359 | 4160 | ||
3360 | /* Clear the PIPE*STAT regs before the IIR */ |
- | |
3361 | if (pipe_stats[pipe] & 0x8000ffff) { |
- | |
3362 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) |
- | |
3363 | DRM_DEBUG_DRIVER("pipe %c underrun\n", |
4161 | /* Clear the PIPE*STAT regs before the IIR */ |
3364 | pipe_name(pipe)); |
4162 | if (pipe_stats[pipe] & 0x8000ffff) { |
3365 | I915_WRITE(reg, pipe_stats[pipe]); |
4163 | I915_WRITE(reg, pipe_stats[pipe]); |
3366 | irq_received = true; |
4164 | irq_received = true; |
3367 | } |
4165 | } |
Line 3368... | Line 4166... | ||
3368 | } |
4166 | } |
3369 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
4167 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
Line 3370... | Line 4168... | ||
3370 | 4168 | ||
3371 | if (!irq_received) |
4169 | if (!irq_received) |
3372 | break; |
4170 | break; |
3373 | - | ||
3374 | /* Consume port. Then clear IIR or we'll miss events */ |
- | |
3375 | if ((I915_HAS_HOTPLUG(dev)) && |
- | |
3376 | (iir & I915_DISPLAY_PORT_INTERRUPT)) { |
- | |
3377 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
- | |
3378 | u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; |
- | |
3379 | 4171 | ||
3380 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
- | |
3381 | hotplug_status); |
- | |
3382 | - | ||
3383 | intel_hpd_irq_handler(dev, hotplug_trigger, hpd_status_i915); |
- | |
Line 3384... | Line 4172... | ||
3384 | 4172 | /* Consume port. Then clear IIR or we'll miss events */ |
|
3385 | I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); |
4173 | if (I915_HAS_HOTPLUG(dev) && |
Line 3386... | Line 4174... | ||
3386 | POSTING_READ(PORT_HOTPLUG_STAT); |
4174 | iir & I915_DISPLAY_PORT_INTERRUPT) |
Line 3404... | Line 4192... | ||
3404 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
4192 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
3405 | blc_event = true; |
4193 | blc_event = true; |
Line 3406... | Line 4194... | ||
3406 | 4194 | ||
3407 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
4195 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
- | 4196 | i9xx_pipe_crc_irq_handler(dev, pipe); |
|
- | 4197 | ||
- | 4198 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && |
|
- | 4199 | intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) |
|
3408 | i9xx_pipe_crc_irq_handler(dev, pipe); |
4200 | DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); |
Line 3409... | Line 4201... | ||
3409 | } |
4201 | } |
3410 | 4202 | ||
Line 3435... | Line 4227... | ||
3435 | return ret; |
4227 | return ret; |
3436 | } |
4228 | } |
Line 3437... | Line 4229... | ||
3437 | 4229 | ||
3438 | static void i915_irq_uninstall(struct drm_device * dev) |
4230 | static void i915_irq_uninstall(struct drm_device * dev) |
3439 | { |
4231 | { |
3440 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4232 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 3441... | Line -... | ||
3441 | int pipe; |
- | |
3442 | - | ||
3443 | del_timer_sync(&dev_priv->hotplug_reenable_timer); |
4233 | int pipe; |
3444 | 4234 | ||
3445 | if (I915_HAS_HOTPLUG(dev)) { |
4235 | if (I915_HAS_HOTPLUG(dev)) { |
3446 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
4236 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
Line 3459... | Line 4249... | ||
3459 | I915_WRITE(IIR, I915_READ(IIR)); |
4249 | I915_WRITE(IIR, I915_READ(IIR)); |
3460 | } |
4250 | } |
Line 3461... | Line 4251... | ||
3461 | 4251 | ||
3462 | static void i965_irq_preinstall(struct drm_device * dev) |
4252 | static void i965_irq_preinstall(struct drm_device * dev) |
3463 | { |
4253 | { |
3464 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4254 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 3465... | Line -... | ||
3465 | int pipe; |
- | |
3466 | - | ||
3467 | atomic_set(&dev_priv->irq_received, 0); |
4255 | int pipe; |
3468 | 4256 | ||
Line 3469... | Line 4257... | ||
3469 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
4257 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
3470 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
4258 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
Line 3477... | Line 4265... | ||
3477 | POSTING_READ(IER); |
4265 | POSTING_READ(IER); |
3478 | } |
4266 | } |
Line 3479... | Line 4267... | ||
3479 | 4267 | ||
3480 | static int i965_irq_postinstall(struct drm_device *dev) |
4268 | static int i965_irq_postinstall(struct drm_device *dev) |
3481 | { |
4269 | { |
3482 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4270 | struct drm_i915_private *dev_priv = dev->dev_private; |
3483 | u32 enable_mask; |
4271 | u32 enable_mask; |
3484 | u32 error_mask; |
4272 | u32 error_mask; |
Line 3485... | Line 4273... | ||
3485 | unsigned long irqflags; |
4273 | unsigned long irqflags; |
Line 3502... | Line 4290... | ||
3502 | enable_mask |= I915_BSD_USER_INTERRUPT; |
4290 | enable_mask |= I915_BSD_USER_INTERRUPT; |
Line 3503... | Line 4291... | ||
3503 | 4291 | ||
3504 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
4292 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3505 | * just to make the assert_spin_locked check happy. */ |
4293 | * just to make the assert_spin_locked check happy. */ |
3506 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
4294 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3507 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_EVENT_ENABLE); |
4295 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); |
3508 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE); |
4296 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3509 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE); |
4297 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); |
Line 3510... | Line 4298... | ||
3510 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
4298 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3511 | 4299 | ||
3512 | /* |
4300 | /* |
Line 3536... | Line 4324... | ||
3536 | return 0; |
4324 | return 0; |
3537 | } |
4325 | } |
Line 3538... | Line 4326... | ||
3538 | 4326 | ||
3539 | static void i915_hpd_irq_setup(struct drm_device *dev) |
4327 | static void i915_hpd_irq_setup(struct drm_device *dev) |
3540 | { |
4328 | { |
3541 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4329 | struct drm_i915_private *dev_priv = dev->dev_private; |
3542 | struct drm_mode_config *mode_config = &dev->mode_config; |
4330 | struct drm_mode_config *mode_config = &dev->mode_config; |
3543 | struct intel_encoder *intel_encoder; |
4331 | struct intel_encoder *intel_encoder; |
Line 3544... | Line 4332... | ||
3544 | u32 hotplug_en; |
4332 | u32 hotplug_en; |
Line 3567... | Line 4355... | ||
3567 | } |
4355 | } |
3568 | } |
4356 | } |
Line 3569... | Line 4357... | ||
3569 | 4357 | ||
3570 | static irqreturn_t i965_irq_handler(int irq, void *arg) |
4358 | static irqreturn_t i965_irq_handler(int irq, void *arg) |
3571 | { |
4359 | { |
3572 | struct drm_device *dev = (struct drm_device *) arg; |
4360 | struct drm_device *dev = arg; |
3573 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4361 | struct drm_i915_private *dev_priv = dev->dev_private; |
3574 | u32 iir, new_iir; |
4362 | u32 iir, new_iir; |
3575 | u32 pipe_stats[I915_MAX_PIPES]; |
4363 | u32 pipe_stats[I915_MAX_PIPES]; |
3576 | unsigned long irqflags; |
- | |
3577 | int irq_received; |
4364 | unsigned long irqflags; |
3578 | int ret = IRQ_NONE, pipe; |
4365 | int ret = IRQ_NONE, pipe; |
3579 | u32 flip_mask = |
4366 | u32 flip_mask = |
3580 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
4367 | I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | |
Line 3581... | Line -... | ||
3581 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
- | |
3582 | - | ||
3583 | atomic_inc(&dev_priv->irq_received); |
4368 | I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; |
Line 3584... | Line 4369... | ||
3584 | 4369 | ||
- | 4370 | iir = I915_READ(IIR); |
|
3585 | iir = I915_READ(IIR); |
4371 | |
Line 3586... | Line -... | ||
3586 | - | ||
3587 | for (;;) { |
- | |
3588 | bool blc_event = false; |
4372 | for (;;) { |
3589 | 4373 | bool irq_received = (iir & ~flip_mask) != 0; |
|
3590 | irq_received = (iir & ~flip_mask) != 0; |
4374 | bool blc_event = false; |
3591 | 4375 | ||
3592 | /* Can't rely on pipestat interrupt bit in iir as it might |
4376 | /* Can't rely on pipestat interrupt bit in iir as it might |
3593 | * have been cleared after the pipestat interrupt was received. |
4377 | * have been cleared after the pipestat interrupt was received. |
3594 | * It doesn't set the bit in iir again, but it still produces |
4378 | * It doesn't set the bit in iir again, but it still produces |
3595 | * interrupts (for non-MSI). |
4379 | * interrupts (for non-MSI). |
- | 4380 | */ |
|
- | 4381 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
|
Line 3596... | Line 4382... | ||
3596 | */ |
4382 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
3597 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
4383 | i915_handle_error(dev, false, |
3598 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
4384 | "Command parser error, iir 0x%08x", |
Line 3599... | Line 4385... | ||
3599 | i915_handle_error(dev, false); |
4385 | iir); |
3600 | 4386 | ||
3601 | for_each_pipe(pipe) { |
4387 | for_each_pipe(pipe) { |
3602 | int reg = PIPESTAT(pipe); |
4388 | int reg = PIPESTAT(pipe); |
3603 | pipe_stats[pipe] = I915_READ(reg); |
- | |
3604 | - | ||
3605 | /* |
- | |
3606 | * Clear the PIPE*STAT regs before the IIR |
4389 | pipe_stats[pipe] = I915_READ(reg); |
3607 | */ |
4390 | |
3608 | if (pipe_stats[pipe] & 0x8000ffff) { |
4391 | /* |
3609 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) |
4392 | * Clear the PIPE*STAT regs before the IIR |
3610 | DRM_DEBUG_DRIVER("pipe %c underrun\n", |
4393 | */ |
Line 3611... | Line 4394... | ||
3611 | pipe_name(pipe)); |
4394 | if (pipe_stats[pipe] & 0x8000ffff) { |
3612 | I915_WRITE(reg, pipe_stats[pipe]); |
4395 | I915_WRITE(reg, pipe_stats[pipe]); |
Line 3613... | Line 4396... | ||
3613 | irq_received = 1; |
4396 | irq_received = true; |
Line 3614... | Line 4397... | ||
3614 | } |
4397 | } |
3615 | } |
4398 | } |
3616 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
- | |
3617 | - | ||
3618 | if (!irq_received) |
- | |
3619 | break; |
- | |
3620 | - | ||
3621 | ret = IRQ_HANDLED; |
- | |
3622 | - | ||
3623 | /* Consume port. Then clear IIR or we'll miss events */ |
- | |
3624 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
- | |
3625 | u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); |
- | |
3626 | u32 hotplug_trigger = hotplug_status & (IS_G4X(dev) ? |
- | |
3627 | HOTPLUG_INT_STATUS_G4X : |
- | |
3628 | HOTPLUG_INT_STATUS_I915); |
- | |
3629 | 4399 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
|
3630 | DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n", |
- | |
3631 | hotplug_status); |
- | |
3632 | - | ||
3633 | intel_hpd_irq_handler(dev, hotplug_trigger, |
- | |
Line 3634... | Line 4400... | ||
3634 | IS_G4X(dev) ? hpd_status_g4x : hpd_status_i915); |
4400 | |
3635 | 4401 | if (!irq_received) |
|
Line 3636... | Line 4402... | ||
3636 | if (IS_G4X(dev) && |
4402 | break; |
Line 3657... | Line 4423... | ||
3657 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
4423 | if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) |
3658 | blc_event = true; |
4424 | blc_event = true; |
Line 3659... | Line 4425... | ||
3659 | 4425 | ||
3660 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
4426 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) |
3661 | i9xx_pipe_crc_irq_handler(dev, pipe); |
- | |
Line -... | Line 4427... | ||
- | 4427 | i9xx_pipe_crc_irq_handler(dev, pipe); |
|
- | 4428 | ||
- | 4429 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && |
|
- | 4430 | intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) |
|
Line 3662... | Line 4431... | ||
3662 | } |
4431 | DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); |
3663 | 4432 | } |
|
Line 3664... | Line 4433... | ||
3664 | 4433 | ||
Line 3691... | Line 4460... | ||
3691 | return ret; |
4460 | return ret; |
3692 | } |
4461 | } |
Line 3693... | Line 4462... | ||
3693 | 4462 | ||
3694 | static void i965_irq_uninstall(struct drm_device * dev) |
4463 | static void i965_irq_uninstall(struct drm_device * dev) |
3695 | { |
4464 | { |
3696 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
4465 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 3697... | Line 4466... | ||
3697 | int pipe; |
4466 | int pipe; |
3698 | 4467 | ||
Line 3699... | Line -... | ||
3699 | if (!dev_priv) |
- | |
3700 | return; |
- | |
3701 | 4468 | if (!dev_priv) |
|
3702 | del_timer_sync(&dev_priv->hotplug_reenable_timer); |
4469 | return; |
Line 3703... | Line 4470... | ||
3703 | 4470 | ||
3704 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
4471 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
Line 3714... | Line 4481... | ||
3714 | I915_WRITE(PIPESTAT(pipe), |
4481 | I915_WRITE(PIPESTAT(pipe), |
3715 | I915_READ(PIPESTAT(pipe)) & 0x8000ffff); |
4482 | I915_READ(PIPESTAT(pipe)) & 0x8000ffff); |
3716 | I915_WRITE(IIR, I915_READ(IIR)); |
4483 | I915_WRITE(IIR, I915_READ(IIR)); |
3717 | } |
4484 | } |
Line 3718... | Line 4485... | ||
3718 | 4485 | ||
3719 | static void i915_reenable_hotplug_timer_func(unsigned long data) |
4486 | static void intel_hpd_irq_reenable(struct work_struct *work) |
3720 | { |
4487 | { |
- | 4488 | struct drm_i915_private *dev_priv = |
|
- | 4489 | container_of(work, typeof(*dev_priv), |
|
3721 | drm_i915_private_t *dev_priv = (drm_i915_private_t *)data; |
4490 | hotplug_reenable_work.work); |
3722 | struct drm_device *dev = dev_priv->dev; |
4491 | struct drm_device *dev = dev_priv->dev; |
3723 | struct drm_mode_config *mode_config = &dev->mode_config; |
4492 | struct drm_mode_config *mode_config = &dev->mode_config; |
3724 | unsigned long irqflags; |
4493 | unsigned long irqflags; |
Line 3737... | Line 4506... | ||
3737 | struct intel_connector *intel_connector = to_intel_connector(connector); |
4506 | struct intel_connector *intel_connector = to_intel_connector(connector); |
Line 3738... | Line 4507... | ||
3738 | 4507 | ||
3739 | if (intel_connector->encoder->hpd_pin == i) { |
4508 | if (intel_connector->encoder->hpd_pin == i) { |
3740 | if (connector->polled != intel_connector->polled) |
4509 | if (connector->polled != intel_connector->polled) |
3741 | DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n", |
4510 | DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n", |
3742 | drm_get_connector_name(connector)); |
4511 | connector->name); |
3743 | connector->polled = intel_connector->polled; |
4512 | connector->polled = intel_connector->polled; |
3744 | if (!connector->polled) |
4513 | if (!connector->polled) |
3745 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
4514 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
3746 | } |
4515 | } |
Line 3758... | Line 4527... | ||
3758 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); |
4527 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); |
3759 | INIT_WORK(&dev_priv->gpu_error.work, i915_error_work_func); |
4528 | INIT_WORK(&dev_priv->gpu_error.work, i915_error_work_func); |
3760 | INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); |
4529 | INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); |
3761 | INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); |
4530 | INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); |
Line -... | Line 4531... | ||
- | 4531 | ||
- | 4532 | /* Let's track the enabled rps events */ |
|
- | 4533 | if (IS_VALLEYVIEW(dev)) |
|
3762 | 4534 | /* WaGsvRC0ResidenncyMethod:VLV */ |
|
- | 4535 | dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; |
|
3763 | setup_timer(&dev_priv->hotplug_reenable_timer, i915_reenable_hotplug_timer_func, |
4536 | else |
Line -... | Line 4537... | ||
- | 4537 | dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; |
|
- | 4538 | ||
Line 3764... | Line 4539... | ||
3764 | (unsigned long) dev_priv); |
4539 | /* Haven't installed the IRQ handler yet */ |
3765 | 4540 | dev_priv->pm._irqs_disabled = true; |
|
3766 | 4541 | ||
3767 | if (IS_GEN2(dev)) { |
4542 | if (IS_GEN2(dev)) { |
Line 3778... | Line 4553... | ||
3778 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
4553 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
3779 | dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; |
4554 | dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; |
3780 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
4555 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
3781 | } |
4556 | } |
Line 3782... | Line 4557... | ||
3782 | 4557 | ||
- | 4558 | if (IS_CHERRYVIEW(dev)) { |
|
- | 4559 | dev->driver->irq_handler = cherryview_irq_handler; |
|
- | 4560 | dev->driver->irq_preinstall = cherryview_irq_preinstall; |
|
- | 4561 | dev->driver->irq_postinstall = cherryview_irq_postinstall; |
|
- | 4562 | dev->driver->irq_uninstall = cherryview_irq_uninstall; |
|
- | 4563 | dev->driver->enable_vblank = valleyview_enable_vblank; |
|
- | 4564 | dev->driver->disable_vblank = valleyview_disable_vblank; |
|
- | 4565 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
|
3783 | if (IS_VALLEYVIEW(dev)) { |
4566 | } else if (IS_VALLEYVIEW(dev)) { |
3784 | dev->driver->irq_handler = valleyview_irq_handler; |
4567 | dev->driver->irq_handler = valleyview_irq_handler; |
3785 | dev->driver->irq_preinstall = valleyview_irq_preinstall; |
4568 | dev->driver->irq_preinstall = valleyview_irq_preinstall; |
3786 | dev->driver->irq_postinstall = valleyview_irq_postinstall; |
4569 | dev->driver->irq_postinstall = valleyview_irq_postinstall; |
3787 | dev->driver->irq_uninstall = valleyview_irq_uninstall; |
4570 | dev->driver->irq_uninstall = valleyview_irq_uninstall; |
3788 | dev->driver->enable_vblank = valleyview_enable_vblank; |
4571 | dev->driver->enable_vblank = valleyview_enable_vblank; |
3789 | dev->driver->disable_vblank = valleyview_disable_vblank; |
4572 | dev->driver->disable_vblank = valleyview_disable_vblank; |
3790 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
4573 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
3791 | } else if (IS_GEN8(dev)) { |
4574 | } else if (IS_GEN8(dev)) { |
3792 | dev->driver->irq_handler = gen8_irq_handler; |
4575 | dev->driver->irq_handler = gen8_irq_handler; |
3793 | dev->driver->irq_preinstall = gen8_irq_preinstall; |
4576 | dev->driver->irq_preinstall = gen8_irq_reset; |
3794 | dev->driver->irq_postinstall = gen8_irq_postinstall; |
4577 | dev->driver->irq_postinstall = gen8_irq_postinstall; |
3795 | dev->driver->irq_uninstall = gen8_irq_uninstall; |
4578 | dev->driver->irq_uninstall = gen8_irq_uninstall; |
3796 | dev->driver->enable_vblank = gen8_enable_vblank; |
4579 | dev->driver->enable_vblank = gen8_enable_vblank; |
3797 | dev->driver->disable_vblank = gen8_disable_vblank; |
4580 | dev->driver->disable_vblank = gen8_disable_vblank; |
3798 | dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; |
4581 | dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; |
3799 | } else if (HAS_PCH_SPLIT(dev)) { |
4582 | } else if (HAS_PCH_SPLIT(dev)) { |
3800 | dev->driver->irq_handler = ironlake_irq_handler; |
4583 | dev->driver->irq_handler = ironlake_irq_handler; |
3801 | dev->driver->irq_preinstall = ironlake_irq_preinstall; |
4584 | dev->driver->irq_preinstall = ironlake_irq_reset; |
3802 | dev->driver->irq_postinstall = ironlake_irq_postinstall; |
4585 | dev->driver->irq_postinstall = ironlake_irq_postinstall; |
3803 | dev->driver->irq_uninstall = ironlake_irq_uninstall; |
4586 | dev->driver->irq_uninstall = ironlake_irq_uninstall; |
3804 | dev->driver->enable_vblank = ironlake_enable_vblank; |
4587 | dev->driver->enable_vblank = ironlake_enable_vblank; |
3805 | dev->driver->disable_vblank = ironlake_disable_vblank; |
4588 | dev->driver->disable_vblank = ironlake_disable_vblank; |
Line 3837... | Line 4620... | ||
3837 | dev_priv->hpd_stats[i].hpd_mark = HPD_ENABLED; |
4620 | dev_priv->hpd_stats[i].hpd_mark = HPD_ENABLED; |
3838 | } |
4621 | } |
3839 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
4622 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
3840 | struct intel_connector *intel_connector = to_intel_connector(connector); |
4623 | struct intel_connector *intel_connector = to_intel_connector(connector); |
3841 | connector->polled = intel_connector->polled; |
4624 | connector->polled = intel_connector->polled; |
3842 | if (!connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE) |
4625 | if (connector->encoder && !connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE) |
- | 4626 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
|
- | 4627 | if (intel_connector->mst_port) |
|
3843 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
4628 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
3844 | } |
4629 | } |
Line 3845... | Line 4630... | ||
3845 | 4630 | ||
3846 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
4631 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
Line 3849... | Line 4634... | ||
3849 | if (dev_priv->display.hpd_irq_setup) |
4634 | if (dev_priv->display.hpd_irq_setup) |
3850 | dev_priv->display.hpd_irq_setup(dev); |
4635 | dev_priv->display.hpd_irq_setup(dev); |
3851 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
4636 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3852 | } |
4637 | } |
Line 3853... | Line 4638... | ||
3853 | 4638 | ||
3854 | /* Disable interrupts so we can allow Package C8+. */ |
4639 | /* Disable interrupts so we can allow runtime PM. */ |
3855 | void hsw_pc8_disable_interrupts(struct drm_device *dev) |
4640 | void intel_runtime_pm_disable_interrupts(struct drm_device *dev) |
3856 | { |
4641 | { |
3857 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3858 | unsigned long irqflags; |
- | |
3859 | - | ||
Line 3860... | Line -... | ||
3860 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
- | |
3861 | - | ||
3862 | dev_priv->pc8.regsave.deimr = I915_READ(DEIMR); |
- | |
3863 | dev_priv->pc8.regsave.sdeimr = I915_READ(SDEIMR); |
4642 | struct drm_i915_private *dev_priv = dev->dev_private; |
3864 | dev_priv->pc8.regsave.gtimr = I915_READ(GTIMR); |
- | |
3865 | dev_priv->pc8.regsave.gtier = I915_READ(GTIER); |
- | |
3866 | dev_priv->pc8.regsave.gen6_pmimr = I915_READ(GEN6_PMIMR); |
- | |
3867 | - | ||
3868 | ironlake_disable_display_irq(dev_priv, 0xffffffff); |
- | |
3869 | ibx_disable_display_interrupt(dev_priv, 0xffffffff); |
- | |
3870 | ilk_disable_gt_irq(dev_priv, 0xffffffff); |
- | |
3871 | snb_disable_pm_irq(dev_priv, 0xffffffff); |
4643 | |
3872 | - | ||
3873 | dev_priv->pc8.irqs_disabled = true; |
- | |
3874 | 4644 | dev->driver->irq_uninstall(dev); |
|
Line 3875... | Line 4645... | ||
3875 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
4645 | dev_priv->pm._irqs_disabled = true; |
3876 | } |
4646 | } |
3877 | 4647 | ||
3878 | /* Restore interrupts so we can recover from Package C8+. */ |
4648 | /* Restore interrupts so we can recover from runtime PM. */ |
3879 | void hsw_pc8_restore_interrupts(struct drm_device *dev) |
- | |
3880 | { |
- | |
3881 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
3882 | unsigned long irqflags; |
- | |
Line 3883... | Line -... | ||
3883 | uint32_t val; |
- | |
3884 | - | ||
3885 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
- | |
3886 | - | ||
3887 | val = I915_READ(DEIMR); |
- | |
3888 | WARN(val != 0xffffffff, "DEIMR is 0x%08x\n", val); |
- | |
3889 | - | ||
3890 | val = I915_READ(SDEIMR); |
- | |
3891 | WARN(val != 0xffffffff, "SDEIMR is 0x%08x\n", val); |
- | |
3892 | - | ||
3893 | val = I915_READ(GTIMR); |
- | |
3894 | WARN(val != 0xffffffff, "GTIMR is 0x%08x\n", val); |
- | |
3895 | 4649 | void intel_runtime_pm_restore_interrupts(struct drm_device *dev) |
|
3896 | val = I915_READ(GEN6_PMIMR); |
- | |
3897 | WARN(val != 0xffffffff, "GEN6_PMIMR is 0x%08x\n", val); |
- | |
3898 | - | ||
3899 | dev_priv->pc8.irqs_disabled = false; |
- | |
3900 | - | ||
3901 | ironlake_enable_display_irq(dev_priv, ~dev_priv->pc8.regsave.deimr); |
4650 | { |
3902 | ibx_enable_display_interrupt(dev_priv, ~dev_priv->pc8.regsave.sdeimr); |
- | |
3903 | ilk_enable_gt_irq(dev_priv, ~dev_priv->pc8.regsave.gtimr); |
4651 | struct drm_i915_private *dev_priv = dev->dev_private; |
3904 | snb_enable_pm_irq(dev_priv, ~dev_priv->pc8.regsave.gen6_pmimr); |
4652 | |
Line 3905... | Line 4653... | ||
3905 | I915_WRITE(GTIER, dev_priv->pc8.regsave.gtier); |
4653 | dev_priv->pm._irqs_disabled = false; |
3906 | 4654 | dev->driver->irq_preinstall(dev); |