diff options
Diffstat (limited to 'drivers/gpu')
30 files changed, 356 insertions, 105 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 = { | |||
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 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 | ||
1375 | static 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 */ |
1373 | static unsigned int i915_vga_set_decode(void *cookie, bool state) | 1385 | static 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 | ||
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 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; | |||
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; |
@@ -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 | */ | ||
4611 | static int | ||
4612 | i915_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 | |||
4642 | err_unpin: | ||
4643 | i915_gem_object_unpin(obj); | ||
4644 | err_unref: | ||
4645 | drm_gem_object_unreference(obj); | ||
4646 | err: | ||
4647 | return ret; | ||
4648 | } | ||
4649 | |||
4557 | static int | 4650 | static int |
4558 | i915_gem_init_hws(struct drm_device *dev) | 4651 | i915_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 | |||
4708 | err_unpin: | ||
4709 | i915_gem_object_unpin(obj); | ||
4710 | err_unref: | ||
4711 | drm_gem_object_unreference(obj); | ||
4712 | err: | ||
4713 | return 0; | ||
4714 | } | ||
4715 | |||
4716 | static void | ||
4717 | i915_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 | ||
4609 | static void | 4733 | static 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 | |||
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 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 | ||
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 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 | ||
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 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); | |||
564 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 564 | bool 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); |
567 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | ||
568 | struct drm_display_mode *adjusted_mode); | ||
567 | void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); | 569 | void 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); |
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) { |