diff options
author | Imre Deak <imre.deak@intel.com> | 2014-02-10 11:42:47 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-02-12 12:52:57 -0500 |
commit | 755e901964a979ea0e1a823ac8c5d477fe8fd108 (patch) | |
tree | 525609560626a652a84256c27747854a1a0a8d95 /drivers/gpu/drm/i915/i915_irq.c | |
parent | c0cc8a556680afbfc6dc5033bdf9c8d2b85088e2 (diff) |
drm/i915: pass status instead of enable flags to i915_enable_pipestat
There isn't any PSR interrupt enable bit for pipe A, so we couldn't
enable it through the current API. Passing the corresponding status bits
solves this and also makes the mapping between enable and status bits
simpler on VLV (addressed in an upcoming patch).
Except of checking for invalid status bit arguments, no functional
change.
v2: split out the low level parts of i915_enable_pipestat accepting
separate enabled and status masks, to make the non-standard mapping
between those masks stand out more (added in the next patch)
(Jesse,Daniel)
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
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 | /* |