Commit 4697995b authored by Jesse Barnes's avatar Jesse Barnes Committed by Keith Packard

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: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: default avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent 674cf967
...@@ -1266,6 +1266,18 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1266,6 +1266,18 @@ static int i915_load_modeset_init(struct drm_device *dev)
intel_modeset_gem_init(dev); intel_modeset_gem_init(dev);
if (HAS_PCH_SPLIT(dev)) {
dev->driver->irq_handler = ironlake_irq_handler;
dev->driver->irq_preinstall = ironlake_irq_preinstall;
dev->driver->irq_postinstall = ironlake_irq_postinstall;
dev->driver->irq_uninstall = ironlake_irq_uninstall;
} else {
dev->driver->irq_preinstall = i915_driver_irq_preinstall;
dev->driver->irq_postinstall = i915_driver_irq_postinstall;
dev->driver->irq_uninstall = i915_driver_irq_uninstall;
dev->driver->irq_handler = i915_driver_irq_handler;
}
ret = drm_irq_install(dev); ret = drm_irq_install(dev);
if (ret) if (ret)
goto cleanup_gem; goto cleanup_gem;
......
...@@ -1028,6 +1028,12 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); ...@@ -1028,6 +1028,12 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(struct drm_device * dev); extern void i915_driver_irq_preinstall(struct drm_device * dev);
extern int i915_driver_irq_postinstall(struct drm_device *dev); extern int i915_driver_irq_postinstall(struct drm_device *dev);
extern void i915_driver_irq_uninstall(struct drm_device * dev); extern void i915_driver_irq_uninstall(struct drm_device * dev);
extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS);
extern void ironlake_irq_preinstall(struct drm_device *dev);
extern int ironlake_irq_postinstall(struct drm_device *dev);
extern void ironlake_irq_uninstall(struct drm_device *dev);
extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
......
...@@ -462,8 +462,9 @@ static void pch_irq_handler(struct drm_device *dev) ...@@ -462,8 +462,9 @@ static void pch_irq_handler(struct drm_device *dev)
DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
} }
static irqreturn_t ironlake_irq_handler(struct drm_device *dev) irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
{ {
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE; int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; 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,6 +472,8 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
struct drm_i915_master_private *master_priv; struct drm_i915_master_private *master_priv;
u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;
atomic_inc(&dev_priv->irq_received);
if (IS_GEN6(dev)) if (IS_GEN6(dev))
bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT; bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT;
...@@ -1134,9 +1137,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) ...@@ -1134,9 +1137,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
atomic_inc(&dev_priv->irq_received); atomic_inc(&dev_priv->irq_received);
if (HAS_PCH_SPLIT(dev))
return ironlake_irq_handler(dev);
iir = I915_READ(IIR); iir = I915_READ(IIR);
if (INTEL_INFO(dev)->gen >= 4) if (INTEL_INFO(dev)->gen >= 4)
...@@ -1593,10 +1593,15 @@ void i915_hangcheck_elapsed(unsigned long data) ...@@ -1593,10 +1593,15 @@ void i915_hangcheck_elapsed(unsigned long data)
/* drm_dma.h hooks /* drm_dma.h hooks
*/ */
static void ironlake_irq_preinstall(struct drm_device *dev) void ironlake_irq_preinstall(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
atomic_set(&dev_priv->irq_received, 0);
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
INIT_WORK(&dev_priv->error_work, i915_error_work_func);
I915_WRITE(HWSTAM, 0xeffe); I915_WRITE(HWSTAM, 0xeffe);
/* XXX hotplug from PCH */ /* XXX hotplug from PCH */
...@@ -1616,7 +1621,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev) ...@@ -1616,7 +1621,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
POSTING_READ(SDEIER); POSTING_READ(SDEIER);
} }
static int ironlake_irq_postinstall(struct drm_device *dev) int ironlake_irq_postinstall(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
/* enable kind of interrupts always enabled */ /* enable kind of interrupts always enabled */
...@@ -1625,6 +1630,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev) ...@@ -1625,6 +1630,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
u32 render_irqs; u32 render_irqs;
u32 hotplug_mask; u32 hotplug_mask;
DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue);
if (HAS_BSD(dev))
DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue);
if (HAS_BLT(dev))
DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue);
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
dev_priv->irq_mask = ~display_mask; dev_priv->irq_mask = ~display_mask;
/* should always can generate irq */ /* should always can generate irq */
...@@ -1692,11 +1704,6 @@ void i915_driver_irq_preinstall(struct drm_device * dev) ...@@ -1692,11 +1704,6 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
INIT_WORK(&dev_priv->error_work, i915_error_work_func); INIT_WORK(&dev_priv->error_work, i915_error_work_func);
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
if (HAS_PCH_SPLIT(dev)) {
ironlake_irq_preinstall(dev);
return;
}
if (I915_HAS_HOTPLUG(dev)) { if (I915_HAS_HOTPLUG(dev)) {
I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
...@@ -1722,9 +1729,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev) ...@@ -1722,9 +1729,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
if (HAS_PCH_SPLIT(dev))
return ironlake_irq_postinstall(dev);
/* Unmask the interrupts that we always want on. */ /* Unmask the interrupts that we always want on. */
dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX; dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX;
...@@ -1793,9 +1797,15 @@ int i915_driver_irq_postinstall(struct drm_device *dev) ...@@ -1793,9 +1797,15 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
return 0; return 0;
} }
static void ironlake_irq_uninstall(struct drm_device *dev) void ironlake_irq_uninstall(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
if (!dev_priv)
return;
dev_priv->vblank_pipe = 0;
I915_WRITE(HWSTAM, 0xffffffff); I915_WRITE(HWSTAM, 0xffffffff);
I915_WRITE(DEIMR, 0xffffffff); I915_WRITE(DEIMR, 0xffffffff);
...@@ -1817,11 +1827,6 @@ void i915_driver_irq_uninstall(struct drm_device * dev) ...@@ -1817,11 +1827,6 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
dev_priv->vblank_pipe = 0; dev_priv->vblank_pipe = 0;
if (HAS_PCH_SPLIT(dev)) {
ironlake_irq_uninstall(dev);
return;
}
if (I915_HAS_HOTPLUG(dev)) { if (I915_HAS_HOTPLUG(dev)) {
I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment