aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-04-22 21:24:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-04-22 21:24:06 -0400
commit7db2ccddd112d8b4b0d0dd7f309ebd8b39373fbb (patch)
tree23b2986db5c47a507039660091cd737506282b4a /drivers/gpu
parenta2b297ff56b9bad251d11a476880a5e4614cd92f (diff)
parente552eb7038a36d9b18860f525aa02875e313fe16 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel: drm/i915: use PIPE_CONTROL instruction on Ironlake and Sandy Bridge drm/i915: cleanup FBC buffers at unload time drm/i915: fix tiling limits for i915 class hw v2 drm/i915: set DIDL using the ACPI video output device _ADR method return. drm/i915: Fix 82854 PCI ID, and treat it like other 85X drm/i915: Attempt to fix watermark setup on 85x (v2)
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c14
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c5
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h10
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c151
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c22
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c8
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c54
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h13
-rw-r--r--drivers/gpu/drm/i915/intel_display.c11
9 files changed, 246 insertions, 42 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2dc93939507d..c3cfafcbfe7d 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1357,6 +1357,8 @@ static void i915_setup_compression(struct drm_device *dev, int size)
1357 1357
1358 dev_priv->cfb_size = size; 1358 dev_priv->cfb_size = size;
1359 1359
1360 dev_priv->compressed_fb = compressed_fb;
1361
1360 if (IS_GM45(dev)) { 1362 if (IS_GM45(dev)) {
1361 g4x_disable_fbc(dev); 1363 g4x_disable_fbc(dev);
1362 I915_WRITE(DPFC_CB_BASE, compressed_fb->start); 1364 I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
@@ -1364,12 +1366,22 @@ static void i915_setup_compression(struct drm_device *dev, int size)
1364 i8xx_disable_fbc(dev); 1366 i8xx_disable_fbc(dev);
1365 I915_WRITE(FBC_CFB_BASE, cfb_base); 1367 I915_WRITE(FBC_CFB_BASE, cfb_base);
1366 I915_WRITE(FBC_LL_BASE, ll_base); 1368 I915_WRITE(FBC_LL_BASE, ll_base);
1369 dev_priv->compressed_llb = compressed_llb;
1367 } 1370 }
1368 1371
1369 DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, 1372 DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
1370 ll_base, size >> 20); 1373 ll_base, size >> 20);
1371} 1374}
1372 1375
1376static void i915_cleanup_compression(struct drm_device *dev)
1377{
1378 struct drm_i915_private *dev_priv = dev->dev_private;
1379
1380 drm_mm_put_block(dev_priv->compressed_fb);
1381 if (!IS_GM45(dev))
1382 drm_mm_put_block(dev_priv->compressed_llb);
1383}
1384
1373/* true = enable decode, false = disable decoder */ 1385/* true = enable decode, false = disable decoder */
1374static unsigned int i915_vga_set_decode(void *cookie, bool state) 1386static unsigned int i915_vga_set_decode(void *cookie, bool state)
1375{ 1387{
@@ -1787,6 +1799,8 @@ int i915_driver_unload(struct drm_device *dev)
1787 mutex_lock(&dev->struct_mutex); 1799 mutex_lock(&dev->struct_mutex);
1788 i915_gem_cleanup_ringbuffer(dev); 1800 i915_gem_cleanup_ringbuffer(dev);
1789 mutex_unlock(&dev->struct_mutex); 1801 mutex_unlock(&dev->struct_mutex);
1802 if (I915_HAS_FBC(dev) && i915_powersave)
1803 i915_cleanup_compression(dev);
1790 drm_mm_takedown(&dev_priv->vram); 1804 drm_mm_takedown(&dev_priv->vram);
1791 i915_gem_lastclose(dev); 1805 i915_gem_lastclose(dev);
1792 1806
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0af3dcc85ce9..cc03537bb883 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -69,7 +69,8 @@ const static struct intel_device_info intel_845g_info = {
69}; 69};
70 70
71const static struct intel_device_info intel_i85x_info = { 71const static struct intel_device_info intel_i85x_info = {
72 .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, 72 .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
73 .cursor_needs_physical = 1,
73}; 74};
74 75
75const static struct intel_device_info intel_i865g_info = { 76const static struct intel_device_info intel_i865g_info = {
@@ -151,7 +152,7 @@ const static struct pci_device_id pciidlist[] = {
151 INTEL_VGA_DEVICE(0x3577, &intel_i830_info), 152 INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
152 INTEL_VGA_DEVICE(0x2562, &intel_845g_info), 153 INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
153 INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), 154 INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
154 INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info), 155 INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
155 INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), 156 INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
156 INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), 157 INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
157 INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), 158 INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6960849522f8..6e4790065d9e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -195,6 +195,7 @@ struct intel_overlay;
195struct intel_device_info { 195struct intel_device_info {
196 u8 is_mobile : 1; 196 u8 is_mobile : 1;
197 u8 is_i8xx : 1; 197 u8 is_i8xx : 1;
198 u8 is_i85x : 1;
198 u8 is_i915g : 1; 199 u8 is_i915g : 1;
199 u8 is_i9xx : 1; 200 u8 is_i9xx : 1;
200 u8 is_i945gm : 1; 201 u8 is_i945gm : 1;
@@ -235,11 +236,14 @@ typedef struct drm_i915_private {
235 236
236 drm_dma_handle_t *status_page_dmah; 237 drm_dma_handle_t *status_page_dmah;
237 void *hw_status_page; 238 void *hw_status_page;
239 void *seqno_page;
238 dma_addr_t dma_status_page; 240 dma_addr_t dma_status_page;
239 uint32_t counter; 241 uint32_t counter;
240 unsigned int status_gfx_addr; 242 unsigned int status_gfx_addr;
243 unsigned int seqno_gfx_addr;
241 drm_local_map_t hws_map; 244 drm_local_map_t hws_map;
242 struct drm_gem_object *hws_obj; 245 struct drm_gem_object *hws_obj;
246 struct drm_gem_object *seqno_obj;
243 struct drm_gem_object *pwrctx; 247 struct drm_gem_object *pwrctx;
244 248
245 struct resource mch_res; 249 struct resource mch_res;
@@ -630,6 +634,9 @@ typedef struct drm_i915_private {
630 u8 max_delay; 634 u8 max_delay;
631 635
632 enum no_fbc_reason no_fbc_reason; 636 enum no_fbc_reason no_fbc_reason;
637
638 struct drm_mm_node *compressed_fb;
639 struct drm_mm_node *compressed_llb;
633} drm_i915_private_t; 640} drm_i915_private_t;
634 641
635/** driver private structure attached to each drm_gem_object */ 642/** driver private structure attached to each drm_gem_object */
@@ -1070,7 +1077,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1070 1077
1071#define IS_I830(dev) ((dev)->pci_device == 0x3577) 1078#define IS_I830(dev) ((dev)->pci_device == 0x3577)
1072#define IS_845G(dev) ((dev)->pci_device == 0x2562) 1079#define IS_845G(dev) ((dev)->pci_device == 0x2562)
1073#define IS_I85X(dev) ((dev)->pci_device == 0x3582) 1080#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x)
1074#define IS_I865G(dev) ((dev)->pci_device == 0x2572) 1081#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
1075#define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) 1082#define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx)
1076#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) 1083#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g)
@@ -1135,6 +1142,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1135 1142
1136#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \ 1143#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \
1137 IS_GEN6(dev)) 1144 IS_GEN6(dev))
1145#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
1138 1146
1139#define PRIMARY_RINGBUFFER_SIZE (128*1024) 1147#define PRIMARY_RINGBUFFER_SIZE (128*1024)
1140 1148
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 80871c62a571..7f52cc124cfe 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1588,6 +1588,13 @@ i915_gem_process_flushing_list(struct drm_device *dev,
1588 } 1588 }
1589} 1589}
1590 1590
1591#define PIPE_CONTROL_FLUSH(addr) \
1592 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \
1593 PIPE_CONTROL_DEPTH_STALL); \
1594 OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \
1595 OUT_RING(0); \
1596 OUT_RING(0); \
1597
1591/** 1598/**
1592 * Creates a new sequence number, emitting a write of it to the status page 1599 * Creates a new sequence number, emitting a write of it to the status page
1593 * plus an interrupt, which will trigger i915_user_interrupt_handler. 1600 * plus an interrupt, which will trigger i915_user_interrupt_handler.
@@ -1622,13 +1629,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1622 if (dev_priv->mm.next_gem_seqno == 0) 1629 if (dev_priv->mm.next_gem_seqno == 0)
1623 dev_priv->mm.next_gem_seqno++; 1630 dev_priv->mm.next_gem_seqno++;
1624 1631
1625 BEGIN_LP_RING(4); 1632 if (HAS_PIPE_CONTROL(dev)) {
1626 OUT_RING(MI_STORE_DWORD_INDEX); 1633 u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
1627 OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
1628 OUT_RING(seqno);
1629 1634
1630 OUT_RING(MI_USER_INTERRUPT); 1635 /*
1631 ADVANCE_LP_RING(); 1636 * Workaround qword write incoherence by flushing the
1637 * PIPE_NOTIFY buffers out to memory before requesting
1638 * an interrupt.
1639 */
1640 BEGIN_LP_RING(32);
1641 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
1642 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
1643 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
1644 OUT_RING(seqno);
1645 OUT_RING(0);
1646 PIPE_CONTROL_FLUSH(scratch_addr);
1647 scratch_addr += 128; /* write to separate cachelines */
1648 PIPE_CONTROL_FLUSH(scratch_addr);
1649 scratch_addr += 128;
1650 PIPE_CONTROL_FLUSH(scratch_addr);
1651 scratch_addr += 128;
1652 PIPE_CONTROL_FLUSH(scratch_addr);
1653 scratch_addr += 128;
1654 PIPE_CONTROL_FLUSH(scratch_addr);
1655 scratch_addr += 128;
1656 PIPE_CONTROL_FLUSH(scratch_addr);
1657 OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
1658 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
1659 PIPE_CONTROL_NOTIFY);
1660 OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
1661 OUT_RING(seqno);
1662 OUT_RING(0);
1663 ADVANCE_LP_RING();
1664 } else {
1665 BEGIN_LP_RING(4);
1666 OUT_RING(MI_STORE_DWORD_INDEX);
1667 OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
1668 OUT_RING(seqno);
1669
1670 OUT_RING(MI_USER_INTERRUPT);
1671 ADVANCE_LP_RING();
1672 }
1632 1673
1633 DRM_DEBUG_DRIVER("%d\n", seqno); 1674 DRM_DEBUG_DRIVER("%d\n", seqno);
1634 1675
@@ -1752,7 +1793,10 @@ i915_get_gem_seqno(struct drm_device *dev)
1752{ 1793{
1753 drm_i915_private_t *dev_priv = dev->dev_private; 1794 drm_i915_private_t *dev_priv = dev->dev_private;
1754 1795
1755 return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); 1796 if (IS_I965G(dev))
1797 return ((volatile u32 *)(dev_priv->seqno_page))[0];
1798 else
1799 return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
1756} 1800}
1757 1801
1758/** 1802/**
@@ -2362,6 +2406,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
2362 pitch_val = obj_priv->stride / tile_width; 2406 pitch_val = obj_priv->stride / tile_width;
2363 pitch_val = ffs(pitch_val) - 1; 2407 pitch_val = ffs(pitch_val) - 1;
2364 2408
2409 if (obj_priv->tiling_mode == I915_TILING_Y &&
2410 HAS_128_BYTE_Y_TILING(dev))
2411 WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL);
2412 else
2413 WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL);
2414
2365 val = obj_priv->gtt_offset; 2415 val = obj_priv->gtt_offset;
2366 if (obj_priv->tiling_mode == I915_TILING_Y) 2416 if (obj_priv->tiling_mode == I915_TILING_Y)
2367 val |= 1 << I830_FENCE_TILING_Y_SHIFT; 2417 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
@@ -4546,6 +4596,49 @@ i915_gem_idle(struct drm_device *dev)
4546 return 0; 4596 return 0;
4547} 4597}
4548 4598
4599/*
4600 * 965+ support PIPE_CONTROL commands, which provide finer grained control
4601 * over cache flushing.
4602 */
4603static int
4604i915_gem_init_pipe_control(struct drm_device *dev)
4605{
4606 drm_i915_private_t *dev_priv = dev->dev_private;
4607 struct drm_gem_object *obj;
4608 struct drm_i915_gem_object *obj_priv;
4609 int ret;
4610
4611 obj = drm_gem_object_alloc(dev, 4096);
4612 if (obj == NULL) {
4613 DRM_ERROR("Failed to allocate seqno page\n");
4614 ret = -ENOMEM;
4615 goto err;
4616 }
4617 obj_priv = to_intel_bo(obj);
4618 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
4619
4620 ret = i915_gem_object_pin(obj, 4096);
4621 if (ret)
4622 goto err_unref;
4623
4624 dev_priv->seqno_gfx_addr = obj_priv->gtt_offset;
4625 dev_priv->seqno_page = kmap(obj_priv->pages[0]);
4626 if (dev_priv->seqno_page == NULL)
4627 goto err_unpin;
4628
4629 dev_priv->seqno_obj = obj;
4630 memset(dev_priv->seqno_page, 0, PAGE_SIZE);
4631
4632 return 0;
4633
4634err_unpin:
4635 i915_gem_object_unpin(obj);
4636err_unref:
4637 drm_gem_object_unreference(obj);
4638err:
4639 return ret;
4640}
4641
4549static int 4642static int
4550i915_gem_init_hws(struct drm_device *dev) 4643i915_gem_init_hws(struct drm_device *dev)
4551{ 4644{
@@ -4563,7 +4656,8 @@ i915_gem_init_hws(struct drm_device *dev)
4563 obj = drm_gem_object_alloc(dev, 4096); 4656 obj = drm_gem_object_alloc(dev, 4096);
4564 if (obj == NULL) { 4657 if (obj == NULL) {
4565 DRM_ERROR("Failed to allocate status page\n"); 4658 DRM_ERROR("Failed to allocate status page\n");
4566 return -ENOMEM; 4659 ret = -ENOMEM;
4660 goto err;
4567 } 4661 }
4568 obj_priv = to_intel_bo(obj); 4662 obj_priv = to_intel_bo(obj);
4569 obj_priv->agp_type = AGP_USER_CACHED_MEMORY; 4663 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
@@ -4571,7 +4665,7 @@ i915_gem_init_hws(struct drm_device *dev)
4571 ret = i915_gem_object_pin(obj, 4096); 4665 ret = i915_gem_object_pin(obj, 4096);
4572 if (ret != 0) { 4666 if (ret != 0) {
4573 drm_gem_object_unreference(obj); 4667 drm_gem_object_unreference(obj);
4574 return ret; 4668 goto err_unref;
4575 } 4669 }
4576 4670
4577 dev_priv->status_gfx_addr = obj_priv->gtt_offset; 4671 dev_priv->status_gfx_addr = obj_priv->gtt_offset;
@@ -4580,10 +4674,16 @@ i915_gem_init_hws(struct drm_device *dev)
4580 if (dev_priv->hw_status_page == NULL) { 4674 if (dev_priv->hw_status_page == NULL) {
4581 DRM_ERROR("Failed to map status page.\n"); 4675 DRM_ERROR("Failed to map status page.\n");
4582 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); 4676 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
4583 i915_gem_object_unpin(obj); 4677 ret = -EINVAL;
4584 drm_gem_object_unreference(obj); 4678 goto err_unpin;
4585 return -EINVAL;
4586 } 4679 }
4680
4681 if (HAS_PIPE_CONTROL(dev)) {
4682 ret = i915_gem_init_pipe_control(dev);
4683 if (ret)
4684 goto err_unpin;
4685 }
4686
4587 dev_priv->hws_obj = obj; 4687 dev_priv->hws_obj = obj;
4588 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 4688 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
4589 if (IS_GEN6(dev)) { 4689 if (IS_GEN6(dev)) {
@@ -4596,6 +4696,30 @@ i915_gem_init_hws(struct drm_device *dev)
4596 DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); 4696 DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
4597 4697
4598 return 0; 4698 return 0;
4699
4700err_unpin:
4701 i915_gem_object_unpin(obj);
4702err_unref:
4703 drm_gem_object_unreference(obj);
4704err:
4705 return 0;
4706}
4707
4708static void
4709i915_gem_cleanup_pipe_control(struct drm_device *dev)
4710{
4711 drm_i915_private_t *dev_priv = dev->dev_private;
4712 struct drm_gem_object *obj;
4713 struct drm_i915_gem_object *obj_priv;
4714
4715 obj = dev_priv->seqno_obj;
4716 obj_priv = to_intel_bo(obj);
4717 kunmap(obj_priv->pages[0]);
4718 i915_gem_object_unpin(obj);
4719 drm_gem_object_unreference(obj);
4720 dev_priv->seqno_obj = NULL;
4721
4722 dev_priv->seqno_page = NULL;
4599} 4723}
4600 4724
4601static void 4725static void
@@ -4619,6 +4743,9 @@ i915_gem_cleanup_hws(struct drm_device *dev)
4619 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); 4743 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
4620 dev_priv->hw_status_page = NULL; 4744 dev_priv->hw_status_page = NULL;
4621 4745
4746 if (HAS_PIPE_CONTROL(dev))
4747 i915_gem_cleanup_pipe_control(dev);
4748
4622 /* Write high address into HWS_PGA when disabling. */ 4749 /* Write high address into HWS_PGA when disabling. */
4623 I915_WRITE(HWS_PGA, 0x1ffff000); 4750 I915_WRITE(HWS_PGA, 0x1ffff000);
4624} 4751}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 449157f71610..4bdccefcf2cf 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
202 * reg, so dont bother to check the size */ 202 * reg, so dont bother to check the size */
203 if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) 203 if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
204 return false; 204 return false;
205 } else if (IS_I9XX(dev)) { 205 } else if (IS_GEN3(dev) || IS_GEN2(dev)) {
206 uint32_t pitch_val = ffs(stride / tile_width) - 1; 206 if (stride > 8192)
207
208 /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
209 * instead of 4 (2KB) on 945s.
210 */
211 if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
212 size > (I830_FENCE_MAX_SIZE_VAL << 20))
213 return false; 207 return false;
214 } else {
215 uint32_t pitch_val = ffs(stride / tile_width) - 1;
216 208
217 if (pitch_val > I830_FENCE_MAX_PITCH_VAL || 209 if (IS_GEN3(dev)) {
218 size > (I830_FENCE_MAX_SIZE_VAL << 19)) 210 if (size > I830_FENCE_MAX_SIZE_VAL << 20)
219 return false; 211 return false;
212 } else {
213 if (size > I830_FENCE_MAX_SIZE_VAL << 19)
214 return false;
215 }
220 } 216 }
221 217
222 /* 965+ just needs multiples of tile width */ 218 /* 965+ just needs multiples of tile width */
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 6421481d6222..2b8b969d0c15 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -349,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
349 READ_BREADCRUMB(dev_priv); 349 READ_BREADCRUMB(dev_priv);
350 } 350 }
351 351
352 if (gt_iir & GT_USER_INTERRUPT) { 352 if (gt_iir & GT_PIPE_NOTIFY) {
353 u32 seqno = i915_get_gem_seqno(dev); 353 u32 seqno = i915_get_gem_seqno(dev);
354 dev_priv->mm.irq_gem_seqno = seqno; 354 dev_priv->mm.irq_gem_seqno = seqno;
355 trace_i915_gem_request_complete(dev, seqno); 355 trace_i915_gem_request_complete(dev, seqno);
@@ -1005,7 +1005,7 @@ void i915_user_irq_get(struct drm_device *dev)
1005 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 1005 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1006 if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { 1006 if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
1007 if (HAS_PCH_SPLIT(dev)) 1007 if (HAS_PCH_SPLIT(dev))
1008 ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); 1008 ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
1009 else 1009 else
1010 i915_enable_irq(dev_priv, I915_USER_INTERRUPT); 1010 i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
1011 } 1011 }
@@ -1021,7 +1021,7 @@ void i915_user_irq_put(struct drm_device *dev)
1021 BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); 1021 BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
1022 if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { 1022 if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
1023 if (HAS_PCH_SPLIT(dev)) 1023 if (HAS_PCH_SPLIT(dev))
1024 ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); 1024 ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
1025 else 1025 else
1026 i915_disable_irq(dev_priv, I915_USER_INTERRUPT); 1026 i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
1027 } 1027 }
@@ -1305,7 +1305,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1305 /* enable kind of interrupts always enabled */ 1305 /* enable kind of interrupts always enabled */
1306 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | 1306 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
1307 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; 1307 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
1308 u32 render_mask = GT_USER_INTERRUPT; 1308 u32 render_mask = GT_PIPE_NOTIFY;
1309 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | 1309 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
1310 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; 1310 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
1311 1311
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 7cc8410239cb..8fcc75c1aa28 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev)
382 struct drm_i915_private *dev_priv = dev->dev_private; 382 struct drm_i915_private *dev_priv = dev->dev_private;
383 struct intel_opregion *opregion = &dev_priv->opregion; 383 struct intel_opregion *opregion = &dev_priv->opregion;
384 struct drm_connector *connector; 384 struct drm_connector *connector;
385 acpi_handle handle;
386 struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
387 unsigned long long device_id;
388 acpi_status status;
385 int i = 0; 389 int i = 0;
386 390
391 handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
392 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev)))
393 return;
394
395 if (acpi_is_video_device(acpi_dev))
396 acpi_video_bus = acpi_dev;
397 else {
398 list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
399 if (acpi_is_video_device(acpi_cdev)) {
400 acpi_video_bus = acpi_cdev;
401 break;
402 }
403 }
404 }
405
406 if (!acpi_video_bus) {
407 printk(KERN_WARNING "No ACPI video bus found\n");
408 return;
409 }
410
411 list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
412 if (i >= 8) {
413 dev_printk (KERN_ERR, &dev->pdev->dev,
414 "More than 8 outputs detected\n");
415 return;
416 }
417 status =
418 acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
419 NULL, &device_id);
420 if (ACPI_SUCCESS(status)) {
421 if (!device_id)
422 goto blind_set;
423 opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f);
424 i++;
425 }
426 }
427
428end:
429 /* If fewer than 8 outputs, the list must be null terminated */
430 if (i < 8)
431 opregion->acpi->didl[i] = 0;
432 return;
433
434blind_set:
435 i = 0;
387 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 436 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
388 int output_type = ACPI_OTHER_OUTPUT; 437 int output_type = ACPI_OTHER_OUTPUT;
389 if (i >= 8) { 438 if (i >= 8) {
@@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev)
416 opregion->acpi->didl[i] |= (1<<31) | output_type | i; 465 opregion->acpi->didl[i] |= (1<<31) | output_type | i;
417 i++; 466 i++;
418 } 467 }
419 468 goto end;
420 /* If fewer than 8 outputs, the list must be null terminated */
421 if (i < 8)
422 opregion->acpi->didl[i] = 0;
423} 469}
424 470
425int intel_opregion_init(struct drm_device *dev, int resume) 471int intel_opregion_init(struct drm_device *dev, int resume)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index cbbf59f56dfa..4cbc5210fd30 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -230,6 +230,16 @@
230#define ASYNC_FLIP (1<<22) 230#define ASYNC_FLIP (1<<22)
231#define DISPLAY_PLANE_A (0<<20) 231#define DISPLAY_PLANE_A (0<<20)
232#define DISPLAY_PLANE_B (1<<20) 232#define DISPLAY_PLANE_B (1<<20)
233#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
234#define PIPE_CONTROL_QW_WRITE (1<<14)
235#define PIPE_CONTROL_DEPTH_STALL (1<<13)
236#define PIPE_CONTROL_WC_FLUSH (1<<12)
237#define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */
238#define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */
239#define PIPE_CONTROL_ISP_DIS (1<<9)
240#define PIPE_CONTROL_NOTIFY (1<<8)
241#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
242#define PIPE_CONTROL_STALL_EN (1<<1) /* in addr word, Ironlake+ only */
233 243
234/* 244/*
235 * Fence registers 245 * Fence registers
@@ -241,7 +251,7 @@
241#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) 251#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
242#define I830_FENCE_PITCH_SHIFT 4 252#define I830_FENCE_PITCH_SHIFT 4
243#define I830_FENCE_REG_VALID (1<<0) 253#define I830_FENCE_REG_VALID (1<<0)
244#define I915_FENCE_MAX_PITCH_VAL 0x10 254#define I915_FENCE_MAX_PITCH_VAL 4
245#define I830_FENCE_MAX_PITCH_VAL 6 255#define I830_FENCE_MAX_PITCH_VAL 6
246#define I830_FENCE_MAX_SIZE_VAL (1<<8) 256#define I830_FENCE_MAX_SIZE_VAL (1<<8)
247 257
@@ -2285,6 +2295,7 @@
2285#define DEIER 0x4400c 2295#define DEIER 0x4400c
2286 2296
2287/* GT interrupt */ 2297/* GT interrupt */
2298#define GT_PIPE_NOTIFY (1 << 4)
2288#define GT_SYNC_STATUS (1 << 2) 2299#define GT_SYNC_STATUS (1 << 2)
2289#define GT_USER_INTERRUPT (1 << 0) 2300#define GT_USER_INTERRUPT (1 << 0)
2290 2301
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e7356fb6c918..c7502b6b1600 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4853,17 +4853,18 @@ static void intel_init_display(struct drm_device *dev)
4853 dev_priv->display.update_wm = g4x_update_wm; 4853 dev_priv->display.update_wm = g4x_update_wm;
4854 else if (IS_I965G(dev)) 4854 else if (IS_I965G(dev))
4855 dev_priv->display.update_wm = i965_update_wm; 4855 dev_priv->display.update_wm = i965_update_wm;
4856 else if (IS_I9XX(dev) || IS_MOBILE(dev)) { 4856 else if (IS_I9XX(dev)) {
4857 dev_priv->display.update_wm = i9xx_update_wm; 4857 dev_priv->display.update_wm = i9xx_update_wm;
4858 dev_priv->display.get_fifo_size = i9xx_get_fifo_size; 4858 dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
4859 } else if (IS_I85X(dev)) {
4860 dev_priv->display.update_wm = i9xx_update_wm;
4861 dev_priv->display.get_fifo_size = i85x_get_fifo_size;
4859 } else { 4862 } else {
4860 if (IS_I85X(dev)) 4863 dev_priv->display.update_wm = i830_update_wm;
4861 dev_priv->display.get_fifo_size = i85x_get_fifo_size; 4864 if (IS_845G(dev))
4862 else if (IS_845G(dev))
4863 dev_priv->display.get_fifo_size = i845_get_fifo_size; 4865 dev_priv->display.get_fifo_size = i845_get_fifo_size;
4864 else 4866 else
4865 dev_priv->display.get_fifo_size = i830_get_fifo_size; 4867 dev_priv->display.get_fifo_size = i830_get_fifo_size;
4866 dev_priv->display.update_wm = i830_update_wm;
4867 } 4868 }
4868} 4869}
4869 4870