diff options
author | Dave Airlie <airlied@redhat.com> | 2010-05-18 19:35:51 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-18 19:35:51 -0400 |
commit | 05ea893c46805b2981ea8ba6df881e3d65edd63b (patch) | |
tree | ea381e22d99f49bd2c95238f88491d48b797a17b /drivers/gpu | |
parent | 26481fb15644b5fd85d4cea020f74a234cdf6803 (diff) | |
parent | a7c542782e92f9487c62a571565637be3d6b0ffd (diff) |
Merge remote branch 'anholt/drm-intel-next' into drm-next
* anholt/drm-intel-next: (515 commits)
drm/i915: Fix out of tree builds
drm/i915: move fence lru to struct drm_i915_fence_reg
drm/i915: don't allow tiling changes on pinned buffers v2
drm/i915: Be extra careful about A/D matching for multifunction SDVO
drm/i915: Fix DDC bus selection for multifunction SDVO
drm/i915: cleanup mode setting before unmapping registers
drm/i915: Make fbc control wrapper functions
drm/i915: Wait for the GPU whilst shrinking, if truly desperate.
drm/i915: Use spatio-temporal dithering on PCH
[MTD] Remove zero-length files mtdbdi.c and internal.ho
pata_pcmcia / ide-cs: Fix bad hashes for Transcend and kingston IDs
libata: Fix several inaccuracies in developer's guide
slub: Fix bad boundary check in init_kmem_cache_nodes()
raid6: fix recovery performance regression
KEYS: call_sbin_request_key() must write lock keyrings before modifying them
KEYS: Use RCU dereference wrappers in keyring key type code
KEYS: find_keyring_by_name() can gain access to a freed keyring
ALSA: hda: Fix 0 dB for Packard Bell models using Conexant CX20549 (Venice)
ALSA: hda - Add quirk for Dell Inspiron 19T using a Conexant CX20582
ALSA: take tu->qlock with irqs disabled
...
Diffstat (limited to 'drivers/gpu')
35 files changed, 526 insertions, 220 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 3bd87276156..a263b7070fc 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 e4865f99989..7732268eced 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 b743411d814..a0c365f2e52 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 49daf37e504..3a3a451d0bf 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/Makefile b/drivers/gpu/drm/i915/Makefile index 9929f84ec3e..95639017bdb 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -33,3 +33,5 @@ i915-$(CONFIG_ACPI) += i915_opregion.o | |||
33 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | 33 | i915-$(CONFIG_COMPAT) += i915_ioc32.o |
34 | 34 | ||
35 | obj-$(CONFIG_DRM_I915) += i915.o | 35 | obj-$(CONFIG_DRM_I915) += i915.o |
36 | |||
37 | CFLAGS_i915_trace_points.o := -I$(src) | ||
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 213aa3f6731..322070c0c63 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -566,23 +566,14 @@ static int i915_fbc_status(struct seq_file *m, void *unused) | |||
566 | { | 566 | { |
567 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 567 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
568 | struct drm_device *dev = node->minor->dev; | 568 | struct drm_device *dev = node->minor->dev; |
569 | struct drm_crtc *crtc; | ||
570 | drm_i915_private_t *dev_priv = dev->dev_private; | 569 | drm_i915_private_t *dev_priv = dev->dev_private; |
571 | bool fbc_enabled = false; | ||
572 | 570 | ||
573 | if (!dev_priv->display.fbc_enabled) { | 571 | if (!I915_HAS_FBC(dev)) { |
574 | seq_printf(m, "FBC unsupported on this chipset\n"); | 572 | seq_printf(m, "FBC unsupported on this chipset\n"); |
575 | return 0; | 573 | return 0; |
576 | } | 574 | } |
577 | 575 | ||
578 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 576 | if (intel_fbc_enabled(dev)) { |
579 | if (!crtc->enabled) | ||
580 | continue; | ||
581 | if (dev_priv->display.fbc_enabled(crtc)) | ||
582 | fbc_enabled = true; | ||
583 | } | ||
584 | |||
585 | if (fbc_enabled) { | ||
586 | seq_printf(m, "FBC enabled\n"); | 577 | seq_printf(m, "FBC enabled\n"); |
587 | } else { | 578 | } else { |
588 | seq_printf(m, "FBC disabled: "); | 579 | seq_printf(m, "FBC disabled: "); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8fe66ac4e1a..2a6b5de5ae5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1357,19 +1357,30 @@ 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 | intel_disable_fbc(dev); | ||
1361 | dev_priv->compressed_fb = compressed_fb; | ||
1362 | |||
1360 | if (IS_GM45(dev)) { | 1363 | if (IS_GM45(dev)) { |
1361 | g4x_disable_fbc(dev); | ||
1362 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); | 1364 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); |
1363 | } else { | 1365 | } else { |
1364 | i8xx_disable_fbc(dev); | ||
1365 | I915_WRITE(FBC_CFB_BASE, cfb_base); | 1366 | I915_WRITE(FBC_CFB_BASE, cfb_base); |
1366 | I915_WRITE(FBC_LL_BASE, ll_base); | 1367 | I915_WRITE(FBC_LL_BASE, ll_base); |
1368 | dev_priv->compressed_llb = compressed_llb; | ||
1367 | } | 1369 | } |
1368 | 1370 | ||
1369 | 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, |
1370 | ll_base, size >> 20); | 1372 | ll_base, size >> 20); |
1371 | } | 1373 | } |
1372 | 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 | |||
1373 | /* true = enable decode, false = disable decoder */ | 1384 | /* true = enable decode, false = disable decoder */ |
1374 | static unsigned int i915_vga_set_decode(void *cookie, bool state) | 1385 | static unsigned int i915_vga_set_decode(void *cookie, bool state) |
1375 | { | 1386 | { |
@@ -1759,6 +1770,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
1759 | } | 1770 | } |
1760 | 1771 | ||
1761 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1772 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1773 | intel_modeset_cleanup(dev); | ||
1774 | |||
1762 | /* | 1775 | /* |
1763 | * free the memory space allocated for the child device | 1776 | * free the memory space allocated for the child device |
1764 | * config parsed from VBT | 1777 | * config parsed from VBT |
@@ -1782,13 +1795,13 @@ int i915_driver_unload(struct drm_device *dev) | |||
1782 | intel_opregion_free(dev, 0); | 1795 | intel_opregion_free(dev, 0); |
1783 | 1796 | ||
1784 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1797 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1785 | intel_modeset_cleanup(dev); | ||
1786 | |||
1787 | i915_gem_free_all_phys_object(dev); | 1798 | i915_gem_free_all_phys_object(dev); |
1788 | 1799 | ||
1789 | mutex_lock(&dev->struct_mutex); | 1800 | mutex_lock(&dev->struct_mutex); |
1790 | i915_gem_cleanup_ringbuffer(dev); | 1801 | i915_gem_cleanup_ringbuffer(dev); |
1791 | mutex_unlock(&dev->struct_mutex); | 1802 | mutex_unlock(&dev->struct_mutex); |
1803 | if (I915_HAS_FBC(dev) && i915_powersave) | ||
1804 | i915_cleanup_compression(dev); | ||
1792 | drm_mm_takedown(&dev_priv->vram); | 1805 | drm_mm_takedown(&dev_priv->vram); |
1793 | i915_gem_lastclose(dev); | 1806 | i915_gem_lastclose(dev); |
1794 | 1807 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 01e91ea5bde..5c51e45ab68 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 242993bedab..7f797ef1ab3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -128,6 +128,7 @@ struct drm_i915_master_private { | |||
128 | 128 | ||
129 | struct drm_i915_fence_reg { | 129 | struct drm_i915_fence_reg { |
130 | struct drm_gem_object *obj; | 130 | struct drm_gem_object *obj; |
131 | struct list_head lru_list; | ||
131 | }; | 132 | }; |
132 | 133 | ||
133 | struct sdvo_device_mapping { | 134 | struct sdvo_device_mapping { |
@@ -135,6 +136,7 @@ struct sdvo_device_mapping { | |||
135 | u8 slave_addr; | 136 | u8 slave_addr; |
136 | u8 dvo_wiring; | 137 | u8 dvo_wiring; |
137 | u8 initialized; | 138 | u8 initialized; |
139 | u8 ddc_pin; | ||
138 | }; | 140 | }; |
139 | 141 | ||
140 | struct drm_i915_error_state { | 142 | struct drm_i915_error_state { |
@@ -175,7 +177,7 @@ struct drm_i915_error_state { | |||
175 | 177 | ||
176 | struct drm_i915_display_funcs { | 178 | struct drm_i915_display_funcs { |
177 | void (*dpms)(struct drm_crtc *crtc, int mode); | 179 | void (*dpms)(struct drm_crtc *crtc, int mode); |
178 | bool (*fbc_enabled)(struct drm_crtc *crtc); | 180 | bool (*fbc_enabled)(struct drm_device *dev); |
179 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); | 181 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); |
180 | void (*disable_fbc)(struct drm_device *dev); | 182 | void (*disable_fbc)(struct drm_device *dev); |
181 | int (*get_display_clock_speed)(struct drm_device *dev); | 183 | int (*get_display_clock_speed)(struct drm_device *dev); |
@@ -195,6 +197,7 @@ struct intel_overlay; | |||
195 | struct intel_device_info { | 197 | struct intel_device_info { |
196 | u8 is_mobile : 1; | 198 | u8 is_mobile : 1; |
197 | u8 is_i8xx : 1; | 199 | u8 is_i8xx : 1; |
200 | u8 is_i85x : 1; | ||
198 | u8 is_i915g : 1; | 201 | u8 is_i915g : 1; |
199 | u8 is_i9xx : 1; | 202 | u8 is_i9xx : 1; |
200 | u8 is_i945gm : 1; | 203 | u8 is_i945gm : 1; |
@@ -242,11 +245,14 @@ typedef struct drm_i915_private { | |||
242 | 245 | ||
243 | drm_dma_handle_t *status_page_dmah; | 246 | drm_dma_handle_t *status_page_dmah; |
244 | void *hw_status_page; | 247 | void *hw_status_page; |
248 | void *seqno_page; | ||
245 | dma_addr_t dma_status_page; | 249 | dma_addr_t dma_status_page; |
246 | uint32_t counter; | 250 | uint32_t counter; |
247 | unsigned int status_gfx_addr; | 251 | unsigned int status_gfx_addr; |
252 | unsigned int seqno_gfx_addr; | ||
248 | drm_local_map_t hws_map; | 253 | drm_local_map_t hws_map; |
249 | struct drm_gem_object *hws_obj; | 254 | struct drm_gem_object *hws_obj; |
255 | struct drm_gem_object *seqno_obj; | ||
250 | struct drm_gem_object *pwrctx; | 256 | struct drm_gem_object *pwrctx; |
251 | 257 | ||
252 | struct resource mch_res; | 258 | struct resource mch_res; |
@@ -641,6 +647,9 @@ typedef struct drm_i915_private { | |||
641 | 647 | ||
642 | enum no_fbc_reason no_fbc_reason; | 648 | enum no_fbc_reason no_fbc_reason; |
643 | 649 | ||
650 | struct drm_mm_node *compressed_fb; | ||
651 | struct drm_mm_node *compressed_llb; | ||
652 | |||
644 | /* list of fbdev register on this device */ | 653 | /* list of fbdev register on this device */ |
645 | struct intel_fbdev *fbdev; | 654 | struct intel_fbdev *fbdev; |
646 | } drm_i915_private_t; | 655 | } drm_i915_private_t; |
@@ -657,9 +666,6 @@ struct drm_i915_gem_object { | |||
657 | /** This object's place on GPU write list */ | 666 | /** This object's place on GPU write list */ |
658 | struct list_head gpu_write_list; | 667 | struct list_head gpu_write_list; |
659 | 668 | ||
660 | /** This object's place on the fenced object LRU */ | ||
661 | struct list_head fence_list; | ||
662 | |||
663 | /** | 669 | /** |
664 | * This is set if the object is on the active or flushing lists | 670 | * This is set if the object is on the active or flushing lists |
665 | * (has pending rendering), and is not set if it's on inactive (ready | 671 | * (has pending rendering), and is not set if it's on inactive (ready |
@@ -1006,6 +1012,9 @@ extern void intel_modeset_cleanup(struct drm_device *dev); | |||
1006 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); | 1012 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); |
1007 | extern void i8xx_disable_fbc(struct drm_device *dev); | 1013 | extern void i8xx_disable_fbc(struct drm_device *dev); |
1008 | extern void g4x_disable_fbc(struct drm_device *dev); | 1014 | extern void g4x_disable_fbc(struct drm_device *dev); |
1015 | extern void intel_disable_fbc(struct drm_device *dev); | ||
1016 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | ||
1017 | extern bool intel_fbc_enabled(struct drm_device *dev); | ||
1009 | 1018 | ||
1010 | extern void intel_detect_pch (struct drm_device *dev); | 1019 | extern void intel_detect_pch (struct drm_device *dev); |
1011 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1020 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
@@ -1088,7 +1097,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1088 | 1097 | ||
1089 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | 1098 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
1090 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | 1099 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) |
1091 | #define IS_I85X(dev) ((dev)->pci_device == 0x3582) | 1100 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) |
1092 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | 1101 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) |
1093 | #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) | 1102 | #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) |
1094 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | 1103 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) |
@@ -1154,6 +1163,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1154 | 1163 | ||
1155 | #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \ | 1164 | #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \ |
1156 | IS_GEN6(dev)) | 1165 | IS_GEN6(dev)) |
1166 | #define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev)) | ||
1157 | 1167 | ||
1158 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) | 1168 | #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) |
1159 | #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) | 1169 | #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 47c46ed384f..112699f71fa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1051,7 +1051,9 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1051 | * about to occur. | 1051 | * about to occur. |
1052 | */ | 1052 | */ |
1053 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | 1053 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
1054 | list_move_tail(&obj_priv->fence_list, | 1054 | struct drm_i915_fence_reg *reg = |
1055 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
1056 | list_move_tail(®->lru_list, | ||
1055 | &dev_priv->mm.fence_list); | 1057 | &dev_priv->mm.fence_list); |
1056 | } | 1058 | } |
1057 | 1059 | ||
@@ -1577,9 +1579,12 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1577 | i915_gem_object_move_to_active(obj, seqno); | 1579 | i915_gem_object_move_to_active(obj, seqno); |
1578 | 1580 | ||
1579 | /* update the fence lru list */ | 1581 | /* update the fence lru list */ |
1580 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1582 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
1581 | list_move_tail(&obj_priv->fence_list, | 1583 | struct drm_i915_fence_reg *reg = |
1584 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
1585 | list_move_tail(®->lru_list, | ||
1582 | &dev_priv->mm.fence_list); | 1586 | &dev_priv->mm.fence_list); |
1587 | } | ||
1583 | 1588 | ||
1584 | trace_i915_gem_object_change_domain(obj, | 1589 | trace_i915_gem_object_change_domain(obj, |
1585 | obj->read_domains, | 1590 | obj->read_domains, |
@@ -1588,6 +1593,13 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1588 | } | 1593 | } |
1589 | } | 1594 | } |
1590 | 1595 | ||
1596 | #define PIPE_CONTROL_FLUSH(addr) \ | ||
1597 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | ||
1598 | PIPE_CONTROL_DEPTH_STALL); \ | ||
1599 | OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ | ||
1600 | OUT_RING(0); \ | ||
1601 | OUT_RING(0); \ | ||
1602 | |||
1591 | /** | 1603 | /** |
1592 | * Creates a new sequence number, emitting a write of it to the status page | 1604 | * 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. | 1605 | * plus an interrupt, which will trigger i915_user_interrupt_handler. |
@@ -1622,13 +1634,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1622 | if (dev_priv->mm.next_gem_seqno == 0) | 1634 | if (dev_priv->mm.next_gem_seqno == 0) |
1623 | dev_priv->mm.next_gem_seqno++; | 1635 | dev_priv->mm.next_gem_seqno++; |
1624 | 1636 | ||
1625 | BEGIN_LP_RING(4); | 1637 | if (HAS_PIPE_CONTROL(dev)) { |
1626 | OUT_RING(MI_STORE_DWORD_INDEX); | 1638 | 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 | 1639 | ||
1630 | OUT_RING(MI_USER_INTERRUPT); | 1640 | /* |
1631 | ADVANCE_LP_RING(); | 1641 | * Workaround qword write incoherence by flushing the |
1642 | * PIPE_NOTIFY buffers out to memory before requesting | ||
1643 | * an interrupt. | ||
1644 | */ | ||
1645 | BEGIN_LP_RING(32); | ||
1646 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
1647 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | ||
1648 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
1649 | OUT_RING(seqno); | ||
1650 | OUT_RING(0); | ||
1651 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1652 | scratch_addr += 128; /* write to separate cachelines */ | ||
1653 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1654 | scratch_addr += 128; | ||
1655 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1656 | scratch_addr += 128; | ||
1657 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1658 | scratch_addr += 128; | ||
1659 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1660 | scratch_addr += 128; | ||
1661 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1662 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
1663 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | ||
1664 | PIPE_CONTROL_NOTIFY); | ||
1665 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
1666 | OUT_RING(seqno); | ||
1667 | OUT_RING(0); | ||
1668 | ADVANCE_LP_RING(); | ||
1669 | } else { | ||
1670 | BEGIN_LP_RING(4); | ||
1671 | OUT_RING(MI_STORE_DWORD_INDEX); | ||
1672 | OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
1673 | OUT_RING(seqno); | ||
1674 | |||
1675 | OUT_RING(MI_USER_INTERRUPT); | ||
1676 | ADVANCE_LP_RING(); | ||
1677 | } | ||
1632 | 1678 | ||
1633 | DRM_DEBUG_DRIVER("%d\n", seqno); | 1679 | DRM_DEBUG_DRIVER("%d\n", seqno); |
1634 | 1680 | ||
@@ -1752,7 +1798,10 @@ i915_get_gem_seqno(struct drm_device *dev) | |||
1752 | { | 1798 | { |
1753 | drm_i915_private_t *dev_priv = dev->dev_private; | 1799 | drm_i915_private_t *dev_priv = dev->dev_private; |
1754 | 1800 | ||
1755 | return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); | 1801 | if (HAS_PIPE_CONTROL(dev)) |
1802 | return ((volatile u32 *)(dev_priv->seqno_page))[0]; | ||
1803 | else | ||
1804 | return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); | ||
1756 | } | 1805 | } |
1757 | 1806 | ||
1758 | /** | 1807 | /** |
@@ -2362,6 +2411,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2362 | pitch_val = obj_priv->stride / tile_width; | 2411 | pitch_val = obj_priv->stride / tile_width; |
2363 | pitch_val = ffs(pitch_val) - 1; | 2412 | pitch_val = ffs(pitch_val) - 1; |
2364 | 2413 | ||
2414 | if (obj_priv->tiling_mode == I915_TILING_Y && | ||
2415 | HAS_128_BYTE_Y_TILING(dev)) | ||
2416 | WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); | ||
2417 | else | ||
2418 | WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); | ||
2419 | |||
2365 | val = obj_priv->gtt_offset; | 2420 | val = obj_priv->gtt_offset; |
2366 | if (obj_priv->tiling_mode == I915_TILING_Y) | 2421 | if (obj_priv->tiling_mode == I915_TILING_Y) |
2367 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; | 2422 | val |= 1 << I830_FENCE_TILING_Y_SHIFT; |
@@ -2435,9 +2490,10 @@ static int i915_find_fence_reg(struct drm_device *dev) | |||
2435 | 2490 | ||
2436 | /* None available, try to steal one or wait for a user to finish */ | 2491 | /* None available, try to steal one or wait for a user to finish */ |
2437 | i = I915_FENCE_REG_NONE; | 2492 | i = I915_FENCE_REG_NONE; |
2438 | list_for_each_entry(obj_priv, &dev_priv->mm.fence_list, | 2493 | list_for_each_entry(reg, &dev_priv->mm.fence_list, |
2439 | fence_list) { | 2494 | lru_list) { |
2440 | obj = &obj_priv->base; | 2495 | obj = reg->obj; |
2496 | obj_priv = to_intel_bo(obj); | ||
2441 | 2497 | ||
2442 | if (obj_priv->pin_count) | 2498 | if (obj_priv->pin_count) |
2443 | continue; | 2499 | continue; |
@@ -2486,7 +2542,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2486 | 2542 | ||
2487 | /* Just update our place in the LRU if our fence is getting used. */ | 2543 | /* Just update our place in the LRU if our fence is getting used. */ |
2488 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | 2544 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
2489 | list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | 2545 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; |
2546 | list_move_tail(®->lru_list, &dev_priv->mm.fence_list); | ||
2490 | return 0; | 2547 | return 0; |
2491 | } | 2548 | } |
2492 | 2549 | ||
@@ -2516,7 +2573,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2516 | 2573 | ||
2517 | obj_priv->fence_reg = ret; | 2574 | obj_priv->fence_reg = ret; |
2518 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; | 2575 | reg = &dev_priv->fence_regs[obj_priv->fence_reg]; |
2519 | list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); | 2576 | list_add_tail(®->lru_list, &dev_priv->mm.fence_list); |
2520 | 2577 | ||
2521 | reg->obj = obj; | 2578 | reg->obj = obj; |
2522 | 2579 | ||
@@ -2548,6 +2605,8 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2548 | struct drm_device *dev = obj->dev; | 2605 | struct drm_device *dev = obj->dev; |
2549 | drm_i915_private_t *dev_priv = dev->dev_private; | 2606 | drm_i915_private_t *dev_priv = dev->dev_private; |
2550 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2607 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2608 | struct drm_i915_fence_reg *reg = | ||
2609 | &dev_priv->fence_regs[obj_priv->fence_reg]; | ||
2551 | 2610 | ||
2552 | if (IS_GEN6(dev)) { | 2611 | if (IS_GEN6(dev)) { |
2553 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2612 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + |
@@ -2566,9 +2625,9 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2566 | I915_WRITE(fence_reg, 0); | 2625 | I915_WRITE(fence_reg, 0); |
2567 | } | 2626 | } |
2568 | 2627 | ||
2569 | dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; | 2628 | reg->obj = NULL; |
2570 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2629 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2571 | list_del_init(&obj_priv->fence_list); | 2630 | list_del_init(®->lru_list); |
2572 | } | 2631 | } |
2573 | 2632 | ||
2574 | /** | 2633 | /** |
@@ -4439,12 +4498,10 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, | |||
4439 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | 4498 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
4440 | 4499 | ||
4441 | obj->agp_type = AGP_USER_MEMORY; | 4500 | obj->agp_type = AGP_USER_MEMORY; |
4442 | |||
4443 | obj->base.driver_private = NULL; | 4501 | obj->base.driver_private = NULL; |
4444 | obj->fence_reg = I915_FENCE_REG_NONE; | 4502 | obj->fence_reg = I915_FENCE_REG_NONE; |
4445 | INIT_LIST_HEAD(&obj->list); | 4503 | INIT_LIST_HEAD(&obj->list); |
4446 | INIT_LIST_HEAD(&obj->gpu_write_list); | 4504 | INIT_LIST_HEAD(&obj->gpu_write_list); |
4447 | INIT_LIST_HEAD(&obj->fence_list); | ||
4448 | obj->madv = I915_MADV_WILLNEED; | 4505 | obj->madv = I915_MADV_WILLNEED; |
4449 | 4506 | ||
4450 | trace_i915_gem_object_create(&obj->base); | 4507 | trace_i915_gem_object_create(&obj->base); |
@@ -4554,6 +4611,49 @@ i915_gem_idle(struct drm_device *dev) | |||
4554 | return 0; | 4611 | return 0; |
4555 | } | 4612 | } |
4556 | 4613 | ||
4614 | /* | ||
4615 | * 965+ support PIPE_CONTROL commands, which provide finer grained control | ||
4616 | * over cache flushing. | ||
4617 | */ | ||
4618 | static int | ||
4619 | i915_gem_init_pipe_control(struct drm_device *dev) | ||
4620 | { | ||
4621 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4622 | struct drm_gem_object *obj; | ||
4623 | struct drm_i915_gem_object *obj_priv; | ||
4624 | int ret; | ||
4625 | |||
4626 | obj = i915_gem_alloc_object(dev, 4096); | ||
4627 | if (obj == NULL) { | ||
4628 | DRM_ERROR("Failed to allocate seqno page\n"); | ||
4629 | ret = -ENOMEM; | ||
4630 | goto err; | ||
4631 | } | ||
4632 | obj_priv = to_intel_bo(obj); | ||
4633 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | ||
4634 | |||
4635 | ret = i915_gem_object_pin(obj, 4096); | ||
4636 | if (ret) | ||
4637 | goto err_unref; | ||
4638 | |||
4639 | dev_priv->seqno_gfx_addr = obj_priv->gtt_offset; | ||
4640 | dev_priv->seqno_page = kmap(obj_priv->pages[0]); | ||
4641 | if (dev_priv->seqno_page == NULL) | ||
4642 | goto err_unpin; | ||
4643 | |||
4644 | dev_priv->seqno_obj = obj; | ||
4645 | memset(dev_priv->seqno_page, 0, PAGE_SIZE); | ||
4646 | |||
4647 | return 0; | ||
4648 | |||
4649 | err_unpin: | ||
4650 | i915_gem_object_unpin(obj); | ||
4651 | err_unref: | ||
4652 | drm_gem_object_unreference(obj); | ||
4653 | err: | ||
4654 | return ret; | ||
4655 | } | ||
4656 | |||
4557 | static int | 4657 | static int |
4558 | i915_gem_init_hws(struct drm_device *dev) | 4658 | i915_gem_init_hws(struct drm_device *dev) |
4559 | { | 4659 | { |
@@ -4571,7 +4671,8 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4571 | obj = i915_gem_alloc_object(dev, 4096); | 4671 | obj = i915_gem_alloc_object(dev, 4096); |
4572 | if (obj == NULL) { | 4672 | if (obj == NULL) { |
4573 | DRM_ERROR("Failed to allocate status page\n"); | 4673 | DRM_ERROR("Failed to allocate status page\n"); |
4574 | return -ENOMEM; | 4674 | ret = -ENOMEM; |
4675 | goto err; | ||
4575 | } | 4676 | } |
4576 | obj_priv = to_intel_bo(obj); | 4677 | obj_priv = to_intel_bo(obj); |
4577 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | 4678 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; |
@@ -4579,7 +4680,7 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4579 | ret = i915_gem_object_pin(obj, 4096); | 4680 | ret = i915_gem_object_pin(obj, 4096); |
4580 | if (ret != 0) { | 4681 | if (ret != 0) { |
4581 | drm_gem_object_unreference(obj); | 4682 | drm_gem_object_unreference(obj); |
4582 | return ret; | 4683 | goto err_unref; |
4583 | } | 4684 | } |
4584 | 4685 | ||
4585 | dev_priv->status_gfx_addr = obj_priv->gtt_offset; | 4686 | dev_priv->status_gfx_addr = obj_priv->gtt_offset; |
@@ -4588,10 +4689,16 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4588 | if (dev_priv->hw_status_page == NULL) { | 4689 | if (dev_priv->hw_status_page == NULL) { |
4589 | DRM_ERROR("Failed to map status page.\n"); | 4690 | DRM_ERROR("Failed to map status page.\n"); |
4590 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | 4691 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); |
4591 | i915_gem_object_unpin(obj); | 4692 | ret = -EINVAL; |
4592 | drm_gem_object_unreference(obj); | 4693 | goto err_unpin; |
4593 | return -EINVAL; | ||
4594 | } | 4694 | } |
4695 | |||
4696 | if (HAS_PIPE_CONTROL(dev)) { | ||
4697 | ret = i915_gem_init_pipe_control(dev); | ||
4698 | if (ret) | ||
4699 | goto err_unpin; | ||
4700 | } | ||
4701 | |||
4595 | dev_priv->hws_obj = obj; | 4702 | dev_priv->hws_obj = obj; |
4596 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | 4703 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); |
4597 | if (IS_GEN6(dev)) { | 4704 | if (IS_GEN6(dev)) { |
@@ -4604,6 +4711,30 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4604 | DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); | 4711 | DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); |
4605 | 4712 | ||
4606 | return 0; | 4713 | return 0; |
4714 | |||
4715 | err_unpin: | ||
4716 | i915_gem_object_unpin(obj); | ||
4717 | err_unref: | ||
4718 | drm_gem_object_unreference(obj); | ||
4719 | err: | ||
4720 | return 0; | ||
4721 | } | ||
4722 | |||
4723 | static void | ||
4724 | i915_gem_cleanup_pipe_control(struct drm_device *dev) | ||
4725 | { | ||
4726 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4727 | struct drm_gem_object *obj; | ||
4728 | struct drm_i915_gem_object *obj_priv; | ||
4729 | |||
4730 | obj = dev_priv->seqno_obj; | ||
4731 | obj_priv = to_intel_bo(obj); | ||
4732 | kunmap(obj_priv->pages[0]); | ||
4733 | i915_gem_object_unpin(obj); | ||
4734 | drm_gem_object_unreference(obj); | ||
4735 | dev_priv->seqno_obj = NULL; | ||
4736 | |||
4737 | dev_priv->seqno_page = NULL; | ||
4607 | } | 4738 | } |
4608 | 4739 | ||
4609 | static void | 4740 | static void |
@@ -4627,6 +4758,9 @@ i915_gem_cleanup_hws(struct drm_device *dev) | |||
4627 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | 4758 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); |
4628 | dev_priv->hw_status_page = NULL; | 4759 | dev_priv->hw_status_page = NULL; |
4629 | 4760 | ||
4761 | if (HAS_PIPE_CONTROL(dev)) | ||
4762 | i915_gem_cleanup_pipe_control(dev); | ||
4763 | |||
4630 | /* Write high address into HWS_PGA when disabling. */ | 4764 | /* Write high address into HWS_PGA when disabling. */ |
4631 | I915_WRITE(HWS_PGA, 0x1ffff000); | 4765 | I915_WRITE(HWS_PGA, 0x1ffff000); |
4632 | } | 4766 | } |
@@ -4838,6 +4972,8 @@ i915_gem_load(struct drm_device *dev) | |||
4838 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4972 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4839 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | 4973 | INIT_LIST_HEAD(&dev_priv->mm.request_list); |
4840 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 4974 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
4975 | for (i = 0; i < 16; i++) | ||
4976 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); | ||
4841 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 4977 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
4842 | i915_gem_retire_work_handler); | 4978 | i915_gem_retire_work_handler); |
4843 | dev_priv->mm.next_gem_seqno = 1; | 4979 | dev_priv->mm.next_gem_seqno = 1; |
@@ -5066,6 +5202,20 @@ void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv) | |||
5066 | } | 5202 | } |
5067 | 5203 | ||
5068 | static int | 5204 | static int |
5205 | i915_gpu_is_active(struct drm_device *dev) | ||
5206 | { | ||
5207 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
5208 | int lists_empty; | ||
5209 | |||
5210 | spin_lock(&dev_priv->mm.active_list_lock); | ||
5211 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && | ||
5212 | list_empty(&dev_priv->mm.active_list); | ||
5213 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
5214 | |||
5215 | return !lists_empty; | ||
5216 | } | ||
5217 | |||
5218 | static int | ||
5069 | i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | 5219 | i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) |
5070 | { | 5220 | { |
5071 | drm_i915_private_t *dev_priv, *next_dev; | 5221 | drm_i915_private_t *dev_priv, *next_dev; |
@@ -5094,6 +5244,7 @@ i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
5094 | 5244 | ||
5095 | spin_lock(&shrink_list_lock); | 5245 | spin_lock(&shrink_list_lock); |
5096 | 5246 | ||
5247 | rescan: | ||
5097 | /* first scan for clean buffers */ | 5248 | /* first scan for clean buffers */ |
5098 | list_for_each_entry_safe(dev_priv, next_dev, | 5249 | list_for_each_entry_safe(dev_priv, next_dev, |
5099 | &shrink_list, mm.shrink_list) { | 5250 | &shrink_list, mm.shrink_list) { |
@@ -5151,6 +5302,36 @@ i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) | |||
5151 | would_deadlock = 0; | 5302 | would_deadlock = 0; |
5152 | } | 5303 | } |
5153 | 5304 | ||
5305 | if (nr_to_scan) { | ||
5306 | int active = 0; | ||
5307 | |||
5308 | /* | ||
5309 | * We are desperate for pages, so as a last resort, wait | ||
5310 | * for the GPU to finish and discard whatever we can. | ||
5311 | * This has a dramatic impact to reduce the number of | ||
5312 | * OOM-killer events whilst running the GPU aggressively. | ||
5313 | */ | ||
5314 | list_for_each_entry(dev_priv, &shrink_list, mm.shrink_list) { | ||
5315 | struct drm_device *dev = dev_priv->dev; | ||
5316 | |||
5317 | if (!mutex_trylock(&dev->struct_mutex)) | ||
5318 | continue; | ||
5319 | |||
5320 | spin_unlock(&shrink_list_lock); | ||
5321 | |||
5322 | if (i915_gpu_is_active(dev)) { | ||
5323 | i915_gpu_idle(dev); | ||
5324 | active++; | ||
5325 | } | ||
5326 | |||
5327 | spin_lock(&shrink_list_lock); | ||
5328 | mutex_unlock(&dev->struct_mutex); | ||
5329 | } | ||
5330 | |||
5331 | if (active) | ||
5332 | goto rescan; | ||
5333 | } | ||
5334 | |||
5154 | spin_unlock(&shrink_list_lock); | 5335 | spin_unlock(&shrink_list_lock); |
5155 | 5336 | ||
5156 | if (would_deadlock) | 5337 | if (would_deadlock) |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 449157f7161..4b7c49d4257 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 */ |
@@ -287,6 +283,11 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
287 | return -EINVAL; | 283 | return -EINVAL; |
288 | } | 284 | } |
289 | 285 | ||
286 | if (obj_priv->pin_count) { | ||
287 | drm_gem_object_unreference_unlocked(obj); | ||
288 | return -EBUSY; | ||
289 | } | ||
290 | |||
290 | if (args->tiling_mode == I915_TILING_NONE) { | 291 | if (args->tiling_mode == I915_TILING_NONE) { |
291 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | 292 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; |
292 | args->stride = 0; | 293 | args->stride = 0; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b034ea36731..26792af7e1a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -353,7 +353,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
353 | READ_BREADCRUMB(dev_priv); | 353 | READ_BREADCRUMB(dev_priv); |
354 | } | 354 | } |
355 | 355 | ||
356 | if (gt_iir & GT_USER_INTERRUPT) { | 356 | if (gt_iir & GT_PIPE_NOTIFY) { |
357 | u32 seqno = i915_get_gem_seqno(dev); | 357 | u32 seqno = i915_get_gem_seqno(dev); |
358 | dev_priv->mm.irq_gem_seqno = seqno; | 358 | dev_priv->mm.irq_gem_seqno = seqno; |
359 | trace_i915_gem_request_complete(dev, seqno); | 359 | trace_i915_gem_request_complete(dev, seqno); |
@@ -1010,7 +1010,7 @@ void i915_user_irq_get(struct drm_device *dev) | |||
1010 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1010 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
1011 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { | 1011 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { |
1012 | if (HAS_PCH_SPLIT(dev)) | 1012 | if (HAS_PCH_SPLIT(dev)) |
1013 | ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); | 1013 | ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); |
1014 | else | 1014 | else |
1015 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | 1015 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); |
1016 | } | 1016 | } |
@@ -1026,7 +1026,7 @@ void i915_user_irq_put(struct drm_device *dev) | |||
1026 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); | 1026 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); |
1027 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { | 1027 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { |
1028 | if (HAS_PCH_SPLIT(dev)) | 1028 | if (HAS_PCH_SPLIT(dev)) |
1029 | ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); | 1029 | ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); |
1030 | else | 1030 | else |
1031 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | 1031 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); |
1032 | } | 1032 | } |
@@ -1310,7 +1310,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1310 | /* enable kind of interrupts always enabled */ | 1310 | /* enable kind of interrupts always enabled */ |
1311 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 1311 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
1312 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; | 1312 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; |
1313 | u32 render_mask = GT_USER_INTERRUPT; | 1313 | u32 render_mask = GT_PIPE_NOTIFY; |
1314 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | | 1314 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | |
1315 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | 1315 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
1316 | 1316 | ||
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index 7cc8410239c..8fcc75c1aa2 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 527d30aecda..f3e39cc46f0 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 | ||
@@ -1922,7 +1932,10 @@ | |||
1922 | /* Display & cursor control */ | 1932 | /* Display & cursor control */ |
1923 | 1933 | ||
1924 | /* dithering flag on Ironlake */ | 1934 | /* dithering flag on Ironlake */ |
1925 | #define PIPE_ENABLE_DITHER (1 << 4) | 1935 | #define PIPE_ENABLE_DITHER (1 << 4) |
1936 | #define PIPE_DITHER_TYPE_MASK (3 << 2) | ||
1937 | #define PIPE_DITHER_TYPE_SPATIAL (0 << 2) | ||
1938 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) | ||
1926 | /* Pipe A */ | 1939 | /* Pipe A */ |
1927 | #define PIPEADSL 0x70000 | 1940 | #define PIPEADSL 0x70000 |
1928 | #define PIPEACONF 0x70008 | 1941 | #define PIPEACONF 0x70008 |
@@ -2339,6 +2352,7 @@ | |||
2339 | #define DEIER 0x4400c | 2352 | #define DEIER 0x4400c |
2340 | 2353 | ||
2341 | /* GT interrupt */ | 2354 | /* GT interrupt */ |
2355 | #define GT_PIPE_NOTIFY (1 << 4) | ||
2342 | #define GT_SYNC_STATUS (1 << 2) | 2356 | #define GT_SYNC_STATUS (1 << 2) |
2343 | #define GT_USER_INTERRUPT (1 << 0) | 2357 | #define GT_USER_INTERRUPT (1 << 0) |
2344 | 2358 | ||
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 303815321c7..9e4c45f68d6 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -276,5 +276,5 @@ DEFINE_EVENT(i915_ring, i915_ring_wait_end, | |||
276 | 276 | ||
277 | /* This part must be outside protection */ | 277 | /* This part must be outside protection */ |
278 | #undef TRACE_INCLUDE_PATH | 278 | #undef TRACE_INCLUDE_PATH |
279 | #define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/i915 | 279 | #define TRACE_INCLUDE_PATH . |
280 | #include <trace/define_trace.h> | 280 | #include <trace/define_trace.h> |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index f9ba452f0cb..4c748d8f73d 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -366,6 +366,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
366 | p_mapping->dvo_port = p_child->dvo_port; | 366 | p_mapping->dvo_port = p_child->dvo_port; |
367 | p_mapping->slave_addr = p_child->slave_addr; | 367 | p_mapping->slave_addr = p_child->slave_addr; |
368 | p_mapping->dvo_wiring = p_child->dvo_wiring; | 368 | p_mapping->dvo_wiring = p_child->dvo_wiring; |
369 | p_mapping->ddc_pin = p_child->ddc_pin; | ||
369 | p_mapping->initialized = 1; | 370 | p_mapping->initialized = 1; |
370 | } else { | 371 | } else { |
371 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " | 372 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4d739a1b13c..8c668e3122a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1048,9 +1048,8 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
1048 | DRM_DEBUG_KMS("disabled FBC\n"); | 1048 | DRM_DEBUG_KMS("disabled FBC\n"); |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | static bool i8xx_fbc_enabled(struct drm_crtc *crtc) | 1051 | static bool i8xx_fbc_enabled(struct drm_device *dev) |
1052 | { | 1052 | { |
1053 | struct drm_device *dev = crtc->dev; | ||
1054 | struct drm_i915_private *dev_priv = dev->dev_private; | 1053 | struct drm_i915_private *dev_priv = dev->dev_private; |
1055 | 1054 | ||
1056 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; | 1055 | return I915_READ(FBC_CONTROL) & FBC_CTL_EN; |
@@ -1107,14 +1106,43 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
1107 | DRM_DEBUG_KMS("disabled FBC\n"); | 1106 | DRM_DEBUG_KMS("disabled FBC\n"); |
1108 | } | 1107 | } |
1109 | 1108 | ||
1110 | static bool g4x_fbc_enabled(struct drm_crtc *crtc) | 1109 | static bool g4x_fbc_enabled(struct drm_device *dev) |
1111 | { | 1110 | { |
1112 | struct drm_device *dev = crtc->dev; | ||
1113 | struct drm_i915_private *dev_priv = dev->dev_private; | 1111 | struct drm_i915_private *dev_priv = dev->dev_private; |
1114 | 1112 | ||
1115 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; | 1113 | return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; |
1116 | } | 1114 | } |
1117 | 1115 | ||
1116 | bool intel_fbc_enabled(struct drm_device *dev) | ||
1117 | { | ||
1118 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1119 | |||
1120 | if (!dev_priv->display.fbc_enabled) | ||
1121 | return false; | ||
1122 | |||
1123 | return dev_priv->display.fbc_enabled(dev); | ||
1124 | } | ||
1125 | |||
1126 | void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | ||
1127 | { | ||
1128 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | ||
1129 | |||
1130 | if (!dev_priv->display.enable_fbc) | ||
1131 | return; | ||
1132 | |||
1133 | dev_priv->display.enable_fbc(crtc, interval); | ||
1134 | } | ||
1135 | |||
1136 | void intel_disable_fbc(struct drm_device *dev) | ||
1137 | { | ||
1138 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1139 | |||
1140 | if (!dev_priv->display.disable_fbc) | ||
1141 | return; | ||
1142 | |||
1143 | dev_priv->display.disable_fbc(dev); | ||
1144 | } | ||
1145 | |||
1118 | /** | 1146 | /** |
1119 | * intel_update_fbc - enable/disable FBC as needed | 1147 | * intel_update_fbc - enable/disable FBC as needed |
1120 | * @crtc: CRTC to point the compressor at | 1148 | * @crtc: CRTC to point the compressor at |
@@ -1149,9 +1177,7 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1149 | if (!i915_powersave) | 1177 | if (!i915_powersave) |
1150 | return; | 1178 | return; |
1151 | 1179 | ||
1152 | if (!dev_priv->display.fbc_enabled || | 1180 | if (!I915_HAS_FBC(dev)) |
1153 | !dev_priv->display.enable_fbc || | ||
1154 | !dev_priv->display.disable_fbc) | ||
1155 | return; | 1181 | return; |
1156 | 1182 | ||
1157 | if (!crtc->fb) | 1183 | if (!crtc->fb) |
@@ -1198,28 +1224,25 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1198 | goto out_disable; | 1224 | goto out_disable; |
1199 | } | 1225 | } |
1200 | 1226 | ||
1201 | if (dev_priv->display.fbc_enabled(crtc)) { | 1227 | if (intel_fbc_enabled(dev)) { |
1202 | /* We can re-enable it in this case, but need to update pitch */ | 1228 | /* We can re-enable it in this case, but need to update pitch */ |
1203 | if (fb->pitch > dev_priv->cfb_pitch) | 1229 | if ((fb->pitch > dev_priv->cfb_pitch) || |
1204 | dev_priv->display.disable_fbc(dev); | 1230 | (obj_priv->fence_reg != dev_priv->cfb_fence) || |
1205 | if (obj_priv->fence_reg != dev_priv->cfb_fence) | 1231 | (plane != dev_priv->cfb_plane)) |
1206 | dev_priv->display.disable_fbc(dev); | 1232 | intel_disable_fbc(dev); |
1207 | if (plane != dev_priv->cfb_plane) | ||
1208 | dev_priv->display.disable_fbc(dev); | ||
1209 | } | 1233 | } |
1210 | 1234 | ||
1211 | if (!dev_priv->display.fbc_enabled(crtc)) { | 1235 | /* Now try to turn it back on if possible */ |
1212 | /* Now try to turn it back on if possible */ | 1236 | if (!intel_fbc_enabled(dev)) |
1213 | dev_priv->display.enable_fbc(crtc, 500); | 1237 | intel_enable_fbc(crtc, 500); |
1214 | } | ||
1215 | 1238 | ||
1216 | return; | 1239 | return; |
1217 | 1240 | ||
1218 | out_disable: | 1241 | out_disable: |
1219 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | 1242 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); |
1220 | /* Multiple disables should be harmless */ | 1243 | /* Multiple disables should be harmless */ |
1221 | if (dev_priv->display.fbc_enabled(crtc)) | 1244 | if (intel_fbc_enabled(dev)) |
1222 | dev_priv->display.disable_fbc(dev); | 1245 | intel_disable_fbc(dev); |
1223 | } | 1246 | } |
1224 | 1247 | ||
1225 | static int | 1248 | static int |
@@ -3677,14 +3700,16 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3677 | /* set the dithering flag */ | 3700 | /* set the dithering flag */ |
3678 | if (IS_I965G(dev)) { | 3701 | if (IS_I965G(dev)) { |
3679 | if (dev_priv->lvds_dither) { | 3702 | if (dev_priv->lvds_dither) { |
3680 | if (HAS_PCH_SPLIT(dev)) | 3703 | if (HAS_PCH_SPLIT(dev)) { |
3681 | pipeconf |= PIPE_ENABLE_DITHER; | 3704 | pipeconf |= PIPE_ENABLE_DITHER; |
3682 | else | 3705 | pipeconf |= PIPE_DITHER_TYPE_ST01; |
3706 | } else | ||
3683 | lvds |= LVDS_ENABLE_DITHER; | 3707 | lvds |= LVDS_ENABLE_DITHER; |
3684 | } else { | 3708 | } else { |
3685 | if (HAS_PCH_SPLIT(dev)) | 3709 | if (HAS_PCH_SPLIT(dev)) { |
3686 | pipeconf &= ~PIPE_ENABLE_DITHER; | 3710 | pipeconf &= ~PIPE_ENABLE_DITHER; |
3687 | else | 3711 | pipeconf &= ~PIPE_DITHER_TYPE_MASK; |
3712 | } else | ||
3688 | lvds &= ~LVDS_ENABLE_DITHER; | 3713 | lvds &= ~LVDS_ENABLE_DITHER; |
3689 | } | 3714 | } |
3690 | } | 3715 | } |
@@ -5202,8 +5227,7 @@ static void intel_init_display(struct drm_device *dev) | |||
5202 | else | 5227 | else |
5203 | dev_priv->display.dpms = i9xx_crtc_dpms; | 5228 | dev_priv->display.dpms = i9xx_crtc_dpms; |
5204 | 5229 | ||
5205 | /* Only mobile has FBC, leave pointers NULL for other chips */ | 5230 | if (I915_HAS_FBC(dev)) { |
5206 | if (IS_MOBILE(dev)) { | ||
5207 | if (IS_GM45(dev)) { | 5231 | if (IS_GM45(dev)) { |
5208 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; | 5232 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; |
5209 | dev_priv->display.enable_fbc = g4x_enable_fbc; | 5233 | dev_priv->display.enable_fbc = g4x_enable_fbc; |
@@ -5268,17 +5292,18 @@ static void intel_init_display(struct drm_device *dev) | |||
5268 | dev_priv->display.update_wm = g4x_update_wm; | 5292 | dev_priv->display.update_wm = g4x_update_wm; |
5269 | else if (IS_I965G(dev)) | 5293 | else if (IS_I965G(dev)) |
5270 | dev_priv->display.update_wm = i965_update_wm; | 5294 | dev_priv->display.update_wm = i965_update_wm; |
5271 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) { | 5295 | else if (IS_I9XX(dev)) { |
5272 | dev_priv->display.update_wm = i9xx_update_wm; | 5296 | dev_priv->display.update_wm = i9xx_update_wm; |
5273 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; | 5297 | dev_priv->display.get_fifo_size = i9xx_get_fifo_size; |
5298 | } else if (IS_I85X(dev)) { | ||
5299 | dev_priv->display.update_wm = i9xx_update_wm; | ||
5300 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; | ||
5274 | } else { | 5301 | } else { |
5275 | if (IS_I85X(dev)) | 5302 | dev_priv->display.update_wm = i830_update_wm; |
5276 | dev_priv->display.get_fifo_size = i85x_get_fifo_size; | 5303 | if (IS_845G(dev)) |
5277 | else if (IS_845G(dev)) | ||
5278 | dev_priv->display.get_fifo_size = i845_get_fifo_size; | 5304 | dev_priv->display.get_fifo_size = i845_get_fifo_size; |
5279 | else | 5305 | else |
5280 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | 5306 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
5281 | dev_priv->display.update_wm = i830_update_wm; | ||
5282 | } | 5307 | } |
5283 | } | 5308 | } |
5284 | 5309 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index ca372abc36c..aba72c489a2 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1504,16 +1504,17 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | enum drm_connector_status | 1506 | enum drm_connector_status |
1507 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | 1507 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
1508 | { | 1508 | { |
1509 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1509 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1510 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1510 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1511 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1511 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1512 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1513 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1512 | enum drm_connector_status status = connector_status_connected; | 1514 | enum drm_connector_status status = connector_status_connected; |
1513 | struct edid *edid = NULL; | 1515 | struct edid *edid = NULL; |
1514 | 1516 | ||
1515 | edid = drm_get_edid(connector, | 1517 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); |
1516 | intel_encoder->ddc_bus); | ||
1517 | 1518 | ||
1518 | /* This is only applied to SDVO cards with multiple outputs */ | 1519 | /* This is only applied to SDVO cards with multiple outputs */ |
1519 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { | 1520 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { |
@@ -1526,8 +1527,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1526 | */ | 1527 | */ |
1527 | while(temp_ddc > 1) { | 1528 | while(temp_ddc > 1) { |
1528 | sdvo_priv->ddc_bus = temp_ddc; | 1529 | sdvo_priv->ddc_bus = temp_ddc; |
1529 | edid = drm_get_edid(connector, | 1530 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); |
1530 | intel_encoder->ddc_bus); | ||
1531 | if (edid) { | 1531 | if (edid) { |
1532 | /* | 1532 | /* |
1533 | * When we can get the EDID, maybe it is the | 1533 | * When we can get the EDID, maybe it is the |
@@ -1544,28 +1544,25 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1544 | /* when there is no edid and no monitor is connected with VGA | 1544 | /* when there is no edid and no monitor is connected with VGA |
1545 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1545 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
1546 | */ | 1546 | */ |
1547 | if (edid == NULL && | 1547 | if (edid == NULL && sdvo_priv->analog_ddc_bus && |
1548 | sdvo_priv->analog_ddc_bus && | ||
1549 | !intel_analog_is_connected(connector->dev)) | 1548 | !intel_analog_is_connected(connector->dev)) |
1550 | edid = drm_get_edid(connector, | 1549 | edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); |
1551 | sdvo_priv->analog_ddc_bus); | 1550 | |
1552 | if (edid != NULL) { | 1551 | if (edid != NULL) { |
1553 | /* Don't report the output as connected if it's a DVI-I | 1552 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); |
1554 | * connector with a non-digital EDID coming out. | 1553 | bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK); |
1555 | */ | ||
1556 | if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1557 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
1558 | sdvo_priv->is_hdmi = | ||
1559 | drm_detect_hdmi_monitor(edid); | ||
1560 | else | ||
1561 | status = connector_status_disconnected; | ||
1562 | } | ||
1563 | 1554 | ||
1564 | kfree(edid); | 1555 | /* DDC bus is shared, match EDID to connector type */ |
1565 | connector->display_info.raw_edid = NULL; | 1556 | if (is_digital && need_digital) |
1557 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | ||
1558 | else if (is_digital != need_digital) | ||
1559 | status = connector_status_disconnected; | ||
1566 | 1560 | ||
1567 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1561 | connector->display_info.raw_edid = NULL; |
1562 | } else | ||
1568 | status = connector_status_disconnected; | 1563 | status = connector_status_disconnected; |
1564 | |||
1565 | kfree(edid); | ||
1569 | 1566 | ||
1570 | return status; | 1567 | return status; |
1571 | } | 1568 | } |
@@ -1601,8 +1598,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1601 | 1598 | ||
1602 | if ((sdvo_connector->output_flag & response) == 0) | 1599 | if ((sdvo_connector->output_flag & response) == 0) |
1603 | ret = connector_status_disconnected; | 1600 | ret = connector_status_disconnected; |
1604 | else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1601 | else if (response & SDVO_TMDS_MASK) |
1605 | ret = intel_sdvo_hdmi_sink_detect(connector, response); | 1602 | ret = intel_sdvo_hdmi_sink_detect(connector); |
1606 | else | 1603 | else |
1607 | ret = connector_status_connected; | 1604 | ret = connector_status_connected; |
1608 | 1605 | ||
@@ -2054,40 +2051,17 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
2054 | * outputs, then LVDS outputs. | 2051 | * outputs, then LVDS outputs. |
2055 | */ | 2052 | */ |
2056 | static void | 2053 | static void |
2057 | intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) | 2054 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
2055 | struct intel_sdvo_priv *sdvo, u32 reg) | ||
2058 | { | 2056 | { |
2059 | uint16_t mask = 0; | 2057 | struct sdvo_device_mapping *mapping; |
2060 | unsigned int num_bits; | ||
2061 | 2058 | ||
2062 | /* Make a mask of outputs less than or equal to our own priority in the | 2059 | if (IS_SDVOB(reg)) |
2063 | * list. | 2060 | mapping = &(dev_priv->sdvo_mappings[0]); |
2064 | */ | 2061 | else |
2065 | switch (dev_priv->controlled_output) { | 2062 | mapping = &(dev_priv->sdvo_mappings[1]); |
2066 | case SDVO_OUTPUT_LVDS1: | ||
2067 | mask |= SDVO_OUTPUT_LVDS1; | ||
2068 | case SDVO_OUTPUT_LVDS0: | ||
2069 | mask |= SDVO_OUTPUT_LVDS0; | ||
2070 | case SDVO_OUTPUT_TMDS1: | ||
2071 | mask |= SDVO_OUTPUT_TMDS1; | ||
2072 | case SDVO_OUTPUT_TMDS0: | ||
2073 | mask |= SDVO_OUTPUT_TMDS0; | ||
2074 | case SDVO_OUTPUT_RGB1: | ||
2075 | mask |= SDVO_OUTPUT_RGB1; | ||
2076 | case SDVO_OUTPUT_RGB0: | ||
2077 | mask |= SDVO_OUTPUT_RGB0; | ||
2078 | break; | ||
2079 | } | ||
2080 | |||
2081 | /* Count bits to find what number we are in the priority list. */ | ||
2082 | mask &= dev_priv->caps.output_flags; | ||
2083 | num_bits = hweight16(mask); | ||
2084 | if (num_bits > 3) { | ||
2085 | /* if more than 3 outputs, default to DDC bus 3 for now */ | ||
2086 | num_bits = 3; | ||
2087 | } | ||
2088 | 2063 | ||
2089 | /* Corresponds to SDVO_CONTROL_BUS_DDCx */ | 2064 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); |
2090 | dev_priv->ddc_bus = 1 << num_bits; | ||
2091 | } | 2065 | } |
2092 | 2066 | ||
2093 | static bool | 2067 | static bool |
@@ -2866,7 +2840,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2866 | goto err_i2c; | 2840 | goto err_i2c; |
2867 | } | 2841 | } |
2868 | 2842 | ||
2869 | intel_sdvo_select_ddc_bus(sdvo_priv); | 2843 | intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg); |
2870 | 2844 | ||
2871 | /* Set the input timing to the screen. Assume always input 0. */ | 2845 | /* Set the input timing to the screen. Assume always input 0. */ |
2872 | intel_sdvo_set_target_input(intel_encoder, true, false); | 2846 | intel_sdvo_set_target_input(intel_encoder, true, false); |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 26986c8e1f4..2ebcb979dd7 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 9a59ba46f07..cc004b05d63 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -3283,7 +3283,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3283 | 3283 | ||
3284 | for (i = 0; i < track->num_cb; i++) { | 3284 | for (i = 0; i < track->num_cb; i++) { |
3285 | if (track->cb[i].robj == NULL) { | 3285 | if (track->cb[i].robj == NULL) { |
3286 | if (!(track->fastfill || track->color_channel_mask || | 3286 | if (!(track->zb_cb_clear || track->color_channel_mask || |
3287 | track->blend_read_enable)) { | 3287 | track->blend_read_enable)) { |
3288 | continue; | 3288 | continue; |
3289 | } | 3289 | } |
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index fadfe68de9c..f47cdca1c00 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 5c54db51de8..b2f9efe2897 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 ea46d558e8f..c5c2742e414 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 87c0e384003..4415a5ee587 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -88,6 +88,12 @@ void r420_pipes_init(struct radeon_device *rdev) | |||
88 | /* get max number of pipes */ | 88 | /* get max number of pipes */ |
89 | gb_pipe_select = RREG32(0x402C); | 89 | gb_pipe_select = RREG32(0x402C); |
90 | num_pipes = ((gb_pipe_select >> 12) & 3) + 1; | 90 | num_pipes = ((gb_pipe_select >> 12) & 3) + 1; |
91 | |||
92 | /* SE chips have 1 pipe */ | ||
93 | if ((rdev->pdev->device == 0x5e4c) || | ||
94 | (rdev->pdev->device == 0x5e4f)) | ||
95 | num_pipes = 1; | ||
96 | |||
91 | rdev->num_gb_pipes = num_pipes; | 97 | rdev->num_gb_pipes = num_pipes; |
92 | tmp = 0; | 98 | tmp = 0; |
93 | switch (num_pipes) { | 99 | switch (num_pipes) { |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index c4457791dff..28e473f1f56 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 9149e4a3af0..1c24dad0ac3 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 765854ed33c..0c7ccc6961a 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -1302,6 +1302,8 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1302 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); | 1302 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
1303 | if (!radeon_connector->ddc_bus) | 1303 | if (!radeon_connector->ddc_bus) |
1304 | goto failed; | 1304 | goto failed; |
1305 | } | ||
1306 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | ||
1305 | radeon_connector->dac_load_detect = true; | 1307 | radeon_connector->dac_load_detect = true; |
1306 | drm_connector_attach_property(&radeon_connector->base, | 1308 | drm_connector_attach_property(&radeon_connector->base, |
1307 | rdev->mode_info.load_detect_property, | 1309 | 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 419630dd207..2f042a3c0e6 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 f48f42454fb..da85cad1152 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 b5dff14ea8c..1ebb100015b 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) |
@@ -272,18 +319,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
272 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; | 319 | adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
273 | 320 | ||
274 | /* get the native mode for LVDS */ | 321 | /* get the native mode for LVDS */ |
275 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { | 322 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) |
276 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | 323 | radeon_panel_mode_fixup(encoder, adjusted_mode); |
277 | int mode_id = adjusted_mode->base.id; | ||
278 | *adjusted_mode = *native_mode; | ||
279 | if (!ASIC_IS_AVIVO(rdev)) { | ||
280 | adjusted_mode->hdisplay = mode->hdisplay; | ||
281 | adjusted_mode->vdisplay = mode->vdisplay; | ||
282 | adjusted_mode->crtc_hdisplay = mode->hdisplay; | ||
283 | adjusted_mode->crtc_vdisplay = mode->vdisplay; | ||
284 | } | ||
285 | adjusted_mode->base.id = mode_id; | ||
286 | } | ||
287 | 324 | ||
288 | /* get the native mode for TV */ | 325 | /* get the native mode for TV */ |
289 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | 326 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { |
@@ -1321,7 +1358,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1321 | 1358 | ||
1322 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1359 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
1323 | 1360 | ||
1324 | if (ASIC_IS_AVIVO(rdev)) { | 1361 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { |
1325 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | 1362 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
1326 | atombios_yuv_setup(encoder, true); | 1363 | atombios_yuv_setup(encoder, true); |
1327 | else | 1364 | else |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 021572a3dd9..04068352ccd 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -183,7 +183,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc) | |||
183 | { | 183 | { |
184 | struct radeon_device *rdev = dev->dev_private; | 184 | struct radeon_device *rdev = dev->dev_private; |
185 | 185 | ||
186 | if (crtc < 0 || crtc > 1) { | 186 | if (crtc < 0 || crtc >= rdev->num_crtc) { |
187 | DRM_ERROR("Invalid crtc %d\n", crtc); | 187 | DRM_ERROR("Invalid crtc %d\n", crtc); |
188 | return -EINVAL; | 188 | return -EINVAL; |
189 | } | 189 | } |
@@ -195,7 +195,7 @@ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) | |||
195 | { | 195 | { |
196 | struct radeon_device *rdev = dev->dev_private; | 196 | struct radeon_device *rdev = dev->dev_private; |
197 | 197 | ||
198 | if (crtc < 0 || crtc > 1) { | 198 | if (crtc < 0 || crtc >= rdev->num_crtc) { |
199 | DRM_ERROR("Invalid crtc %d\n", crtc); | 199 | DRM_ERROR("Invalid crtc %d\n", crtc); |
200 | return -EINVAL; | 200 | return -EINVAL; |
201 | } | 201 | } |
@@ -209,7 +209,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) | |||
209 | { | 209 | { |
210 | struct radeon_device *rdev = dev->dev_private; | 210 | struct radeon_device *rdev = dev->dev_private; |
211 | 211 | ||
212 | if (crtc < 0 || crtc > 1) { | 212 | if (crtc < 0 || crtc >= rdev->num_crtc) { |
213 | DRM_ERROR("Invalid crtc %d\n", crtc); | 213 | DRM_ERROR("Invalid crtc %d\n", crtc); |
214 | return; | 214 | return; |
215 | } | 215 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 341df86a253..5a13b3eeef1 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -221,16 +221,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, | |||
221 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 221 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
222 | 222 | ||
223 | /* get the native mode for LVDS */ | 223 | /* get the native mode for LVDS */ |
224 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { | 224 | if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) |
225 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | 225 | radeon_panel_mode_fixup(encoder, adjusted_mode); |
226 | int mode_id = adjusted_mode->base.id; | ||
227 | *adjusted_mode = *native_mode; | ||
228 | adjusted_mode->hdisplay = mode->hdisplay; | ||
229 | adjusted_mode->vdisplay = mode->vdisplay; | ||
230 | adjusted_mode->crtc_hdisplay = mode->hdisplay; | ||
231 | adjusted_mode->crtc_vdisplay = mode->vdisplay; | ||
232 | adjusted_mode->base.id = mode_id; | ||
233 | } | ||
234 | 226 | ||
235 | return true; | 227 | return true; |
236 | } | 228 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 38c0b63e9bb..71e1f0e7438 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 6ec04ac1245..6efac8117c9 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 d6d1149d525..c8768f38511 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) { |