diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 89 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 308 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 12 |
12 files changed, 363 insertions, 224 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4d46441cbe2..0a893f7400f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -1207,13 +1207,17 @@ static int i915_context_status(struct seq_file *m, void *unused) | |||
1207 | if (ret) | 1207 | if (ret) |
1208 | return ret; | 1208 | return ret; |
1209 | 1209 | ||
1210 | seq_printf(m, "power context "); | 1210 | if (dev_priv->pwrctx) { |
1211 | describe_obj(m, dev_priv->pwrctx); | 1211 | seq_printf(m, "power context "); |
1212 | seq_printf(m, "\n"); | 1212 | describe_obj(m, dev_priv->pwrctx); |
1213 | seq_printf(m, "\n"); | ||
1214 | } | ||
1213 | 1215 | ||
1214 | seq_printf(m, "render context "); | 1216 | if (dev_priv->renderctx) { |
1215 | describe_obj(m, dev_priv->renderctx); | 1217 | seq_printf(m, "render context "); |
1216 | seq_printf(m, "\n"); | 1218 | describe_obj(m, dev_priv->renderctx); |
1219 | seq_printf(m, "\n"); | ||
1220 | } | ||
1217 | 1221 | ||
1218 | mutex_unlock(&dev->mode_config.mutex); | 1222 | mutex_unlock(&dev->mode_config.mutex); |
1219 | 1223 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 0239e9974bf..e1787022d6c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1266,30 +1266,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1266 | 1266 | ||
1267 | intel_modeset_gem_init(dev); | 1267 | intel_modeset_gem_init(dev); |
1268 | 1268 | ||
1269 | if (IS_IVYBRIDGE(dev)) { | ||
1270 | /* Share pre & uninstall handlers with ILK/SNB */ | ||
1271 | dev->driver->irq_handler = ivybridge_irq_handler; | ||
1272 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
1273 | dev->driver->irq_postinstall = ivybridge_irq_postinstall; | ||
1274 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
1275 | dev->driver->enable_vblank = ivybridge_enable_vblank; | ||
1276 | dev->driver->disable_vblank = ivybridge_disable_vblank; | ||
1277 | } else if (HAS_PCH_SPLIT(dev)) { | ||
1278 | dev->driver->irq_handler = ironlake_irq_handler; | ||
1279 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
1280 | dev->driver->irq_postinstall = ironlake_irq_postinstall; | ||
1281 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
1282 | dev->driver->enable_vblank = ironlake_enable_vblank; | ||
1283 | dev->driver->disable_vblank = ironlake_disable_vblank; | ||
1284 | } else { | ||
1285 | dev->driver->irq_preinstall = i915_driver_irq_preinstall; | ||
1286 | dev->driver->irq_postinstall = i915_driver_irq_postinstall; | ||
1287 | dev->driver->irq_uninstall = i915_driver_irq_uninstall; | ||
1288 | dev->driver->irq_handler = i915_driver_irq_handler; | ||
1289 | dev->driver->enable_vblank = i915_enable_vblank; | ||
1290 | dev->driver->disable_vblank = i915_disable_vblank; | ||
1291 | } | ||
1292 | |||
1293 | ret = drm_irq_install(dev); | 1269 | ret = drm_irq_install(dev); |
1294 | if (ret) | 1270 | if (ret) |
1295 | goto cleanup_gem; | 1271 | goto cleanup_gem; |
@@ -2017,12 +1993,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2017 | /* enable GEM by default */ | 1993 | /* enable GEM by default */ |
2018 | dev_priv->has_gem = 1; | 1994 | dev_priv->has_gem = 1; |
2019 | 1995 | ||
2020 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1996 | intel_irq_init(dev); |
2021 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | ||
2022 | if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { | ||
2023 | dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ | ||
2024 | dev->driver->get_vblank_counter = gm45_get_vblank_counter; | ||
2025 | } | ||
2026 | 1997 | ||
2027 | /* Try to make sure MCHBAR is enabled before poking at it */ | 1998 | /* Try to make sure MCHBAR is enabled before poking at it */ |
2028 | intel_setup_mchbar(dev); | 1999 | intel_setup_mchbar(dev); |
@@ -2182,9 +2153,8 @@ int i915_driver_unload(struct drm_device *dev) | |||
2182 | /* Flush any outstanding unpin_work. */ | 2153 | /* Flush any outstanding unpin_work. */ |
2183 | flush_workqueue(dev_priv->wq); | 2154 | flush_workqueue(dev_priv->wq); |
2184 | 2155 | ||
2185 | i915_gem_free_all_phys_object(dev); | ||
2186 | |||
2187 | mutex_lock(&dev->struct_mutex); | 2156 | mutex_lock(&dev->struct_mutex); |
2157 | i915_gem_free_all_phys_object(dev); | ||
2188 | i915_gem_cleanup_ringbuffer(dev); | 2158 | i915_gem_cleanup_ringbuffer(dev); |
2189 | mutex_unlock(&dev->struct_mutex); | 2159 | mutex_unlock(&dev->struct_mutex); |
2190 | if (I915_HAS_FBC(dev) && i915_powersave) | 2160 | if (I915_HAS_FBC(dev) && i915_powersave) |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0defd427059..013d304455b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -579,6 +579,9 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
579 | } else switch (INTEL_INFO(dev)->gen) { | 579 | } else switch (INTEL_INFO(dev)->gen) { |
580 | case 6: | 580 | case 6: |
581 | ret = gen6_do_reset(dev, flags); | 581 | ret = gen6_do_reset(dev, flags); |
582 | /* If reset with a user forcewake, try to restore */ | ||
583 | if (atomic_read(&dev_priv->forcewake_count)) | ||
584 | __gen6_gt_force_wake_get(dev_priv); | ||
582 | break; | 585 | break; |
583 | case 5: | 586 | case 5: |
584 | ret = ironlake_do_reset(dev, flags); | 587 | ret = ironlake_do_reset(dev, flags); |
@@ -762,14 +765,6 @@ static struct drm_driver driver = { | |||
762 | .resume = i915_resume, | 765 | .resume = i915_resume, |
763 | 766 | ||
764 | .device_is_agp = i915_driver_device_is_agp, | 767 | .device_is_agp = i915_driver_device_is_agp, |
765 | .enable_vblank = i915_enable_vblank, | ||
766 | .disable_vblank = i915_disable_vblank, | ||
767 | .get_vblank_timestamp = i915_get_vblank_timestamp, | ||
768 | .get_scanout_position = i915_get_crtc_scanoutpos, | ||
769 | .irq_preinstall = i915_driver_irq_preinstall, | ||
770 | .irq_postinstall = i915_driver_irq_postinstall, | ||
771 | .irq_uninstall = i915_driver_irq_uninstall, | ||
772 | .irq_handler = i915_driver_irq_handler, | ||
773 | .reclaim_buffers = drm_core_reclaim_buffers, | 768 | .reclaim_buffers = drm_core_reclaim_buffers, |
774 | .master_create = i915_master_create, | 769 | .master_create = i915_master_create, |
775 | .master_destroy = i915_master_destroy, | 770 | .master_destroy = i915_master_destroy, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f63ee162f12..f245c588ae9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -211,6 +211,9 @@ struct drm_i915_display_funcs { | |||
211 | void (*fdi_link_train)(struct drm_crtc *crtc); | 211 | void (*fdi_link_train)(struct drm_crtc *crtc); |
212 | void (*init_clock_gating)(struct drm_device *dev); | 212 | void (*init_clock_gating)(struct drm_device *dev); |
213 | void (*init_pch_clock_gating)(struct drm_device *dev); | 213 | void (*init_pch_clock_gating)(struct drm_device *dev); |
214 | int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, | ||
215 | struct drm_framebuffer *fb, | ||
216 | struct drm_i915_gem_object *obj); | ||
214 | /* clock updates for mode set */ | 217 | /* clock updates for mode set */ |
215 | /* cursor updates */ | 218 | /* cursor updates */ |
216 | /* render clock increase/decrease */ | 219 | /* render clock increase/decrease */ |
@@ -994,8 +997,6 @@ extern unsigned int i915_enable_fbc; | |||
994 | 997 | ||
995 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 998 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
996 | extern int i915_resume(struct drm_device *dev); | 999 | extern int i915_resume(struct drm_device *dev); |
997 | extern void i915_save_display(struct drm_device *dev); | ||
998 | extern void i915_restore_display(struct drm_device *dev); | ||
999 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); | 1000 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); |
1000 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); | 1001 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); |
1001 | 1002 | ||
@@ -1030,33 +1031,12 @@ extern int i915_irq_emit(struct drm_device *dev, void *data, | |||
1030 | extern int i915_irq_wait(struct drm_device *dev, void *data, | 1031 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
1031 | struct drm_file *file_priv); | 1032 | struct drm_file *file_priv); |
1032 | 1033 | ||
1033 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 1034 | extern void intel_irq_init(struct drm_device *dev); |
1034 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | ||
1035 | extern int i915_driver_irq_postinstall(struct drm_device *dev); | ||
1036 | extern void i915_driver_irq_uninstall(struct drm_device * dev); | ||
1037 | |||
1038 | extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS); | ||
1039 | extern void ironlake_irq_preinstall(struct drm_device *dev); | ||
1040 | extern int ironlake_irq_postinstall(struct drm_device *dev); | ||
1041 | extern void ironlake_irq_uninstall(struct drm_device *dev); | ||
1042 | |||
1043 | extern irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS); | ||
1044 | extern void ivybridge_irq_preinstall(struct drm_device *dev); | ||
1045 | extern int ivybridge_irq_postinstall(struct drm_device *dev); | ||
1046 | extern void ivybridge_irq_uninstall(struct drm_device *dev); | ||
1047 | 1035 | ||
1048 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, | 1036 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, |
1049 | struct drm_file *file_priv); | 1037 | struct drm_file *file_priv); |
1050 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, | 1038 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, |
1051 | struct drm_file *file_priv); | 1039 | struct drm_file *file_priv); |
1052 | extern int i915_enable_vblank(struct drm_device *dev, int crtc); | ||
1053 | extern void i915_disable_vblank(struct drm_device *dev, int crtc); | ||
1054 | extern int ironlake_enable_vblank(struct drm_device *dev, int crtc); | ||
1055 | extern void ironlake_disable_vblank(struct drm_device *dev, int crtc); | ||
1056 | extern int ivybridge_enable_vblank(struct drm_device *dev, int crtc); | ||
1057 | extern void ivybridge_disable_vblank(struct drm_device *dev, int crtc); | ||
1058 | extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); | ||
1059 | extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); | ||
1060 | extern int i915_vblank_swap(struct drm_device *dev, void *data, | 1040 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
1061 | struct drm_file *file_priv); | 1041 | struct drm_file *file_priv); |
1062 | 1042 | ||
@@ -1067,13 +1047,6 @@ void | |||
1067 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | 1047 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); |
1068 | 1048 | ||
1069 | void intel_enable_asle (struct drm_device *dev); | 1049 | void intel_enable_asle (struct drm_device *dev); |
1070 | int i915_get_vblank_timestamp(struct drm_device *dev, int crtc, | ||
1071 | int *max_error, | ||
1072 | struct timeval *vblank_time, | ||
1073 | unsigned flags); | ||
1074 | |||
1075 | int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | ||
1076 | int *vpos, int *hpos); | ||
1077 | 1050 | ||
1078 | #ifdef CONFIG_DEBUG_FS | 1051 | #ifdef CONFIG_DEBUG_FS |
1079 | extern void i915_destroy_error_state(struct drm_device *dev); | 1052 | extern void i915_destroy_error_state(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 12d32579b95..5c0d1247f45 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
32 | #include "i915_trace.h" | 32 | #include "i915_trace.h" |
33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
34 | #include <linux/shmem_fs.h> | ||
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <linux/swap.h> | 36 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
@@ -359,8 +360,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, | |||
359 | if ((page_offset + remain) > PAGE_SIZE) | 360 | if ((page_offset + remain) > PAGE_SIZE) |
360 | page_length = PAGE_SIZE - page_offset; | 361 | page_length = PAGE_SIZE - page_offset; |
361 | 362 | ||
362 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, | 363 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); |
363 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
364 | if (IS_ERR(page)) | 364 | if (IS_ERR(page)) |
365 | return PTR_ERR(page); | 365 | return PTR_ERR(page); |
366 | 366 | ||
@@ -463,10 +463,11 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, | |||
463 | if ((data_page_offset + page_length) > PAGE_SIZE) | 463 | if ((data_page_offset + page_length) > PAGE_SIZE) |
464 | page_length = PAGE_SIZE - data_page_offset; | 464 | page_length = PAGE_SIZE - data_page_offset; |
465 | 465 | ||
466 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, | 466 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); |
467 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | 467 | if (IS_ERR(page)) { |
468 | if (IS_ERR(page)) | 468 | ret = PTR_ERR(page); |
469 | return PTR_ERR(page); | 469 | goto out; |
470 | } | ||
470 | 471 | ||
471 | if (do_bit17_swizzling) { | 472 | if (do_bit17_swizzling) { |
472 | slow_shmem_bit17_copy(page, | 473 | slow_shmem_bit17_copy(page, |
@@ -795,8 +796,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, | |||
795 | if ((page_offset + remain) > PAGE_SIZE) | 796 | if ((page_offset + remain) > PAGE_SIZE) |
796 | page_length = PAGE_SIZE - page_offset; | 797 | page_length = PAGE_SIZE - page_offset; |
797 | 798 | ||
798 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, | 799 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); |
799 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
800 | if (IS_ERR(page)) | 800 | if (IS_ERR(page)) |
801 | return PTR_ERR(page); | 801 | return PTR_ERR(page); |
802 | 802 | ||
@@ -905,8 +905,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, | |||
905 | if ((data_page_offset + page_length) > PAGE_SIZE) | 905 | if ((data_page_offset + page_length) > PAGE_SIZE) |
906 | page_length = PAGE_SIZE - data_page_offset; | 906 | page_length = PAGE_SIZE - data_page_offset; |
907 | 907 | ||
908 | page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, | 908 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); |
909 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
910 | if (IS_ERR(page)) { | 909 | if (IS_ERR(page)) { |
911 | ret = PTR_ERR(page); | 910 | ret = PTR_ERR(page); |
912 | goto out; | 911 | goto out; |
@@ -1217,11 +1216,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1217 | ret = i915_gem_object_bind_to_gtt(obj, 0, true); | 1216 | ret = i915_gem_object_bind_to_gtt(obj, 0, true); |
1218 | if (ret) | 1217 | if (ret) |
1219 | goto unlock; | 1218 | goto unlock; |
1220 | } | ||
1221 | 1219 | ||
1222 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | 1220 | ret = i915_gem_object_set_to_gtt_domain(obj, write); |
1223 | if (ret) | 1221 | if (ret) |
1224 | goto unlock; | 1222 | goto unlock; |
1223 | } | ||
1225 | 1224 | ||
1226 | if (obj->tiling_mode == I915_TILING_NONE) | 1225 | if (obj->tiling_mode == I915_TILING_NONE) |
1227 | ret = i915_gem_object_put_fence(obj); | 1226 | ret = i915_gem_object_put_fence(obj); |
@@ -1556,12 +1555,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, | |||
1556 | 1555 | ||
1557 | inode = obj->base.filp->f_path.dentry->d_inode; | 1556 | inode = obj->base.filp->f_path.dentry->d_inode; |
1558 | mapping = inode->i_mapping; | 1557 | mapping = inode->i_mapping; |
1558 | gfpmask |= mapping_gfp_mask(mapping); | ||
1559 | |||
1559 | for (i = 0; i < page_count; i++) { | 1560 | for (i = 0; i < page_count; i++) { |
1560 | page = read_cache_page_gfp(mapping, i, | 1561 | page = shmem_read_mapping_page_gfp(mapping, i, gfpmask); |
1561 | GFP_HIGHUSER | | ||
1562 | __GFP_COLD | | ||
1563 | __GFP_RECLAIMABLE | | ||
1564 | gfpmask); | ||
1565 | if (IS_ERR(page)) | 1562 | if (IS_ERR(page)) |
1566 | goto err_pages; | 1563 | goto err_pages; |
1567 | 1564 | ||
@@ -1699,13 +1696,10 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj) | |||
1699 | /* Our goal here is to return as much of the memory as | 1696 | /* Our goal here is to return as much of the memory as |
1700 | * is possible back to the system as we are called from OOM. | 1697 | * is possible back to the system as we are called from OOM. |
1701 | * To do this we must instruct the shmfs to drop all of its | 1698 | * To do this we must instruct the shmfs to drop all of its |
1702 | * backing pages, *now*. Here we mirror the actions taken | 1699 | * backing pages, *now*. |
1703 | * when by shmem_delete_inode() to release the backing store. | ||
1704 | */ | 1700 | */ |
1705 | inode = obj->base.filp->f_path.dentry->d_inode; | 1701 | inode = obj->base.filp->f_path.dentry->d_inode; |
1706 | truncate_inode_pages(inode->i_mapping, 0); | 1702 | shmem_truncate_range(inode, 0, (loff_t)-1); |
1707 | if (inode->i_op->truncate_range) | ||
1708 | inode->i_op->truncate_range(inode, 0, (loff_t)-1); | ||
1709 | 1703 | ||
1710 | obj->madv = __I915_MADV_PURGED; | 1704 | obj->madv = __I915_MADV_PURGED; |
1711 | } | 1705 | } |
@@ -2078,8 +2072,8 @@ i915_wait_request(struct intel_ring_buffer *ring, | |||
2078 | if (!ier) { | 2072 | if (!ier) { |
2079 | DRM_ERROR("something (likely vbetool) disabled " | 2073 | DRM_ERROR("something (likely vbetool) disabled " |
2080 | "interrupts, re-enabling\n"); | 2074 | "interrupts, re-enabling\n"); |
2081 | i915_driver_irq_preinstall(ring->dev); | 2075 | ring->dev->driver->irq_preinstall(ring->dev); |
2082 | i915_driver_irq_postinstall(ring->dev); | 2076 | ring->dev->driver->irq_postinstall(ring->dev); |
2083 | } | 2077 | } |
2084 | 2078 | ||
2085 | trace_i915_gem_request_wait_begin(ring, seqno); | 2079 | trace_i915_gem_request_wait_begin(ring, seqno); |
@@ -2924,8 +2918,6 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) | |||
2924 | */ | 2918 | */ |
2925 | wmb(); | 2919 | wmb(); |
2926 | 2920 | ||
2927 | i915_gem_release_mmap(obj); | ||
2928 | |||
2929 | old_write_domain = obj->base.write_domain; | 2921 | old_write_domain = obj->base.write_domain; |
2930 | obj->base.write_domain = 0; | 2922 | obj->base.write_domain = 0; |
2931 | 2923 | ||
@@ -3565,6 +3557,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | |||
3565 | { | 3557 | { |
3566 | struct drm_i915_private *dev_priv = dev->dev_private; | 3558 | struct drm_i915_private *dev_priv = dev->dev_private; |
3567 | struct drm_i915_gem_object *obj; | 3559 | struct drm_i915_gem_object *obj; |
3560 | struct address_space *mapping; | ||
3568 | 3561 | ||
3569 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); | 3562 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); |
3570 | if (obj == NULL) | 3563 | if (obj == NULL) |
@@ -3575,6 +3568,9 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | |||
3575 | return NULL; | 3568 | return NULL; |
3576 | } | 3569 | } |
3577 | 3570 | ||
3571 | mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; | ||
3572 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
3573 | |||
3578 | i915_gem_info_add_obj(dev_priv, size); | 3574 | i915_gem_info_add_obj(dev_priv, size); |
3579 | 3575 | ||
3580 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 3576 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
@@ -3950,8 +3946,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, | |||
3950 | 3946 | ||
3951 | page_count = obj->base.size / PAGE_SIZE; | 3947 | page_count = obj->base.size / PAGE_SIZE; |
3952 | for (i = 0; i < page_count; i++) { | 3948 | for (i = 0; i < page_count; i++) { |
3953 | struct page *page = read_cache_page_gfp(mapping, i, | 3949 | struct page *page = shmem_read_mapping_page(mapping, i); |
3954 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
3955 | if (!IS_ERR(page)) { | 3950 | if (!IS_ERR(page)) { |
3956 | char *dst = kmap_atomic(page); | 3951 | char *dst = kmap_atomic(page); |
3957 | memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE); | 3952 | memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE); |
@@ -4012,8 +4007,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4012 | struct page *page; | 4007 | struct page *page; |
4013 | char *dst, *src; | 4008 | char *dst, *src; |
4014 | 4009 | ||
4015 | page = read_cache_page_gfp(mapping, i, | 4010 | page = shmem_read_mapping_page(mapping, i); |
4016 | GFP_HIGHUSER | __GFP_RECLAIMABLE); | ||
4017 | if (IS_ERR(page)) | 4011 | if (IS_ERR(page)) |
4018 | return PTR_ERR(page); | 4012 | return PTR_ERR(page); |
4019 | 4013 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 20a4cc5b818..4934cf84c32 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -187,10 +187,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, | |||
187 | if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) | 187 | if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) |
188 | i915_gem_clflush_object(obj); | 188 | i915_gem_clflush_object(obj); |
189 | 189 | ||
190 | /* blow away mappings if mapped through GTT */ | ||
191 | if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT) | ||
192 | i915_gem_release_mmap(obj); | ||
193 | |||
194 | if (obj->base.pending_write_domain) | 190 | if (obj->base.pending_write_domain) |
195 | cd->flips |= atomic_read(&obj->pending_flip); | 191 | cd->flips |= atomic_read(&obj->pending_flip); |
196 | 192 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b9fafe3b045..3b03f85ea62 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -152,7 +152,7 @@ i915_pipe_enabled(struct drm_device *dev, int pipe) | |||
152 | /* Called from drm generic code, passed a 'crtc', which | 152 | /* Called from drm generic code, passed a 'crtc', which |
153 | * we use as a pipe index | 153 | * we use as a pipe index |
154 | */ | 154 | */ |
155 | u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | 155 | static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) |
156 | { | 156 | { |
157 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 157 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
158 | unsigned long high_frame; | 158 | unsigned long high_frame; |
@@ -184,7 +184,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
184 | return (high1 << 8) | low; | 184 | return (high1 << 8) | low; |
185 | } | 185 | } |
186 | 186 | ||
187 | u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | 187 | static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) |
188 | { | 188 | { |
189 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 189 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
190 | int reg = PIPE_FRMCOUNT_GM45(pipe); | 190 | int reg = PIPE_FRMCOUNT_GM45(pipe); |
@@ -198,7 +198,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | |||
198 | return I915_READ(reg); | 198 | return I915_READ(reg); |
199 | } | 199 | } |
200 | 200 | ||
201 | int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | 201 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, |
202 | int *vpos, int *hpos) | 202 | int *vpos, int *hpos) |
203 | { | 203 | { |
204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -264,7 +264,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | |||
264 | return ret; | 264 | return ret; |
265 | } | 265 | } |
266 | 266 | ||
267 | int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, | 267 | static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, |
268 | int *max_error, | 268 | int *max_error, |
269 | struct timeval *vblank_time, | 269 | struct timeval *vblank_time, |
270 | unsigned flags) | 270 | unsigned flags) |
@@ -462,7 +462,7 @@ static void pch_irq_handler(struct drm_device *dev) | |||
462 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); | 462 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); |
463 | } | 463 | } |
464 | 464 | ||
465 | irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) | 465 | static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) |
466 | { | 466 | { |
467 | struct drm_device *dev = (struct drm_device *) arg; | 467 | struct drm_device *dev = (struct drm_device *) arg; |
468 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 468 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -550,7 +550,7 @@ done: | |||
550 | return ret; | 550 | return ret; |
551 | } | 551 | } |
552 | 552 | ||
553 | irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) | 553 | static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) |
554 | { | 554 | { |
555 | struct drm_device *dev = (struct drm_device *) arg; | 555 | struct drm_device *dev = (struct drm_device *) arg; |
556 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 556 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -1209,7 +1209,7 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | |||
1209 | } | 1209 | } |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 1212 | static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
1213 | { | 1213 | { |
1214 | struct drm_device *dev = (struct drm_device *) arg; | 1214 | struct drm_device *dev = (struct drm_device *) arg; |
1215 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1215 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -1454,7 +1454,7 @@ int i915_irq_wait(struct drm_device *dev, void *data, | |||
1454 | /* Called from drm generic code, passed 'crtc' which | 1454 | /* Called from drm generic code, passed 'crtc' which |
1455 | * we use as a pipe index | 1455 | * we use as a pipe index |
1456 | */ | 1456 | */ |
1457 | int i915_enable_vblank(struct drm_device *dev, int pipe) | 1457 | static int i915_enable_vblank(struct drm_device *dev, int pipe) |
1458 | { | 1458 | { |
1459 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1459 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1460 | unsigned long irqflags; | 1460 | unsigned long irqflags; |
@@ -1478,7 +1478,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
1478 | return 0; | 1478 | return 0; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | int ironlake_enable_vblank(struct drm_device *dev, int pipe) | 1481 | static int ironlake_enable_vblank(struct drm_device *dev, int pipe) |
1482 | { | 1482 | { |
1483 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1483 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1484 | unsigned long irqflags; | 1484 | unsigned long irqflags; |
@@ -1494,7 +1494,7 @@ int ironlake_enable_vblank(struct drm_device *dev, int pipe) | |||
1494 | return 0; | 1494 | return 0; |
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | int ivybridge_enable_vblank(struct drm_device *dev, int pipe) | 1497 | static int ivybridge_enable_vblank(struct drm_device *dev, int pipe) |
1498 | { | 1498 | { |
1499 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1499 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1500 | unsigned long irqflags; | 1500 | unsigned long irqflags; |
@@ -1513,7 +1513,7 @@ int ivybridge_enable_vblank(struct drm_device *dev, int pipe) | |||
1513 | /* Called from drm generic code, passed 'crtc' which | 1513 | /* Called from drm generic code, passed 'crtc' which |
1514 | * we use as a pipe index | 1514 | * we use as a pipe index |
1515 | */ | 1515 | */ |
1516 | void i915_disable_vblank(struct drm_device *dev, int pipe) | 1516 | static void i915_disable_vblank(struct drm_device *dev, int pipe) |
1517 | { | 1517 | { |
1518 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1518 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1519 | unsigned long irqflags; | 1519 | unsigned long irqflags; |
@@ -1529,7 +1529,7 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) | |||
1529 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1529 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1530 | } | 1530 | } |
1531 | 1531 | ||
1532 | void ironlake_disable_vblank(struct drm_device *dev, int pipe) | 1532 | static void ironlake_disable_vblank(struct drm_device *dev, int pipe) |
1533 | { | 1533 | { |
1534 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1534 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1535 | unsigned long irqflags; | 1535 | unsigned long irqflags; |
@@ -1540,7 +1540,7 @@ void ironlake_disable_vblank(struct drm_device *dev, int pipe) | |||
1540 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1540 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1541 | } | 1541 | } |
1542 | 1542 | ||
1543 | void ivybridge_disable_vblank(struct drm_device *dev, int pipe) | 1543 | static void ivybridge_disable_vblank(struct drm_device *dev, int pipe) |
1544 | { | 1544 | { |
1545 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1545 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1546 | unsigned long irqflags; | 1546 | unsigned long irqflags; |
@@ -1728,7 +1728,7 @@ repeat: | |||
1728 | 1728 | ||
1729 | /* drm_dma.h hooks | 1729 | /* drm_dma.h hooks |
1730 | */ | 1730 | */ |
1731 | void ironlake_irq_preinstall(struct drm_device *dev) | 1731 | static void ironlake_irq_preinstall(struct drm_device *dev) |
1732 | { | 1732 | { |
1733 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1733 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1734 | 1734 | ||
@@ -1740,6 +1740,17 @@ void ironlake_irq_preinstall(struct drm_device *dev) | |||
1740 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); | 1740 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); |
1741 | 1741 | ||
1742 | I915_WRITE(HWSTAM, 0xeffe); | 1742 | I915_WRITE(HWSTAM, 0xeffe); |
1743 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | ||
1744 | /* Workaround stalls observed on Sandy Bridge GPUs by | ||
1745 | * making the blitter command streamer generate a | ||
1746 | * write to the Hardware Status Page for | ||
1747 | * MI_USER_INTERRUPT. This appears to serialize the | ||
1748 | * previous seqno write out before the interrupt | ||
1749 | * happens. | ||
1750 | */ | ||
1751 | I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT); | ||
1752 | I915_WRITE(GEN6_BSD_HWSTAM, ~GEN6_BSD_USER_INTERRUPT); | ||
1753 | } | ||
1743 | 1754 | ||
1744 | /* XXX hotplug from PCH */ | 1755 | /* XXX hotplug from PCH */ |
1745 | 1756 | ||
@@ -1758,7 +1769,7 @@ void ironlake_irq_preinstall(struct drm_device *dev) | |||
1758 | POSTING_READ(SDEIER); | 1769 | POSTING_READ(SDEIER); |
1759 | } | 1770 | } |
1760 | 1771 | ||
1761 | int ironlake_irq_postinstall(struct drm_device *dev) | 1772 | static int ironlake_irq_postinstall(struct drm_device *dev) |
1762 | { | 1773 | { |
1763 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1774 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1764 | /* enable kind of interrupts always enabled */ | 1775 | /* enable kind of interrupts always enabled */ |
@@ -1830,7 +1841,7 @@ int ironlake_irq_postinstall(struct drm_device *dev) | |||
1830 | return 0; | 1841 | return 0; |
1831 | } | 1842 | } |
1832 | 1843 | ||
1833 | int ivybridge_irq_postinstall(struct drm_device *dev) | 1844 | static int ivybridge_irq_postinstall(struct drm_device *dev) |
1834 | { | 1845 | { |
1835 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1846 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1836 | /* enable kind of interrupts always enabled */ | 1847 | /* enable kind of interrupts always enabled */ |
@@ -1880,7 +1891,7 @@ int ivybridge_irq_postinstall(struct drm_device *dev) | |||
1880 | return 0; | 1891 | return 0; |
1881 | } | 1892 | } |
1882 | 1893 | ||
1883 | void i915_driver_irq_preinstall(struct drm_device * dev) | 1894 | static void i915_driver_irq_preinstall(struct drm_device * dev) |
1884 | { | 1895 | { |
1885 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1896 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1886 | int pipe; | 1897 | int pipe; |
@@ -1907,7 +1918,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
1907 | * Must be called after intel_modeset_init or hotplug interrupts won't be | 1918 | * Must be called after intel_modeset_init or hotplug interrupts won't be |
1908 | * enabled correctly. | 1919 | * enabled correctly. |
1909 | */ | 1920 | */ |
1910 | int i915_driver_irq_postinstall(struct drm_device *dev) | 1921 | static int i915_driver_irq_postinstall(struct drm_device *dev) |
1911 | { | 1922 | { |
1912 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1923 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1913 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 1924 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
@@ -1983,7 +1994,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1983 | return 0; | 1994 | return 0; |
1984 | } | 1995 | } |
1985 | 1996 | ||
1986 | void ironlake_irq_uninstall(struct drm_device *dev) | 1997 | static void ironlake_irq_uninstall(struct drm_device *dev) |
1987 | { | 1998 | { |
1988 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1999 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1989 | 2000 | ||
@@ -2003,7 +2014,7 @@ void ironlake_irq_uninstall(struct drm_device *dev) | |||
2003 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 2014 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
2004 | } | 2015 | } |
2005 | 2016 | ||
2006 | void i915_driver_irq_uninstall(struct drm_device * dev) | 2017 | static void i915_driver_irq_uninstall(struct drm_device * dev) |
2007 | { | 2018 | { |
2008 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 2019 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2009 | int pipe; | 2020 | int pipe; |
@@ -2029,3 +2040,41 @@ void i915_driver_irq_uninstall(struct drm_device * dev) | |||
2029 | I915_READ(PIPESTAT(pipe)) & 0x8000ffff); | 2040 | I915_READ(PIPESTAT(pipe)) & 0x8000ffff); |
2030 | I915_WRITE(IIR, I915_READ(IIR)); | 2041 | I915_WRITE(IIR, I915_READ(IIR)); |
2031 | } | 2042 | } |
2043 | |||
2044 | void intel_irq_init(struct drm_device *dev) | ||
2045 | { | ||
2046 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | ||
2047 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | ||
2048 | if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { | ||
2049 | dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ | ||
2050 | dev->driver->get_vblank_counter = gm45_get_vblank_counter; | ||
2051 | } | ||
2052 | |||
2053 | |||
2054 | dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; | ||
2055 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; | ||
2056 | |||
2057 | if (IS_IVYBRIDGE(dev)) { | ||
2058 | /* Share pre & uninstall handlers with ILK/SNB */ | ||
2059 | dev->driver->irq_handler = ivybridge_irq_handler; | ||
2060 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
2061 | dev->driver->irq_postinstall = ivybridge_irq_postinstall; | ||
2062 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
2063 | dev->driver->enable_vblank = ivybridge_enable_vblank; | ||
2064 | dev->driver->disable_vblank = ivybridge_disable_vblank; | ||
2065 | } else if (HAS_PCH_SPLIT(dev)) { | ||
2066 | dev->driver->irq_handler = ironlake_irq_handler; | ||
2067 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
2068 | dev->driver->irq_postinstall = ironlake_irq_postinstall; | ||
2069 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
2070 | dev->driver->enable_vblank = ironlake_enable_vblank; | ||
2071 | dev->driver->disable_vblank = ironlake_disable_vblank; | ||
2072 | } else { | ||
2073 | dev->driver->irq_preinstall = i915_driver_irq_preinstall; | ||
2074 | dev->driver->irq_postinstall = i915_driver_irq_postinstall; | ||
2075 | dev->driver->irq_uninstall = i915_driver_irq_uninstall; | ||
2076 | dev->driver->irq_handler = i915_driver_irq_handler; | ||
2077 | dev->driver->enable_vblank = i915_enable_vblank; | ||
2078 | dev->driver->disable_vblank = i915_disable_vblank; | ||
2079 | } | ||
2080 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2f967af8e62..5d5def756c9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -531,6 +531,7 @@ | |||
531 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 | 531 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 |
532 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) | 532 | #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) |
533 | 533 | ||
534 | #define GEN6_BSD_HWSTAM 0x12098 | ||
534 | #define GEN6_BSD_IMR 0x120a8 | 535 | #define GEN6_BSD_IMR 0x120a8 |
535 | #define GEN6_BSD_USER_INTERRUPT (1 << 12) | 536 | #define GEN6_BSD_USER_INTERRUPT (1 << 12) |
536 | 537 | ||
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 60a94d2b526..5257cfc34c3 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -597,7 +597,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
597 | return; | 597 | return; |
598 | } | 598 | } |
599 | 599 | ||
600 | void i915_save_display(struct drm_device *dev) | 600 | static void i915_save_display(struct drm_device *dev) |
601 | { | 601 | { |
602 | struct drm_i915_private *dev_priv = dev->dev_private; | 602 | struct drm_i915_private *dev_priv = dev->dev_private; |
603 | 603 | ||
@@ -689,7 +689,7 @@ void i915_save_display(struct drm_device *dev) | |||
689 | i915_save_vga(dev); | 689 | i915_save_vga(dev); |
690 | } | 690 | } |
691 | 691 | ||
692 | void i915_restore_display(struct drm_device *dev) | 692 | static void i915_restore_display(struct drm_device *dev) |
693 | { | 693 | { |
694 | struct drm_i915_private *dev_priv = dev->dev_private; | 694 | struct drm_i915_private *dev_priv = dev->dev_private; |
695 | 695 | ||
@@ -780,6 +780,7 @@ void i915_restore_display(struct drm_device *dev) | |||
780 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); | 780 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); |
781 | else | 781 | else |
782 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | 782 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); |
783 | |||
783 | I915_WRITE(VGA0, dev_priv->saveVGA0); | 784 | I915_WRITE(VGA0, dev_priv->saveVGA0); |
784 | I915_WRITE(VGA1, dev_priv->saveVGA1); | 785 | I915_WRITE(VGA1, dev_priv->saveVGA1); |
785 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | 786 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); |
@@ -796,6 +797,8 @@ int i915_save_state(struct drm_device *dev) | |||
796 | 797 | ||
797 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 798 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
798 | 799 | ||
800 | mutex_lock(&dev->struct_mutex); | ||
801 | |||
799 | /* Hardware status page */ | 802 | /* Hardware status page */ |
800 | dev_priv->saveHWS = I915_READ(HWS_PGA); | 803 | dev_priv->saveHWS = I915_READ(HWS_PGA); |
801 | 804 | ||
@@ -835,6 +838,8 @@ int i915_save_state(struct drm_device *dev) | |||
835 | for (i = 0; i < 3; i++) | 838 | for (i = 0; i < 3; i++) |
836 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | 839 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); |
837 | 840 | ||
841 | mutex_unlock(&dev->struct_mutex); | ||
842 | |||
838 | return 0; | 843 | return 0; |
839 | } | 844 | } |
840 | 845 | ||
@@ -845,6 +850,8 @@ int i915_restore_state(struct drm_device *dev) | |||
845 | 850 | ||
846 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 851 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); |
847 | 852 | ||
853 | mutex_lock(&dev->struct_mutex); | ||
854 | |||
848 | /* Hardware status page */ | 855 | /* Hardware status page */ |
849 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 856 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
850 | 857 | ||
@@ -862,6 +869,7 @@ int i915_restore_state(struct drm_device *dev) | |||
862 | I915_WRITE(IER, dev_priv->saveIER); | 869 | I915_WRITE(IER, dev_priv->saveIER); |
863 | I915_WRITE(IMR, dev_priv->saveIMR); | 870 | I915_WRITE(IMR, dev_priv->saveIMR); |
864 | } | 871 | } |
872 | mutex_unlock(&dev->struct_mutex); | ||
865 | 873 | ||
866 | intel_init_clock_gating(dev); | 874 | intel_init_clock_gating(dev); |
867 | 875 | ||
@@ -873,6 +881,8 @@ int i915_restore_state(struct drm_device *dev) | |||
873 | if (IS_GEN6(dev)) | 881 | if (IS_GEN6(dev)) |
874 | gen6_enable_rps(dev_priv); | 882 | gen6_enable_rps(dev_priv); |
875 | 883 | ||
884 | mutex_lock(&dev->struct_mutex); | ||
885 | |||
876 | /* Cache mode state */ | 886 | /* Cache mode state */ |
877 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | 887 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); |
878 | 888 | ||
@@ -886,6 +896,8 @@ int i915_restore_state(struct drm_device *dev) | |||
886 | for (i = 0; i < 3; i++) | 896 | for (i = 0; i < 3; i++) |
887 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | 897 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); |
888 | 898 | ||
899 | mutex_unlock(&dev->struct_mutex); | ||
900 | |||
889 | intel_i2c_reset(dev); | 901 | intel_i2c_reset(dev); |
890 | 902 | ||
891 | return 0; | 903 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 81a9059b6a9..21b6f93fe91 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4687,6 +4687,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
4687 | 4687 | ||
4688 | I915_WRITE(DSPCNTR(plane), dspcntr); | 4688 | I915_WRITE(DSPCNTR(plane), dspcntr); |
4689 | POSTING_READ(DSPCNTR(plane)); | 4689 | POSTING_READ(DSPCNTR(plane)); |
4690 | intel_enable_plane(dev_priv, plane, pipe); | ||
4690 | 4691 | ||
4691 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4692 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
4692 | 4693 | ||
@@ -5217,8 +5218,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5217 | 5218 | ||
5218 | I915_WRITE(DSPCNTR(plane), dspcntr); | 5219 | I915_WRITE(DSPCNTR(plane), dspcntr); |
5219 | POSTING_READ(DSPCNTR(plane)); | 5220 | POSTING_READ(DSPCNTR(plane)); |
5220 | if (!HAS_PCH_SPLIT(dev)) | ||
5221 | intel_enable_plane(dev_priv, plane, pipe); | ||
5222 | 5221 | ||
5223 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 5222 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
5224 | 5223 | ||
@@ -6262,6 +6261,197 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) | |||
6262 | spin_unlock_irqrestore(&dev->event_lock, flags); | 6261 | spin_unlock_irqrestore(&dev->event_lock, flags); |
6263 | } | 6262 | } |
6264 | 6263 | ||
6264 | static int intel_gen2_queue_flip(struct drm_device *dev, | ||
6265 | struct drm_crtc *crtc, | ||
6266 | struct drm_framebuffer *fb, | ||
6267 | struct drm_i915_gem_object *obj) | ||
6268 | { | ||
6269 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6270 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6271 | unsigned long offset; | ||
6272 | u32 flip_mask; | ||
6273 | int ret; | ||
6274 | |||
6275 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | ||
6276 | if (ret) | ||
6277 | goto out; | ||
6278 | |||
6279 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | ||
6280 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; | ||
6281 | |||
6282 | ret = BEGIN_LP_RING(6); | ||
6283 | if (ret) | ||
6284 | goto out; | ||
6285 | |||
6286 | /* Can't queue multiple flips, so wait for the previous | ||
6287 | * one to finish before executing the next. | ||
6288 | */ | ||
6289 | if (intel_crtc->plane) | ||
6290 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | ||
6291 | else | ||
6292 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
6293 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | ||
6294 | OUT_RING(MI_NOOP); | ||
6295 | OUT_RING(MI_DISPLAY_FLIP | | ||
6296 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6297 | OUT_RING(fb->pitch); | ||
6298 | OUT_RING(obj->gtt_offset + offset); | ||
6299 | OUT_RING(MI_NOOP); | ||
6300 | ADVANCE_LP_RING(); | ||
6301 | out: | ||
6302 | return ret; | ||
6303 | } | ||
6304 | |||
6305 | static int intel_gen3_queue_flip(struct drm_device *dev, | ||
6306 | struct drm_crtc *crtc, | ||
6307 | struct drm_framebuffer *fb, | ||
6308 | struct drm_i915_gem_object *obj) | ||
6309 | { | ||
6310 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6311 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6312 | unsigned long offset; | ||
6313 | u32 flip_mask; | ||
6314 | int ret; | ||
6315 | |||
6316 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | ||
6317 | if (ret) | ||
6318 | goto out; | ||
6319 | |||
6320 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | ||
6321 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; | ||
6322 | |||
6323 | ret = BEGIN_LP_RING(6); | ||
6324 | if (ret) | ||
6325 | goto out; | ||
6326 | |||
6327 | if (intel_crtc->plane) | ||
6328 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | ||
6329 | else | ||
6330 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
6331 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | ||
6332 | OUT_RING(MI_NOOP); | ||
6333 | OUT_RING(MI_DISPLAY_FLIP_I915 | | ||
6334 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6335 | OUT_RING(fb->pitch); | ||
6336 | OUT_RING(obj->gtt_offset + offset); | ||
6337 | OUT_RING(MI_NOOP); | ||
6338 | |||
6339 | ADVANCE_LP_RING(); | ||
6340 | out: | ||
6341 | return ret; | ||
6342 | } | ||
6343 | |||
6344 | static int intel_gen4_queue_flip(struct drm_device *dev, | ||
6345 | struct drm_crtc *crtc, | ||
6346 | struct drm_framebuffer *fb, | ||
6347 | struct drm_i915_gem_object *obj) | ||
6348 | { | ||
6349 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6350 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6351 | uint32_t pf, pipesrc; | ||
6352 | int ret; | ||
6353 | |||
6354 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | ||
6355 | if (ret) | ||
6356 | goto out; | ||
6357 | |||
6358 | ret = BEGIN_LP_RING(4); | ||
6359 | if (ret) | ||
6360 | goto out; | ||
6361 | |||
6362 | /* i965+ uses the linear or tiled offsets from the | ||
6363 | * Display Registers (which do not change across a page-flip) | ||
6364 | * so we need only reprogram the base address. | ||
6365 | */ | ||
6366 | OUT_RING(MI_DISPLAY_FLIP | | ||
6367 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6368 | OUT_RING(fb->pitch); | ||
6369 | OUT_RING(obj->gtt_offset | obj->tiling_mode); | ||
6370 | |||
6371 | /* XXX Enabling the panel-fitter across page-flip is so far | ||
6372 | * untested on non-native modes, so ignore it for now. | ||
6373 | * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
6374 | */ | ||
6375 | pf = 0; | ||
6376 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; | ||
6377 | OUT_RING(pf | pipesrc); | ||
6378 | ADVANCE_LP_RING(); | ||
6379 | out: | ||
6380 | return ret; | ||
6381 | } | ||
6382 | |||
6383 | static int intel_gen6_queue_flip(struct drm_device *dev, | ||
6384 | struct drm_crtc *crtc, | ||
6385 | struct drm_framebuffer *fb, | ||
6386 | struct drm_i915_gem_object *obj) | ||
6387 | { | ||
6388 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6389 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6390 | uint32_t pf, pipesrc; | ||
6391 | int ret; | ||
6392 | |||
6393 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | ||
6394 | if (ret) | ||
6395 | goto out; | ||
6396 | |||
6397 | ret = BEGIN_LP_RING(4); | ||
6398 | if (ret) | ||
6399 | goto out; | ||
6400 | |||
6401 | OUT_RING(MI_DISPLAY_FLIP | | ||
6402 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6403 | OUT_RING(fb->pitch | obj->tiling_mode); | ||
6404 | OUT_RING(obj->gtt_offset); | ||
6405 | |||
6406 | pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; | ||
6407 | pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; | ||
6408 | OUT_RING(pf | pipesrc); | ||
6409 | ADVANCE_LP_RING(); | ||
6410 | out: | ||
6411 | return ret; | ||
6412 | } | ||
6413 | |||
6414 | /* | ||
6415 | * On gen7 we currently use the blit ring because (in early silicon at least) | ||
6416 | * the render ring doesn't give us interrpts for page flip completion, which | ||
6417 | * means clients will hang after the first flip is queued. Fortunately the | ||
6418 | * blit ring generates interrupts properly, so use it instead. | ||
6419 | */ | ||
6420 | static int intel_gen7_queue_flip(struct drm_device *dev, | ||
6421 | struct drm_crtc *crtc, | ||
6422 | struct drm_framebuffer *fb, | ||
6423 | struct drm_i915_gem_object *obj) | ||
6424 | { | ||
6425 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6426 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6427 | struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; | ||
6428 | int ret; | ||
6429 | |||
6430 | ret = intel_pin_and_fence_fb_obj(dev, obj, ring); | ||
6431 | if (ret) | ||
6432 | goto out; | ||
6433 | |||
6434 | ret = intel_ring_begin(ring, 4); | ||
6435 | if (ret) | ||
6436 | goto out; | ||
6437 | |||
6438 | intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); | ||
6439 | intel_ring_emit(ring, (fb->pitch | obj->tiling_mode)); | ||
6440 | intel_ring_emit(ring, (obj->gtt_offset)); | ||
6441 | intel_ring_emit(ring, (MI_NOOP)); | ||
6442 | intel_ring_advance(ring); | ||
6443 | out: | ||
6444 | return ret; | ||
6445 | } | ||
6446 | |||
6447 | static int intel_default_queue_flip(struct drm_device *dev, | ||
6448 | struct drm_crtc *crtc, | ||
6449 | struct drm_framebuffer *fb, | ||
6450 | struct drm_i915_gem_object *obj) | ||
6451 | { | ||
6452 | return -ENODEV; | ||
6453 | } | ||
6454 | |||
6265 | static int intel_crtc_page_flip(struct drm_crtc *crtc, | 6455 | static int intel_crtc_page_flip(struct drm_crtc *crtc, |
6266 | struct drm_framebuffer *fb, | 6456 | struct drm_framebuffer *fb, |
6267 | struct drm_pending_vblank_event *event) | 6457 | struct drm_pending_vblank_event *event) |
@@ -6272,9 +6462,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
6272 | struct drm_i915_gem_object *obj; | 6462 | struct drm_i915_gem_object *obj; |
6273 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 6463 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
6274 | struct intel_unpin_work *work; | 6464 | struct intel_unpin_work *work; |
6275 | unsigned long flags, offset; | 6465 | unsigned long flags; |
6276 | int pipe = intel_crtc->pipe; | ||
6277 | u32 pf, pipesrc; | ||
6278 | int ret; | 6466 | int ret; |
6279 | 6467 | ||
6280 | work = kzalloc(sizeof *work, GFP_KERNEL); | 6468 | work = kzalloc(sizeof *work, GFP_KERNEL); |
@@ -6303,9 +6491,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
6303 | obj = intel_fb->obj; | 6491 | obj = intel_fb->obj; |
6304 | 6492 | ||
6305 | mutex_lock(&dev->struct_mutex); | 6493 | mutex_lock(&dev->struct_mutex); |
6306 | ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); | ||
6307 | if (ret) | ||
6308 | goto cleanup_work; | ||
6309 | 6494 | ||
6310 | /* Reference the objects for the scheduled work. */ | 6495 | /* Reference the objects for the scheduled work. */ |
6311 | drm_gem_object_reference(&work->old_fb_obj->base); | 6496 | drm_gem_object_reference(&work->old_fb_obj->base); |
@@ -6317,91 +6502,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
6317 | if (ret) | 6502 | if (ret) |
6318 | goto cleanup_objs; | 6503 | goto cleanup_objs; |
6319 | 6504 | ||
6320 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | ||
6321 | u32 flip_mask; | ||
6322 | |||
6323 | /* Can't queue multiple flips, so wait for the previous | ||
6324 | * one to finish before executing the next. | ||
6325 | */ | ||
6326 | ret = BEGIN_LP_RING(2); | ||
6327 | if (ret) | ||
6328 | goto cleanup_objs; | ||
6329 | |||
6330 | if (intel_crtc->plane) | ||
6331 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | ||
6332 | else | ||
6333 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
6334 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | ||
6335 | OUT_RING(MI_NOOP); | ||
6336 | ADVANCE_LP_RING(); | ||
6337 | } | ||
6338 | |||
6339 | work->pending_flip_obj = obj; | 6505 | work->pending_flip_obj = obj; |
6340 | 6506 | ||
6341 | work->enable_stall_check = true; | 6507 | work->enable_stall_check = true; |
6342 | 6508 | ||
6343 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | ||
6344 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; | ||
6345 | |||
6346 | ret = BEGIN_LP_RING(4); | ||
6347 | if (ret) | ||
6348 | goto cleanup_objs; | ||
6349 | |||
6350 | /* Block clients from rendering to the new back buffer until | 6509 | /* Block clients from rendering to the new back buffer until |
6351 | * the flip occurs and the object is no longer visible. | 6510 | * the flip occurs and the object is no longer visible. |
6352 | */ | 6511 | */ |
6353 | atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); | 6512 | atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); |
6354 | 6513 | ||
6355 | switch (INTEL_INFO(dev)->gen) { | 6514 | ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); |
6356 | case 2: | 6515 | if (ret) |
6357 | OUT_RING(MI_DISPLAY_FLIP | | 6516 | goto cleanup_pending; |
6358 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6359 | OUT_RING(fb->pitch); | ||
6360 | OUT_RING(obj->gtt_offset + offset); | ||
6361 | OUT_RING(MI_NOOP); | ||
6362 | break; | ||
6363 | |||
6364 | case 3: | ||
6365 | OUT_RING(MI_DISPLAY_FLIP_I915 | | ||
6366 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6367 | OUT_RING(fb->pitch); | ||
6368 | OUT_RING(obj->gtt_offset + offset); | ||
6369 | OUT_RING(MI_NOOP); | ||
6370 | break; | ||
6371 | |||
6372 | case 4: | ||
6373 | case 5: | ||
6374 | /* i965+ uses the linear or tiled offsets from the | ||
6375 | * Display Registers (which do not change across a page-flip) | ||
6376 | * so we need only reprogram the base address. | ||
6377 | */ | ||
6378 | OUT_RING(MI_DISPLAY_FLIP | | ||
6379 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6380 | OUT_RING(fb->pitch); | ||
6381 | OUT_RING(obj->gtt_offset | obj->tiling_mode); | ||
6382 | |||
6383 | /* XXX Enabling the panel-fitter across page-flip is so far | ||
6384 | * untested on non-native modes, so ignore it for now. | ||
6385 | * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
6386 | */ | ||
6387 | pf = 0; | ||
6388 | pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff; | ||
6389 | OUT_RING(pf | pipesrc); | ||
6390 | break; | ||
6391 | |||
6392 | case 6: | ||
6393 | case 7: | ||
6394 | OUT_RING(MI_DISPLAY_FLIP | | ||
6395 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
6396 | OUT_RING(fb->pitch | obj->tiling_mode); | ||
6397 | OUT_RING(obj->gtt_offset); | ||
6398 | |||
6399 | pf = I915_READ(PF_CTL(pipe)) & PF_ENABLE; | ||
6400 | pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff; | ||
6401 | OUT_RING(pf | pipesrc); | ||
6402 | break; | ||
6403 | } | ||
6404 | ADVANCE_LP_RING(); | ||
6405 | 6517 | ||
6406 | mutex_unlock(&dev->struct_mutex); | 6518 | mutex_unlock(&dev->struct_mutex); |
6407 | 6519 | ||
@@ -6409,10 +6521,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
6409 | 6521 | ||
6410 | return 0; | 6522 | return 0; |
6411 | 6523 | ||
6524 | cleanup_pending: | ||
6525 | atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); | ||
6412 | cleanup_objs: | 6526 | cleanup_objs: |
6413 | drm_gem_object_unreference(&work->old_fb_obj->base); | 6527 | drm_gem_object_unreference(&work->old_fb_obj->base); |
6414 | drm_gem_object_unreference(&obj->base); | 6528 | drm_gem_object_unreference(&obj->base); |
6415 | cleanup_work: | ||
6416 | mutex_unlock(&dev->struct_mutex); | 6529 | mutex_unlock(&dev->struct_mutex); |
6417 | 6530 | ||
6418 | spin_lock_irqsave(&dev->event_lock, flags); | 6531 | spin_lock_irqsave(&dev->event_lock, flags); |
@@ -7657,6 +7770,31 @@ static void intel_init_display(struct drm_device *dev) | |||
7657 | else | 7770 | else |
7658 | dev_priv->display.get_fifo_size = i830_get_fifo_size; | 7771 | dev_priv->display.get_fifo_size = i830_get_fifo_size; |
7659 | } | 7772 | } |
7773 | |||
7774 | /* Default just returns -ENODEV to indicate unsupported */ | ||
7775 | dev_priv->display.queue_flip = intel_default_queue_flip; | ||
7776 | |||
7777 | switch (INTEL_INFO(dev)->gen) { | ||
7778 | case 2: | ||
7779 | dev_priv->display.queue_flip = intel_gen2_queue_flip; | ||
7780 | break; | ||
7781 | |||
7782 | case 3: | ||
7783 | dev_priv->display.queue_flip = intel_gen3_queue_flip; | ||
7784 | break; | ||
7785 | |||
7786 | case 4: | ||
7787 | case 5: | ||
7788 | dev_priv->display.queue_flip = intel_gen4_queue_flip; | ||
7789 | break; | ||
7790 | |||
7791 | case 6: | ||
7792 | dev_priv->display.queue_flip = intel_gen6_queue_flip; | ||
7793 | break; | ||
7794 | case 7: | ||
7795 | dev_priv->display.queue_flip = intel_gen7_queue_flip; | ||
7796 | break; | ||
7797 | } | ||
7660 | } | 7798 | } |
7661 | 7799 | ||
7662 | /* | 7800 | /* |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index d3b903bce7c..d98cee60b60 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -401,8 +401,7 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
401 | bus->reg0 = i | GMBUS_RATE_100KHZ; | 401 | bus->reg0 = i | GMBUS_RATE_100KHZ; |
402 | 402 | ||
403 | /* XXX force bit banging until GMBUS is fully debugged */ | 403 | /* XXX force bit banging until GMBUS is fully debugged */ |
404 | if (IS_GEN2(dev)) | 404 | bus->force_bit = intel_gpio_create(dev_priv, i); |
405 | bus->force_bit = intel_gpio_create(dev_priv, i); | ||
406 | } | 405 | } |
407 | 406 | ||
408 | intel_i2c_reset(dev_priv->dev); | 407 | intel_i2c_reset(dev_priv->dev); |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index a670c006982..9e2959bc91c 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -1409,6 +1409,11 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1409 | overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); | 1409 | overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); |
1410 | if (!overlay) | 1410 | if (!overlay) |
1411 | return; | 1411 | return; |
1412 | |||
1413 | mutex_lock(&dev->struct_mutex); | ||
1414 | if (WARN_ON(dev_priv->overlay)) | ||
1415 | goto out_free; | ||
1416 | |||
1412 | overlay->dev = dev; | 1417 | overlay->dev = dev; |
1413 | 1418 | ||
1414 | reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); | 1419 | reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); |
@@ -1448,7 +1453,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1448 | 1453 | ||
1449 | regs = intel_overlay_map_regs(overlay); | 1454 | regs = intel_overlay_map_regs(overlay); |
1450 | if (!regs) | 1455 | if (!regs) |
1451 | goto out_free_bo; | 1456 | goto out_unpin_bo; |
1452 | 1457 | ||
1453 | memset(regs, 0, sizeof(struct overlay_registers)); | 1458 | memset(regs, 0, sizeof(struct overlay_registers)); |
1454 | update_polyphase_filter(regs); | 1459 | update_polyphase_filter(regs); |
@@ -1457,14 +1462,17 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1457 | intel_overlay_unmap_regs(overlay, regs); | 1462 | intel_overlay_unmap_regs(overlay, regs); |
1458 | 1463 | ||
1459 | dev_priv->overlay = overlay; | 1464 | dev_priv->overlay = overlay; |
1465 | mutex_unlock(&dev->struct_mutex); | ||
1460 | DRM_INFO("initialized overlay support\n"); | 1466 | DRM_INFO("initialized overlay support\n"); |
1461 | return; | 1467 | return; |
1462 | 1468 | ||
1463 | out_unpin_bo: | 1469 | out_unpin_bo: |
1464 | i915_gem_object_unpin(reg_bo); | 1470 | if (!OVERLAY_NEEDS_PHYSICAL(dev)) |
1471 | i915_gem_object_unpin(reg_bo); | ||
1465 | out_free_bo: | 1472 | out_free_bo: |
1466 | drm_gem_object_unreference(®_bo->base); | 1473 | drm_gem_object_unreference(®_bo->base); |
1467 | out_free: | 1474 | out_free: |
1475 | mutex_unlock(&dev->struct_mutex); | ||
1468 | kfree(overlay); | 1476 | kfree(overlay); |
1469 | return; | 1477 | return; |
1470 | } | 1478 | } |