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 | } | ||
