aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-04-07 16:53:55 -0400
committerKeith Packard <keithp@keithp.com>2011-05-13 20:02:44 -0400
commit4697995b98417c6da9ab2708a36f5e2bc926c8ac (patch)
tree4cf90662b8ebcec9ac999c140816d130adfae097
parent674cf967614f31826f45d30c8f8f8e050cc3eef2 (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.c12
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h6
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c45
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);
1028extern void i915_driver_irq_preinstall(struct drm_device * dev); 1028extern void i915_driver_irq_preinstall(struct drm_device * dev);
1029extern int i915_driver_irq_postinstall(struct drm_device *dev); 1029extern int i915_driver_irq_postinstall(struct drm_device *dev);
1030extern void i915_driver_irq_uninstall(struct drm_device * dev); 1030extern void i915_driver_irq_uninstall(struct drm_device * dev);
1031
1032extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS);
1033extern void ironlake_irq_preinstall(struct drm_device *dev);
1034extern int ironlake_irq_postinstall(struct drm_device *dev);
1035extern void ironlake_irq_uninstall(struct drm_device *dev);
1036
1031extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, 1037extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
1032 struct drm_file *file_priv); 1038 struct drm_file *file_priv);
1033extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, 1039extern 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
465static irqreturn_t ironlake_irq_handler(struct drm_device *dev) 465irqreturn_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*/
1596static void ironlake_irq_preinstall(struct drm_device *dev) 1596void 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
1619static int ironlake_irq_postinstall(struct drm_device *dev) 1624int 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
1796static void ironlake_irq_uninstall(struct drm_device *dev) 1800void 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));