|
@@ -152,7 +152,7 @@ i915_pipe_enabled(struct drm_device *dev, int pipe)
|
|
/* Called from drm generic code, passed a 'crtc', which
|
|
/* Called from drm generic code, passed a 'crtc', which
|
|
* we use as a pipe index
|
|
* we use as a pipe index
|
|
*/
|
|
*/
|
|
-u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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;
|
|
unsigned long high_frame;
|
|
unsigned long high_frame;
|
|
@@ -184,7 +184,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
|
|
return (high1 << 8) | low;
|
|
return (high1 << 8) | low;
|
|
}
|
|
}
|
|
|
|
|
|
-u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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 reg = PIPE_FRMCOUNT_GM45(pipe);
|
|
int reg = PIPE_FRMCOUNT_GM45(pipe);
|
|
@@ -198,7 +198,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
|
|
return I915_READ(reg);
|
|
return I915_READ(reg);
|
|
}
|
|
}
|
|
|
|
|
|
-int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
|
|
|
|
|
|
+static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
|
|
int *vpos, int *hpos)
|
|
int *vpos, int *hpos)
|
|
{
|
|
{
|
|
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;
|
|
@@ -264,7 +264,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
|
|
|
|
|
|
+static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
|
|
int *max_error,
|
|
int *max_error,
|
|
struct timeval *vblank_time,
|
|
struct timeval *vblank_time,
|
|
unsigned flags)
|
|
unsigned flags)
|
|
@@ -462,7 +462,7 @@ 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");
|
|
}
|
|
}
|
|
|
|
|
|
-irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
|
|
|
|
|
|
+static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
|
|
{
|
|
{
|
|
struct drm_device *dev = (struct drm_device *) arg;
|
|
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;
|
|
@@ -550,7 +550,7 @@ done:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
|
|
|
|
|
|
+static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
|
|
{
|
|
{
|
|
struct drm_device *dev = (struct drm_device *) arg;
|
|
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;
|
|
@@ -1209,7 +1209,7 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|
|
|
|
|
+static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
|
|
{
|
|
{
|
|
struct drm_device *dev = (struct drm_device *) arg;
|
|
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;
|
|
@@ -1454,7 +1454,7 @@ int i915_irq_wait(struct drm_device *dev, void *data,
|
|
/* 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
|
|
*/
|
|
*/
|
|
-int i915_enable_vblank(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static int i915_enable_vblank(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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;
|
|
unsigned long irqflags;
|
|
unsigned long irqflags;
|
|
@@ -1478,7 +1478,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int ironlake_enable_vblank(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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;
|
|
unsigned long irqflags;
|
|
unsigned long irqflags;
|
|
@@ -1494,7 +1494,7 @@ int ironlake_enable_vblank(struct drm_device *dev, int pipe)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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;
|
|
unsigned long irqflags;
|
|
unsigned long irqflags;
|
|
@@ -1513,7 +1513,7 @@ int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
|
|
/* 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
|
|
*/
|
|
*/
|
|
-void i915_disable_vblank(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static void i915_disable_vblank(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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;
|
|
unsigned long irqflags;
|
|
unsigned long irqflags;
|
|
@@ -1529,7 +1529,7 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
|
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
|
}
|
|
}
|
|
|
|
|
|
-void ironlake_disable_vblank(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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;
|
|
unsigned long irqflags;
|
|
unsigned long irqflags;
|
|
@@ -1540,7 +1540,7 @@ void ironlake_disable_vblank(struct drm_device *dev, int pipe)
|
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
|
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
|
}
|
|
}
|
|
|
|
|
|
-void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
|
|
|
|
|
|
+static void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
|
|
{
|
|
{
|
|
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;
|
|
unsigned long irqflags;
|
|
unsigned long irqflags;
|
|
@@ -1728,7 +1728,7 @@ repeat:
|
|
|
|
|
|
/* drm_dma.h hooks
|
|
/* drm_dma.h hooks
|
|
*/
|
|
*/
|
|
-void ironlake_irq_preinstall(struct drm_device *dev)
|
|
|
|
|
|
+static 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;
|
|
|
|
|
|
@@ -1740,7 +1740,7 @@ void ironlake_irq_preinstall(struct drm_device *dev)
|
|
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
|
|
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
|
|
|
|
|
|
I915_WRITE(HWSTAM, 0xeffe);
|
|
I915_WRITE(HWSTAM, 0xeffe);
|
|
- if (IS_GEN6(dev)) {
|
|
|
|
|
|
+ if (IS_GEN6(dev) || IS_GEN7(dev)) {
|
|
/* Workaround stalls observed on Sandy Bridge GPUs by
|
|
/* Workaround stalls observed on Sandy Bridge GPUs by
|
|
* making the blitter command streamer generate a
|
|
* making the blitter command streamer generate a
|
|
* write to the Hardware Status Page for
|
|
* write to the Hardware Status Page for
|
|
@@ -1769,7 +1769,7 @@ void ironlake_irq_preinstall(struct drm_device *dev)
|
|
POSTING_READ(SDEIER);
|
|
POSTING_READ(SDEIER);
|
|
}
|
|
}
|
|
|
|
|
|
-int ironlake_irq_postinstall(struct drm_device *dev)
|
|
|
|
|
|
+static 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 */
|
|
@@ -1841,7 +1841,7 @@ int ironlake_irq_postinstall(struct drm_device *dev)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int ivybridge_irq_postinstall(struct drm_device *dev)
|
|
|
|
|
|
+static int ivybridge_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 */
|
|
@@ -1891,7 +1891,7 @@ int ivybridge_irq_postinstall(struct drm_device *dev)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-void i915_driver_irq_preinstall(struct drm_device * dev)
|
|
|
|
|
|
+static void i915_driver_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;
|
|
int pipe;
|
|
int pipe;
|
|
@@ -1918,7 +1918,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
|
|
* Must be called after intel_modeset_init or hotplug interrupts won't be
|
|
* Must be called after intel_modeset_init or hotplug interrupts won't be
|
|
* enabled correctly.
|
|
* enabled correctly.
|
|
*/
|
|
*/
|
|
-int i915_driver_irq_postinstall(struct drm_device *dev)
|
|
|
|
|
|
+static int i915_driver_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;
|
|
u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
|
|
u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
|
|
@@ -1994,7 +1994,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-void ironlake_irq_uninstall(struct drm_device *dev)
|
|
|
|
|
|
+static 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;
|
|
|
|
|
|
@@ -2014,7 +2014,7 @@ void ironlake_irq_uninstall(struct drm_device *dev)
|
|
I915_WRITE(GTIIR, I915_READ(GTIIR));
|
|
I915_WRITE(GTIIR, I915_READ(GTIIR));
|
|
}
|
|
}
|
|
|
|
|
|
-void i915_driver_irq_uninstall(struct drm_device * dev)
|
|
|
|
|
|
+static void i915_driver_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;
|
|
int pipe;
|
|
int pipe;
|
|
@@ -2040,3 +2040,41 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
|
|
I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
|
|
I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
|
|
I915_WRITE(IIR, I915_READ(IIR));
|
|
I915_WRITE(IIR, I915_READ(IIR));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+void intel_irq_init(struct drm_device *dev)
|
|
|
|
+{
|
|
|
|
+ dev->driver->get_vblank_counter = i915_get_vblank_counter;
|
|
|
|
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
|
|
|
|
+ if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
|
|
|
|
+ dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
|
|
|
|
+ dev->driver->get_vblank_counter = gm45_get_vblank_counter;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
|
|
|
|
+ dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
|
|
|
|
+
|
|
|
|
+ if (IS_IVYBRIDGE(dev)) {
|
|
|
|
+ /* Share pre & uninstall handlers with ILK/SNB */
|
|
|
|
+ dev->driver->irq_handler = ivybridge_irq_handler;
|
|
|
|
+ dev->driver->irq_preinstall = ironlake_irq_preinstall;
|
|
|
|
+ dev->driver->irq_postinstall = ivybridge_irq_postinstall;
|
|
|
|
+ dev->driver->irq_uninstall = ironlake_irq_uninstall;
|
|
|
|
+ dev->driver->enable_vblank = ivybridge_enable_vblank;
|
|
|
|
+ dev->driver->disable_vblank = ivybridge_disable_vblank;
|
|
|
|
+ } else 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;
|
|
|
|
+ dev->driver->enable_vblank = ironlake_enable_vblank;
|
|
|
|
+ dev->driver->disable_vblank = ironlake_disable_vblank;
|
|
|
|
+ } 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;
|
|
|
|
+ dev->driver->enable_vblank = i915_enable_vblank;
|
|
|
|
+ dev->driver->disable_vblank = i915_disable_vblank;
|
|
|
|
+ }
|
|
|
|
+}
|