diff options
author | Imre Deak <imre.deak@intel.com> | 2014-02-04 14:35:46 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-02-05 11:04:28 -0500 |
commit | c1874ed7c987664176bd00301f844e91609fe535 (patch) | |
tree | 8bb1a9deb339f954180d710e8b49d19fec4f0dbb | |
parent | b7e634cc8dcd320123199a18bae0937b40dc28b8 (diff) |
drm/i915: factor out valleyview_pipestat_irq_handler
This will be used by other platforms too, so factor it out.
The only functional change is the reordeing of gmbus_irq_handler() wrt.
the hotplug handling, but since it only schedules a work, it isn't an
issue.
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
[danvet: Don't keep on using the private_t typedef.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 76 |
1 files changed, 42 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9d3817e96d27..a34714de7968 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1477,15 +1477,53 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | |||
1477 | } | 1477 | } |
1478 | } | 1478 | } |
1479 | 1479 | ||
1480 | static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) | ||
1481 | { | ||
1482 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1483 | u32 pipe_stats[I915_MAX_PIPES]; | ||
1484 | unsigned long irqflags; | ||
1485 | int pipe; | ||
1486 | |||
1487 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
1488 | for_each_pipe(pipe) { | ||
1489 | int reg = PIPESTAT(pipe); | ||
1490 | pipe_stats[pipe] = I915_READ(reg); | ||
1491 | |||
1492 | /* | ||
1493 | * Clear the PIPE*STAT regs before the IIR | ||
1494 | */ | ||
1495 | if (pipe_stats[pipe] & 0x8000ffff) | ||
1496 | I915_WRITE(reg, pipe_stats[pipe]); | ||
1497 | } | ||
1498 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
1499 | |||
1500 | for_each_pipe(pipe) { | ||
1501 | if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) | ||
1502 | drm_handle_vblank(dev, pipe); | ||
1503 | |||
1504 | if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) { | ||
1505 | intel_prepare_page_flip(dev, pipe); | ||
1506 | intel_finish_page_flip(dev, pipe); | ||
1507 | } | ||
1508 | |||
1509 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) | ||
1510 | i9xx_pipe_crc_irq_handler(dev, pipe); | ||
1511 | |||
1512 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && | ||
1513 | intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) | ||
1514 | DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); | ||
1515 | } | ||
1516 | |||
1517 | if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) | ||
1518 | gmbus_irq_handler(dev); | ||
1519 | } | ||
1520 | |||
1480 | static irqreturn_t valleyview_irq_handler(int irq, void *arg) | 1521 | static irqreturn_t valleyview_irq_handler(int irq, void *arg) |
1481 | { | 1522 | { |
1482 | struct drm_device *dev = (struct drm_device *) arg; | 1523 | struct drm_device *dev = (struct drm_device *) arg; |
1483 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1524 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1484 | u32 iir, gt_iir, pm_iir; | 1525 | u32 iir, gt_iir, pm_iir; |
1485 | irqreturn_t ret = IRQ_NONE; | 1526 | irqreturn_t ret = IRQ_NONE; |
1486 | unsigned long irqflags; | ||
1487 | int pipe; | ||
1488 | u32 pipe_stats[I915_MAX_PIPES]; | ||
1489 | 1527 | ||
1490 | while (true) { | 1528 | while (true) { |
1491 | iir = I915_READ(VLV_IIR); | 1529 | iir = I915_READ(VLV_IIR); |
@@ -1499,35 +1537,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) | |||
1499 | 1537 | ||
1500 | snb_gt_irq_handler(dev, dev_priv, gt_iir); | 1538 | snb_gt_irq_handler(dev, dev_priv, gt_iir); |
1501 | 1539 | ||
1502 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 1540 | valleyview_pipestat_irq_handler(dev, iir); |
1503 | for_each_pipe(pipe) { | ||
1504 | int reg = PIPESTAT(pipe); | ||
1505 | pipe_stats[pipe] = I915_READ(reg); | ||
1506 | |||
1507 | /* | ||
1508 | * Clear the PIPE*STAT regs before the IIR | ||
1509 | */ | ||
1510 | if (pipe_stats[pipe] & 0x8000ffff) | ||
1511 | I915_WRITE(reg, pipe_stats[pipe]); | ||
1512 | } | ||
1513 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
1514 | |||
1515 | for_each_pipe(pipe) { | ||
1516 | if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) | ||
1517 | drm_handle_vblank(dev, pipe); | ||
1518 | |||
1519 | if (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) { | ||
1520 | intel_prepare_page_flip(dev, pipe); | ||
1521 | intel_finish_page_flip(dev, pipe); | ||
1522 | } | ||
1523 | |||
1524 | if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) | ||
1525 | i9xx_pipe_crc_irq_handler(dev, pipe); | ||
1526 | |||
1527 | if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS && | ||
1528 | intel_set_cpu_fifo_underrun_reporting(dev, pipe, false)) | ||
1529 | DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); | ||
1530 | } | ||
1531 | 1541 | ||
1532 | /* Consume port. Then clear IIR or we'll miss events */ | 1542 | /* Consume port. Then clear IIR or we'll miss events */ |
1533 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { | 1543 | if (iir & I915_DISPLAY_PORT_INTERRUPT) { |
@@ -1543,8 +1553,6 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) | |||
1543 | I915_READ(PORT_HOTPLUG_STAT); | 1553 | I915_READ(PORT_HOTPLUG_STAT); |
1544 | } | 1554 | } |
1545 | 1555 | ||
1546 | if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) | ||
1547 | gmbus_irq_handler(dev); | ||
1548 | 1556 | ||
1549 | if (pm_iir) | 1557 | if (pm_iir) |
1550 | gen6_rps_irq_handler(dev_priv, pm_iir); | 1558 | gen6_rps_irq_handler(dev_priv, pm_iir); |