aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2012-03-28 16:39:38 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-03-28 18:11:22 -0400
commit7e231dbe0c2a4359472f929732d4200479d8f939 (patch)
tree1ead8e89c693687c7d39c8cbe44920705b99045a /drivers
parentc46ce4d7e69d129c02640c118f45a86a4412774b (diff)
drm/i915: ValleyView IRQ support
ValleyView has a new interrupt architecture; best to put it in a new set of functions. Also make sure the ring mask functions handle ValleyView. FIXME: fix flipping; need to enable interrupts and call prepare/finish Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c40
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c338
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h7
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c4
4 files changed, 383 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index e74674b3097d..d226f2f2f7bc 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -468,7 +468,45 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
468 if (ret) 468 if (ret)
469 return ret; 469 return ret;
470 470
471 if (!HAS_PCH_SPLIT(dev)) { 471 if (IS_VALLEYVIEW(dev)) {
472 seq_printf(m, "Display IER:\t%08x\n",
473 I915_READ(VLV_IER));
474 seq_printf(m, "Display IIR:\t%08x\n",
475 I915_READ(VLV_IIR));
476 seq_printf(m, "Display IIR_RW:\t%08x\n",
477 I915_READ(VLV_IIR_RW));
478 seq_printf(m, "Display IMR:\t%08x\n",
479 I915_READ(VLV_IMR));
480 for_each_pipe(pipe)
481 seq_printf(m, "Pipe %c stat:\t%08x\n",
482 pipe_name(pipe),
483 I915_READ(PIPESTAT(pipe)));
484
485 seq_printf(m, "Master IER:\t%08x\n",
486 I915_READ(VLV_MASTER_IER));
487
488 seq_printf(m, "Render IER:\t%08x\n",
489 I915_READ(GTIER));
490 seq_printf(m, "Render IIR:\t%08x\n",
491 I915_READ(GTIIR));
492 seq_printf(m, "Render IMR:\t%08x\n",
493 I915_READ(GTIMR));
494
495 seq_printf(m, "PM IER:\t\t%08x\n",
496 I915_READ(GEN6_PMIER));
497 seq_printf(m, "PM IIR:\t\t%08x\n",
498 I915_READ(GEN6_PMIIR));
499 seq_printf(m, "PM IMR:\t\t%08x\n",
500 I915_READ(GEN6_PMIMR));
501
502 seq_printf(m, "Port hotplug:\t%08x\n",
503 I915_READ(PORT_HOTPLUG_EN));
504 seq_printf(m, "DPFLIPSTAT:\t%08x\n",
505 I915_READ(VLV_DPFLIPSTAT));
506 seq_printf(m, "DPINVGTT:\t%08x\n",
507 I915_READ(DPINVGTT));
508
509 } else if (!HAS_PCH_SPLIT(dev)) {
472 seq_printf(m, "Interrupt enable: %08x\n", 510 seq_printf(m, "Interrupt enable: %08x\n",
473 I915_READ(IER)); 511 I915_READ(IER));
474 seq_printf(m, "Interrupt identity: %08x\n", 512 seq_printf(m, "Interrupt identity: %08x\n",
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 998116e871f0..01fb65097977 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -120,6 +120,10 @@ void intel_enable_asle(struct drm_device *dev)
120 drm_i915_private_t *dev_priv = dev->dev_private; 120 drm_i915_private_t *dev_priv = dev->dev_private;
121 unsigned long irqflags; 121 unsigned long irqflags;
122 122
123 /* FIXME: opregion/asle for VLV */
124 if (IS_VALLEYVIEW(dev))
125 return;
126
123 spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 127 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
124 128
125 if (HAS_PCH_SPLIT(dev)) 129 if (HAS_PCH_SPLIT(dev))
@@ -426,6 +430,119 @@ static void gen6_pm_rps_work(struct work_struct *work)
426 mutex_unlock(&dev_priv->dev->struct_mutex); 430 mutex_unlock(&dev_priv->dev->struct_mutex);
427} 431}
428 432
433static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
434{
435 struct drm_device *dev = (struct drm_device *) arg;
436 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
437 u32 iir, gt_iir, pm_iir;
438 irqreturn_t ret = IRQ_NONE;
439 unsigned long irqflags;
440 int pipe;
441 u32 pipe_stats[I915_MAX_PIPES];
442 u32 vblank_status;
443 int vblank = 0;
444 bool blc_event;
445
446 atomic_inc(&dev_priv->irq_received);
447
448 vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS |
449 PIPE_VBLANK_INTERRUPT_STATUS;
450
451 while (true) {
452 iir = I915_READ(VLV_IIR);
453 gt_iir = I915_READ(GTIIR);
454 pm_iir = I915_READ(GEN6_PMIIR);
455
456 if (gt_iir == 0 && pm_iir == 0 && iir == 0)
457 goto out;
458
459 ret = IRQ_HANDLED;
460
461 if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
462 notify_ring(dev, &dev_priv->ring[RCS]);
463 if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
464 notify_ring(dev, &dev_priv->ring[VCS]);
465 if (gt_iir & GT_BLT_USER_INTERRUPT)
466 notify_ring(dev, &dev_priv->ring[BCS]);
467
468 if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT |
469 GT_GEN6_BSD_CS_ERROR_INTERRUPT |
470 GT_RENDER_CS_ERROR_INTERRUPT)) {
471 DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir);
472 i915_handle_error(dev, false);
473 }
474
475 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
476 for_each_pipe(pipe) {
477 int reg = PIPESTAT(pipe);
478 pipe_stats[pipe] = I915_READ(reg);
479
480 /*
481 * Clear the PIPE*STAT regs before the IIR
482 */
483 if (pipe_stats[pipe] & 0x8000ffff) {
484 if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
485 DRM_DEBUG_DRIVER("pipe %c underrun\n",
486 pipe_name(pipe));
487 I915_WRITE(reg, pipe_stats[pipe]);
488 }
489 }
490 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
491
492 /* Consume port. Then clear IIR or we'll miss events */
493 if (iir & I915_DISPLAY_PORT_INTERRUPT) {
494 u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
495
496 DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
497 hotplug_status);
498 if (hotplug_status & dev_priv->hotplug_supported_mask)
499 queue_work(dev_priv->wq,
500 &dev_priv->hotplug_work);
501
502 I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
503 I915_READ(PORT_HOTPLUG_STAT);
504 }
505
506
507 if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) {
508 drm_handle_vblank(dev, 0);
509 vblank++;
510 if (!dev_priv->flip_pending_is_done) {
511 intel_finish_page_flip(dev, 0);
512 }
513 }
514
515 if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) {
516 drm_handle_vblank(dev, 1);
517 vblank++;
518 if (!dev_priv->flip_pending_is_done) {
519 intel_finish_page_flip(dev, 0);
520 }
521 }
522
523 if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
524 blc_event = true;
525
526 if (pm_iir & GEN6_PM_DEFERRED_EVENTS) {
527 unsigned long flags;
528 spin_lock_irqsave(&dev_priv->rps_lock, flags);
529 WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n");
530 dev_priv->pm_iir |= pm_iir;
531 I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir);
532 POSTING_READ(GEN6_PMIMR);
533 spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
534 queue_work(dev_priv->wq, &dev_priv->rps_work);
535 }
536
537 I915_WRITE(GTIIR, gt_iir);
538 I915_WRITE(GEN6_PMIIR, pm_iir);
539 I915_WRITE(VLV_IIR, iir);
540 }
541
542out:
543 return ret;
544}
545
429static void pch_irq_handler(struct drm_device *dev) 546static void pch_irq_handler(struct drm_device *dev)
430{ 547{
431 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 548 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1567,6 +1684,32 @@ static int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
1567 return 0; 1684 return 0;
1568} 1685}
1569 1686
1687static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
1688{
1689 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1690 unsigned long irqflags;
1691 u32 dpfl, imr;
1692
1693 if (!i915_pipe_enabled(dev, pipe))
1694 return -EINVAL;
1695
1696 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
1697 dpfl = I915_READ(VLV_DPFLIPSTAT);
1698 imr = I915_READ(VLV_IMR);
1699 if (pipe == 0) {
1700 dpfl |= PIPEA_VBLANK_INT_EN;
1701 imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1702 } else {
1703 dpfl |= PIPEA_VBLANK_INT_EN;
1704 imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1705 }
1706 I915_WRITE(VLV_DPFLIPSTAT, dpfl);
1707 I915_WRITE(VLV_IMR, imr);
1708 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
1709
1710 return 0;
1711}
1712
1570/* Called from drm generic code, passed 'crtc' which 1713/* Called from drm generic code, passed 'crtc' which
1571 * we use as a pipe index 1714 * we use as a pipe index
1572 */ 1715 */
@@ -1608,6 +1751,28 @@ static void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
1608 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 1751 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
1609} 1752}
1610 1753
1754static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
1755{
1756 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1757 unsigned long irqflags;
1758 u32 dpfl, imr;
1759
1760 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
1761 dpfl = I915_READ(VLV_DPFLIPSTAT);
1762 imr = I915_READ(VLV_IMR);
1763 if (pipe == 0) {
1764 dpfl &= ~PIPEA_VBLANK_INT_EN;
1765 imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1766 } else {
1767 dpfl &= ~PIPEB_VBLANK_INT_EN;
1768 imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1769 }
1770 I915_WRITE(VLV_IMR, imr);
1771 I915_WRITE(VLV_DPFLIPSTAT, dpfl);
1772 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
1773}
1774
1775
1611/* Set the vblank monitor pipe 1776/* Set the vblank monitor pipe
1612 */ 1777 */
1613int i915_vblank_pipe_set(struct drm_device *dev, void *data, 1778int i915_vblank_pipe_set(struct drm_device *dev, void *data,
@@ -1817,6 +1982,53 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
1817 POSTING_READ(SDEIER); 1982 POSTING_READ(SDEIER);
1818} 1983}
1819 1984
1985static void valleyview_irq_preinstall(struct drm_device *dev)
1986{
1987 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1988 int pipe;
1989
1990 atomic_set(&dev_priv->irq_received, 0);
1991
1992 INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
1993 INIT_WORK(&dev_priv->error_work, i915_error_work_func);
1994
1995 /* VLV magic */
1996 I915_WRITE(VLV_IMR, 0);
1997 I915_WRITE(RING_IMR(RENDER_RING_BASE), 0);
1998 I915_WRITE(RING_IMR(GEN6_BSD_RING_BASE), 0);
1999 I915_WRITE(RING_IMR(BLT_RING_BASE), 0);
2000
2001 if (IS_GEN6(dev) || IS_GEN7(dev)) {
2002 /* Workaround stalls observed on Sandy Bridge GPUs by
2003 * making the blitter command streamer generate a
2004 * write to the Hardware Status Page for
2005 * MI_USER_INTERRUPT. This appears to serialize the
2006 * previous seqno write out before the interrupt
2007 * happens.
2008 */
2009 I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT);
2010 I915_WRITE(GEN6_BSD_HWSTAM, ~GEN6_BSD_USER_INTERRUPT);
2011 }
2012
2013 /* and GT */
2014 I915_WRITE(GTIIR, I915_READ(GTIIR));
2015 I915_WRITE(GTIIR, I915_READ(GTIIR));
2016 I915_WRITE(GTIMR, 0xffffffff);
2017 I915_WRITE(GTIER, 0x0);
2018 POSTING_READ(GTIER);
2019
2020 I915_WRITE(DPINVGTT, 0xff);
2021
2022 I915_WRITE(PORT_HOTPLUG_EN, 0);
2023 I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
2024 for_each_pipe(pipe)
2025 I915_WRITE(PIPESTAT(pipe), 0xffff);
2026 I915_WRITE(VLV_IIR, 0xffffffff);
2027 I915_WRITE(VLV_IMR, 0xffffffff);
2028 I915_WRITE(VLV_IER, 0x0);
2029 POSTING_READ(VLV_IER);
2030}
2031
1820/* 2032/*
1821 * Enable digital hotplug on the PCH, and configure the DP short pulse 2033 * Enable digital hotplug on the PCH, and configure the DP short pulse
1822 * duration to 2ms (which is the minimum in the Display Port spec) 2034 * duration to 2ms (which is the minimum in the Display Port spec)
@@ -1963,6 +2175,96 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
1963 return 0; 2175 return 0;
1964} 2176}
1965 2177
2178static int valleyview_irq_postinstall(struct drm_device *dev)
2179{
2180 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2181 u32 render_irqs;
2182 u32 enable_mask;
2183 u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
2184 u16 msid;
2185
2186 enable_mask = I915_DISPLAY_PORT_INTERRUPT;
2187 enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
2188 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
2189
2190 dev_priv->irq_mask = ~enable_mask;
2191
2192
2193 DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue);
2194 DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue);
2195 DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue);
2196
2197 dev_priv->pipestat[0] = 0;
2198 dev_priv->pipestat[1] = 0;
2199
2200 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
2201
2202 /* Hack for broken MSIs on VLV */
2203 pci_write_config_dword(dev_priv->dev->pdev, 0x94, 0xfee00000);
2204 pci_read_config_word(dev->pdev, 0x98, &msid);
2205 msid &= 0xff; /* mask out delivery bits */
2206 msid |= (1<<14);
2207 pci_write_config_word(dev_priv->dev->pdev, 0x98, msid);
2208
2209 I915_WRITE(VLV_IMR, dev_priv->irq_mask);
2210 I915_WRITE(VLV_IER, enable_mask);
2211 I915_WRITE(VLV_IIR, 0xffffffff);
2212 I915_WRITE(PIPESTAT(0), 0xffff);
2213 I915_WRITE(PIPESTAT(1), 0xffff);
2214 POSTING_READ(VLV_IER);
2215
2216 I915_WRITE(VLV_IIR, 0xffffffff);
2217 I915_WRITE(VLV_IIR, 0xffffffff);
2218
2219 render_irqs = GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT |
2220 GT_GEN6_BLT_CS_ERROR_INTERRUPT |
2221 GT_BLT_USER_INTERRUPT |
2222 GT_GEN6_BSD_USER_INTERRUPT |
2223 GT_GEN6_BSD_CS_ERROR_INTERRUPT |
2224 GT_GEN7_L3_PARITY_ERROR_INTERRUPT |
2225 GT_PIPE_NOTIFY |
2226 GT_RENDER_CS_ERROR_INTERRUPT |
2227 GT_SYNC_STATUS |
2228 GT_USER_INTERRUPT;
2229
2230 dev_priv->gt_irq_mask = ~render_irqs;
2231
2232 I915_WRITE(GTIIR, I915_READ(GTIIR));
2233 I915_WRITE(GTIIR, I915_READ(GTIIR));
2234 I915_WRITE(GTIMR, 0);
2235 I915_WRITE(GTIER, render_irqs);
2236 POSTING_READ(GTIER);
2237
2238 /* ack & enable invalid PTE error interrupts */
2239#if 0 /* FIXME: add support to irq handler for checking these bits */
2240 I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK);
2241 I915_WRITE(DPINVGTT, DPINVGTT_EN_MASK);
2242#endif
2243
2244 I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE);
2245#if 0 /* FIXME: check register definitions; some have moved */
2246 /* Note HDMI and DP share bits */
2247 if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS)
2248 hotplug_en |= HDMIB_HOTPLUG_INT_EN;
2249 if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS)
2250 hotplug_en |= HDMIC_HOTPLUG_INT_EN;
2251 if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS)
2252 hotplug_en |= HDMID_HOTPLUG_INT_EN;
2253 if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS)
2254 hotplug_en |= SDVOC_HOTPLUG_INT_EN;
2255 if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS)
2256 hotplug_en |= SDVOB_HOTPLUG_INT_EN;
2257 if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
2258 hotplug_en |= CRT_HOTPLUG_INT_EN;
2259 hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
2260 }
2261#endif
2262
2263 I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
2264
2265 return 0;
2266}
2267
1966static void i915_driver_irq_preinstall(struct drm_device * dev) 2268static void i915_driver_irq_preinstall(struct drm_device * dev)
1967{ 2269{
1968 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 2270 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -2066,6 +2368,30 @@ static int i915_driver_irq_postinstall(struct drm_device *dev)
2066 return 0; 2368 return 0;
2067} 2369}
2068 2370
2371static void valleyview_irq_uninstall(struct drm_device *dev)
2372{
2373 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2374 int pipe;
2375
2376 if (!dev_priv)
2377 return;
2378
2379 dev_priv->vblank_pipe = 0;
2380
2381 for_each_pipe(pipe)
2382 I915_WRITE(PIPESTAT(pipe), 0xffff);
2383
2384 I915_WRITE(HWSTAM, 0xffffffff);
2385 I915_WRITE(PORT_HOTPLUG_EN, 0);
2386 I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
2387 for_each_pipe(pipe)
2388 I915_WRITE(PIPESTAT(pipe), 0xffff);
2389 I915_WRITE(VLV_IIR, 0xffffffff);
2390 I915_WRITE(VLV_IMR, 0xffffffff);
2391 I915_WRITE(VLV_IER, 0x0);
2392 POSTING_READ(VLV_IER);
2393}
2394
2069static void ironlake_irq_uninstall(struct drm_device *dev) 2395static void ironlake_irq_uninstall(struct drm_device *dev)
2070{ 2396{
2071 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 2397 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -2121,7 +2447,8 @@ void intel_irq_init(struct drm_device *dev)
2121{ 2447{
2122 dev->driver->get_vblank_counter = i915_get_vblank_counter; 2448 dev->driver->get_vblank_counter = i915_get_vblank_counter;
2123 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 2449 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
2124 if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { 2450 if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev) ||
2451 IS_VALLEYVIEW(dev)) {
2125 dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ 2452 dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
2126 dev->driver->get_vblank_counter = gm45_get_vblank_counter; 2453 dev->driver->get_vblank_counter = gm45_get_vblank_counter;
2127 } 2454 }
@@ -2132,7 +2459,14 @@ void intel_irq_init(struct drm_device *dev)
2132 dev->driver->get_vblank_timestamp = NULL; 2459 dev->driver->get_vblank_timestamp = NULL;
2133 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; 2460 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
2134 2461
2135 if (IS_IVYBRIDGE(dev)) { 2462 if (IS_VALLEYVIEW(dev)) {
2463 dev->driver->irq_handler = valleyview_irq_handler;
2464 dev->driver->irq_preinstall = valleyview_irq_preinstall;
2465 dev->driver->irq_postinstall = valleyview_irq_postinstall;
2466 dev->driver->irq_uninstall = valleyview_irq_uninstall;
2467 dev->driver->enable_vblank = valleyview_enable_vblank;
2468 dev->driver->disable_vblank = valleyview_disable_vblank;
2469 } else if (IS_IVYBRIDGE(dev)) {
2136 /* Share pre & uninstall handlers with ILK/SNB */ 2470 /* Share pre & uninstall handlers with ILK/SNB */
2137 dev->driver->irq_handler = ivybridge_irq_handler; 2471 dev->driver->irq_handler = ivybridge_irq_handler;
2138 dev->driver->irq_preinstall = ironlake_irq_preinstall; 2472 dev->driver->irq_preinstall = ironlake_irq_preinstall;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0bcad74de7be..908550c72a0d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -510,6 +510,11 @@
510#define IIR 0x020a4 510#define IIR 0x020a4
511#define IMR 0x020a8 511#define IMR 0x020a8
512#define ISR 0x020ac 512#define ISR 0x020ac
513#define VLV_IIR_RW 0x182084
514#define VLV_IER 0x1820a0
515#define VLV_IIR 0x1820a4
516#define VLV_IMR 0x1820a8
517#define VLV_ISR 0x1820ac
513#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18) 518#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
514#define I915_DISPLAY_PORT_INTERRUPT (1<<17) 519#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
515#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15) 520#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
@@ -2533,7 +2538,7 @@
2533#define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL) 2538#define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL)
2534#define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT) 2539#define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT)
2535 2540
2536#define DPFLIPSTAT_VLV 0x70028 2541#define VLV_DPFLIPSTAT 0x70028
2537#define PIPEB_LINE_COMPARE_STATUS (1<<29) 2542#define PIPEB_LINE_COMPARE_STATUS (1<<29)
2538#define PIPEB_HLINE_INT_EN (1<<28) 2543#define PIPEB_HLINE_INT_EN (1<<28)
2539#define PIPEB_VBLANK_INT_EN (1<<27) 2544#define PIPEB_VBLANK_INT_EN (1<<27)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b7b50a5b0478..75081f146390 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -687,7 +687,7 @@ render_ring_get_irq(struct intel_ring_buffer *ring)
687 687
688 spin_lock(&ring->irq_lock); 688 spin_lock(&ring->irq_lock);
689 if (ring->irq_refcount++ == 0) { 689 if (ring->irq_refcount++ == 0) {
690 if (HAS_PCH_SPLIT(dev)) 690 if (HAS_PCH_SPLIT(dev) || IS_VALLEYVIEW(dev))
691 ironlake_enable_irq(dev_priv, 691 ironlake_enable_irq(dev_priv,
692 GT_PIPE_NOTIFY | GT_USER_INTERRUPT); 692 GT_PIPE_NOTIFY | GT_USER_INTERRUPT);
693 else 693 else
@@ -706,7 +706,7 @@ render_ring_put_irq(struct intel_ring_buffer *ring)
706 706
707 spin_lock(&ring->irq_lock); 707 spin_lock(&ring->irq_lock);
708 if (--ring->irq_refcount == 0) { 708 if (--ring->irq_refcount == 0) {
709 if (HAS_PCH_SPLIT(dev)) 709 if (HAS_PCH_SPLIT(dev) || IS_VALLEYVIEW(dev))
710 ironlake_disable_irq(dev_priv, 710 ironlake_disable_irq(dev_priv,
711 GT_USER_INTERRUPT | 711 GT_USER_INTERRUPT |
712 GT_PIPE_NOTIFY); 712 GT_PIPE_NOTIFY);