diff options
Diffstat (limited to 'drivers/gpu')
33 files changed, 374 insertions, 147 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_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 1a1825b29f5f..25bbd30ed7af 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 = { | |||
354 | int drm_sysfs_connector_add(struct drm_connector *connector) | 354 | int 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 | ||
416 | err_out_files: | 419 | err_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 | ||
423 | out: | 426 | out: |
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 | ||
1376 | static 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 */ |
1374 | static unsigned int i915_vga_set_decode(void *cookie, bool state) | 1386 | static 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 | ||
71 | const static struct intel_device_info intel_i85x_info = { | 71 | const 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 | ||
75 | const static struct intel_device_info intel_i865g_info = { | 76 | const 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; | |||
195 | struct intel_device_info { | 195 | struct 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..ef3d91dda71a 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; |
@@ -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 | */ | ||
4603 | static int | ||
4604 | i915_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 | |||
4634 | err_unpin: | ||
4635 | i915_gem_object_unpin(obj); | ||
4636 | err_unref: | ||
4637 | drm_gem_object_unreference(obj); | ||
4638 | err: | ||
4639 | return ret; | ||
4640 | } | ||
4641 | |||
4549 | static int | 4642 | static int |
4550 | i915_gem_init_hws(struct drm_device *dev) | 4643 | i915_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 | |||
4700 | err_unpin: | ||
4701 | i915_gem_object_unpin(obj); | ||
4702 | err_unref: | ||
4703 | drm_gem_object_unreference(obj); | ||
4704 | err: | ||
4705 | return 0; | ||
4706 | } | ||
4707 | |||
4708 | static void | ||
4709 | i915_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 | ||
4601 | static void | 4725 | static 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..df6a9cd82c4d 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); |
@@ -456,11 +456,15 @@ i915_error_object_create(struct drm_device *dev, | |||
456 | 456 | ||
457 | for (page = 0; page < page_count; page++) { | 457 | for (page = 0; page < page_count; page++) { |
458 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | 458 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); |
459 | unsigned long flags; | ||
460 | |||
459 | if (d == NULL) | 461 | if (d == NULL) |
460 | goto unwind; | 462 | goto unwind; |
461 | s = kmap_atomic(src_priv->pages[page], KM_USER0); | 463 | local_irq_save(flags); |
464 | s = kmap_atomic(src_priv->pages[page], KM_IRQ0); | ||
462 | memcpy(d, s, PAGE_SIZE); | 465 | memcpy(d, s, PAGE_SIZE); |
463 | kunmap_atomic(s, KM_USER0); | 466 | kunmap_atomic(s, KM_IRQ0); |
467 | local_irq_restore(flags); | ||
464 | dst->pages[page] = d; | 468 | dst->pages[page] = d; |
465 | } | 469 | } |
466 | dst->page_count = page_count; | 470 | dst->page_count = page_count; |
@@ -1005,7 +1009,7 @@ void i915_user_irq_get(struct drm_device *dev) | |||
1005 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1009 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
1006 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { | 1010 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { |
1007 | if (HAS_PCH_SPLIT(dev)) | 1011 | if (HAS_PCH_SPLIT(dev)) |
1008 | ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); | 1012 | ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); |
1009 | else | 1013 | else |
1010 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | 1014 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); |
1011 | } | 1015 | } |
@@ -1021,7 +1025,7 @@ void i915_user_irq_put(struct drm_device *dev) | |||
1021 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); | 1025 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); |
1022 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { | 1026 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { |
1023 | if (HAS_PCH_SPLIT(dev)) | 1027 | if (HAS_PCH_SPLIT(dev)) |
1024 | ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); | 1028 | ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); |
1025 | else | 1029 | else |
1026 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | 1030 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); |
1027 | } | 1031 | } |
@@ -1305,7 +1309,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1305 | /* enable kind of interrupts always enabled */ | 1309 | /* enable kind of interrupts always enabled */ |
1306 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 1310 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
1307 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; | 1311 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; |
1308 | u32 render_mask = GT_USER_INTERRUPT; | 1312 | u32 render_mask = GT_PIPE_NOTIFY; |
1309 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | | 1313 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | |
1310 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | 1314 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
1311 | 1315 | ||
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 | |||
428 | end: | ||
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 | |||
434 | blind_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 | ||
425 | int intel_opregion_init(struct drm_device *dev, int resume) | 471 | int 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 | ||
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 6732b5dd8ff4..27e2c715be11 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 | ||
2918 | typedef struct _ATOM_DPCD_INFO | 2918 | typedef struct _ATOM_DPCD_INFO |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index d7388fdb6d0b..cf60c0b3ef15 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -2975,7 +2975,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
2975 | 2975 | ||
2976 | for (i = 0; i < track->num_cb; i++) { | 2976 | for (i = 0; i < track->num_cb; i++) { |
2977 | if (track->cb[i].robj == NULL) { | 2977 | if (track->cb[i].robj == NULL) { |
2978 | if (!(track->fastfill || track->color_channel_mask || | 2978 | if (!(track->zb_cb_clear || track->color_channel_mask || |
2979 | track->blend_read_enable)) { | 2979 | track->blend_read_enable)) { |
2980 | continue; | 2980 | continue; |
2981 | } | 2981 | } |
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 bd75f99bd65e..a5ff8076b423 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -324,13 +324,12 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
324 | uint32_t gb_tile_config, tmp; | 324 | uint32_t gb_tile_config, tmp; |
325 | 325 | ||
326 | r100_hdp_reset(rdev); | 326 | r100_hdp_reset(rdev); |
327 | /* FIXME: rv380 one pipes ? */ | ||
328 | if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || | 327 | if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || |
329 | (rdev->family == CHIP_R350)) { | 328 | (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) { |
330 | /* r300,r350 */ | 329 | /* r300,r350 */ |
331 | rdev->num_gb_pipes = 2; | 330 | rdev->num_gb_pipes = 2; |
332 | } else { | 331 | } else { |
333 | /* rv350,rv370,rv380,r300 AD */ | 332 | /* rv350,rv370,rv380,r300 AD, r350 AH */ |
334 | rdev->num_gb_pipes = 1; | 333 | rdev->num_gb_pipes = 1; |
335 | } | 334 | } |
336 | rdev->num_z_pipes = 1; | 335 | 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 3dc968c9f5a4..c2bda4ad62e7 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 5673665ff216..9916d825401c 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 1331351c5178..4559a53d5e57 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -1316,6 +1316,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1316 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); | 1316 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
1317 | if (!radeon_connector->ddc_bus) | 1317 | if (!radeon_connector->ddc_bus) |
1318 | goto failed; | 1318 | goto failed; |
1319 | } | ||
1320 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | ||
1319 | radeon_connector->dac_load_detect = true; | 1321 | radeon_connector->dac_load_detect = true; |
1320 | drm_connector_attach_property(&radeon_connector->base, | 1322 | drm_connector_attach_property(&radeon_connector->base, |
1321 | rdev->mode_info.load_detect_property, | 1323 | 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 b8d672828246..bb1c122cad21 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_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4b05563d99e1..b3749d47be7b 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -216,6 +216,7 @@ static struct drm_driver driver_old = { | |||
216 | .mmap = drm_mmap, | 216 | .mmap = drm_mmap, |
217 | .poll = drm_poll, | 217 | .poll = drm_poll, |
218 | .fasync = drm_fasync, | 218 | .fasync = drm_fasync, |
219 | .read = drm_read, | ||
219 | #ifdef CONFIG_COMPAT | 220 | #ifdef CONFIG_COMPAT |
220 | .compat_ioctl = radeon_compat_ioctl, | 221 | .compat_ioctl = radeon_compat_ioctl, |
221 | #endif | 222 | #endif |
@@ -304,6 +305,7 @@ static struct drm_driver kms_driver = { | |||
304 | .mmap = radeon_mmap, | 305 | .mmap = radeon_mmap, |
305 | .poll = drm_poll, | 306 | .poll = drm_poll, |
306 | .fasync = drm_fasync, | 307 | .fasync = drm_fasync, |
308 | .read = drm_read, | ||
307 | #ifdef CONFIG_COMPAT | 309 | #ifdef CONFIG_COMPAT |
308 | .compat_ioctl = radeon_kms_compat_ioctl, | 310 | .compat_ioctl = radeon_kms_compat_ioctl, |
309 | #endif | 311 | #endif |
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 | ||
257 | void 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 | |||
257 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 304 | static 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 0b8e32776b10..5413fcd63086 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -558,6 +558,8 @@ extern int radeon_static_clocks_init(struct drm_device *dev); | |||
558 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 558 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
559 | struct drm_display_mode *mode, | 559 | struct drm_display_mode *mode, |
560 | struct drm_display_mode *adjusted_mode); | 560 | struct drm_display_mode *adjusted_mode); |
561 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | ||
562 | struct drm_display_mode *adjusted_mode); | ||
561 | void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); | 563 | void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); |
562 | 564 | ||
563 | /* legacy tv */ | 565 | /* legacy tv */ |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 40ab6d9c3736..cc5316dcf580 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -424,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t * | |||
424 | if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && | 424 | if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && |
425 | (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | 425 | (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { |
426 | u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); | 426 | u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); |
427 | offset = *cmd << 10; | 427 | offset = *cmd3 << 10; |
428 | if (radeon_check_and_fixup_offset | 428 | if (radeon_check_and_fixup_offset |
429 | (dev_priv, file_priv, &offset)) { | 429 | (dev_priv, file_priv, &offset)) { |
430 | DRM_ERROR("Invalid second packet offset\n"); | 430 | DRM_ERROR("Invalid second packet offset\n"); |
@@ -2895,9 +2895,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, | |||
2895 | return rv; | 2895 | return rv; |
2896 | rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer, | 2896 | rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer, |
2897 | cmdbuf->bufsz); | 2897 | cmdbuf->bufsz); |
2898 | if (rv) | 2898 | if (rv) { |
2899 | drm_buffer_free(cmdbuf->buffer); | ||
2899 | return rv; | 2900 | return rv; |
2900 | } | 2901 | } |
2902 | } else | ||
2903 | goto done; | ||
2901 | 2904 | ||
2902 | orig_nbox = cmdbuf->nbox; | 2905 | orig_nbox = cmdbuf->nbox; |
2903 | 2906 | ||
@@ -2905,8 +2908,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, | |||
2905 | int temp; | 2908 | int temp; |
2906 | temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); | 2909 | temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); |
2907 | 2910 | ||
2908 | if (cmdbuf->bufsz != 0) | 2911 | drm_buffer_free(cmdbuf->buffer); |
2909 | drm_buffer_free(cmdbuf->buffer); | ||
2910 | 2912 | ||
2911 | return temp; | 2913 | return temp; |
2912 | } | 2914 | } |
@@ -3012,16 +3014,15 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, | |||
3012 | } | 3014 | } |
3013 | } | 3015 | } |
3014 | 3016 | ||
3015 | if (cmdbuf->bufsz != 0) | 3017 | drm_buffer_free(cmdbuf->buffer); |
3016 | drm_buffer_free(cmdbuf->buffer); | ||
3017 | 3018 | ||
3019 | done: | ||
3018 | DRM_DEBUG("DONE\n"); | 3020 | DRM_DEBUG("DONE\n"); |
3019 | COMMIT_RING(); | 3021 | COMMIT_RING(); |
3020 | return 0; | 3022 | return 0; |
3021 | 3023 | ||
3022 | err: | 3024 | err: |
3023 | if (cmdbuf->bufsz != 0) | 3025 | drm_buffer_free(cmdbuf->buffer); |
3024 | drm_buffer_free(cmdbuf->buffer); | ||
3025 | return -EINVAL; | 3026 | return -EINVAL; |
3026 | } | 3027 | } |
3027 | 3028 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index dd47b2a9a791..0e3754a3a303 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -1716,40 +1716,12 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, | |||
1716 | } | 1716 | } |
1717 | EXPORT_SYMBOL(ttm_bo_wait); | 1717 | EXPORT_SYMBOL(ttm_bo_wait); |
1718 | 1718 | ||
1719 | void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo) | ||
1720 | { | ||
1721 | atomic_set(&bo->reserved, 0); | ||
1722 | wake_up_all(&bo->event_queue); | ||
1723 | } | ||
1724 | |||
1725 | int ttm_bo_block_reservation(struct ttm_buffer_object *bo, bool interruptible, | ||
1726 | bool no_wait) | ||
1727 | { | ||
1728 | int ret; | ||
1729 | |||
1730 | while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { | ||
1731 | if (no_wait) | ||
1732 | return -EBUSY; | ||
1733 | else if (interruptible) { | ||
1734 | ret = wait_event_interruptible | ||
1735 | (bo->event_queue, atomic_read(&bo->reserved) == 0); | ||
1736 | if (unlikely(ret != 0)) | ||
1737 | return ret; | ||
1738 | } else { | ||
1739 | wait_event(bo->event_queue, | ||
1740 | atomic_read(&bo->reserved) == 0); | ||
1741 | } | ||
1742 | } | ||
1743 | return 0; | ||
1744 | } | ||
1745 | |||
1746 | int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait) | 1719 | int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait) |
1747 | { | 1720 | { |
1748 | int ret = 0; | 1721 | int ret = 0; |
1749 | 1722 | ||
1750 | /* | 1723 | /* |
1751 | * Using ttm_bo_reserve instead of ttm_bo_block_reservation | 1724 | * Using ttm_bo_reserve makes sure the lru lists are updated. |
1752 | * makes sure the lru lists are updated. | ||
1753 | */ | 1725 | */ |
1754 | 1726 | ||
1755 | ret = ttm_bo_reserve(bo, true, no_wait, false, 0); | 1727 | ret = ttm_bo_reserve(bo, true, no_wait, false, 0); |
diff --git a/drivers/gpu/drm/ttm/ttm_lock.c b/drivers/gpu/drm/ttm/ttm_lock.c index 3d172ef04ee1..de41e55a944a 100644 --- a/drivers/gpu/drm/ttm/ttm_lock.c +++ b/drivers/gpu/drm/ttm/ttm_lock.c | |||
@@ -204,7 +204,6 @@ static int __ttm_vt_unlock(struct ttm_lock *lock) | |||
204 | lock->flags &= ~TTM_VT_LOCK; | 204 | lock->flags &= ~TTM_VT_LOCK; |
205 | wake_up_all(&lock->queue); | 205 | wake_up_all(&lock->queue); |
206 | spin_unlock(&lock->lock); | 206 | spin_unlock(&lock->lock); |
207 | printk(KERN_INFO TTM_PFX "vt unlock.\n"); | ||
208 | 207 | ||
209 | return ret; | 208 | return ret; |
210 | } | 209 | } |
@@ -265,10 +264,8 @@ int ttm_vt_lock(struct ttm_lock *lock, | |||
265 | ttm_lock_type, &ttm_vt_lock_remove, NULL); | 264 | ttm_lock_type, &ttm_vt_lock_remove, NULL); |
266 | if (ret) | 265 | if (ret) |
267 | (void)__ttm_vt_unlock(lock); | 266 | (void)__ttm_vt_unlock(lock); |
268 | else { | 267 | else |
269 | lock->vt_holder = tfile; | 268 | lock->vt_holder = tfile; |
270 | printk(KERN_INFO TTM_PFX "vt lock.\n"); | ||
271 | } | ||
272 | 269 | ||
273 | return ret; | 270 | return ret; |
274 | } | 271 | } |
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); |
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index d6d1149d525d..c8768f38511e 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
@@ -276,8 +276,10 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, | |||
276 | 276 | ||
277 | mutex_lock(&vgasr_mutex); | 277 | mutex_lock(&vgasr_mutex); |
278 | 278 | ||
279 | if (!vgasr_priv.active) | 279 | if (!vgasr_priv.active) { |
280 | return -EINVAL; | 280 | cnt = -EINVAL; |
281 | goto out; | ||
282 | } | ||
281 | 283 | ||
282 | /* pwr off the device not in use */ | 284 | /* pwr off the device not in use */ |
283 | if (strncmp(usercmd, "OFF", 3) == 0) { | 285 | if (strncmp(usercmd, "OFF", 3) == 0) { |