aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-05-07 17:30:03 -0400
committerEric Anholt <eric@anholt.net>2010-05-10 16:36:52 -0400
commit34dc4d4423dc342848d72be764832cbc0852854a (patch)
tree056402a4afc2b7ef2f4dee30a712ce847279c13a /drivers/gpu/drm
parent3d8620cc5f8538364ee152811e2bd8713abb1d58 (diff)
parent722154e4cacf015161efe60009ae9be23d492296 (diff)
Merge remote branch 'origin/master' into drm-intel-next
Conflicts: drivers/gpu/drm/i915/i915_dma.c drivers/gpu/drm/i915/i915_drv.h drivers/gpu/drm/radeon/r300.c The BSD ringbuffer support that is landing in this branch significantly conflicts with the Ironlake PIPE_CONTROL fix on master, and requires it to be tested successfully anyway.
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/drm_irq.c1
-rw-r--r--drivers/gpu/drm/drm_memory.c2
-rw-r--r--drivers/gpu/drm/drm_stub.c4
-rw-r--r--drivers/gpu/drm/drm_sysfs.c21
-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
-rw-r--r--drivers/gpu/drm/radeon/atombios.h2
-rw-r--r--drivers/gpu/drm/radeon/r100.c2
-rw-r--r--drivers/gpu/drm/radeon/r100_track.h2
-rw-r--r--drivers/gpu/drm/radeon/r300.c7
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c2
-rw-r--r--drivers/gpu/drm/radeon/r420.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_agp.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c63
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
-rw-r--r--drivers/gpu/drm/via/via_video.c2
29 files changed, 352 insertions, 103 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 3bd872761567..a263b7070fc6 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -476,6 +476,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
476 unsigned long irqflags; 476 unsigned long irqflags;
477 477
478 spin_lock_irqsave(&dev->vbl_lock, irqflags); 478 spin_lock_irqsave(&dev->vbl_lock, irqflags);
479 dev->driver->disable_vblank(dev, crtc);
479 DRM_WAKEUP(&dev->vbl_queue[crtc]); 480 DRM_WAKEUP(&dev->vbl_queue[crtc]);
480 dev->vblank_enabled[crtc] = 0; 481 dev->vblank_enabled[crtc] = 0;
481 dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); 482 dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index e4865f99989c..7732268eced2 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -77,7 +77,7 @@ static void *agp_remap(unsigned long offset, unsigned long size,
77 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= 77 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
78 (offset + size)) 78 (offset + size))
79 break; 79 break;
80 if (!agpmem) 80 if (&agpmem->head == &dev->agp->memory)
81 return NULL; 81 return NULL;
82 82
83 /* 83 /*
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index b743411d8144..a0c365f2e521 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -516,8 +516,6 @@ void drm_put_dev(struct drm_device *dev)
516 } 516 }
517 driver = dev->driver; 517 driver = dev->driver;
518 518
519 drm_vblank_cleanup(dev);
520
521 drm_lastclose(dev); 519 drm_lastclose(dev);
522 520
523 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && 521 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
@@ -537,6 +535,8 @@ void drm_put_dev(struct drm_device *dev)
537 dev->agp = NULL; 535 dev->agp = NULL;
538 } 536 }
539 537
538 drm_vblank_cleanup(dev);
539
540 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) 540 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
541 drm_rmmap(dev, r_list->map); 541 drm_rmmap(dev, r_list->map);
542 drm_ht_remove(&dev->map_hash); 542 drm_ht_remove(&dev->map_hash);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 49daf37e5043..3a3a451d0bf8 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -354,7 +354,10 @@ static struct bin_attribute edid_attr = {
354int drm_sysfs_connector_add(struct drm_connector *connector) 354int drm_sysfs_connector_add(struct drm_connector *connector)
355{ 355{
356 struct drm_device *dev = connector->dev; 356 struct drm_device *dev = connector->dev;
357 int ret = 0, i, j; 357 int attr_cnt = 0;
358 int opt_cnt = 0;
359 int i;
360 int ret = 0;
358 361
359 /* We shouldn't get called more than once for the same connector */ 362 /* We shouldn't get called more than once for the same connector */
360 BUG_ON(device_is_registered(&connector->kdev)); 363 BUG_ON(device_is_registered(&connector->kdev));
@@ -377,8 +380,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
377 380
378 /* Standard attributes */ 381 /* Standard attributes */
379 382
380 for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) { 383 for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) {
381 ret = device_create_file(&connector->kdev, &connector_attrs[i]); 384 ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]);
382 if (ret) 385 if (ret)
383 goto err_out_files; 386 goto err_out_files;
384 } 387 }
@@ -394,8 +397,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
394 case DRM_MODE_CONNECTOR_SVIDEO: 397 case DRM_MODE_CONNECTOR_SVIDEO:
395 case DRM_MODE_CONNECTOR_Component: 398 case DRM_MODE_CONNECTOR_Component:
396 case DRM_MODE_CONNECTOR_TV: 399 case DRM_MODE_CONNECTOR_TV:
397 for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) { 400 for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) {
398 ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]); 401 ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]);
399 if (ret) 402 if (ret)
400 goto err_out_files; 403 goto err_out_files;
401 } 404 }
@@ -414,10 +417,10 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
414 return 0; 417 return 0;
415 418
416err_out_files: 419err_out_files:
417 if (i > 0) 420 for (i = 0; i < opt_cnt; i++)
418 for (j = 0; j < i; j++) 421 device_remove_file(&connector->kdev, &connector_attrs_opt1[i]);
419 device_remove_file(&connector->kdev, 422 for (i = 0; i < attr_cnt; i++)
420 &connector_attrs[i]); 423 device_remove_file(&connector->kdev, &connector_attrs[i]);
421 device_unregister(&connector->kdev); 424 device_unregister(&connector->kdev);
422 425
423out: 426out:
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index bf7d601fc37d..851a2f8ed6e6 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1358,17 +1358,29 @@ static void i915_setup_compression(struct drm_device *dev, int size)
1358 dev_priv->cfb_size = size; 1358 dev_priv->cfb_size = size;
1359 1359
1360 intel_disable_fbc(dev); 1360 intel_disable_fbc(dev);
1361 dev_priv->compressed_fb = compressed_fb;
1362
1361 if (IS_GM45(dev)) { 1363 if (IS_GM45(dev)) {
1362 I915_WRITE(DPFC_CB_BASE, compressed_fb->start); 1364 I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
1363 } else { 1365 } else {
1364 I915_WRITE(FBC_CFB_BASE, cfb_base); 1366 I915_WRITE(FBC_CFB_BASE, cfb_base);
1365 I915_WRITE(FBC_LL_BASE, ll_base); 1367 I915_WRITE(FBC_LL_BASE, ll_base);
1368 dev_priv->compressed_llb = compressed_llb;
1366 } 1369 }
1367 1370
1368 DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, 1371 DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
1369 ll_base, size >> 20); 1372 ll_base, size >> 20);
1370} 1373}
1371 1374
1375static void i915_cleanup_compression(struct drm_device *dev)
1376{
1377 struct drm_i915_private *dev_priv = dev->dev_private;
1378
1379 drm_mm_put_block(dev_priv->compressed_fb);
1380 if (!IS_GM45(dev))
1381 drm_mm_put_block(dev_priv->compressed_llb);
1382}
1383
1372/* true = enable decode, false = disable decoder */ 1384/* true = enable decode, false = disable decoder */
1373static unsigned int i915_vga_set_decode(void *cookie, bool state) 1385static unsigned int i915_vga_set_decode(void *cookie, bool state)
1374{ 1386{
@@ -1788,6 +1800,8 @@ int i915_driver_unload(struct drm_device *dev)
1788 mutex_lock(&dev->struct_mutex); 1800 mutex_lock(&dev->struct_mutex);
1789 i915_gem_cleanup_ringbuffer(dev); 1801 i915_gem_cleanup_ringbuffer(dev);
1790 mutex_unlock(&dev->struct_mutex); 1802 mutex_unlock(&dev->struct_mutex);
1803 if (I915_HAS_FBC(dev) && i915_powersave)
1804 i915_cleanup_compression(dev);
1791 drm_mm_takedown(&dev_priv->vram); 1805 drm_mm_takedown(&dev_priv->vram);
1792 i915_gem_lastclose(dev); 1806 i915_gem_lastclose(dev);
1793 1807
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 01e91ea5bdea..5c51e45ab68d 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 c06d203b709b..bf11ad9998db 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;
@@ -242,11 +243,14 @@ typedef struct drm_i915_private {
242 243
243 drm_dma_handle_t *status_page_dmah; 244 drm_dma_handle_t *status_page_dmah;
244 void *hw_status_page; 245 void *hw_status_page;
246 void *seqno_page;
245 dma_addr_t dma_status_page; 247 dma_addr_t dma_status_page;
246 uint32_t counter; 248 uint32_t counter;
247 unsigned int status_gfx_addr; 249 unsigned int status_gfx_addr;
250 unsigned int seqno_gfx_addr;
248 drm_local_map_t hws_map; 251 drm_local_map_t hws_map;
249 struct drm_gem_object *hws_obj; 252 struct drm_gem_object *hws_obj;
253 struct drm_gem_object *seqno_obj;
250 struct drm_gem_object *pwrctx; 254 struct drm_gem_object *pwrctx;
251 255
252 struct resource mch_res; 256 struct resource mch_res;
@@ -641,6 +645,9 @@ typedef struct drm_i915_private {
641 645
642 enum no_fbc_reason no_fbc_reason; 646 enum no_fbc_reason no_fbc_reason;
643 647
648 struct drm_mm_node *compressed_fb;
649 struct drm_mm_node *compressed_llb;
650
644 /* list of fbdev register on this device */ 651 /* list of fbdev register on this device */
645 struct intel_fbdev *fbdev; 652 struct intel_fbdev *fbdev;
646} drm_i915_private_t; 653} drm_i915_private_t;
@@ -1091,7 +1098,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1091 1098
1092#define IS_I830(dev) ((dev)->pci_device == 0x3577) 1099#define IS_I830(dev) ((dev)->pci_device == 0x3577)
1093#define IS_845G(dev) ((dev)->pci_device == 0x2562) 1100#define IS_845G(dev) ((dev)->pci_device == 0x2562)
1094#define IS_I85X(dev) ((dev)->pci_device == 0x3582) 1101#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x)
1095#define IS_I865G(dev) ((dev)->pci_device == 0x2572) 1102#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
1096#define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) 1103#define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx)
1097#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) 1104#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g)
@@ -1157,6 +1164,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1157 1164
1158#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \ 1165#define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \
1159 IS_GEN6(dev)) 1166 IS_GEN6(dev))
1167#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
1160 1168
1161#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) 1169#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
1162#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) 1170#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3471dece13e7..666d75570502 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 (HAS_PIPE_CONTROL(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;
@@ -4554,6 +4604,49 @@ i915_gem_idle(struct drm_device *dev)
4554 return 0; 4604 return 0;
4555} 4605}
4556 4606
4607/*
4608 * 965+ support PIPE_CONTROL commands, which provide finer grained control
4609 * over cache flushing.
4610 */
4611static int
4612i915_gem_init_pipe_control(struct drm_device *dev)
4613{
4614 drm_i915_private_t *dev_priv = dev->dev_private;
4615 struct drm_gem_object *obj;
4616 struct drm_i915_gem_object *obj_priv;
4617 int ret;
4618
4619 obj = i915_gem_alloc_object(dev, 4096);
4620 if (obj == NULL) {
4621 DRM_ERROR("Failed to allocate seqno page\n");
4622 ret = -ENOMEM;
4623 goto err;
4624 }
4625 obj_priv = to_intel_bo(obj);
4626 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
4627
4628 ret = i915_gem_object_pin(obj, 4096);
4629 if (ret)
4630 goto err_unref;
4631
4632 dev_priv->seqno_gfx_addr = obj_priv->gtt_offset;
4633 dev_priv->seqno_page = kmap(obj_priv->pages[0]);
4634 if (dev_priv->seqno_page == NULL)
4635 goto err_unpin;
4636
4637 dev_priv->seqno_obj = obj;
4638 memset(dev_priv->seqno_page, 0, PAGE_SIZE);
4639
4640 return 0;
4641
4642err_unpin:
4643 i915_gem_object_unpin(obj);
4644err_unref:
4645 drm_gem_object_unreference(obj);
4646err:
4647 return ret;
4648}
4649
4557static int 4650static int
4558i915_gem_init_hws(struct drm_device *dev) 4651i915_gem_init_hws(struct drm_device *dev)
4559{ 4652{
@@ -4571,7 +4664,8 @@ i915_gem_init_hws(struct drm_device *dev)
4571 obj = i915_gem_alloc_object(dev, 4096); 4664 obj = i915_gem_alloc_object(dev, 4096);
4572 if (obj == NULL) { 4665 if (obj == NULL) {
4573 DRM_ERROR("Failed to allocate status page\n"); 4666 DRM_ERROR("Failed to allocate status page\n");
4574 return -ENOMEM; 4667 ret = -ENOMEM;
4668 goto err;
4575 } 4669 }
4576 obj_priv = to_intel_bo(obj); 4670 obj_priv = to_intel_bo(obj);
4577 obj_priv->agp_type = AGP_USER_CACHED_MEMORY; 4671 obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
@@ -4579,7 +4673,7 @@ i915_gem_init_hws(struct drm_device *dev)
4579 ret = i915_gem_object_pin(obj, 4096); 4673 ret = i915_gem_object_pin(obj, 4096);
4580 if (ret != 0) { 4674 if (ret != 0) {
4581 drm_gem_object_unreference(obj); 4675 drm_gem_object_unreference(obj);
4582 return ret; 4676 goto err_unref;
4583 } 4677 }
4584 4678
4585 dev_priv->status_gfx_addr = obj_priv->gtt_offset; 4679 dev_priv->status_gfx_addr = obj_priv->gtt_offset;
@@ -4588,10 +4682,16 @@ i915_gem_init_hws(struct drm_device *dev)
4588 if (dev_priv->hw_status_page == NULL) { 4682 if (dev_priv->hw_status_page == NULL) {
4589 DRM_ERROR("Failed to map status page.\n"); 4683 DRM_ERROR("Failed to map status page.\n");
4590 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); 4684 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
4591 i915_gem_object_unpin(obj); 4685 ret = -EINVAL;
4592 drm_gem_object_unreference(obj); 4686 goto err_unpin;
4593 return -EINVAL;
4594 } 4687 }
4688
4689 if (HAS_PIPE_CONTROL(dev)) {
4690 ret = i915_gem_init_pipe_control(dev);
4691 if (ret)
4692 goto err_unpin;
4693 }
4694
4595 dev_priv->hws_obj = obj; 4695 dev_priv->hws_obj = obj;
4596 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 4696 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
4597 if (IS_GEN6(dev)) { 4697 if (IS_GEN6(dev)) {
@@ -4604,6 +4704,30 @@ i915_gem_init_hws(struct drm_device *dev)
4604 DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); 4704 DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
4605 4705
4606 return 0; 4706 return 0;
4707
4708err_unpin:
4709 i915_gem_object_unpin(obj);
4710err_unref:
4711 drm_gem_object_unreference(obj);
4712err:
4713 return 0;
4714}
4715
4716static void
4717i915_gem_cleanup_pipe_control(struct drm_device *dev)
4718{
4719 drm_i915_private_t *dev_priv = dev->dev_private;
4720 struct drm_gem_object *obj;
4721 struct drm_i915_gem_object *obj_priv;
4722
4723 obj = dev_priv->seqno_obj;
4724 obj_priv = to_intel_bo(obj);
4725 kunmap(obj_priv->pages[0]);
4726 i915_gem_object_unpin(obj);
4727 drm_gem_object_unreference(obj);
4728 dev_priv->seqno_obj = NULL;
4729
4730 dev_priv->seqno_page = NULL;
4607} 4731}
4608 4732
4609static void 4733static void
@@ -4627,6 +4751,9 @@ i915_gem_cleanup_hws(struct drm_device *dev)
4627 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); 4751 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
4628 dev_priv->hw_status_page = NULL; 4752 dev_priv->hw_status_page = NULL;
4629 4753
4754 if (HAS_PIPE_CONTROL(dev))
4755 i915_gem_cleanup_pipe_control(dev);
4756
4630 /* Write high address into HWS_PGA when disabling. */ 4757 /* Write high address into HWS_PGA when disabling. */
4631 I915_WRITE(HWS_PGA, 0x1ffff000); 4758 I915_WRITE(HWS_PGA, 0x1ffff000);
4632} 4759}
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 ed26b7b7376a..a7e4b1f27497 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -354,7 +354,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
354 READ_BREADCRUMB(dev_priv); 354 READ_BREADCRUMB(dev_priv);
355 } 355 }
356 356
357 if (gt_iir & GT_USER_INTERRUPT) { 357 if (gt_iir & GT_PIPE_NOTIFY) {
358 u32 seqno = i915_get_gem_seqno(dev); 358 u32 seqno = i915_get_gem_seqno(dev);
359 dev_priv->mm.irq_gem_seqno = seqno; 359 dev_priv->mm.irq_gem_seqno = seqno;
360 trace_i915_gem_request_complete(dev, seqno); 360 trace_i915_gem_request_complete(dev, seqno);
@@ -1011,7 +1011,7 @@ void i915_user_irq_get(struct drm_device *dev)
1011 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 1011 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1012 if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { 1012 if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
1013 if (HAS_PCH_SPLIT(dev)) 1013 if (HAS_PCH_SPLIT(dev))
1014 ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); 1014 ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
1015 else 1015 else
1016 i915_enable_irq(dev_priv, I915_USER_INTERRUPT); 1016 i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
1017 } 1017 }
@@ -1027,7 +1027,7 @@ void i915_user_irq_put(struct drm_device *dev)
1027 BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); 1027 BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
1028 if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { 1028 if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
1029 if (HAS_PCH_SPLIT(dev)) 1029 if (HAS_PCH_SPLIT(dev))
1030 ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); 1030 ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
1031 else 1031 else
1032 i915_disable_irq(dev_priv, I915_USER_INTERRUPT); 1032 i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
1033 } 1033 }
@@ -1311,7 +1311,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1311 /* enable kind of interrupts always enabled */ 1311 /* enable kind of interrupts always enabled */
1312 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | 1312 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
1313 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; 1313 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
1314 u32 render_mask = GT_USER_INTERRUPT; 1314 u32 render_mask = GT_PIPE_NOTIFY;
1315 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | 1315 u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
1316 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; 1316 SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
1317 1317
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 0bbbb7753950..f3e39cc46f0d 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
@@ -2342,6 +2352,7 @@
2342#define DEIER 0x4400c 2352#define DEIER 0x4400c
2343 2353
2344/* GT interrupt */ 2354/* GT interrupt */
2355#define GT_PIPE_NOTIFY (1 << 4)
2345#define GT_SYNC_STATUS (1 << 2) 2356#define GT_SYNC_STATUS (1 << 2)
2346#define GT_USER_INTERRUPT (1 << 0) 2357#define GT_USER_INTERRUPT (1 << 0)
2347 2358
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 84c1aca8637e..e775ce67be33 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5291,17 +5291,18 @@ static void intel_init_display(struct drm_device *dev)
5291 dev_priv->display.update_wm = g4x_update_wm; 5291 dev_priv->display.update_wm = g4x_update_wm;
5292 else if (IS_I965G(dev)) 5292 else if (IS_I965G(dev))
5293 dev_priv->display.update_wm = i965_update_wm; 5293 dev_priv->display.update_wm = i965_update_wm;
5294 else if (IS_I9XX(dev) || IS_MOBILE(dev)) { 5294 else if (IS_I9XX(dev)) {
5295 dev_priv->display.update_wm = i9xx_update_wm; 5295 dev_priv->display.update_wm = i9xx_update_wm;
5296 dev_priv->display.get_fifo_size = i9xx_get_fifo_size; 5296 dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
5297 } else if (IS_I85X(dev)) {
5298 dev_priv->display.update_wm = i9xx_update_wm;
5299 dev_priv->display.get_fifo_size = i85x_get_fifo_size;
5297 } else { 5300 } else {
5298 if (IS_I85X(dev)) 5301 dev_priv->display.update_wm = i830_update_wm;
5299 dev_priv->display.get_fifo_size = i85x_get_fifo_size; 5302 if (IS_845G(dev))
5300 else if (IS_845G(dev))
5301 dev_priv->display.get_fifo_size = i845_get_fifo_size; 5303 dev_priv->display.get_fifo_size = i845_get_fifo_size;
5302 else 5304 else
5303 dev_priv->display.get_fifo_size = i830_get_fifo_size; 5305 dev_priv->display.get_fifo_size = i830_get_fifo_size;
5304 dev_priv->display.update_wm = i830_update_wm;
5305 } 5306 }
5306} 5307}
5307 5308
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
index 26986c8e1f45..2ebcb979dd7e 100644
--- a/drivers/gpu/drm/radeon/atombios.h
+++ b/drivers/gpu/drm/radeon/atombios.h
@@ -2912,7 +2912,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2
2912 UCHAR ucTV_BootUpDefaultStandard; 2912 UCHAR ucTV_BootUpDefaultStandard;
2913 UCHAR ucExt_TV_ASIC_ID; 2913 UCHAR ucExt_TV_ASIC_ID;
2914 UCHAR ucExt_TV_ASIC_SlaveAddr; 2914 UCHAR ucExt_TV_ASIC_SlaveAddr;
2915 ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING]; 2915 ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING_V1_2];
2916}ATOM_ANALOG_TV_INFO_V1_2; 2916}ATOM_ANALOG_TV_INFO_V1_2;
2917 2917
2918typedef struct _ATOM_DPCD_INFO 2918typedef struct _ATOM_DPCD_INFO
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 9bdccb964999..4de41b0ad5ce 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3004,7 +3004,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
3004 3004
3005 for (i = 0; i < track->num_cb; i++) { 3005 for (i = 0; i < track->num_cb; i++) {
3006 if (track->cb[i].robj == NULL) { 3006 if (track->cb[i].robj == NULL) {
3007 if (!(track->fastfill || track->color_channel_mask || 3007 if (!(track->zb_cb_clear || track->color_channel_mask ||
3008 track->blend_read_enable)) { 3008 track->blend_read_enable)) {
3009 continue; 3009 continue;
3010 } 3010 }
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
index fadfe68de9cc..f47cdca1c004 100644
--- a/drivers/gpu/drm/radeon/r100_track.h
+++ b/drivers/gpu/drm/radeon/r100_track.h
@@ -75,7 +75,7 @@ struct r100_cs_track {
75 struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; 75 struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE];
76 bool z_enabled; 76 bool z_enabled;
77 bool separate_cube; 77 bool separate_cube;
78 bool fastfill; 78 bool zb_cb_clear;
79 bool blend_read_enable; 79 bool blend_read_enable;
80}; 80};
81 81
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 5d622cb39b33..6d9569e002f7 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -328,13 +328,12 @@ void r300_gpu_init(struct radeon_device *rdev)
328{ 328{
329 uint32_t gb_tile_config, tmp; 329 uint32_t gb_tile_config, tmp;
330 330
331 /* FIXME: rv380 one pipes ? */
332 if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || 331 if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
333 (rdev->family == CHIP_R350)) { 332 (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) {
334 /* r300,r350 */ 333 /* r300,r350 */
335 rdev->num_gb_pipes = 2; 334 rdev->num_gb_pipes = 2;
336 } else { 335 } else {
337 /* rv350,rv370,rv380,r300 AD */ 336 /* rv350,rv370,rv380,r300 AD, r350 AH */
338 rdev->num_gb_pipes = 1; 337 rdev->num_gb_pipes = 1;
339 } 338 }
340 rdev->num_z_pipes = 1; 339 rdev->num_z_pipes = 1;
@@ -1045,7 +1044,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1045 break; 1044 break;
1046 case 0x4d1c: 1045 case 0x4d1c:
1047 /* ZB_BW_CNTL */ 1046 /* ZB_BW_CNTL */
1048 track->fastfill = !!(idx_value & (1 << 2)); 1047 track->zb_cb_clear = !!(idx_value & (1 << 5));
1049 break; 1048 break;
1050 case 0x4e04: 1049 case 0x4e04:
1051 /* RB3D_BLENDCNTL */ 1050 /* RB3D_BLENDCNTL */
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index ea46d558e8f3..c5c2742e4140 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -921,7 +921,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
921 921
922 ptr_addr = drm_buffer_read_object(cmdbuf->buffer, 922 ptr_addr = drm_buffer_read_object(cmdbuf->buffer,
923 sizeof(stack_ptr_addr), &stack_ptr_addr); 923 sizeof(stack_ptr_addr), &stack_ptr_addr);
924 ref_age_base = (u32 *)(unsigned long)*ptr_addr; 924 ref_age_base = (u32 *)(unsigned long)get_unaligned(ptr_addr);
925 925
926 for (i=0; i < header.scratch.n_bufs; i++) { 926 for (i=0; i < header.scratch.n_bufs; i++) {
927 buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); 927 buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 3759d8384294..be092d243f84 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -59,6 +59,12 @@ void r420_pipes_init(struct radeon_device *rdev)
59 /* get max number of pipes */ 59 /* get max number of pipes */
60 gb_pipe_select = RREG32(0x402C); 60 gb_pipe_select = RREG32(0x402C);
61 num_pipes = ((gb_pipe_select >> 12) & 3) + 1; 61 num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
62
63 /* SE chips have 1 pipe */
64 if ((rdev->pdev->device == 0x5e4c) ||
65 (rdev->pdev->device == 0x5e4f))
66 num_pipes = 1;
67
62 rdev->num_gb_pipes = num_pipes; 68 rdev->num_gb_pipes = num_pipes;
63 tmp = 0; 69 tmp = 0;
64 switch (num_pipes) { 70 switch (num_pipes) {
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c
index c4457791dff1..28e473f1f56f 100644
--- a/drivers/gpu/drm/radeon/radeon_agp.c
+++ b/drivers/gpu/drm/radeon/radeon_agp.c
@@ -134,12 +134,10 @@ int radeon_agp_init(struct radeon_device *rdev)
134 int ret; 134 int ret;
135 135
136 /* Acquire AGP. */ 136 /* Acquire AGP. */
137 if (!rdev->ddev->agp->acquired) { 137 ret = drm_agp_acquire(rdev->ddev);
138 ret = drm_agp_acquire(rdev->ddev); 138 if (ret) {
139 if (ret) { 139 DRM_ERROR("Unable to acquire AGP: %d\n", ret);
140 DRM_ERROR("Unable to acquire AGP: %d\n", ret); 140 return ret;
141 return ret;
142 }
143 } 141 }
144 142
145 ret = drm_agp_info(rdev->ddev, &info); 143 ret = drm_agp_info(rdev->ddev, &info);
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 273019925e0b..1d05debdd604 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1264,7 +1264,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
1264 switch (crev) { 1264 switch (crev) {
1265 case 1: 1265 case 1:
1266 tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); 1266 tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
1267 if (index > MAX_SUPPORTED_TV_TIMING) 1267 if (index >= MAX_SUPPORTED_TV_TIMING)
1268 return false; 1268 return false;
1269 1269
1270 mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); 1270 mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
@@ -1302,7 +1302,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
1302 break; 1302 break;
1303 case 2: 1303 case 2:
1304 tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); 1304 tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
1305 if (index > MAX_SUPPORTED_TV_TIMING_V1_2) 1305 if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)
1306 return false; 1306 return false;
1307 1307
1308 dtd_timings = &tv_info_v1_2->aModeTimings[index]; 1308 dtd_timings = &tv_info_v1_2->aModeTimings[index];
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index c48934677adf..40a24c941f20 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1294,6 +1294,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
1294 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 1294 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
1295 if (!radeon_connector->ddc_bus) 1295 if (!radeon_connector->ddc_bus)
1296 goto failed; 1296 goto failed;
1297 }
1298 if (connector_type == DRM_MODE_CONNECTOR_DVII) {
1297 radeon_connector->dac_load_detect = true; 1299 radeon_connector->dac_load_detect = true;
1298 drm_connector_attach_property(&radeon_connector->base, 1300 drm_connector_attach_property(&radeon_connector->base,
1299 rdev->mode_info.load_detect_property, 1301 rdev->mode_info.load_detect_property,
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 419630dd2075..2f042a3c0e62 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -435,14 +435,19 @@ static void radeon_init_pipes(struct drm_device *dev)
435 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) { 435 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
436 gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT); 436 gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
437 dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; 437 dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
438 /* SE cards have 1 pipe */
439 if ((dev->pdev->device == 0x5e4c) ||
440 (dev->pdev->device == 0x5e4f))
441 dev_priv->num_gb_pipes = 1;
438 } else { 442 } else {
439 /* R3xx */ 443 /* R3xx */
440 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 && 444 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
441 dev->pdev->device != 0x4144) || 445 dev->pdev->device != 0x4144) ||
442 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) { 446 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 &&
447 dev->pdev->device != 0x4148)) {
443 dev_priv->num_gb_pipes = 2; 448 dev_priv->num_gb_pipes = 2;
444 } else { 449 } else {
445 /* RV3xx/R300 AD */ 450 /* RV3xx/R300 AD/R350 AH */
446 dev_priv->num_gb_pipes = 1; 451 dev_priv->num_gb_pipes = 1;
447 } 452 }
448 } 453 }
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 243c1c4bc836..ce5163ed1fa6 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -86,12 +86,12 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
86 WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff); 86 WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
87 WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); 87 WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
88 88
89 WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id); 89 WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
90 WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007); 90 WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
91 91
92 WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0); 92 WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
93 for (i = 0; i < 256; i++) { 93 for (i = 0; i < 256; i++) {
94 WREG32(EVERGREEN_DC_LUT_30_COLOR, 94 WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
95 (radeon_crtc->lut_r[i] << 20) | 95 (radeon_crtc->lut_r[i] << 20) |
96 (radeon_crtc->lut_g[i] << 10) | 96 (radeon_crtc->lut_g[i] << 10) |
97 (radeon_crtc->lut_b[i] << 0)); 97 (radeon_crtc->lut_b[i] << 0));
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 30293bec0801..c5ddaf58563a 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -254,6 +254,53 @@ radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder)
254 return dig_connector; 254 return dig_connector;
255} 255}
256 256
257void radeon_panel_mode_fixup(struct drm_encoder *encoder,
258 struct drm_display_mode *adjusted_mode)
259{
260 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
261 struct drm_device *dev = encoder->dev;
262 struct radeon_device *rdev = dev->dev_private;
263 struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
264 unsigned hblank = native_mode->htotal - native_mode->hdisplay;
265 unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
266 unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
267 unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
268 unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
269 unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
270
271 adjusted_mode->clock = native_mode->clock;
272 adjusted_mode->flags = native_mode->flags;
273
274 if (ASIC_IS_AVIVO(rdev)) {
275 adjusted_mode->hdisplay = native_mode->hdisplay;
276 adjusted_mode->vdisplay = native_mode->vdisplay;
277 }
278
279 adjusted_mode->htotal = native_mode->hdisplay + hblank;
280 adjusted_mode->hsync_start = native_mode->hdisplay + hover;
281 adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
282
283 adjusted_mode->vtotal = native_mode->vdisplay + vblank;
284 adjusted_mode->vsync_start = native_mode->vdisplay + vover;
285 adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
286
287 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
288
289 if (ASIC_IS_AVIVO(rdev)) {
290 adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
291 adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
292 }
293
294 adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
295 adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
296 adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
297
298 adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
299 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
300 adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
301
302}
303
257static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, 304static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
258 struct drm_display_mode *mode, 305 struct drm_display_mode *mode,
259 struct drm_display_mode *adjusted_mode) 306 struct drm_display_mode *adjusted_mode)
@@ -275,18 +322,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
275 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; 322 adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
276 323
277 /* get the native mode for LVDS */ 324 /* get the native mode for LVDS */
278 if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { 325 if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
279 struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 326 radeon_panel_mode_fixup(encoder, adjusted_mode);
280 int mode_id = adjusted_mode->base.id;
281 *adjusted_mode = *native_mode;
282 if (!ASIC_IS_AVIVO(rdev)) {
283 adjusted_mode->hdisplay = mode->hdisplay;
284 adjusted_mode->vdisplay = mode->vdisplay;
285 adjusted_mode->crtc_hdisplay = mode->hdisplay;
286 adjusted_mode->crtc_vdisplay = mode->vdisplay;
287 }
288 adjusted_mode->base.id = mode_id;
289 }
290 327
291 /* get the native mode for TV */ 328 /* get the native mode for TV */
292 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { 329 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
@@ -1326,7 +1363,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1326 1363
1327 radeon_encoder->pixel_clock = adjusted_mode->clock; 1364 radeon_encoder->pixel_clock = adjusted_mode->clock;
1328 1365
1329 if (ASIC_IS_AVIVO(rdev)) { 1366 if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
1330 if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) 1367 if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
1331 atombios_yuv_setup(encoder, true); 1368 atombios_yuv_setup(encoder, true);
1332 else 1369 else
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index d3657dcfdd26..c633319f98ed 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -165,7 +165,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
165{ 165{
166 struct radeon_device *rdev = dev->dev_private; 166 struct radeon_device *rdev = dev->dev_private;
167 167
168 if (crtc < 0 || crtc > 1) { 168 if (crtc < 0 || crtc >= rdev->num_crtc) {
169 DRM_ERROR("Invalid crtc %d\n", crtc); 169 DRM_ERROR("Invalid crtc %d\n", crtc);
170 return -EINVAL; 170 return -EINVAL;
171 } 171 }
@@ -177,7 +177,7 @@ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
177{ 177{
178 struct radeon_device *rdev = dev->dev_private; 178 struct radeon_device *rdev = dev->dev_private;
179 179
180 if (crtc < 0 || crtc > 1) { 180 if (crtc < 0 || crtc >= rdev->num_crtc) {
181 DRM_ERROR("Invalid crtc %d\n", crtc); 181 DRM_ERROR("Invalid crtc %d\n", crtc);
182 return -EINVAL; 182 return -EINVAL;
183 } 183 }
@@ -191,7 +191,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
191{ 191{
192 struct radeon_device *rdev = dev->dev_private; 192 struct radeon_device *rdev = dev->dev_private;
193 193
194 if (crtc < 0 || crtc > 1) { 194 if (crtc < 0 || crtc >= rdev->num_crtc) {
195 DRM_ERROR("Invalid crtc %d\n", crtc); 195 DRM_ERROR("Invalid crtc %d\n", crtc);
196 return; 196 return;
197 } 197 }
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 2441cca7d775..0274abe17ad9 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -228,16 +228,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
228 drm_mode_set_crtcinfo(adjusted_mode, 0); 228 drm_mode_set_crtcinfo(adjusted_mode, 0);
229 229
230 /* get the native mode for LVDS */ 230 /* get the native mode for LVDS */
231 if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { 231 if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
232 struct drm_display_mode *native_mode = &radeon_encoder->native_mode; 232 radeon_panel_mode_fixup(encoder, adjusted_mode);
233 int mode_id = adjusted_mode->base.id;
234 *adjusted_mode = *native_mode;
235 adjusted_mode->hdisplay = mode->hdisplay;
236 adjusted_mode->vdisplay = mode->vdisplay;
237 adjusted_mode->crtc_hdisplay = mode->hdisplay;
238 adjusted_mode->crtc_vdisplay = mode->vdisplay;
239 adjusted_mode->base.id = mode_id;
240 }
241 233
242 return true; 234 return true;
243} 235}
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index dd451c55c533..a2bc31465e4f 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -564,6 +564,8 @@ extern int radeon_static_clocks_init(struct drm_device *dev);
564bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, 564bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
565 struct drm_display_mode *mode, 565 struct drm_display_mode *mode,
566 struct drm_display_mode *adjusted_mode); 566 struct drm_display_mode *adjusted_mode);
567void radeon_panel_mode_fixup(struct drm_encoder *encoder,
568 struct drm_display_mode *adjusted_mode);
567void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); 569void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
568 570
569/* legacy tv */ 571/* legacy tv */
diff --git a/drivers/gpu/drm/via/via_video.c b/drivers/gpu/drm/via/via_video.c
index 6ec04ac12459..6efac8117c93 100644
--- a/drivers/gpu/drm/via/via_video.c
+++ b/drivers/gpu/drm/via/via_video.c
@@ -75,7 +75,7 @@ int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_
75 75
76 DRM_DEBUG("\n"); 76 DRM_DEBUG("\n");
77 77
78 if (fx->lock > VIA_NR_XVMC_LOCKS) 78 if (fx->lock >= VIA_NR_XVMC_LOCKS)
79 return -EFAULT; 79 return -EFAULT;
80 80
81 lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock); 81 lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);