diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-04-07 16:53:55 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-05-13 20:02:44 -0400 |
commit | 4697995b98417c6da9ab2708a36f5e2bc926c8ac (patch) | |
tree | 4cf90662b8ebcec9ac999c140816d130adfae097 | |
parent | 674cf967614f31826f45d30c8f8f8e050cc3eef2 (diff) |
drm/i915: split irq handling into per-chipset functions
Set the IRQ handling functions in driver load so they'll just be used
directly, rather than branching over most of the code in the chipset
functions.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 45 |
3 files changed, 43 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b1ddcdc0748e..a3ee159b64ee 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1266,6 +1266,18 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1266 | 1266 | ||
1267 | intel_modeset_gem_init(dev); | 1267 | intel_modeset_gem_init(dev); |
1268 | 1268 | ||
1269 | if (HAS_PCH_SPLIT(dev)) { | ||
1270 | dev->driver->irq_handler = ironlake_irq_handler; | ||
1271 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
1272 | dev->driver->irq_postinstall = ironlake_irq_postinstall; | ||
1273 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
1274 | } else { | ||
1275 | dev->driver->irq_preinstall = i915_driver_irq_preinstall; | ||
1276 | dev->driver->irq_postinstall = i915_driver_irq_postinstall; | ||
1277 | dev->driver->irq_uninstall = i915_driver_irq_uninstall; | ||
1278 | dev->driver->irq_handler = i915_driver_irq_handler; | ||
1279 | } | ||
1280 | |||
1269 | ret = drm_irq_install(dev); | 1281 | ret = drm_irq_install(dev); |
1270 | if (ret) | 1282 | if (ret) |
1271 | goto cleanup_gem; | 1283 | goto cleanup_gem; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4dbf4dfafb59..3c3233413df0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1028,6 +1028,12 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | |||
1028 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | 1028 | extern void i915_driver_irq_preinstall(struct drm_device * dev); |
1029 | extern int i915_driver_irq_postinstall(struct drm_device *dev); | 1029 | extern int i915_driver_irq_postinstall(struct drm_device *dev); |
1030 | extern void i915_driver_irq_uninstall(struct drm_device * dev); | 1030 | extern void i915_driver_irq_uninstall(struct drm_device * dev); |
1031 | |||
1032 | extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS); | ||
1033 | extern void ironlake_irq_preinstall(struct drm_device *dev); | ||
1034 | extern int ironlake_irq_postinstall(struct drm_device *dev); | ||
1035 | extern void ironlake_irq_uninstall(struct drm_device *dev); | ||
1036 | |||
1031 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, | 1037 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, |
1032 | struct drm_file *file_priv); | 1038 | struct drm_file *file_priv); |
1033 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, | 1039 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5be2aa0f54af..d967e1754cf2 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -462,8 +462,9 @@ static void pch_irq_handler(struct drm_device *dev) | |||
462 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); | 462 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); |
463 | } | 463 | } |
464 | 464 | ||
465 | static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | 465 | irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) |
466 | { | 466 | { |
467 | struct drm_device *dev = (struct drm_device *) arg; | ||
467 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 468 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
468 | int ret = IRQ_NONE; | 469 | int ret = IRQ_NONE; |
469 | u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; | 470 | u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; |
@@ -471,6 +472,8 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
471 | struct drm_i915_master_private *master_priv; | 472 | struct drm_i915_master_private *master_priv; |
472 | u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; | 473 | u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; |
473 | 474 | ||
475 | atomic_inc(&dev_priv->irq_received); | ||
476 | |||
474 | if (IS_GEN6(dev)) | 477 | if (IS_GEN6(dev)) |
475 | bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT; | 478 | bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT; |
476 | 479 | ||
@@ -1134,9 +1137,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
1134 | 1137 | ||
1135 | atomic_inc(&dev_priv->irq_received); | 1138 | atomic_inc(&dev_priv->irq_received); |
1136 | 1139 | ||
1137 | if (HAS_PCH_SPLIT(dev)) | ||
1138 | return ironlake_irq_handler(dev); | ||
1139 | |||
1140 | iir = I915_READ(IIR); | 1140 | iir = I915_READ(IIR); |
1141 | 1141 | ||
1142 | if (INTEL_INFO(dev)->gen >= 4) | 1142 | if (INTEL_INFO(dev)->gen >= 4) |
@@ -1593,10 +1593,15 @@ repeat: | |||
1593 | 1593 | ||
1594 | /* drm_dma.h hooks | 1594 | /* drm_dma.h hooks |
1595 | */ | 1595 | */ |
1596 | static void ironlake_irq_preinstall(struct drm_device *dev) | 1596 | void ironlake_irq_preinstall(struct drm_device *dev) |
1597 | { | 1597 | { |
1598 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1598 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1599 | 1599 | ||
1600 | atomic_set(&dev_priv->irq_received, 0); | ||
1601 | |||
1602 | INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); | ||
1603 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); | ||
1604 | |||
1600 | I915_WRITE(HWSTAM, 0xeffe); | 1605 | I915_WRITE(HWSTAM, 0xeffe); |
1601 | 1606 | ||
1602 | /* XXX hotplug from PCH */ | 1607 | /* XXX hotplug from PCH */ |
@@ -1616,7 +1621,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev) | |||
1616 | POSTING_READ(SDEIER); | 1621 | POSTING_READ(SDEIER); |
1617 | } | 1622 | } |
1618 | 1623 | ||
1619 | static int ironlake_irq_postinstall(struct drm_device *dev) | 1624 | int ironlake_irq_postinstall(struct drm_device *dev) |
1620 | { | 1625 | { |
1621 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1626 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1622 | /* enable kind of interrupts always enabled */ | 1627 | /* enable kind of interrupts always enabled */ |
@@ -1625,6 +1630,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1625 | u32 render_irqs; | 1630 | u32 render_irqs; |
1626 | u32 hotplug_mask; | 1631 | u32 hotplug_mask; |
1627 | 1632 | ||
1633 | DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); | ||
1634 | if (HAS_BSD(dev)) | ||
1635 | DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); | ||
1636 | if (HAS_BLT(dev)) | ||
1637 | DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); | ||
1638 | |||
1639 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; | ||
1628 | dev_priv->irq_mask = ~display_mask; | 1640 | dev_priv->irq_mask = ~display_mask; |
1629 | 1641 | ||
1630 | /* should always can generate irq */ | 1642 | /* should always can generate irq */ |
@@ -1692,11 +1704,6 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
1692 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); | 1704 | INIT_WORK(&dev_priv->error_work, i915_error_work_func); |
1693 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); | 1705 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); |
1694 | 1706 | ||
1695 | if (HAS_PCH_SPLIT(dev)) { | ||
1696 | ironlake_irq_preinstall(dev); | ||
1697 | return; | ||
1698 | } | ||
1699 | |||
1700 | if (I915_HAS_HOTPLUG(dev)) { | 1707 | if (I915_HAS_HOTPLUG(dev)) { |
1701 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 1708 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
1702 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | 1709 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |
@@ -1722,9 +1729,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1722 | 1729 | ||
1723 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; | 1730 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; |
1724 | 1731 | ||
1725 | if (HAS_PCH_SPLIT(dev)) | ||
1726 | return ironlake_irq_postinstall(dev); | ||
1727 | |||
1728 | /* Unmask the interrupts that we always want on. */ | 1732 | /* Unmask the interrupts that we always want on. */ |
1729 | dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX; | 1733 | dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX; |
1730 | 1734 | ||
@@ -1793,9 +1797,15 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1793 | return 0; | 1797 | return 0; |
1794 | } | 1798 | } |
1795 | 1799 | ||
1796 | static void ironlake_irq_uninstall(struct drm_device *dev) | 1800 | void ironlake_irq_uninstall(struct drm_device *dev) |
1797 | { | 1801 | { |
1798 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1802 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1803 | |||
1804 | if (!dev_priv) | ||
1805 | return; | ||
1806 | |||
1807 | dev_priv->vblank_pipe = 0; | ||
1808 | |||
1799 | I915_WRITE(HWSTAM, 0xffffffff); | 1809 | I915_WRITE(HWSTAM, 0xffffffff); |
1800 | 1810 | ||
1801 | I915_WRITE(DEIMR, 0xffffffff); | 1811 | I915_WRITE(DEIMR, 0xffffffff); |
@@ -1817,11 +1827,6 @@ void i915_driver_irq_uninstall(struct drm_device * dev) | |||
1817 | 1827 | ||
1818 | dev_priv->vblank_pipe = 0; | 1828 | dev_priv->vblank_pipe = 0; |
1819 | 1829 | ||
1820 | if (HAS_PCH_SPLIT(dev)) { | ||
1821 | ironlake_irq_uninstall(dev); | ||
1822 | return; | ||
1823 | } | ||
1824 | |||
1825 | if (I915_HAS_HOTPLUG(dev)) { | 1830 | if (I915_HAS_HOTPLUG(dev)) { |
1826 | I915_WRITE(PORT_HOTPLUG_EN, 0); | 1831 | I915_WRITE(PORT_HOTPLUG_EN, 0); |
1827 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); | 1832 | I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); |