diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 319 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 12 |
5 files changed, 136 insertions, 231 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 96177eec0a0e..eedb023af27d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -1833,7 +1833,6 @@ int i915_driver_unload(struct drm_device *dev) | |||
| 1833 | flush_workqueue(dev_priv->wq); | 1833 | flush_workqueue(dev_priv->wq); |
| 1834 | 1834 | ||
| 1835 | mutex_lock(&dev->struct_mutex); | 1835 | mutex_lock(&dev->struct_mutex); |
| 1836 | i915_gem_free_all_phys_object(dev); | ||
| 1837 | i915_gem_cleanup_ringbuffer(dev); | 1836 | i915_gem_cleanup_ringbuffer(dev); |
| 1838 | i915_gem_context_fini(dev); | 1837 | i915_gem_context_fini(dev); |
| 1839 | WARN_ON(dev_priv->mm.aliasing_ppgtt); | 1838 | WARN_ON(dev_priv->mm.aliasing_ppgtt); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 108e1ec2fa4b..ec5f6fb42ab3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -242,18 +242,6 @@ struct intel_ddi_plls { | |||
| 242 | #define WATCH_LISTS 0 | 242 | #define WATCH_LISTS 0 |
| 243 | #define WATCH_GTT 0 | 243 | #define WATCH_GTT 0 |
| 244 | 244 | ||
| 245 | #define I915_GEM_PHYS_CURSOR_0 1 | ||
| 246 | #define I915_GEM_PHYS_CURSOR_1 2 | ||
| 247 | #define I915_GEM_PHYS_OVERLAY_REGS 3 | ||
| 248 | #define I915_MAX_PHYS_OBJECT (I915_GEM_PHYS_OVERLAY_REGS) | ||
| 249 | |||
| 250 | struct drm_i915_gem_phys_object { | ||
| 251 | int id; | ||
| 252 | struct page **page_list; | ||
| 253 | drm_dma_handle_t *handle; | ||
| 254 | struct drm_i915_gem_object *cur_obj; | ||
| 255 | }; | ||
| 256 | |||
| 257 | struct opregion_header; | 245 | struct opregion_header; |
| 258 | struct opregion_acpi; | 246 | struct opregion_acpi; |
| 259 | struct opregion_swsci; | 247 | struct opregion_swsci; |
| @@ -1187,9 +1175,6 @@ struct i915_gem_mm { | |||
| 1187 | /** Bit 6 swizzling required for Y tiling */ | 1175 | /** Bit 6 swizzling required for Y tiling */ |
| 1188 | uint32_t bit_6_swizzle_y; | 1176 | uint32_t bit_6_swizzle_y; |
| 1189 | 1177 | ||
| 1190 | /* storage for physical objects */ | ||
| 1191 | struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; | ||
| 1192 | |||
| 1193 | /* accounting, useful for userland debugging */ | 1178 | /* accounting, useful for userland debugging */ |
| 1194 | spinlock_t object_stat_lock; | 1179 | spinlock_t object_stat_lock; |
| 1195 | size_t object_memory; | 1180 | size_t object_memory; |
| @@ -1769,7 +1754,7 @@ struct drm_i915_gem_object { | |||
| 1769 | struct drm_file *pin_filp; | 1754 | struct drm_file *pin_filp; |
| 1770 | 1755 | ||
| 1771 | /** for phy allocated objects */ | 1756 | /** for phy allocated objects */ |
| 1772 | struct drm_i915_gem_phys_object *phys_obj; | 1757 | drm_dma_handle_t *phys_handle; |
| 1773 | }; | 1758 | }; |
| 1774 | 1759 | ||
| 1775 | #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) | 1760 | #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) |
| @@ -2334,13 +2319,8 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, | |||
| 2334 | u32 alignment, | 2319 | u32 alignment, |
| 2335 | struct intel_ring_buffer *pipelined); | 2320 | struct intel_ring_buffer *pipelined); |
| 2336 | void i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj); | 2321 | void i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj); |
| 2337 | int i915_gem_attach_phys_object(struct drm_device *dev, | 2322 | int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, |
| 2338 | struct drm_i915_gem_object *obj, | ||
| 2339 | int id, | ||
| 2340 | int align); | 2323 | int align); |
| 2341 | void i915_gem_detach_phys_object(struct drm_device *dev, | ||
| 2342 | struct drm_i915_gem_object *obj); | ||
| 2343 | void i915_gem_free_all_phys_object(struct drm_device *dev); | ||
| 2344 | int i915_gem_open(struct drm_device *dev, struct drm_file *file); | 2324 | int i915_gem_open(struct drm_device *dev, struct drm_file *file); |
| 2345 | void i915_gem_release(struct drm_device *dev, struct drm_file *file); | 2325 | void i915_gem_release(struct drm_device *dev, struct drm_file *file); |
| 2346 | 2326 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2871ce75f438..b391f30f9985 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -43,10 +43,6 @@ static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *o | |||
| 43 | static __must_check int | 43 | static __must_check int |
| 44 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, | 44 | i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, |
| 45 | bool readonly); | 45 | bool readonly); |
| 46 | static int i915_gem_phys_pwrite(struct drm_device *dev, | ||
| 47 | struct drm_i915_gem_object *obj, | ||
| 48 | struct drm_i915_gem_pwrite *args, | ||
| 49 | struct drm_file *file); | ||
| 50 | 46 | ||
| 51 | static void i915_gem_write_fence(struct drm_device *dev, int reg, | 47 | static void i915_gem_write_fence(struct drm_device *dev, int reg, |
| 52 | struct drm_i915_gem_object *obj); | 48 | struct drm_i915_gem_object *obj); |
| @@ -209,6 +205,128 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
| 209 | return 0; | 205 | return 0; |
| 210 | } | 206 | } |
| 211 | 207 | ||
| 208 | static void i915_gem_object_detach_phys(struct drm_i915_gem_object *obj) | ||
| 209 | { | ||
| 210 | drm_dma_handle_t *phys = obj->phys_handle; | ||
| 211 | |||
| 212 | if (!phys) | ||
| 213 | return; | ||
| 214 | |||
| 215 | if (obj->madv == I915_MADV_WILLNEED) { | ||
| 216 | struct address_space *mapping = file_inode(obj->base.filp)->i_mapping; | ||
| 217 | char *vaddr = phys->vaddr; | ||
| 218 | int i; | ||
| 219 | |||
| 220 | for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { | ||
| 221 | struct page *page = shmem_read_mapping_page(mapping, i); | ||
| 222 | if (!IS_ERR(page)) { | ||
| 223 | char *dst = kmap_atomic(page); | ||
| 224 | memcpy(dst, vaddr, PAGE_SIZE); | ||
| 225 | drm_clflush_virt_range(dst, PAGE_SIZE); | ||
| 226 | kunmap_atomic(dst); | ||
| 227 | |||
| 228 | set_page_dirty(page); | ||
| 229 | mark_page_accessed(page); | ||
| 230 | page_cache_release(page); | ||
| 231 | } | ||
| 232 | vaddr += PAGE_SIZE; | ||
| 233 | } | ||
| 234 | i915_gem_chipset_flush(obj->base.dev); | ||
| 235 | } | ||
| 236 | |||
| 237 | #ifdef CONFIG_X86 | ||
| 238 | set_memory_wb((unsigned long)phys->vaddr, phys->size / PAGE_SIZE); | ||
| 239 | #endif | ||
| 240 | drm_pci_free(obj->base.dev, phys); | ||
| 241 | obj->phys_handle = NULL; | ||
| 242 | } | ||
| 243 | |||
| 244 | int | ||
| 245 | i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, | ||
| 246 | int align) | ||
| 247 | { | ||
| 248 | drm_dma_handle_t *phys; | ||
| 249 | struct address_space *mapping; | ||
| 250 | char *vaddr; | ||
| 251 | int i; | ||
| 252 | |||
| 253 | if (obj->phys_handle) { | ||
| 254 | if ((unsigned long)obj->phys_handle->vaddr & (align -1)) | ||
| 255 | return -EBUSY; | ||
| 256 | |||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | if (obj->madv != I915_MADV_WILLNEED) | ||
| 261 | return -EFAULT; | ||
| 262 | |||
| 263 | if (obj->base.filp == NULL) | ||
| 264 | return -EINVAL; | ||
| 265 | |||
| 266 | /* create a new object */ | ||
| 267 | phys = drm_pci_alloc(obj->base.dev, obj->base.size, align); | ||
| 268 | if (!phys) | ||
| 269 | return -ENOMEM; | ||
| 270 | |||
| 271 | vaddr = phys->vaddr; | ||
| 272 | #ifdef CONFIG_X86 | ||
| 273 | set_memory_wc((unsigned long)vaddr, phys->size / PAGE_SIZE); | ||
| 274 | #endif | ||
| 275 | mapping = file_inode(obj->base.filp)->i_mapping; | ||
| 276 | for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { | ||
| 277 | struct page *page; | ||
| 278 | char *src; | ||
| 279 | |||
| 280 | page = shmem_read_mapping_page(mapping, i); | ||
| 281 | if (IS_ERR(page)) { | ||
| 282 | #ifdef CONFIG_X86 | ||
| 283 | set_memory_wb((unsigned long)phys->vaddr, phys->size / PAGE_SIZE); | ||
| 284 | #endif | ||
| 285 | drm_pci_free(obj->base.dev, phys); | ||
| 286 | return PTR_ERR(page); | ||
| 287 | } | ||
| 288 | |||
| 289 | src = kmap_atomic(page); | ||
| 290 | memcpy(vaddr, src, PAGE_SIZE); | ||
| 291 | kunmap_atomic(src); | ||
| 292 | |||
| 293 | mark_page_accessed(page); | ||
| 294 | page_cache_release(page); | ||
| 295 | |||
| 296 | vaddr += PAGE_SIZE; | ||
| 297 | } | ||
| 298 | |||
| 299 | obj->phys_handle = phys; | ||
| 300 | return 0; | ||
| 301 | } | ||
| 302 | |||
| 303 | static int | ||
| 304 | i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, | ||
| 305 | struct drm_i915_gem_pwrite *args, | ||
| 306 | struct drm_file *file_priv) | ||
| 307 | { | ||
| 308 | struct drm_device *dev = obj->base.dev; | ||
| 309 | void *vaddr = obj->phys_handle->vaddr + args->offset; | ||
| 310 | char __user *user_data = to_user_ptr(args->data_ptr); | ||
| 311 | |||
| 312 | if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { | ||
| 313 | unsigned long unwritten; | ||
| 314 | |||
| 315 | /* The physical object once assigned is fixed for the lifetime | ||
| 316 | * of the obj, so we can safely drop the lock and continue | ||
| 317 | * to access vaddr. | ||
| 318 | */ | ||
| 319 | mutex_unlock(&dev->struct_mutex); | ||
| 320 | unwritten = copy_from_user(vaddr, user_data, args->size); | ||
| 321 | mutex_lock(&dev->struct_mutex); | ||
| 322 | if (unwritten) | ||
| 323 | return -EFAULT; | ||
| 324 | } | ||
| 325 | |||
| 326 | i915_gem_chipset_flush(dev); | ||
| 327 | return 0; | ||
| 328 | } | ||
| 329 | |||
| 212 | void *i915_gem_object_alloc(struct drm_device *dev) | 330 | void *i915_gem_object_alloc(struct drm_device *dev) |
| 213 | { | 331 | { |
| 214 | struct drm_i915_private *dev_priv = dev->dev_private; | 332 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -921,8 +1039,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
| 921 | * pread/pwrite currently are reading and writing from the CPU | 1039 | * pread/pwrite currently are reading and writing from the CPU |
| 922 | * perspective, requiring manual detiling by the client. | 1040 | * perspective, requiring manual detiling by the client. |
| 923 | */ | 1041 | */ |
| 924 | if (obj->phys_obj) { | 1042 | if (obj->phys_handle) { |
| 925 | ret = i915_gem_phys_pwrite(dev, obj, args, file); | 1043 | ret = i915_gem_phys_pwrite(obj, args, file); |
| 926 | goto out; | 1044 | goto out; |
| 927 | } | 1045 | } |
| 928 | 1046 | ||
| @@ -4163,9 +4281,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) | |||
| 4163 | 4281 | ||
| 4164 | trace_i915_gem_object_destroy(obj); | 4282 | trace_i915_gem_object_destroy(obj); |
| 4165 | 4283 | ||
| 4166 | if (obj->phys_obj) | ||
| 4167 | i915_gem_detach_phys_object(dev, obj); | ||
| 4168 | |||
| 4169 | list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) { | 4284 | list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) { |
| 4170 | int ret; | 4285 | int ret; |
| 4171 | 4286 | ||
| @@ -4183,6 +4298,8 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) | |||
| 4183 | } | 4298 | } |
| 4184 | } | 4299 | } |
| 4185 | 4300 | ||
| 4301 | i915_gem_object_detach_phys(obj); | ||
| 4302 | |||
| 4186 | /* Stolen objects don't hold a ref, but do hold pin count. Fix that up | 4303 | /* Stolen objects don't hold a ref, but do hold pin count. Fix that up |
| 4187 | * before progressing. */ | 4304 | * before progressing. */ |
| 4188 | if (obj->stolen) | 4305 | if (obj->stolen) |
| @@ -4646,190 +4763,6 @@ i915_gem_load(struct drm_device *dev) | |||
| 4646 | register_shrinker(&dev_priv->mm.inactive_shrinker); | 4763 | register_shrinker(&dev_priv->mm.inactive_shrinker); |
| 4647 | } | 4764 | } |
| 4648 | 4765 | ||
| 4649 | /* | ||
| 4650 | * Create a physically contiguous memory object for this object | ||
| 4651 | * e.g. for cursor + overlay regs | ||
| 4652 | */ | ||
| 4653 | static int i915_gem_init_phys_object(struct drm_device *dev, | ||
| 4654 | int id, int size, int align) | ||
| 4655 | { | ||
| 4656 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 4657 | struct drm_i915_gem_phys_object *phys_obj; | ||
| 4658 | int ret; | ||
| 4659 | |||
| 4660 | if (dev_priv->mm.phys_objs[id - 1] || !size) | ||
| 4661 | return 0; | ||
| 4662 | |||
| 4663 | phys_obj = kzalloc(sizeof(*phys_obj), GFP_KERNEL); | ||
| 4664 | if (!phys_obj) | ||
| 4665 | return -ENOMEM; | ||
| 4666 | |||
| 4667 | phys_obj->id = id; | ||
| 4668 | |||
| 4669 | phys_obj->handle = drm_pci_alloc(dev, size, align); | ||
| 4670 | if (!phys_obj->handle) { | ||
| 4671 | ret = -ENOMEM; | ||
| 4672 | goto kfree_obj; | ||
| 4673 | } | ||
| 4674 | #ifdef CONFIG_X86 | ||
| 4675 | set_memory_wc((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); | ||
| 4676 | #endif | ||
| 4677 | |||
| 4678 | dev_priv->mm.phys_objs[id - 1] = phys_obj; | ||
| 4679 | |||
| 4680 | return 0; | ||
| 4681 | kfree_obj: | ||
| 4682 | kfree(phys_obj); | ||
| 4683 | return ret; | ||
| 4684 | } | ||
| 4685 | |||
| 4686 | static void i915_gem_free_phys_object(struct drm_device *dev, int id) | ||
| 4687 | { | ||
| 4688 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 4689 | struct drm_i915_gem_phys_object *phys_obj; | ||
| 4690 | |||
| 4691 | if (!dev_priv->mm.phys_objs[id - 1]) | ||
| 4692 | return; | ||
| 4693 | |||
| 4694 | phys_obj = dev_priv->mm.phys_objs[id - 1]; | ||
| 4695 | if (phys_obj->cur_obj) { | ||
| 4696 | i915_gem_detach_phys_object(dev, phys_obj->cur_obj); | ||
| 4697 | } | ||
| 4698 | |||
| 4699 | #ifdef CONFIG_X86 | ||
| 4700 | set_memory_wb((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE); | ||
| 4701 | #endif | ||
| 4702 | drm_pci_free(dev, phys_obj->handle); | ||
| 4703 | kfree(phys_obj); | ||
| 4704 | dev_priv->mm.phys_objs[id - 1] = NULL; | ||
| 4705 | } | ||
| 4706 | |||
| 4707 | void i915_gem_free_all_phys_object(struct drm_device *dev) | ||
| 4708 | { | ||
| 4709 | int i; | ||
| 4710 | |||
| 4711 | for (i = I915_GEM_PHYS_CURSOR_0; i <= I915_MAX_PHYS_OBJECT; i++) | ||
| 4712 | i915_gem_free_phys_object(dev, i); | ||
| 4713 | } | ||
| 4714 | |||
| 4715 | void i915_gem_detach_phys_object(struct drm_device *dev, | ||
| 4716 | struct drm_i915_gem_object *obj) | ||
| 4717 | { | ||
| 4718 | struct address_space *mapping = file_inode(obj->base.filp)->i_mapping; | ||
| 4719 | char *vaddr; | ||
| 4720 | int i; | ||
| 4721 | int page_count; | ||
| 4722 | |||
| 4723 | if (!obj->phys_obj) | ||
| 4724 | return; | ||
| 4725 | vaddr = obj->phys_obj->handle->vaddr; | ||
| 4726 | |||
| 4727 | page_count = obj->base.size / PAGE_SIZE; | ||
| 4728 | for (i = 0; i < page_count; i++) { | ||
| 4729 | struct page *page = shmem_read_mapping_page(mapping, i); | ||
| 4730 | if (!IS_ERR(page)) { | ||
| 4731 | char *dst = kmap_atomic(page); | ||
| 4732 | memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE); | ||
| 4733 | kunmap_atomic(dst); | ||
| 4734 | |||
| 4735 | drm_clflush_pages(&page, 1); | ||
| 4736 | |||
| 4737 | set_page_dirty(page); | ||
| 4738 | mark_page_accessed(page); | ||
| 4739 | page_cache_release(page); | ||
| 4740 | } | ||
| 4741 | } | ||
| 4742 | i915_gem_chipset_flush(dev); | ||
| 4743 | |||
| 4744 | obj->phys_obj->cur_obj = NULL; | ||
| 4745 | obj->phys_obj = NULL; | ||
| 4746 | } | ||
| 4747 | |||
| 4748 | int | ||
| 4749 | i915_gem_attach_phys_object(struct drm_device *dev, | ||
| 4750 | struct drm_i915_gem_object *obj, | ||
| 4751 | int id, | ||
| 4752 | int align) | ||
| 4753 | { | ||
| 4754 | struct address_space *mapping = file_inode(obj->base.filp)->i_mapping; | ||
| 4755 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 4756 | int ret = 0; | ||
| 4757 | int page_count; | ||
| 4758 | int i; | ||
| 4759 | |||
| 4760 | if (id > I915_MAX_PHYS_OBJECT) | ||
| 4761 | return -EINVAL; | ||
| 4762 | |||
| 4763 | if (obj->phys_obj) { | ||
| 4764 | if (obj->phys_obj->id == id) | ||
| 4765 | return 0; | ||
| 4766 | i915_gem_detach_phys_object(dev, obj); | ||
| 4767 | } | ||
| 4768 | |||
| 4769 | /* create a new object */ | ||
| 4770 | if (!dev_priv->mm.phys_objs[id - 1]) { | ||
| 4771 | ret = i915_gem_init_phys_object(dev, id, | ||
| 4772 | obj->base.size, align); | ||
| 4773 | if (ret) { | ||
| 4774 | DRM_ERROR("failed to init phys object %d size: %zu\n", | ||
| 4775 | id, obj->base.size); | ||
| 4776 | return ret; | ||
| 4777 | } | ||
| 4778 | } | ||
| 4779 | |||
| 4780 | /* bind to the object */ | ||
| 4781 | obj->phys_obj = dev_priv->mm.phys_objs[id - 1]; | ||
| 4782 | obj->phys_obj->cur_obj = obj; | ||
| 4783 | |||
| 4784 | page_count = obj->base.size / PAGE_SIZE; | ||
| 4785 | |||
| 4786 | for (i = 0; i < page_count; i++) { | ||
| 4787 | struct page *page; | ||
| 4788 | char *dst, *src; | ||
| 4789 | |||
| 4790 | page = shmem_read_mapping_page(mapping, i); | ||
| 4791 | if (IS_ERR(page)) | ||
| 4792 | return PTR_ERR(page); | ||
| 4793 | |||
| 4794 | src = kmap_atomic(page); | ||
| 4795 | dst = obj->phys_obj->handle->vaddr + (i * PAGE_SIZE); | ||
| 4796 | memcpy(dst, src, PAGE_SIZE); | ||
| 4797 | kunmap_atomic(src); | ||
| 4798 | |||
| 4799 | mark_page_accessed(page); | ||
| 4800 | page_cache_release(page); | ||
| 4801 | } | ||
| 4802 | |||
| 4803 | return 0; | ||
| 4804 | } | ||
| 4805 | |||
| 4806 | static int | ||
| 4807 | i915_gem_phys_pwrite(struct drm_device *dev, | ||
| 4808 | struct drm_i915_gem_object *obj, | ||
| 4809 | struct drm_i915_gem_pwrite *args, | ||
| 4810 | struct drm_file *file_priv) | ||
| 4811 | { | ||
| 4812 | void *vaddr = obj->phys_obj->handle->vaddr + args->offset; | ||
| 4813 | char __user *user_data = to_user_ptr(args->data_ptr); | ||
| 4814 | |||
| 4815 | if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { | ||
| 4816 | unsigned long unwritten; | ||
| 4817 | |||
| 4818 | /* The physical object once assigned is fixed for the lifetime | ||
| 4819 | * of the obj, so we can safely drop the lock and continue | ||
| 4820 | * to access vaddr. | ||
| 4821 | */ | ||
| 4822 | mutex_unlock(&dev->struct_mutex); | ||
| 4823 | unwritten = copy_from_user(vaddr, user_data, args->size); | ||
| 4824 | mutex_lock(&dev->struct_mutex); | ||
| 4825 | if (unwritten) | ||
| 4826 | return -EFAULT; | ||
| 4827 | } | ||
| 4828 | |||
| 4829 | i915_gem_chipset_flush(dev); | ||
| 4830 | return 0; | ||
| 4831 | } | ||
| 4832 | |||
| 4833 | void i915_gem_release(struct drm_device *dev, struct drm_file *file) | 4766 | void i915_gem_release(struct drm_device *dev, struct drm_file *file) |
| 4834 | { | 4767 | { |
| 4835 | struct drm_i915_file_private *file_priv = file->driver_priv; | 4768 | struct drm_i915_file_private *file_priv = file->driver_priv; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 48aa516a1ac0..5b60e25baa32 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -7825,14 +7825,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 7825 | addr = i915_gem_obj_ggtt_offset(obj); | 7825 | addr = i915_gem_obj_ggtt_offset(obj); |
| 7826 | } else { | 7826 | } else { |
| 7827 | int align = IS_I830(dev) ? 16 * 1024 : 256; | 7827 | int align = IS_I830(dev) ? 16 * 1024 : 256; |
| 7828 | ret = i915_gem_attach_phys_object(dev, obj, | 7828 | ret = i915_gem_object_attach_phys(obj, align); |
| 7829 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, | ||
| 7830 | align); | ||
| 7831 | if (ret) { | 7829 | if (ret) { |
| 7832 | DRM_DEBUG_KMS("failed to attach phys object\n"); | 7830 | DRM_DEBUG_KMS("failed to attach phys object\n"); |
| 7833 | goto fail_locked; | 7831 | goto fail_locked; |
| 7834 | } | 7832 | } |
| 7835 | addr = obj->phys_obj->handle->busaddr; | 7833 | addr = obj->phys_handle->busaddr; |
| 7836 | } | 7834 | } |
| 7837 | 7835 | ||
| 7838 | if (IS_GEN2(dev)) | 7836 | if (IS_GEN2(dev)) |
| @@ -7840,10 +7838,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 7840 | 7838 | ||
| 7841 | finish: | 7839 | finish: |
| 7842 | if (intel_crtc->cursor_bo) { | 7840 | if (intel_crtc->cursor_bo) { |
| 7843 | if (INTEL_INFO(dev)->cursor_needs_physical) { | 7841 | if (!INTEL_INFO(dev)->cursor_needs_physical) |
| 7844 | if (intel_crtc->cursor_bo != obj) | ||
| 7845 | i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); | ||
| 7846 | } else | ||
| 7847 | i915_gem_object_unpin_from_display_plane(intel_crtc->cursor_bo); | 7842 | i915_gem_object_unpin_from_display_plane(intel_crtc->cursor_bo); |
| 7848 | drm_gem_object_unreference(&intel_crtc->cursor_bo->base); | 7843 | drm_gem_object_unreference(&intel_crtc->cursor_bo->base); |
| 7849 | } | 7844 | } |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d8adc9104dca..129db0c7d835 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
| @@ -193,7 +193,7 @@ intel_overlay_map_regs(struct intel_overlay *overlay) | |||
| 193 | struct overlay_registers __iomem *regs; | 193 | struct overlay_registers __iomem *regs; |
| 194 | 194 | ||
| 195 | if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) | 195 | if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) |
| 196 | regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_obj->handle->vaddr; | 196 | regs = (struct overlay_registers __iomem *)overlay->reg_bo->phys_handle->vaddr; |
| 197 | else | 197 | else |
| 198 | regs = io_mapping_map_wc(dev_priv->gtt.mappable, | 198 | regs = io_mapping_map_wc(dev_priv->gtt.mappable, |
| 199 | i915_gem_obj_ggtt_offset(overlay->reg_bo)); | 199 | i915_gem_obj_ggtt_offset(overlay->reg_bo)); |
| @@ -1340,14 +1340,12 @@ void intel_setup_overlay(struct drm_device *dev) | |||
| 1340 | overlay->reg_bo = reg_bo; | 1340 | overlay->reg_bo = reg_bo; |
| 1341 | 1341 | ||
| 1342 | if (OVERLAY_NEEDS_PHYSICAL(dev)) { | 1342 | if (OVERLAY_NEEDS_PHYSICAL(dev)) { |
| 1343 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1343 | ret = i915_gem_object_attach_phys(reg_bo, PAGE_SIZE); |
| 1344 | I915_GEM_PHYS_OVERLAY_REGS, | ||
| 1345 | PAGE_SIZE); | ||
| 1346 | if (ret) { | 1344 | if (ret) { |
| 1347 | DRM_ERROR("failed to attach phys overlay regs\n"); | 1345 | DRM_ERROR("failed to attach phys overlay regs\n"); |
| 1348 | goto out_free_bo; | 1346 | goto out_free_bo; |
| 1349 | } | 1347 | } |
| 1350 | overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; | 1348 | overlay->flip_addr = reg_bo->phys_handle->busaddr; |
| 1351 | } else { | 1349 | } else { |
| 1352 | ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, PIN_MAPPABLE); | 1350 | ret = i915_gem_obj_ggtt_pin(reg_bo, PAGE_SIZE, PIN_MAPPABLE); |
| 1353 | if (ret) { | 1351 | if (ret) { |
| @@ -1428,7 +1426,7 @@ intel_overlay_map_regs_atomic(struct intel_overlay *overlay) | |||
| 1428 | /* Cast to make sparse happy, but it's wc memory anyway, so | 1426 | /* Cast to make sparse happy, but it's wc memory anyway, so |
| 1429 | * equivalent to the wc io mapping on X86. */ | 1427 | * equivalent to the wc io mapping on X86. */ |
| 1430 | regs = (struct overlay_registers __iomem *) | 1428 | regs = (struct overlay_registers __iomem *) |
| 1431 | overlay->reg_bo->phys_obj->handle->vaddr; | 1429 | overlay->reg_bo->phys_handle->vaddr; |
| 1432 | else | 1430 | else |
| 1433 | regs = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, | 1431 | regs = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, |
| 1434 | i915_gem_obj_ggtt_offset(overlay->reg_bo)); | 1432 | i915_gem_obj_ggtt_offset(overlay->reg_bo)); |
| @@ -1462,7 +1460,7 @@ intel_overlay_capture_error_state(struct drm_device *dev) | |||
| 1462 | error->dovsta = I915_READ(DOVSTA); | 1460 | error->dovsta = I915_READ(DOVSTA); |
| 1463 | error->isr = I915_READ(ISR); | 1461 | error->isr = I915_READ(ISR); |
| 1464 | if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) | 1462 | if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) |
| 1465 | error->base = (__force long)overlay->reg_bo->phys_obj->handle->vaddr; | 1463 | error->base = (__force long)overlay->reg_bo->phys_handle->vaddr; |
| 1466 | else | 1464 | else |
| 1467 | error->base = i915_gem_obj_ggtt_offset(overlay->reg_bo); | 1465 | error->base = i915_gem_obj_ggtt_offset(overlay->reg_bo); |
| 1468 | 1466 | ||
