drm/i915: split enable/disable vblank code into chipset specific functions

This makes the Ironlake+ code trivial and generally simplifies things.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Jesse Barnes 2011-04-07 13:58:17 -07:00 committed by Keith Packard
parent 4697995b98
commit f796cf8f51
3 changed files with 37 additions and 11 deletions

View File

@ -1271,11 +1271,15 @@ static int i915_load_modeset_init(struct drm_device *dev)
dev->driver->irq_preinstall = ironlake_irq_preinstall; dev->driver->irq_preinstall = ironlake_irq_preinstall;
dev->driver->irq_postinstall = ironlake_irq_postinstall; dev->driver->irq_postinstall = ironlake_irq_postinstall;
dev->driver->irq_uninstall = ironlake_irq_uninstall; dev->driver->irq_uninstall = ironlake_irq_uninstall;
dev->driver->enable_vblank = ironlake_enable_vblank;
dev->driver->disable_vblank = ironlake_disable_vblank;
} else { } else {
dev->driver->irq_preinstall = i915_driver_irq_preinstall; dev->driver->irq_preinstall = i915_driver_irq_preinstall;
dev->driver->irq_postinstall = i915_driver_irq_postinstall; dev->driver->irq_postinstall = i915_driver_irq_postinstall;
dev->driver->irq_uninstall = i915_driver_irq_uninstall; dev->driver->irq_uninstall = i915_driver_irq_uninstall;
dev->driver->irq_handler = i915_driver_irq_handler; dev->driver->irq_handler = i915_driver_irq_handler;
dev->driver->enable_vblank = i915_enable_vblank;
dev->driver->disable_vblank = i915_disable_vblank;
} }
ret = drm_irq_install(dev); ret = drm_irq_install(dev);

View File

@ -1040,6 +1040,8 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
extern int i915_enable_vblank(struct drm_device *dev, int crtc); extern int i915_enable_vblank(struct drm_device *dev, int crtc);
extern void i915_disable_vblank(struct drm_device *dev, int crtc); extern void i915_disable_vblank(struct drm_device *dev, int crtc);
extern int ironlake_enable_vblank(struct drm_device *dev, int crtc);
extern void ironlake_disable_vblank(struct drm_device *dev, int crtc);
extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data, extern int i915_vblank_swap(struct drm_device *dev, void *data,

View File

@ -1375,10 +1375,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags); spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
if (HAS_PCH_SPLIT(dev)) if (INTEL_INFO(dev)->gen >= 4)
ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
else if (INTEL_INFO(dev)->gen >= 4)
i915_enable_pipestat(dev_priv, pipe, i915_enable_pipestat(dev_priv, pipe,
PIPE_START_VBLANK_INTERRUPT_ENABLE); PIPE_START_VBLANK_INTERRUPT_ENABLE);
else else
@ -1393,6 +1390,22 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
return 0; return 0;
} }
int ironlake_enable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
if (!i915_pipe_enabled(dev, pipe))
return -EINVAL;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
return 0;
}
/* Called from drm generic code, passed 'crtc' which /* Called from drm generic code, passed 'crtc' which
* we use as a pipe index * we use as a pipe index
*/ */
@ -1406,13 +1419,20 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
I915_WRITE(INSTPM, I915_WRITE(INSTPM,
INSTPM_AGPBUSY_DIS << 16 | INSTPM_AGPBUSY_DIS); INSTPM_AGPBUSY_DIS << 16 | INSTPM_AGPBUSY_DIS);
if (HAS_PCH_SPLIT(dev)) i915_disable_pipestat(dev_priv, pipe,
ironlake_disable_display_irq(dev_priv, (pipe == 0) ? PIPE_VBLANK_INTERRUPT_ENABLE |
DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); PIPE_START_VBLANK_INTERRUPT_ENABLE);
else spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
i915_disable_pipestat(dev_priv, pipe, }
PIPE_VBLANK_INTERRUPT_ENABLE |
PIPE_START_VBLANK_INTERRUPT_ENABLE); void ironlake_disable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
ironlake_disable_display_irq(dev_priv, (pipe == 0) ?
DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
} }