Skip to content

Commit

Permalink
drm/i915: split irq handling into per-chipset functions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jesse Barnes authored and Keith Packard committed May 14, 2011
1 parent 674cf96 commit 4697995
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 20 deletions.
12 changes: 12 additions & 0 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,18 @@ static int i915_load_modeset_init(struct drm_device *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);
if (ret)
goto cleanup_gem;
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 int i915_driver_irq_postinstall(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,
struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
Expand Down
45 changes: 25 additions & 20 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,15 +462,18 @@ static void pch_irq_handler(struct drm_device *dev)
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;
int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
u32 hotplug_mask;
struct drm_i915_master_private *master_priv;
u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;

atomic_inc(&dev_priv->irq_received);

if (IS_GEN6(dev))
bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT;

Expand Down Expand Up @@ -1134,9 +1137,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)

atomic_inc(&dev_priv->irq_received);

if (HAS_PCH_SPLIT(dev))
return ironlake_irq_handler(dev);

iir = I915_READ(IIR);

if (INTEL_INFO(dev)->gen >= 4)
Expand Down Expand Up @@ -1593,10 +1593,15 @@ void i915_hangcheck_elapsed(unsigned long data)

/* 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;

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);

/* XXX hotplug from PCH */
Expand All @@ -1616,7 +1621,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
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;
/* enable kind of interrupts always enabled */
Expand All @@ -1625,6 +1630,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
u32 render_irqs;
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;

/* should always can generate irq */
Expand Down Expand Up @@ -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->rps_work, gen6_pm_rps_work);

if (HAS_PCH_SPLIT(dev)) {
ironlake_irq_preinstall(dev);
return;
}

if (I915_HAS_HOTPLUG(dev)) {
I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
Expand All @@ -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;

if (HAS_PCH_SPLIT(dev))
return ironlake_irq_postinstall(dev);

/* Unmask the interrupts that we always want on. */
dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX;

Expand Down Expand Up @@ -1793,9 +1797,15 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
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;

if (!dev_priv)
return;

dev_priv->vblank_pipe = 0;

I915_WRITE(HWSTAM, 0xffffffff);

I915_WRITE(DEIMR, 0xffffffff);
Expand All @@ -1817,11 +1827,6 @@ void i915_driver_irq_uninstall(struct drm_device * dev)

dev_priv->vblank_pipe = 0;

if (HAS_PCH_SPLIT(dev)) {
ironlake_irq_uninstall(dev);
return;
}

if (I915_HAS_HOTPLUG(dev)) {
I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
Expand Down

0 comments on commit 4697995

Please sign in to comment.