diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d4defd86b27c..cdb158d1bfde 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -473,38 +473,68 @@ done: | |||
473 | 473 | ||
474 | 474 | ||
475 | void | 475 | void |
476 | i915_enable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask) | 476 | __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
477 | u32 enable_mask, u32 status_mask) | ||
477 | { | 478 | { |
478 | u32 reg = PIPESTAT(pipe); | 479 | u32 reg = PIPESTAT(pipe); |
479 | u32 pipestat = I915_READ(reg) & 0x7fff0000; | 480 | u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; |
480 | 481 | ||
481 | assert_spin_locked(&dev_priv->irq_lock); | 482 | assert_spin_locked(&dev_priv->irq_lock); |
482 | 483 | ||
483 | if ((pipestat & mask) == mask) | 484 | if (WARN_ON_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || |
485 | status_mask & ~PIPESTAT_INT_STATUS_MASK)) | ||
486 | return; | ||
487 | |||
488 | if ((pipestat & enable_mask) == enable_mask) | ||
484 | return; | 489 | return; |
485 | 490 | ||
486 | /* Enable the interrupt, clear any pending status */ | 491 | /* Enable the interrupt, clear any pending status */ |
487 | pipestat |= mask | (mask >> 16); | 492 | pipestat |= enable_mask | status_mask; |
488 | I915_WRITE(reg, pipestat); | 493 | I915_WRITE(reg, pipestat); |
489 | POSTING_READ(reg); | 494 | POSTING_READ(reg); |
490 | } | 495 | } |
491 | 496 | ||
492 | void | 497 | void |
493 | i915_disable_pipestat(drm_i915_private_t *dev_priv, enum pipe pipe, u32 mask) | 498 | __i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, |
499 | u32 enable_mask, u32 status_mask) | ||
494 | { | 500 | { |
495 | u32 reg = PIPESTAT(pipe); | 501 | u32 reg = PIPESTAT(pipe); |
496 | u32 pipestat = I915_READ(reg) & 0x7fff0000; | 502 | u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; |
497 | 503 | ||
498 | assert_spin_locked(&dev_priv->irq_lock); | 504 | assert_spin_locked(&dev_priv->irq_lock); |
499 | 505 | ||
500 | if ((pipestat & mask) == 0) | 506 | if (WARN_ON_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || |
507 | status_mask & ~PIPESTAT_INT_STATUS_MASK)) | ||
501 | return; | 508 | return; |
502 | 509 | ||
503 | pipestat &= ~mask; | 510 | if ((pipestat & enable_mask) == 0) |
511 | return; | ||
512 | |||
513 | pipestat &= ~enable_mask; | ||
504 | I915_WRITE(reg, pipestat); | 514 | I915_WRITE(reg, pipestat); |
505 | POSTING_READ(reg); | 515 | POSTING_READ(reg); |
506 | } | 516 | } |
507 | 517 | ||
518 | void | ||
519 | i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, | ||
520 | u32 status_mask) | ||
521 | { | ||
522 | u32 enable_mask; | ||
523 | |||
524 | enable_mask = status_mask << 16; | ||
525 | __i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask); | ||
526 | } | ||
527 | |||
528 | void | ||
529 | i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, | ||
530 | u32 status_mask) | ||
531 | { | ||
532 | u32 enable_mask; | ||
533 | |||
534 | enable_mask = status_mask << 16; | ||
535 | __i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask); | ||
536 | } | ||
537 | |||
508 | /** | 538 | /** |
509 | * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion | 539 | * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion |
510 | */ | 540 | */ |
@@ -518,10 +548,10 @@ static void i915_enable_asle_pipestat(struct drm_device *dev) | |||
518 | 548 | ||
519 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 549 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
520 | 550 | ||
521 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_ENABLE); | 551 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS); |
522 | if (INTEL_INFO(dev)->gen >= 4) | 552 | if (INTEL_INFO(dev)->gen >= 4) |
523 | i915_enable_pipestat(dev_priv, PIPE_A, | 553 | i915_enable_pipestat(dev_priv, PIPE_A, |
524 | PIPE_LEGACY_BLC_EVENT_ENABLE); | 554 | PIPE_LEGACY_BLC_EVENT_STATUS); |
525 | 555 | ||
526 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 556 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
527 | } | 557 | } |
@@ -2270,10 +2300,10 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
2270 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 2300 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2271 | if (INTEL_INFO(dev)->gen >= 4) | 2301 | if (INTEL_INFO(dev)->gen >= 4) |
2272 | i915_enable_pipestat(dev_priv, pipe, | 2302 | i915_enable_pipestat(dev_priv, pipe, |
2273 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | 2303 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
2274 | else | 2304 | else |
2275 | i915_enable_pipestat(dev_priv, pipe, | 2305 | i915_enable_pipestat(dev_priv, pipe, |
2276 | PIPE_VBLANK_INTERRUPT_ENABLE); | 2306 | PIPE_VBLANK_INTERRUPT_STATUS); |
2277 | 2307 | ||
2278 | /* maintain vblank delivery even in deep C-states */ | 2308 | /* maintain vblank delivery even in deep C-states */ |
2279 | if (INTEL_INFO(dev)->gen == 3) | 2309 | if (INTEL_INFO(dev)->gen == 3) |
@@ -2310,7 +2340,7 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe) | |||
2310 | 2340 | ||
2311 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 2341 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2312 | i915_enable_pipestat(dev_priv, pipe, | 2342 | i915_enable_pipestat(dev_priv, pipe, |
2313 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | 2343 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
2314 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 2344 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2315 | 2345 | ||
2316 | return 0; | 2346 | return 0; |
@@ -2345,8 +2375,8 @@ static void i915_disable_vblank(struct drm_device *dev, int pipe) | |||
2345 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_DIS)); | 2375 | I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_DIS)); |
2346 | 2376 | ||
2347 | i915_disable_pipestat(dev_priv, pipe, | 2377 | i915_disable_pipestat(dev_priv, pipe, |
2348 | PIPE_VBLANK_INTERRUPT_ENABLE | | 2378 | PIPE_VBLANK_INTERRUPT_STATUS | |
2349 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | 2379 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
2350 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 2380 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2351 | } | 2381 | } |
2352 | 2382 | ||
@@ -2369,7 +2399,7 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe) | |||
2369 | 2399 | ||
2370 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 2400 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2371 | i915_disable_pipestat(dev_priv, pipe, | 2401 | i915_disable_pipestat(dev_priv, pipe, |
2372 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | 2402 | PIPE_START_VBLANK_INTERRUPT_STATUS); |
2373 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 2403 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2374 | } | 2404 | } |
2375 | 2405 | ||
@@ -2917,8 +2947,8 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
2917 | { | 2947 | { |
2918 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 2948 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2919 | u32 enable_mask; | 2949 | u32 enable_mask; |
2920 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV | | 2950 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV | |
2921 | PIPE_CRC_DONE_ENABLE; | 2951 | PIPE_CRC_DONE_INTERRUPT_STATUS; |
2922 | unsigned long irqflags; | 2952 | unsigned long irqflags; |
2923 | 2953 | ||
2924 | enable_mask = I915_DISPLAY_PORT_INTERRUPT; | 2954 | enable_mask = I915_DISPLAY_PORT_INTERRUPT; |
@@ -2949,7 +2979,7 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
2949 | * just to make the assert_spin_locked check happy. */ | 2979 | * just to make the assert_spin_locked check happy. */ |
2950 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 2980 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
2951 | i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable); | 2981 | i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable); |
2952 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_EVENT_ENABLE); | 2982 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); |
2953 | i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable); | 2983 | i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable); |
2954 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 2984 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
2955 | 2985 | ||
@@ -3172,8 +3202,8 @@ static int i8xx_irq_postinstall(struct drm_device *dev) | |||
3172 | /* Interrupt setup is already guaranteed to be single-threaded, this is | 3202 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3173 | * just to make the assert_spin_locked check happy. */ | 3203 | * just to make the assert_spin_locked check happy. */ |
3174 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3204 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3175 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE); | 3205 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3176 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE); | 3206 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3177 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 3207 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3178 | 3208 | ||
3179 | return 0; | 3209 | return 0; |
@@ -3355,8 +3385,8 @@ static int i915_irq_postinstall(struct drm_device *dev) | |||
3355 | /* Interrupt setup is already guaranteed to be single-threaded, this is | 3385 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3356 | * just to make the assert_spin_locked check happy. */ | 3386 | * just to make the assert_spin_locked check happy. */ |
3357 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3387 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3358 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE); | 3388 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3359 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE); | 3389 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3360 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 3390 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3361 | 3391 | ||
3362 | return 0; | 3392 | return 0; |
@@ -3565,9 +3595,9 @@ static int i965_irq_postinstall(struct drm_device *dev) | |||
3565 | /* Interrupt setup is already guaranteed to be single-threaded, this is | 3595 | /* Interrupt setup is already guaranteed to be single-threaded, this is |
3566 | * just to make the assert_spin_locked check happy. */ | 3596 | * just to make the assert_spin_locked check happy. */ |
3567 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3597 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3568 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_EVENT_ENABLE); | 3598 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); |
3569 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_ENABLE); | 3599 | i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3570 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_ENABLE); | 3600 | i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); |
3571 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 3601 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3572 | 3602 | ||
3573 | /* | 3603 | /* |