blob: 73702e583eb986c61ab2fe1dee4ca63d8584e7df [file] [log] [blame]
Eric Anholt673a3942008-07-30 12:06:12 -07001/*
2 * Copyright © 2008 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include "drmP.h"
29#include "drm.h"
30#include "i915_drm.h"
31#include "i915_drv.h"
Chris Wilson1c5d22f2009-08-25 11:15:50 +010032#include "i915_trace.h"
Jesse Barnes652c3932009-08-17 13:31:43 -070033#include "intel_drv.h"
Hugh Dickins5949eac2011-06-27 16:18:18 -070034#include <linux/shmem_fs.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090035#include <linux/slab.h>
Eric Anholt673a3942008-07-30 12:06:12 -070036#include <linux/swap.h>
Jesse Barnes79e53942008-11-07 14:24:08 -080037#include <linux/pci.h>
Daniel Vetter1286ff72012-05-10 15:25:09 +020038#include <linux/dma-buf.h>
Eric Anholt673a3942008-07-30 12:06:12 -070039
Chris Wilson05394f32010-11-08 19:18:58 +000040static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
41static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
Chris Wilson88241782011-01-07 17:09:48 +000042static __must_check int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
43 unsigned alignment,
Chris Wilson86a1ee22012-08-11 15:41:04 +010044 bool map_and_fenceable,
45 bool nonblocking);
Chris Wilson05394f32010-11-08 19:18:58 +000046static int i915_gem_phys_pwrite(struct drm_device *dev,
47 struct drm_i915_gem_object *obj,
Dave Airlie71acb5e2008-12-30 20:31:46 +100048 struct drm_i915_gem_pwrite *args,
Chris Wilson05394f32010-11-08 19:18:58 +000049 struct drm_file *file);
Eric Anholt673a3942008-07-30 12:06:12 -070050
Chris Wilson61050802012-04-17 15:31:31 +010051static void i915_gem_write_fence(struct drm_device *dev, int reg,
52 struct drm_i915_gem_object *obj);
53static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
54 struct drm_i915_fence_reg *fence,
55 bool enable);
56
Chris Wilson17250b72010-10-28 12:51:39 +010057static int i915_gem_inactive_shrink(struct shrinker *shrinker,
Ying Han1495f232011-05-24 17:12:27 -070058 struct shrink_control *sc);
Chris Wilson6c085a72012-08-20 11:40:46 +020059static long i915_gem_purge(struct drm_i915_private *dev_priv, long target);
60static void i915_gem_shrink_all(struct drm_i915_private *dev_priv);
Daniel Vetter8c599672011-12-14 13:57:31 +010061static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
Chris Wilson31169712009-09-14 16:50:28 +010062
Chris Wilson61050802012-04-17 15:31:31 +010063static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
64{
65 if (obj->tiling_mode)
66 i915_gem_release_mmap(obj);
67
68 /* As we do not have an associated fence register, we will force
69 * a tiling change if we ever need to acquire one.
70 */
Chris Wilson5d82e3e2012-04-21 16:23:23 +010071 obj->fence_dirty = false;
Chris Wilson61050802012-04-17 15:31:31 +010072 obj->fence_reg = I915_FENCE_REG_NONE;
73}
74
Chris Wilson73aa8082010-09-30 11:46:12 +010075/* some bookkeeping */
76static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv,
77 size_t size)
78{
79 dev_priv->mm.object_count++;
80 dev_priv->mm.object_memory += size;
81}
82
83static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv,
84 size_t size)
85{
86 dev_priv->mm.object_count--;
87 dev_priv->mm.object_memory -= size;
88}
89
Chris Wilson21dd3732011-01-26 15:55:56 +000090static int
91i915_gem_wait_for_error(struct drm_device *dev)
Chris Wilson30dbf0c2010-09-25 10:19:17 +010092{
93 struct drm_i915_private *dev_priv = dev->dev_private;
94 struct completion *x = &dev_priv->error_completion;
95 unsigned long flags;
96 int ret;
97
98 if (!atomic_read(&dev_priv->mm.wedged))
99 return 0;
100
Daniel Vetter0a6759c2012-07-04 22:18:41 +0200101 /*
102 * Only wait 10 seconds for the gpu reset to complete to avoid hanging
103 * userspace. If it takes that long something really bad is going on and
104 * we should simply try to bail out and fail as gracefully as possible.
105 */
106 ret = wait_for_completion_interruptible_timeout(x, 10*HZ);
107 if (ret == 0) {
108 DRM_ERROR("Timed out waiting for the gpu reset to complete\n");
109 return -EIO;
110 } else if (ret < 0) {
Chris Wilson30dbf0c2010-09-25 10:19:17 +0100111 return ret;
Daniel Vetter0a6759c2012-07-04 22:18:41 +0200112 }
Chris Wilson30dbf0c2010-09-25 10:19:17 +0100113
Chris Wilson21dd3732011-01-26 15:55:56 +0000114 if (atomic_read(&dev_priv->mm.wedged)) {
115 /* GPU is hung, bump the completion count to account for
116 * the token we just consumed so that we never hit zero and
117 * end up waiting upon a subsequent completion event that
118 * will never happen.
119 */
120 spin_lock_irqsave(&x->wait.lock, flags);
121 x->done++;
122 spin_unlock_irqrestore(&x->wait.lock, flags);
123 }
124 return 0;
Chris Wilson30dbf0c2010-09-25 10:19:17 +0100125}
126
Chris Wilson54cf91d2010-11-25 18:00:26 +0000127int i915_mutex_lock_interruptible(struct drm_device *dev)
Chris Wilson76c1dec2010-09-25 11:22:51 +0100128{
Chris Wilson76c1dec2010-09-25 11:22:51 +0100129 int ret;
130
Chris Wilson21dd3732011-01-26 15:55:56 +0000131 ret = i915_gem_wait_for_error(dev);
Chris Wilson76c1dec2010-09-25 11:22:51 +0100132 if (ret)
133 return ret;
134
135 ret = mutex_lock_interruptible(&dev->struct_mutex);
136 if (ret)
137 return ret;
138
Chris Wilson23bc5982010-09-29 16:10:57 +0100139 WARN_ON(i915_verify_lists(dev));
Chris Wilson76c1dec2010-09-25 11:22:51 +0100140 return 0;
141}
Chris Wilson30dbf0c2010-09-25 10:19:17 +0100142
Chris Wilson7d1c4802010-08-07 21:45:03 +0100143static inline bool
Chris Wilson05394f32010-11-08 19:18:58 +0000144i915_gem_object_is_inactive(struct drm_i915_gem_object *obj)
Chris Wilson7d1c4802010-08-07 21:45:03 +0100145{
Chris Wilson6c085a72012-08-20 11:40:46 +0200146 return obj->gtt_space && !obj->active;
Chris Wilson7d1c4802010-08-07 21:45:03 +0100147}
148
Eric Anholt673a3942008-07-30 12:06:12 -0700149int
150i915_gem_init_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +0000151 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -0700152{
Eric Anholt673a3942008-07-30 12:06:12 -0700153 struct drm_i915_gem_init *args = data;
Chris Wilson20217462010-11-23 15:26:33 +0000154
Daniel Vetter7bb6fb82012-04-24 08:22:52 +0200155 if (drm_core_check_feature(dev, DRIVER_MODESET))
156 return -ENODEV;
157
Chris Wilson20217462010-11-23 15:26:33 +0000158 if (args->gtt_start >= args->gtt_end ||
159 (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1))
160 return -EINVAL;
Eric Anholt673a3942008-07-30 12:06:12 -0700161
Daniel Vetterf534bc02012-03-26 22:37:04 +0200162 /* GEM with user mode setting was never supported on ilk and later. */
163 if (INTEL_INFO(dev)->gen >= 5)
164 return -ENODEV;
165
Eric Anholt673a3942008-07-30 12:06:12 -0700166 mutex_lock(&dev->struct_mutex);
Daniel Vetter644ec022012-03-26 09:45:40 +0200167 i915_gem_init_global_gtt(dev, args->gtt_start,
168 args->gtt_end, args->gtt_end);
Eric Anholt673a3942008-07-30 12:06:12 -0700169 mutex_unlock(&dev->struct_mutex);
170
Chris Wilson20217462010-11-23 15:26:33 +0000171 return 0;
Eric Anholt673a3942008-07-30 12:06:12 -0700172}
173
Eric Anholt5a125c32008-10-22 21:40:13 -0700174int
175i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +0000176 struct drm_file *file)
Eric Anholt5a125c32008-10-22 21:40:13 -0700177{
Chris Wilson73aa8082010-09-30 11:46:12 +0100178 struct drm_i915_private *dev_priv = dev->dev_private;
Eric Anholt5a125c32008-10-22 21:40:13 -0700179 struct drm_i915_gem_get_aperture *args = data;
Chris Wilson6299f992010-11-24 12:23:44 +0000180 struct drm_i915_gem_object *obj;
181 size_t pinned;
Eric Anholt5a125c32008-10-22 21:40:13 -0700182
Chris Wilson6299f992010-11-24 12:23:44 +0000183 pinned = 0;
Chris Wilson73aa8082010-09-30 11:46:12 +0100184 mutex_lock(&dev->struct_mutex);
Chris Wilson6c085a72012-08-20 11:40:46 +0200185 list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
Chris Wilson1b502472012-04-24 15:47:30 +0100186 if (obj->pin_count)
187 pinned += obj->gtt_space->size;
Chris Wilson73aa8082010-09-30 11:46:12 +0100188 mutex_unlock(&dev->struct_mutex);
Eric Anholt5a125c32008-10-22 21:40:13 -0700189
Chris Wilson6299f992010-11-24 12:23:44 +0000190 args->aper_size = dev_priv->mm.gtt_total;
Akshay Joshi0206e352011-08-16 15:34:10 -0400191 args->aper_available_size = args->aper_size - pinned;
Chris Wilson6299f992010-11-24 12:23:44 +0000192
Eric Anholt5a125c32008-10-22 21:40:13 -0700193 return 0;
194}
195
Dave Airlieff72145b2011-02-07 12:16:14 +1000196static int
197i915_gem_create(struct drm_file *file,
198 struct drm_device *dev,
199 uint64_t size,
200 uint32_t *handle_p)
Eric Anholt673a3942008-07-30 12:06:12 -0700201{
Chris Wilson05394f32010-11-08 19:18:58 +0000202 struct drm_i915_gem_object *obj;
Pekka Paalanena1a2d1d2009-08-23 12:40:55 +0300203 int ret;
204 u32 handle;
Eric Anholt673a3942008-07-30 12:06:12 -0700205
Dave Airlieff72145b2011-02-07 12:16:14 +1000206 size = roundup(size, PAGE_SIZE);
Chris Wilson8ffc0242011-09-14 14:14:28 +0200207 if (size == 0)
208 return -EINVAL;
Eric Anholt673a3942008-07-30 12:06:12 -0700209
210 /* Allocate the new object */
Dave Airlieff72145b2011-02-07 12:16:14 +1000211 obj = i915_gem_alloc_object(dev, size);
Eric Anholt673a3942008-07-30 12:06:12 -0700212 if (obj == NULL)
213 return -ENOMEM;
214
Chris Wilson05394f32010-11-08 19:18:58 +0000215 ret = drm_gem_handle_create(file, &obj->base, &handle);
Chris Wilson1dfd9752010-09-06 14:44:14 +0100216 if (ret) {
Chris Wilson05394f32010-11-08 19:18:58 +0000217 drm_gem_object_release(&obj->base);
218 i915_gem_info_remove_obj(dev->dev_private, obj->base.size);
Chris Wilson202f2fe2010-10-14 13:20:40 +0100219 kfree(obj);
Eric Anholt673a3942008-07-30 12:06:12 -0700220 return ret;
Chris Wilson1dfd9752010-09-06 14:44:14 +0100221 }
222
Chris Wilson202f2fe2010-10-14 13:20:40 +0100223 /* drop reference from allocate - handle holds it now */
Chris Wilson05394f32010-11-08 19:18:58 +0000224 drm_gem_object_unreference(&obj->base);
Chris Wilson202f2fe2010-10-14 13:20:40 +0100225 trace_i915_gem_object_create(obj);
226
Dave Airlieff72145b2011-02-07 12:16:14 +1000227 *handle_p = handle;
Eric Anholt673a3942008-07-30 12:06:12 -0700228 return 0;
229}
230
Dave Airlieff72145b2011-02-07 12:16:14 +1000231int
232i915_gem_dumb_create(struct drm_file *file,
233 struct drm_device *dev,
234 struct drm_mode_create_dumb *args)
235{
236 /* have to work out size/pitch and return them */
Chris Wilsoned0291f2011-03-19 08:21:45 +0000237 args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
Dave Airlieff72145b2011-02-07 12:16:14 +1000238 args->size = args->pitch * args->height;
239 return i915_gem_create(file, dev,
240 args->size, &args->handle);
241}
242
243int i915_gem_dumb_destroy(struct drm_file *file,
244 struct drm_device *dev,
245 uint32_t handle)
246{
247 return drm_gem_handle_delete(file, handle);
248}
249
250/**
251 * Creates a new mm object and returns a handle to it.
252 */
253int
254i915_gem_create_ioctl(struct drm_device *dev, void *data,
255 struct drm_file *file)
256{
257 struct drm_i915_gem_create *args = data;
Daniel Vetter63ed2cb2012-04-23 16:50:50 +0200258
Dave Airlieff72145b2011-02-07 12:16:14 +1000259 return i915_gem_create(file, dev,
260 args->size, &args->handle);
261}
262
Chris Wilson05394f32010-11-08 19:18:58 +0000263static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
Eric Anholt280b7132009-03-12 16:56:27 -0700264{
Chris Wilson05394f32010-11-08 19:18:58 +0000265 drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
Eric Anholt280b7132009-03-12 16:56:27 -0700266
267 return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
Chris Wilson05394f32010-11-08 19:18:58 +0000268 obj->tiling_mode != I915_TILING_NONE;
Eric Anholt280b7132009-03-12 16:56:27 -0700269}
270
Daniel Vetter8c599672011-12-14 13:57:31 +0100271static inline int
Daniel Vetter8461d222011-12-14 13:57:32 +0100272__copy_to_user_swizzled(char __user *cpu_vaddr,
273 const char *gpu_vaddr, int gpu_offset,
274 int length)
275{
276 int ret, cpu_offset = 0;
277
278 while (length > 0) {
279 int cacheline_end = ALIGN(gpu_offset + 1, 64);
280 int this_length = min(cacheline_end - gpu_offset, length);
281 int swizzled_gpu_offset = gpu_offset ^ 64;
282
283 ret = __copy_to_user(cpu_vaddr + cpu_offset,
284 gpu_vaddr + swizzled_gpu_offset,
285 this_length);
286 if (ret)
287 return ret + length;
288
289 cpu_offset += this_length;
290 gpu_offset += this_length;
291 length -= this_length;
292 }
293
294 return 0;
295}
296
297static inline int
Ben Widawsky4f0c7cf2012-04-16 14:07:47 -0700298__copy_from_user_swizzled(char *gpu_vaddr, int gpu_offset,
299 const char __user *cpu_vaddr,
Daniel Vetter8c599672011-12-14 13:57:31 +0100300 int length)
301{
302 int ret, cpu_offset = 0;
303
304 while (length > 0) {
305 int cacheline_end = ALIGN(gpu_offset + 1, 64);
306 int this_length = min(cacheline_end - gpu_offset, length);
307 int swizzled_gpu_offset = gpu_offset ^ 64;
308
309 ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset,
310 cpu_vaddr + cpu_offset,
311 this_length);
312 if (ret)
313 return ret + length;
314
315 cpu_offset += this_length;
316 gpu_offset += this_length;
317 length -= this_length;
318 }
319
320 return 0;
321}
322
Daniel Vetterd174bd62012-03-25 19:47:40 +0200323/* Per-page copy function for the shmem pread fastpath.
324 * Flushes invalid cachelines before reading the target if
325 * needs_clflush is set. */
Eric Anholteb014592009-03-10 11:44:52 -0700326static int
Daniel Vetterd174bd62012-03-25 19:47:40 +0200327shmem_pread_fast(struct page *page, int shmem_page_offset, int page_length,
328 char __user *user_data,
329 bool page_do_bit17_swizzling, bool needs_clflush)
330{
331 char *vaddr;
332 int ret;
333
Daniel Vettere7e58eb2012-03-25 19:47:43 +0200334 if (unlikely(page_do_bit17_swizzling))
Daniel Vetterd174bd62012-03-25 19:47:40 +0200335 return -EINVAL;
336
337 vaddr = kmap_atomic(page);
338 if (needs_clflush)
339 drm_clflush_virt_range(vaddr + shmem_page_offset,
340 page_length);
341 ret = __copy_to_user_inatomic(user_data,
342 vaddr + shmem_page_offset,
343 page_length);
344 kunmap_atomic(vaddr);
345
346 return ret;
347}
348
Daniel Vetter23c18c72012-03-25 19:47:42 +0200349static void
350shmem_clflush_swizzled_range(char *addr, unsigned long length,
351 bool swizzled)
352{
Daniel Vettere7e58eb2012-03-25 19:47:43 +0200353 if (unlikely(swizzled)) {
Daniel Vetter23c18c72012-03-25 19:47:42 +0200354 unsigned long start = (unsigned long) addr;
355 unsigned long end = (unsigned long) addr + length;
356
357 /* For swizzling simply ensure that we always flush both
358 * channels. Lame, but simple and it works. Swizzled
359 * pwrite/pread is far from a hotpath - current userspace
360 * doesn't use it at all. */
361 start = round_down(start, 128);
362 end = round_up(end, 128);
363
364 drm_clflush_virt_range((void *)start, end - start);
365 } else {
366 drm_clflush_virt_range(addr, length);
367 }
368
369}
370
Daniel Vetterd174bd62012-03-25 19:47:40 +0200371/* Only difference to the fast-path function is that this can handle bit17
372 * and uses non-atomic copy and kmap functions. */
373static int
374shmem_pread_slow(struct page *page, int shmem_page_offset, int page_length,
375 char __user *user_data,
376 bool page_do_bit17_swizzling, bool needs_clflush)
377{
378 char *vaddr;
379 int ret;
380
381 vaddr = kmap(page);
382 if (needs_clflush)
Daniel Vetter23c18c72012-03-25 19:47:42 +0200383 shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
384 page_length,
385 page_do_bit17_swizzling);
Daniel Vetterd174bd62012-03-25 19:47:40 +0200386
387 if (page_do_bit17_swizzling)
388 ret = __copy_to_user_swizzled(user_data,
389 vaddr, shmem_page_offset,
390 page_length);
391 else
392 ret = __copy_to_user(user_data,
393 vaddr + shmem_page_offset,
394 page_length);
395 kunmap(page);
396
397 return ret;
398}
399
Eric Anholteb014592009-03-10 11:44:52 -0700400static int
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200401i915_gem_shmem_pread(struct drm_device *dev,
402 struct drm_i915_gem_object *obj,
403 struct drm_i915_gem_pread *args,
404 struct drm_file *file)
Eric Anholteb014592009-03-10 11:44:52 -0700405{
Chris Wilson05394f32010-11-08 19:18:58 +0000406 struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
Daniel Vetter8461d222011-12-14 13:57:32 +0100407 char __user *user_data;
Eric Anholteb014592009-03-10 11:44:52 -0700408 ssize_t remain;
Daniel Vetter8461d222011-12-14 13:57:32 +0100409 loff_t offset;
Ben Widawskyeb2c0c82012-02-15 14:42:43 +0100410 int shmem_page_offset, page_length, ret = 0;
Daniel Vetter8461d222011-12-14 13:57:32 +0100411 int obj_do_bit17_swizzling, page_do_bit17_swizzling;
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200412 int hit_slowpath = 0;
Daniel Vetter96d79b52012-03-25 19:47:36 +0200413 int prefaulted = 0;
Daniel Vetter84897312012-03-25 19:47:31 +0200414 int needs_clflush = 0;
Daniel Vetter692a5762012-03-25 19:47:34 +0200415 int release_page;
Eric Anholteb014592009-03-10 11:44:52 -0700416
Daniel Vetter8461d222011-12-14 13:57:32 +0100417 user_data = (char __user *) (uintptr_t) args->data_ptr;
Eric Anholteb014592009-03-10 11:44:52 -0700418 remain = args->size;
419
Daniel Vetter8461d222011-12-14 13:57:32 +0100420 obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
Eric Anholteb014592009-03-10 11:44:52 -0700421
Daniel Vetter84897312012-03-25 19:47:31 +0200422 if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) {
423 /* If we're not in the cpu read domain, set ourself into the gtt
424 * read domain and manually flush cachelines (if required). This
425 * optimizes for the case when the gpu will dirty the data
426 * anyway again before the next pread happens. */
427 if (obj->cache_level == I915_CACHE_NONE)
428 needs_clflush = 1;
Chris Wilson6c085a72012-08-20 11:40:46 +0200429 if (obj->gtt_space) {
430 ret = i915_gem_object_set_to_gtt_domain(obj, false);
431 if (ret)
432 return ret;
433 }
Daniel Vetter84897312012-03-25 19:47:31 +0200434 }
Eric Anholteb014592009-03-10 11:44:52 -0700435
Eric Anholteb014592009-03-10 11:44:52 -0700436 offset = args->offset;
Daniel Vetter8461d222011-12-14 13:57:32 +0100437
Eric Anholteb014592009-03-10 11:44:52 -0700438 while (remain > 0) {
Chris Wilsone5281cc2010-10-28 13:45:36 +0100439 struct page *page;
440
Eric Anholteb014592009-03-10 11:44:52 -0700441 /* Operation in this page
442 *
Eric Anholteb014592009-03-10 11:44:52 -0700443 * shmem_page_offset = offset within page in shmem file
Eric Anholteb014592009-03-10 11:44:52 -0700444 * page_length = bytes to copy for this page
445 */
Chris Wilsonc8cbbb82011-05-12 22:17:11 +0100446 shmem_page_offset = offset_in_page(offset);
Eric Anholteb014592009-03-10 11:44:52 -0700447 page_length = remain;
448 if ((shmem_page_offset + page_length) > PAGE_SIZE)
449 page_length = PAGE_SIZE - shmem_page_offset;
Eric Anholteb014592009-03-10 11:44:52 -0700450
Daniel Vetter692a5762012-03-25 19:47:34 +0200451 if (obj->pages) {
452 page = obj->pages[offset >> PAGE_SHIFT];
453 release_page = 0;
454 } else {
455 page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
456 if (IS_ERR(page)) {
457 ret = PTR_ERR(page);
458 goto out;
459 }
460 release_page = 1;
Jesper Juhlb65552f2011-06-12 20:53:44 +0000461 }
Chris Wilsone5281cc2010-10-28 13:45:36 +0100462
Daniel Vetter8461d222011-12-14 13:57:32 +0100463 page_do_bit17_swizzling = obj_do_bit17_swizzling &&
464 (page_to_phys(page) & (1 << 17)) != 0;
465
Daniel Vetterd174bd62012-03-25 19:47:40 +0200466 ret = shmem_pread_fast(page, shmem_page_offset, page_length,
467 user_data, page_do_bit17_swizzling,
468 needs_clflush);
469 if (ret == 0)
470 goto next_page;
Eric Anholteb014592009-03-10 11:44:52 -0700471
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200472 hit_slowpath = 1;
Daniel Vetter692a5762012-03-25 19:47:34 +0200473 page_cache_get(page);
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200474 mutex_unlock(&dev->struct_mutex);
475
Daniel Vetter96d79b52012-03-25 19:47:36 +0200476 if (!prefaulted) {
Daniel Vetterf56f8212012-03-25 19:47:41 +0200477 ret = fault_in_multipages_writeable(user_data, remain);
Daniel Vetter96d79b52012-03-25 19:47:36 +0200478 /* Userspace is tricking us, but we've already clobbered
479 * its pages with the prefault and promised to write the
480 * data up to the first fault. Hence ignore any errors
481 * and just continue. */
482 (void)ret;
483 prefaulted = 1;
484 }
485
Daniel Vetterd174bd62012-03-25 19:47:40 +0200486 ret = shmem_pread_slow(page, shmem_page_offset, page_length,
487 user_data, page_do_bit17_swizzling,
488 needs_clflush);
Eric Anholteb014592009-03-10 11:44:52 -0700489
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200490 mutex_lock(&dev->struct_mutex);
Chris Wilsone5281cc2010-10-28 13:45:36 +0100491 page_cache_release(page);
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200492next_page:
Chris Wilsone5281cc2010-10-28 13:45:36 +0100493 mark_page_accessed(page);
Daniel Vetter692a5762012-03-25 19:47:34 +0200494 if (release_page)
495 page_cache_release(page);
Chris Wilsone5281cc2010-10-28 13:45:36 +0100496
Daniel Vetter8461d222011-12-14 13:57:32 +0100497 if (ret) {
498 ret = -EFAULT;
499 goto out;
500 }
501
Eric Anholteb014592009-03-10 11:44:52 -0700502 remain -= page_length;
Daniel Vetter8461d222011-12-14 13:57:32 +0100503 user_data += page_length;
Eric Anholteb014592009-03-10 11:44:52 -0700504 offset += page_length;
505 }
506
Chris Wilson4f27b752010-10-14 15:26:45 +0100507out:
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200508 if (hit_slowpath) {
509 /* Fixup: Kill any reinstated backing storage pages */
510 if (obj->madv == __I915_MADV_PURGED)
511 i915_gem_object_truncate(obj);
512 }
Eric Anholteb014592009-03-10 11:44:52 -0700513
514 return ret;
515}
516
Eric Anholt673a3942008-07-30 12:06:12 -0700517/**
518 * Reads data from the object referenced by handle.
519 *
520 * On error, the contents of *data are undefined.
521 */
522int
523i915_gem_pread_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +0000524 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -0700525{
526 struct drm_i915_gem_pread *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +0000527 struct drm_i915_gem_object *obj;
Chris Wilson35b62a82010-09-26 20:23:38 +0100528 int ret = 0;
Eric Anholt673a3942008-07-30 12:06:12 -0700529
Chris Wilson51311d02010-11-17 09:10:42 +0000530 if (args->size == 0)
531 return 0;
532
533 if (!access_ok(VERIFY_WRITE,
534 (char __user *)(uintptr_t)args->data_ptr,
535 args->size))
536 return -EFAULT;
537
Chris Wilson4f27b752010-10-14 15:26:45 +0100538 ret = i915_mutex_lock_interruptible(dev);
Chris Wilson1d7cfea2010-10-17 09:45:41 +0100539 if (ret)
Chris Wilson4f27b752010-10-14 15:26:45 +0100540 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -0700541
Chris Wilson05394f32010-11-08 19:18:58 +0000542 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +0000543 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +0100544 ret = -ENOENT;
545 goto unlock;
Chris Wilson4f27b752010-10-14 15:26:45 +0100546 }
Eric Anholt673a3942008-07-30 12:06:12 -0700547
Chris Wilson7dcd2492010-09-26 20:21:44 +0100548 /* Bounds check source. */
Chris Wilson05394f32010-11-08 19:18:58 +0000549 if (args->offset > obj->base.size ||
550 args->size > obj->base.size - args->offset) {
Chris Wilsonce9d4192010-09-26 20:50:05 +0100551 ret = -EINVAL;
Chris Wilson35b62a82010-09-26 20:23:38 +0100552 goto out;
Chris Wilsonce9d4192010-09-26 20:50:05 +0100553 }
554
Daniel Vetter1286ff72012-05-10 15:25:09 +0200555 /* prime objects have no backing filp to GEM pread/pwrite
556 * pages from.
557 */
558 if (!obj->base.filp) {
559 ret = -EINVAL;
560 goto out;
561 }
562
Chris Wilsondb53a302011-02-03 11:57:46 +0000563 trace_i915_gem_object_pread(obj, args->offset, args->size);
564
Daniel Vetterdbf7bff2012-03-25 19:47:29 +0200565 ret = i915_gem_shmem_pread(dev, obj, args, file);
Eric Anholt673a3942008-07-30 12:06:12 -0700566
Chris Wilson35b62a82010-09-26 20:23:38 +0100567out:
Chris Wilson05394f32010-11-08 19:18:58 +0000568 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +0100569unlock:
Chris Wilson4f27b752010-10-14 15:26:45 +0100570 mutex_unlock(&dev->struct_mutex);
Eric Anholteb014592009-03-10 11:44:52 -0700571 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -0700572}
573
Keith Packard0839ccb2008-10-30 19:38:48 -0700574/* This is the fast write path which cannot handle
575 * page faults in the source data
Linus Torvalds9b7530cc2008-10-20 14:16:43 -0700576 */
Linus Torvalds9b7530cc2008-10-20 14:16:43 -0700577
Keith Packard0839ccb2008-10-30 19:38:48 -0700578static inline int
579fast_user_write(struct io_mapping *mapping,
580 loff_t page_base, int page_offset,
581 char __user *user_data,
582 int length)
583{
Ben Widawsky4f0c7cf2012-04-16 14:07:47 -0700584 void __iomem *vaddr_atomic;
585 void *vaddr;
Keith Packard0839ccb2008-10-30 19:38:48 -0700586 unsigned long unwritten;
587
Peter Zijlstra3e4d3af2010-10-26 14:21:51 -0700588 vaddr_atomic = io_mapping_map_atomic_wc(mapping, page_base);
Ben Widawsky4f0c7cf2012-04-16 14:07:47 -0700589 /* We can use the cpu mem copy function because this is X86. */
590 vaddr = (void __force*)vaddr_atomic + page_offset;
591 unwritten = __copy_from_user_inatomic_nocache(vaddr,
Keith Packard0839ccb2008-10-30 19:38:48 -0700592 user_data, length);
Peter Zijlstra3e4d3af2010-10-26 14:21:51 -0700593 io_mapping_unmap_atomic(vaddr_atomic);
Chris Wilsonfbd5a262010-10-14 15:03:58 +0100594 return unwritten;
Keith Packard0839ccb2008-10-30 19:38:48 -0700595}
596
Eric Anholt3de09aa2009-03-09 09:42:23 -0700597/**
598 * This is the fast pwrite path, where we copy the data directly from the
599 * user into the GTT, uncached.
600 */
Eric Anholt673a3942008-07-30 12:06:12 -0700601static int
Chris Wilson05394f32010-11-08 19:18:58 +0000602i915_gem_gtt_pwrite_fast(struct drm_device *dev,
603 struct drm_i915_gem_object *obj,
Eric Anholt3de09aa2009-03-09 09:42:23 -0700604 struct drm_i915_gem_pwrite *args,
Chris Wilson05394f32010-11-08 19:18:58 +0000605 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -0700606{
Keith Packard0839ccb2008-10-30 19:38:48 -0700607 drm_i915_private_t *dev_priv = dev->dev_private;
Eric Anholt673a3942008-07-30 12:06:12 -0700608 ssize_t remain;
Keith Packard0839ccb2008-10-30 19:38:48 -0700609 loff_t offset, page_base;
Eric Anholt673a3942008-07-30 12:06:12 -0700610 char __user *user_data;
Daniel Vetter935aaa62012-03-25 19:47:35 +0200611 int page_offset, page_length, ret;
612
Chris Wilson86a1ee22012-08-11 15:41:04 +0100613 ret = i915_gem_object_pin(obj, 0, true, true);
Daniel Vetter935aaa62012-03-25 19:47:35 +0200614 if (ret)
615 goto out;
616
617 ret = i915_gem_object_set_to_gtt_domain(obj, true);
618 if (ret)
619 goto out_unpin;
620
621 ret = i915_gem_object_put_fence(obj);
622 if (ret)
623 goto out_unpin;
Eric Anholt673a3942008-07-30 12:06:12 -0700624
625 user_data = (char __user *) (uintptr_t) args->data_ptr;
626 remain = args->size;
Eric Anholt673a3942008-07-30 12:06:12 -0700627
Chris Wilson05394f32010-11-08 19:18:58 +0000628 offset = obj->gtt_offset + args->offset;
Eric Anholt673a3942008-07-30 12:06:12 -0700629
630 while (remain > 0) {
631 /* Operation in this page
632 *
Keith Packard0839ccb2008-10-30 19:38:48 -0700633 * page_base = page offset within aperture
634 * page_offset = offset within page
635 * page_length = bytes to copy for this page
Eric Anholt673a3942008-07-30 12:06:12 -0700636 */
Chris Wilsonc8cbbb82011-05-12 22:17:11 +0100637 page_base = offset & PAGE_MASK;
638 page_offset = offset_in_page(offset);
Keith Packard0839ccb2008-10-30 19:38:48 -0700639 page_length = remain;
640 if ((page_offset + remain) > PAGE_SIZE)
641 page_length = PAGE_SIZE - page_offset;
Eric Anholt673a3942008-07-30 12:06:12 -0700642
Keith Packard0839ccb2008-10-30 19:38:48 -0700643 /* If we get a fault while copying data, then (presumably) our
Eric Anholt3de09aa2009-03-09 09:42:23 -0700644 * source page isn't available. Return the error and we'll
645 * retry in the slow path.
Keith Packard0839ccb2008-10-30 19:38:48 -0700646 */
Chris Wilsonfbd5a262010-10-14 15:03:58 +0100647 if (fast_user_write(dev_priv->mm.gtt_mapping, page_base,
Daniel Vetter935aaa62012-03-25 19:47:35 +0200648 page_offset, user_data, page_length)) {
649 ret = -EFAULT;
650 goto out_unpin;
651 }
Eric Anholt673a3942008-07-30 12:06:12 -0700652
Keith Packard0839ccb2008-10-30 19:38:48 -0700653 remain -= page_length;
654 user_data += page_length;
655 offset += page_length;
Eric Anholt673a3942008-07-30 12:06:12 -0700656 }
Eric Anholt673a3942008-07-30 12:06:12 -0700657
Daniel Vetter935aaa62012-03-25 19:47:35 +0200658out_unpin:
659 i915_gem_object_unpin(obj);
660out:
Eric Anholt3de09aa2009-03-09 09:42:23 -0700661 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -0700662}
663
Daniel Vetterd174bd62012-03-25 19:47:40 +0200664/* Per-page copy function for the shmem pwrite fastpath.
665 * Flushes invalid cachelines before writing to the target if
666 * needs_clflush_before is set and flushes out any written cachelines after
667 * writing if needs_clflush is set. */
Eric Anholt673a3942008-07-30 12:06:12 -0700668static int
Daniel Vetterd174bd62012-03-25 19:47:40 +0200669shmem_pwrite_fast(struct page *page, int shmem_page_offset, int page_length,
670 char __user *user_data,
671 bool page_do_bit17_swizzling,
672 bool needs_clflush_before,
673 bool needs_clflush_after)
Eric Anholt673a3942008-07-30 12:06:12 -0700674{
Daniel Vetterd174bd62012-03-25 19:47:40 +0200675 char *vaddr;
Eric Anholt3de09aa2009-03-09 09:42:23 -0700676 int ret;
Eric Anholt3de09aa2009-03-09 09:42:23 -0700677
Daniel Vettere7e58eb2012-03-25 19:47:43 +0200678 if (unlikely(page_do_bit17_swizzling))
Daniel Vetterd174bd62012-03-25 19:47:40 +0200679 return -EINVAL;
Eric Anholt3de09aa2009-03-09 09:42:23 -0700680
Daniel Vetterd174bd62012-03-25 19:47:40 +0200681 vaddr = kmap_atomic(page);
682 if (needs_clflush_before)
683 drm_clflush_virt_range(vaddr + shmem_page_offset,
684 page_length);
685 ret = __copy_from_user_inatomic_nocache(vaddr + shmem_page_offset,
686 user_data,
687 page_length);
688 if (needs_clflush_after)
689 drm_clflush_virt_range(vaddr + shmem_page_offset,
690 page_length);
691 kunmap_atomic(vaddr);
Eric Anholt3de09aa2009-03-09 09:42:23 -0700692
Chris Wilson755d2212012-09-04 21:02:55 +0100693 return ret ? -EFAULT : 0;
Eric Anholt3de09aa2009-03-09 09:42:23 -0700694}
695
Daniel Vetterd174bd62012-03-25 19:47:40 +0200696/* Only difference to the fast-path function is that this can handle bit17
697 * and uses non-atomic copy and kmap functions. */
Eric Anholt3043c602008-10-02 12:24:47 -0700698static int
Daniel Vetterd174bd62012-03-25 19:47:40 +0200699shmem_pwrite_slow(struct page *page, int shmem_page_offset, int page_length,
700 char __user *user_data,
701 bool page_do_bit17_swizzling,
702 bool needs_clflush_before,
703 bool needs_clflush_after)
Eric Anholt673a3942008-07-30 12:06:12 -0700704{
Daniel Vetterd174bd62012-03-25 19:47:40 +0200705 char *vaddr;
706 int ret;
Eric Anholt40123c12009-03-09 13:42:30 -0700707
Daniel Vetterd174bd62012-03-25 19:47:40 +0200708 vaddr = kmap(page);
Daniel Vettere7e58eb2012-03-25 19:47:43 +0200709 if (unlikely(needs_clflush_before || page_do_bit17_swizzling))
Daniel Vetter23c18c72012-03-25 19:47:42 +0200710 shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
711 page_length,
712 page_do_bit17_swizzling);
Daniel Vetterd174bd62012-03-25 19:47:40 +0200713 if (page_do_bit17_swizzling)
714 ret = __copy_from_user_swizzled(vaddr, shmem_page_offset,
Chris Wilsone5281cc2010-10-28 13:45:36 +0100715 user_data,
716 page_length);
Daniel Vetterd174bd62012-03-25 19:47:40 +0200717 else
718 ret = __copy_from_user(vaddr + shmem_page_offset,
719 user_data,
720 page_length);
721 if (needs_clflush_after)
Daniel Vetter23c18c72012-03-25 19:47:42 +0200722 shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
723 page_length,
724 page_do_bit17_swizzling);
Daniel Vetterd174bd62012-03-25 19:47:40 +0200725 kunmap(page);
Chris Wilsone5281cc2010-10-28 13:45:36 +0100726
Chris Wilson755d2212012-09-04 21:02:55 +0100727 return ret ? -EFAULT : 0;
Eric Anholt40123c12009-03-09 13:42:30 -0700728}
729
Eric Anholt40123c12009-03-09 13:42:30 -0700730static int
Daniel Vettere244a442012-03-25 19:47:28 +0200731i915_gem_shmem_pwrite(struct drm_device *dev,
732 struct drm_i915_gem_object *obj,
733 struct drm_i915_gem_pwrite *args,
734 struct drm_file *file)
Eric Anholt40123c12009-03-09 13:42:30 -0700735{
Eric Anholt40123c12009-03-09 13:42:30 -0700736 ssize_t remain;
Daniel Vetter8c599672011-12-14 13:57:31 +0100737 loff_t offset;
738 char __user *user_data;
Ben Widawskyeb2c0c82012-02-15 14:42:43 +0100739 int shmem_page_offset, page_length, ret = 0;
Daniel Vetter8c599672011-12-14 13:57:31 +0100740 int obj_do_bit17_swizzling, page_do_bit17_swizzling;
Daniel Vettere244a442012-03-25 19:47:28 +0200741 int hit_slowpath = 0;
Daniel Vetter58642882012-03-25 19:47:37 +0200742 int needs_clflush_after = 0;
743 int needs_clflush_before = 0;
Eric Anholt40123c12009-03-09 13:42:30 -0700744
Daniel Vetter8c599672011-12-14 13:57:31 +0100745 user_data = (char __user *) (uintptr_t) args->data_ptr;
Eric Anholt40123c12009-03-09 13:42:30 -0700746 remain = args->size;
747
Daniel Vetter8c599672011-12-14 13:57:31 +0100748 obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
Eric Anholt40123c12009-03-09 13:42:30 -0700749
Daniel Vetter58642882012-03-25 19:47:37 +0200750 if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
751 /* If we're not in the cpu write domain, set ourself into the gtt
752 * write domain and manually flush cachelines (if required). This
753 * optimizes for the case when the gpu will use the data
754 * right away and we therefore have to clflush anyway. */
755 if (obj->cache_level == I915_CACHE_NONE)
756 needs_clflush_after = 1;
Chris Wilson6c085a72012-08-20 11:40:46 +0200757 if (obj->gtt_space) {
758 ret = i915_gem_object_set_to_gtt_domain(obj, true);
759 if (ret)
760 return ret;
761 }
Daniel Vetter58642882012-03-25 19:47:37 +0200762 }
763 /* Same trick applies for invalidate partially written cachelines before
764 * writing. */
765 if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)
766 && obj->cache_level == I915_CACHE_NONE)
767 needs_clflush_before = 1;
768
Chris Wilson755d2212012-09-04 21:02:55 +0100769 ret = i915_gem_object_get_pages(obj);
770 if (ret)
771 return ret;
772
773 i915_gem_object_pin_pages(obj);
774
Eric Anholt40123c12009-03-09 13:42:30 -0700775 offset = args->offset;
Chris Wilson05394f32010-11-08 19:18:58 +0000776 obj->dirty = 1;
Eric Anholt40123c12009-03-09 13:42:30 -0700777
778 while (remain > 0) {
Chris Wilsone5281cc2010-10-28 13:45:36 +0100779 struct page *page;
Daniel Vetter58642882012-03-25 19:47:37 +0200780 int partial_cacheline_write;
Chris Wilsone5281cc2010-10-28 13:45:36 +0100781
Eric Anholt40123c12009-03-09 13:42:30 -0700782 /* Operation in this page
783 *
Eric Anholt40123c12009-03-09 13:42:30 -0700784 * shmem_page_offset = offset within page in shmem file
Eric Anholt40123c12009-03-09 13:42:30 -0700785 * page_length = bytes to copy for this page
786 */
Chris Wilsonc8cbbb82011-05-12 22:17:11 +0100787 shmem_page_offset = offset_in_page(offset);
Eric Anholt40123c12009-03-09 13:42:30 -0700788
789 page_length = remain;
790 if ((shmem_page_offset + page_length) > PAGE_SIZE)
791 page_length = PAGE_SIZE - shmem_page_offset;
Eric Anholt40123c12009-03-09 13:42:30 -0700792
Daniel Vetter58642882012-03-25 19:47:37 +0200793 /* If we don't overwrite a cacheline completely we need to be
794 * careful to have up-to-date data by first clflushing. Don't
795 * overcomplicate things and flush the entire patch. */
796 partial_cacheline_write = needs_clflush_before &&
797 ((shmem_page_offset | page_length)
798 & (boot_cpu_data.x86_clflush_size - 1));
799
Chris Wilson755d2212012-09-04 21:02:55 +0100800 page = obj->pages[offset >> PAGE_SHIFT];
Daniel Vetter8c599672011-12-14 13:57:31 +0100801 page_do_bit17_swizzling = obj_do_bit17_swizzling &&
802 (page_to_phys(page) & (1 << 17)) != 0;
803
Daniel Vetterd174bd62012-03-25 19:47:40 +0200804 ret = shmem_pwrite_fast(page, shmem_page_offset, page_length,
805 user_data, page_do_bit17_swizzling,
806 partial_cacheline_write,
807 needs_clflush_after);
808 if (ret == 0)
809 goto next_page;
Eric Anholt40123c12009-03-09 13:42:30 -0700810
Daniel Vettere244a442012-03-25 19:47:28 +0200811 hit_slowpath = 1;
Daniel Vettere244a442012-03-25 19:47:28 +0200812 mutex_unlock(&dev->struct_mutex);
Daniel Vetterd174bd62012-03-25 19:47:40 +0200813 ret = shmem_pwrite_slow(page, shmem_page_offset, page_length,
814 user_data, page_do_bit17_swizzling,
815 partial_cacheline_write,
816 needs_clflush_after);
Eric Anholt40123c12009-03-09 13:42:30 -0700817
Daniel Vettere244a442012-03-25 19:47:28 +0200818 mutex_lock(&dev->struct_mutex);
Chris Wilson755d2212012-09-04 21:02:55 +0100819
Daniel Vettere244a442012-03-25 19:47:28 +0200820next_page:
Chris Wilsone5281cc2010-10-28 13:45:36 +0100821 set_page_dirty(page);
822 mark_page_accessed(page);
Chris Wilsone5281cc2010-10-28 13:45:36 +0100823
Chris Wilson755d2212012-09-04 21:02:55 +0100824 if (ret)
Daniel Vetter8c599672011-12-14 13:57:31 +0100825 goto out;
Daniel Vetter8c599672011-12-14 13:57:31 +0100826
Eric Anholt40123c12009-03-09 13:42:30 -0700827 remain -= page_length;
Daniel Vetter8c599672011-12-14 13:57:31 +0100828 user_data += page_length;
Eric Anholt40123c12009-03-09 13:42:30 -0700829 offset += page_length;
830 }
831
Chris Wilsonfbd5a262010-10-14 15:03:58 +0100832out:
Chris Wilson755d2212012-09-04 21:02:55 +0100833 i915_gem_object_unpin_pages(obj);
834
Daniel Vettere244a442012-03-25 19:47:28 +0200835 if (hit_slowpath) {
836 /* Fixup: Kill any reinstated backing storage pages */
837 if (obj->madv == __I915_MADV_PURGED)
838 i915_gem_object_truncate(obj);
839 /* and flush dirty cachelines in case the object isn't in the cpu write
840 * domain anymore. */
841 if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
842 i915_gem_clflush_object(obj);
843 intel_gtt_chipset_flush();
844 }
Daniel Vetter8c599672011-12-14 13:57:31 +0100845 }
Eric Anholt40123c12009-03-09 13:42:30 -0700846
Daniel Vetter58642882012-03-25 19:47:37 +0200847 if (needs_clflush_after)
848 intel_gtt_chipset_flush();
849
Eric Anholt40123c12009-03-09 13:42:30 -0700850 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -0700851}
852
853/**
854 * Writes data to the object referenced by handle.
855 *
856 * On error, the contents of the buffer that were to be modified are undefined.
857 */
858int
859i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
Chris Wilsonfbd5a262010-10-14 15:03:58 +0100860 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -0700861{
862 struct drm_i915_gem_pwrite *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +0000863 struct drm_i915_gem_object *obj;
Chris Wilson51311d02010-11-17 09:10:42 +0000864 int ret;
865
866 if (args->size == 0)
867 return 0;
868
869 if (!access_ok(VERIFY_READ,
870 (char __user *)(uintptr_t)args->data_ptr,
871 args->size))
872 return -EFAULT;
873
Daniel Vetterf56f8212012-03-25 19:47:41 +0200874 ret = fault_in_multipages_readable((char __user *)(uintptr_t)args->data_ptr,
875 args->size);
Chris Wilson51311d02010-11-17 09:10:42 +0000876 if (ret)
877 return -EFAULT;
Eric Anholt673a3942008-07-30 12:06:12 -0700878
Chris Wilson1d7cfea2010-10-17 09:45:41 +0100879 ret = i915_mutex_lock_interruptible(dev);
880 if (ret)
881 return ret;
882
Chris Wilson05394f32010-11-08 19:18:58 +0000883 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +0000884 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +0100885 ret = -ENOENT;
886 goto unlock;
887 }
Eric Anholt673a3942008-07-30 12:06:12 -0700888
Chris Wilson7dcd2492010-09-26 20:21:44 +0100889 /* Bounds check destination. */
Chris Wilson05394f32010-11-08 19:18:58 +0000890 if (args->offset > obj->base.size ||
891 args->size > obj->base.size - args->offset) {
Chris Wilsonce9d4192010-09-26 20:50:05 +0100892 ret = -EINVAL;
Chris Wilson35b62a82010-09-26 20:23:38 +0100893 goto out;
Chris Wilsonce9d4192010-09-26 20:50:05 +0100894 }
895
Daniel Vetter1286ff72012-05-10 15:25:09 +0200896 /* prime objects have no backing filp to GEM pread/pwrite
897 * pages from.
898 */
899 if (!obj->base.filp) {
900 ret = -EINVAL;
901 goto out;
902 }
903
Chris Wilsondb53a302011-02-03 11:57:46 +0000904 trace_i915_gem_object_pwrite(obj, args->offset, args->size);
905
Daniel Vetter935aaa62012-03-25 19:47:35 +0200906 ret = -EFAULT;
Eric Anholt673a3942008-07-30 12:06:12 -0700907 /* We can only do the GTT pwrite on untiled buffers, as otherwise
908 * it would end up going through the fenced access, and we'll get
909 * different detiling behavior between reading and writing.
910 * pread/pwrite currently are reading and writing from the CPU
911 * perspective, requiring manual detiling by the client.
912 */
Daniel Vetter5c0480f2011-12-14 13:57:30 +0100913 if (obj->phys_obj) {
Chris Wilsonfbd5a262010-10-14 15:03:58 +0100914 ret = i915_gem_phys_pwrite(dev, obj, args, file);
Daniel Vetter5c0480f2011-12-14 13:57:30 +0100915 goto out;
916 }
917
Chris Wilson86a1ee22012-08-11 15:41:04 +0100918 if (obj->cache_level == I915_CACHE_NONE &&
Daniel Vetterc07496f2012-04-13 15:51:51 +0200919 obj->tiling_mode == I915_TILING_NONE &&
Daniel Vetter5c0480f2011-12-14 13:57:30 +0100920 obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
Chris Wilsonfbd5a262010-10-14 15:03:58 +0100921 ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file);
Daniel Vetter935aaa62012-03-25 19:47:35 +0200922 /* Note that the gtt paths might fail with non-page-backed user
923 * pointers (e.g. gtt mappings when moving data between
924 * textures). Fallback to the shmem path in that case. */
Eric Anholt40123c12009-03-09 13:42:30 -0700925 }
Eric Anholt673a3942008-07-30 12:06:12 -0700926
Chris Wilson86a1ee22012-08-11 15:41:04 +0100927 if (ret == -EFAULT || ret == -ENOSPC)
Daniel Vetter935aaa62012-03-25 19:47:35 +0200928 ret = i915_gem_shmem_pwrite(dev, obj, args, file);
Daniel Vetter5c0480f2011-12-14 13:57:30 +0100929
Chris Wilson35b62a82010-09-26 20:23:38 +0100930out:
Chris Wilson05394f32010-11-08 19:18:58 +0000931 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +0100932unlock:
Chris Wilsonfbd5a262010-10-14 15:03:58 +0100933 mutex_unlock(&dev->struct_mutex);
Eric Anholt673a3942008-07-30 12:06:12 -0700934 return ret;
935}
936
Chris Wilsonb3612372012-08-24 09:35:08 +0100937int
938i915_gem_check_wedge(struct drm_i915_private *dev_priv,
939 bool interruptible)
940{
941 if (atomic_read(&dev_priv->mm.wedged)) {
942 struct completion *x = &dev_priv->error_completion;
943 bool recovery_complete;
944 unsigned long flags;
945
946 /* Give the error handler a chance to run. */
947 spin_lock_irqsave(&x->wait.lock, flags);
948 recovery_complete = x->done > 0;
949 spin_unlock_irqrestore(&x->wait.lock, flags);
950
951 /* Non-interruptible callers can't handle -EAGAIN, hence return
952 * -EIO unconditionally for these. */
953 if (!interruptible)
954 return -EIO;
955
956 /* Recovery complete, but still wedged means reset failure. */
957 if (recovery_complete)
958 return -EIO;
959
960 return -EAGAIN;
961 }
962
963 return 0;
964}
965
966/*
967 * Compare seqno against outstanding lazy request. Emit a request if they are
968 * equal.
969 */
970static int
971i915_gem_check_olr(struct intel_ring_buffer *ring, u32 seqno)
972{
973 int ret;
974
975 BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
976
977 ret = 0;
978 if (seqno == ring->outstanding_lazy_request)
979 ret = i915_add_request(ring, NULL, NULL);
980
981 return ret;
982}
983
984/**
985 * __wait_seqno - wait until execution of seqno has finished
986 * @ring: the ring expected to report seqno
987 * @seqno: duh!
988 * @interruptible: do an interruptible wait (normally yes)
989 * @timeout: in - how long to wait (NULL forever); out - how much time remaining
990 *
991 * Returns 0 if the seqno was found within the alloted time. Else returns the
992 * errno with remaining time filled in timeout argument.
993 */
994static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
995 bool interruptible, struct timespec *timeout)
996{
997 drm_i915_private_t *dev_priv = ring->dev->dev_private;
998 struct timespec before, now, wait_time={1,0};
999 unsigned long timeout_jiffies;
1000 long end;
1001 bool wait_forever = true;
1002 int ret;
1003
1004 if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
1005 return 0;
1006
1007 trace_i915_gem_request_wait_begin(ring, seqno);
1008
1009 if (timeout != NULL) {
1010 wait_time = *timeout;
1011 wait_forever = false;
1012 }
1013
1014 timeout_jiffies = timespec_to_jiffies(&wait_time);
1015
1016 if (WARN_ON(!ring->irq_get(ring)))
1017 return -ENODEV;
1018
1019 /* Record current time in case interrupted by signal, or wedged * */
1020 getrawmonotonic(&before);
1021
1022#define EXIT_COND \
1023 (i915_seqno_passed(ring->get_seqno(ring, false), seqno) || \
1024 atomic_read(&dev_priv->mm.wedged))
1025 do {
1026 if (interruptible)
1027 end = wait_event_interruptible_timeout(ring->irq_queue,
1028 EXIT_COND,
1029 timeout_jiffies);
1030 else
1031 end = wait_event_timeout(ring->irq_queue, EXIT_COND,
1032 timeout_jiffies);
1033
1034 ret = i915_gem_check_wedge(dev_priv, interruptible);
1035 if (ret)
1036 end = ret;
1037 } while (end == 0 && wait_forever);
1038
1039 getrawmonotonic(&now);
1040
1041 ring->irq_put(ring);
1042 trace_i915_gem_request_wait_end(ring, seqno);
1043#undef EXIT_COND
1044
1045 if (timeout) {
1046 struct timespec sleep_time = timespec_sub(now, before);
1047 *timeout = timespec_sub(*timeout, sleep_time);
1048 }
1049
1050 switch (end) {
1051 case -EIO:
1052 case -EAGAIN: /* Wedged */
1053 case -ERESTARTSYS: /* Signal */
1054 return (int)end;
1055 case 0: /* Timeout */
1056 if (timeout)
1057 set_normalized_timespec(timeout, 0, 0);
1058 return -ETIME;
1059 default: /* Completed */
1060 WARN_ON(end < 0); /* We're not aware of other errors */
1061 return 0;
1062 }
1063}
1064
1065/**
1066 * Waits for a sequence number to be signaled, and cleans up the
1067 * request and object lists appropriately for that event.
1068 */
1069int
1070i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
1071{
1072 struct drm_device *dev = ring->dev;
1073 struct drm_i915_private *dev_priv = dev->dev_private;
1074 bool interruptible = dev_priv->mm.interruptible;
1075 int ret;
1076
1077 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
1078 BUG_ON(seqno == 0);
1079
1080 ret = i915_gem_check_wedge(dev_priv, interruptible);
1081 if (ret)
1082 return ret;
1083
1084 ret = i915_gem_check_olr(ring, seqno);
1085 if (ret)
1086 return ret;
1087
1088 return __wait_seqno(ring, seqno, interruptible, NULL);
1089}
1090
1091/**
1092 * Ensures that all rendering to the object has completed and the object is
1093 * safe to unbind from the GTT or access from the CPU.
1094 */
1095static __must_check int
1096i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
1097 bool readonly)
1098{
1099 struct intel_ring_buffer *ring = obj->ring;
1100 u32 seqno;
1101 int ret;
1102
1103 seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
1104 if (seqno == 0)
1105 return 0;
1106
1107 ret = i915_wait_seqno(ring, seqno);
1108 if (ret)
1109 return ret;
1110
1111 i915_gem_retire_requests_ring(ring);
1112
1113 /* Manually manage the write flush as we may have not yet
1114 * retired the buffer.
1115 */
1116 if (obj->last_write_seqno &&
1117 i915_seqno_passed(seqno, obj->last_write_seqno)) {
1118 obj->last_write_seqno = 0;
1119 obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
1120 }
1121
1122 return 0;
1123}
1124
Chris Wilson3236f572012-08-24 09:35:09 +01001125/* A nonblocking variant of the above wait. This is a highly dangerous routine
1126 * as the object state may change during this call.
1127 */
1128static __must_check int
1129i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
1130 bool readonly)
1131{
1132 struct drm_device *dev = obj->base.dev;
1133 struct drm_i915_private *dev_priv = dev->dev_private;
1134 struct intel_ring_buffer *ring = obj->ring;
1135 u32 seqno;
1136 int ret;
1137
1138 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
1139 BUG_ON(!dev_priv->mm.interruptible);
1140
1141 seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
1142 if (seqno == 0)
1143 return 0;
1144
1145 ret = i915_gem_check_wedge(dev_priv, true);
1146 if (ret)
1147 return ret;
1148
1149 ret = i915_gem_check_olr(ring, seqno);
1150 if (ret)
1151 return ret;
1152
1153 mutex_unlock(&dev->struct_mutex);
1154 ret = __wait_seqno(ring, seqno, true, NULL);
1155 mutex_lock(&dev->struct_mutex);
1156
1157 i915_gem_retire_requests_ring(ring);
1158
1159 /* Manually manage the write flush as we may have not yet
1160 * retired the buffer.
1161 */
1162 if (obj->last_write_seqno &&
1163 i915_seqno_passed(seqno, obj->last_write_seqno)) {
1164 obj->last_write_seqno = 0;
1165 obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
1166 }
1167
1168 return ret;
1169}
1170
Eric Anholt673a3942008-07-30 12:06:12 -07001171/**
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001172 * Called when user space prepares to use an object with the CPU, either
1173 * through the mmap ioctl's mapping or a GTT mapping.
Eric Anholt673a3942008-07-30 12:06:12 -07001174 */
1175int
1176i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +00001177 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -07001178{
1179 struct drm_i915_gem_set_domain *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +00001180 struct drm_i915_gem_object *obj;
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001181 uint32_t read_domains = args->read_domains;
1182 uint32_t write_domain = args->write_domain;
Eric Anholt673a3942008-07-30 12:06:12 -07001183 int ret;
1184
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001185 /* Only handle setting domains to types used by the CPU. */
Chris Wilson21d509e2009-06-06 09:46:02 +01001186 if (write_domain & I915_GEM_GPU_DOMAINS)
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001187 return -EINVAL;
1188
Chris Wilson21d509e2009-06-06 09:46:02 +01001189 if (read_domains & I915_GEM_GPU_DOMAINS)
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001190 return -EINVAL;
1191
1192 /* Having something in the write domain implies it's in the read
1193 * domain, and only that read domain. Enforce that in the request.
1194 */
1195 if (write_domain != 0 && read_domains != write_domain)
1196 return -EINVAL;
1197
Chris Wilson76c1dec2010-09-25 11:22:51 +01001198 ret = i915_mutex_lock_interruptible(dev);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001199 if (ret)
Chris Wilson76c1dec2010-09-25 11:22:51 +01001200 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07001201
Chris Wilson05394f32010-11-08 19:18:58 +00001202 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +00001203 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001204 ret = -ENOENT;
1205 goto unlock;
Chris Wilson76c1dec2010-09-25 11:22:51 +01001206 }
Jesse Barnes652c3932009-08-17 13:31:43 -07001207
Chris Wilson3236f572012-08-24 09:35:09 +01001208 /* Try to flush the object off the GPU without holding the lock.
1209 * We will repeat the flush holding the lock in the normal manner
1210 * to catch cases where we are gazumped.
1211 */
1212 ret = i915_gem_object_wait_rendering__nonblocking(obj, !write_domain);
1213 if (ret)
1214 goto unref;
1215
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001216 if (read_domains & I915_GEM_DOMAIN_GTT) {
1217 ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
Eric Anholt02354392008-11-26 13:58:13 -08001218
1219 /* Silently promote "you're not bound, there was nothing to do"
1220 * to success, since the client was just asking us to
1221 * make sure everything was done.
1222 */
1223 if (ret == -EINVAL)
1224 ret = 0;
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001225 } else {
Eric Anholte47c68e2008-11-14 13:35:19 -08001226 ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0);
Eric Anholt2ef7eea2008-11-10 10:53:25 -08001227 }
1228
Chris Wilson3236f572012-08-24 09:35:09 +01001229unref:
Chris Wilson05394f32010-11-08 19:18:58 +00001230 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001231unlock:
Eric Anholt673a3942008-07-30 12:06:12 -07001232 mutex_unlock(&dev->struct_mutex);
1233 return ret;
1234}
1235
1236/**
1237 * Called when user space has done writes to this buffer
1238 */
1239int
1240i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +00001241 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -07001242{
1243 struct drm_i915_gem_sw_finish *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +00001244 struct drm_i915_gem_object *obj;
Eric Anholt673a3942008-07-30 12:06:12 -07001245 int ret = 0;
1246
Chris Wilson76c1dec2010-09-25 11:22:51 +01001247 ret = i915_mutex_lock_interruptible(dev);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001248 if (ret)
Chris Wilson76c1dec2010-09-25 11:22:51 +01001249 return ret;
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001250
Chris Wilson05394f32010-11-08 19:18:58 +00001251 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +00001252 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001253 ret = -ENOENT;
1254 goto unlock;
Eric Anholt673a3942008-07-30 12:06:12 -07001255 }
1256
Eric Anholt673a3942008-07-30 12:06:12 -07001257 /* Pinned buffers may be scanout, so flush the cache */
Chris Wilson05394f32010-11-08 19:18:58 +00001258 if (obj->pin_count)
Eric Anholte47c68e2008-11-14 13:35:19 -08001259 i915_gem_object_flush_cpu_write_domain(obj);
1260
Chris Wilson05394f32010-11-08 19:18:58 +00001261 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001262unlock:
Eric Anholt673a3942008-07-30 12:06:12 -07001263 mutex_unlock(&dev->struct_mutex);
1264 return ret;
1265}
1266
1267/**
1268 * Maps the contents of an object, returning the address it is mapped
1269 * into.
1270 *
1271 * While the mapping holds a reference on the contents of the object, it doesn't
1272 * imply a ref on the object itself.
1273 */
1274int
1275i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +00001276 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -07001277{
1278 struct drm_i915_gem_mmap *args = data;
1279 struct drm_gem_object *obj;
Eric Anholt673a3942008-07-30 12:06:12 -07001280 unsigned long addr;
1281
Chris Wilson05394f32010-11-08 19:18:58 +00001282 obj = drm_gem_object_lookup(dev, file, args->handle);
Eric Anholt673a3942008-07-30 12:06:12 -07001283 if (obj == NULL)
Chris Wilsonbf79cb92010-08-04 14:19:46 +01001284 return -ENOENT;
Eric Anholt673a3942008-07-30 12:06:12 -07001285
Daniel Vetter1286ff72012-05-10 15:25:09 +02001286 /* prime objects have no backing filp to GEM mmap
1287 * pages from.
1288 */
1289 if (!obj->filp) {
1290 drm_gem_object_unreference_unlocked(obj);
1291 return -EINVAL;
1292 }
1293
Linus Torvalds6be5ceb2012-04-20 17:13:58 -07001294 addr = vm_mmap(obj->filp, 0, args->size,
Eric Anholt673a3942008-07-30 12:06:12 -07001295 PROT_READ | PROT_WRITE, MAP_SHARED,
1296 args->offset);
Luca Barbieribc9025b2010-02-09 05:49:12 +00001297 drm_gem_object_unreference_unlocked(obj);
Eric Anholt673a3942008-07-30 12:06:12 -07001298 if (IS_ERR((void *)addr))
1299 return addr;
1300
1301 args->addr_ptr = (uint64_t) addr;
1302
1303 return 0;
1304}
1305
Jesse Barnesde151cf2008-11-12 10:03:55 -08001306/**
1307 * i915_gem_fault - fault a page into the GTT
1308 * vma: VMA in question
1309 * vmf: fault info
1310 *
1311 * The fault handler is set up by drm_gem_mmap() when a object is GTT mapped
1312 * from userspace. The fault handler takes care of binding the object to
1313 * the GTT (if needed), allocating and programming a fence register (again,
1314 * only if needed based on whether the old reg is still valid or the object
1315 * is tiled) and inserting a new PTE into the faulting process.
1316 *
1317 * Note that the faulting process may involve evicting existing objects
1318 * from the GTT and/or fence registers to make room. So performance may
1319 * suffer if the GTT working set is large or there are few fence registers
1320 * left.
1321 */
1322int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1323{
Chris Wilson05394f32010-11-08 19:18:58 +00001324 struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data);
1325 struct drm_device *dev = obj->base.dev;
Chris Wilson7d1c4802010-08-07 21:45:03 +01001326 drm_i915_private_t *dev_priv = dev->dev_private;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001327 pgoff_t page_offset;
1328 unsigned long pfn;
1329 int ret = 0;
Jesse Barnes0f973f22009-01-26 17:10:45 -08001330 bool write = !!(vmf->flags & FAULT_FLAG_WRITE);
Jesse Barnesde151cf2008-11-12 10:03:55 -08001331
1332 /* We don't use vmf->pgoff since that has the fake offset */
1333 page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >>
1334 PAGE_SHIFT;
1335
Chris Wilsond9bc7e92011-02-07 13:09:31 +00001336 ret = i915_mutex_lock_interruptible(dev);
1337 if (ret)
1338 goto out;
Chris Wilsona00b10c2010-09-24 21:15:47 +01001339
Chris Wilsondb53a302011-02-03 11:57:46 +00001340 trace_i915_gem_object_fault(obj, page_offset, true, write);
1341
Chris Wilsond9bc7e92011-02-07 13:09:31 +00001342 /* Now bind it into the GTT if needed */
Chris Wilson919926a2010-11-12 13:42:53 +00001343 if (!obj->map_and_fenceable) {
1344 ret = i915_gem_object_unbind(obj);
1345 if (ret)
1346 goto unlock;
Chris Wilsona00b10c2010-09-24 21:15:47 +01001347 }
Chris Wilson05394f32010-11-08 19:18:58 +00001348 if (!obj->gtt_space) {
Chris Wilson86a1ee22012-08-11 15:41:04 +01001349 ret = i915_gem_object_bind_to_gtt(obj, 0, true, false);
Chris Wilsonc7150892009-09-23 00:43:56 +01001350 if (ret)
1351 goto unlock;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001352
Eric Anholte92d03b2011-06-14 16:43:09 -07001353 ret = i915_gem_object_set_to_gtt_domain(obj, write);
1354 if (ret)
1355 goto unlock;
1356 }
Chris Wilson4a684a42010-10-28 14:44:08 +01001357
Daniel Vetter74898d72012-02-15 23:50:22 +01001358 if (!obj->has_global_gtt_mapping)
1359 i915_gem_gtt_bind_object(obj, obj->cache_level);
1360
Chris Wilson06d98132012-04-17 15:31:24 +01001361 ret = i915_gem_object_get_fence(obj);
Chris Wilsond9e86c02010-11-10 16:40:20 +00001362 if (ret)
1363 goto unlock;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001364
Chris Wilson05394f32010-11-08 19:18:58 +00001365 if (i915_gem_object_is_inactive(obj))
1366 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
Chris Wilson7d1c4802010-08-07 21:45:03 +01001367
Chris Wilson6299f992010-11-24 12:23:44 +00001368 obj->fault_mappable = true;
1369
Daniel Vetterdd2757f2012-06-07 15:55:57 +02001370 pfn = ((dev_priv->mm.gtt_base_addr + obj->gtt_offset) >> PAGE_SHIFT) +
Jesse Barnesde151cf2008-11-12 10:03:55 -08001371 page_offset;
1372
1373 /* Finally, remap it using the new GTT offset */
1374 ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
Chris Wilsonc7150892009-09-23 00:43:56 +01001375unlock:
Jesse Barnesde151cf2008-11-12 10:03:55 -08001376 mutex_unlock(&dev->struct_mutex);
Chris Wilsond9bc7e92011-02-07 13:09:31 +00001377out:
Jesse Barnesde151cf2008-11-12 10:03:55 -08001378 switch (ret) {
Chris Wilsond9bc7e92011-02-07 13:09:31 +00001379 case -EIO:
Daniel Vettera9340cc2012-07-04 22:18:42 +02001380 /* If this -EIO is due to a gpu hang, give the reset code a
1381 * chance to clean up the mess. Otherwise return the proper
1382 * SIGBUS. */
1383 if (!atomic_read(&dev_priv->mm.wedged))
1384 return VM_FAULT_SIGBUS;
Chris Wilson045e7692010-11-07 09:18:22 +00001385 case -EAGAIN:
Chris Wilsond9bc7e92011-02-07 13:09:31 +00001386 /* Give the error handler a chance to run and move the
1387 * objects off the GPU active list. Next time we service the
1388 * fault, we should be able to transition the page into the
1389 * GTT without touching the GPU (and so avoid further
1390 * EIO/EGAIN). If the GPU is wedged, then there is no issue
1391 * with coherency, just lost writes.
1392 */
Chris Wilson045e7692010-11-07 09:18:22 +00001393 set_need_resched();
Chris Wilsonc7150892009-09-23 00:43:56 +01001394 case 0:
1395 case -ERESTARTSYS:
Chris Wilsonbed636a2011-02-11 20:31:19 +00001396 case -EINTR:
Chris Wilsonc7150892009-09-23 00:43:56 +01001397 return VM_FAULT_NOPAGE;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001398 case -ENOMEM:
Jesse Barnesde151cf2008-11-12 10:03:55 -08001399 return VM_FAULT_OOM;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001400 default:
Chris Wilsonc7150892009-09-23 00:43:56 +01001401 return VM_FAULT_SIGBUS;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001402 }
1403}
1404
1405/**
Chris Wilson901782b2009-07-10 08:18:50 +01001406 * i915_gem_release_mmap - remove physical page mappings
1407 * @obj: obj in question
1408 *
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02001409 * Preserve the reservation of the mmapping with the DRM core code, but
Chris Wilson901782b2009-07-10 08:18:50 +01001410 * relinquish ownership of the pages back to the system.
1411 *
1412 * It is vital that we remove the page mapping if we have mapped a tiled
1413 * object through the GTT and then lose the fence register due to
1414 * resource pressure. Similarly if the object has been moved out of the
1415 * aperture, than pages mapped into userspace must be revoked. Removing the
1416 * mapping will then trigger a page fault on the next user access, allowing
1417 * fixup by i915_gem_fault().
1418 */
Eric Anholtd05ca302009-07-10 13:02:26 -07001419void
Chris Wilson05394f32010-11-08 19:18:58 +00001420i915_gem_release_mmap(struct drm_i915_gem_object *obj)
Chris Wilson901782b2009-07-10 08:18:50 +01001421{
Chris Wilson6299f992010-11-24 12:23:44 +00001422 if (!obj->fault_mappable)
1423 return;
Chris Wilson901782b2009-07-10 08:18:50 +01001424
Chris Wilsonf6e47882011-03-20 21:09:12 +00001425 if (obj->base.dev->dev_mapping)
1426 unmap_mapping_range(obj->base.dev->dev_mapping,
1427 (loff_t)obj->base.map_list.hash.key<<PAGE_SHIFT,
1428 obj->base.size, 1);
Daniel Vetterfb7d5162010-10-01 22:05:20 +02001429
Chris Wilson6299f992010-11-24 12:23:44 +00001430 obj->fault_mappable = false;
Chris Wilson901782b2009-07-10 08:18:50 +01001431}
1432
Chris Wilson92b88ae2010-11-09 11:47:32 +00001433static uint32_t
Chris Wilsone28f8712011-07-18 13:11:49 -07001434i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
Chris Wilson92b88ae2010-11-09 11:47:32 +00001435{
Chris Wilsone28f8712011-07-18 13:11:49 -07001436 uint32_t gtt_size;
Chris Wilson92b88ae2010-11-09 11:47:32 +00001437
1438 if (INTEL_INFO(dev)->gen >= 4 ||
Chris Wilsone28f8712011-07-18 13:11:49 -07001439 tiling_mode == I915_TILING_NONE)
1440 return size;
Chris Wilson92b88ae2010-11-09 11:47:32 +00001441
1442 /* Previous chips need a power-of-two fence region when tiling */
1443 if (INTEL_INFO(dev)->gen == 3)
Chris Wilsone28f8712011-07-18 13:11:49 -07001444 gtt_size = 1024*1024;
Chris Wilson92b88ae2010-11-09 11:47:32 +00001445 else
Chris Wilsone28f8712011-07-18 13:11:49 -07001446 gtt_size = 512*1024;
Chris Wilson92b88ae2010-11-09 11:47:32 +00001447
Chris Wilsone28f8712011-07-18 13:11:49 -07001448 while (gtt_size < size)
1449 gtt_size <<= 1;
Chris Wilson92b88ae2010-11-09 11:47:32 +00001450
Chris Wilsone28f8712011-07-18 13:11:49 -07001451 return gtt_size;
Chris Wilson92b88ae2010-11-09 11:47:32 +00001452}
1453
Jesse Barnesde151cf2008-11-12 10:03:55 -08001454/**
1455 * i915_gem_get_gtt_alignment - return required GTT alignment for an object
1456 * @obj: object to check
1457 *
1458 * Return the required GTT alignment for an object, taking into account
Daniel Vetter5e783302010-11-14 22:32:36 +01001459 * potential fence register mapping.
Jesse Barnesde151cf2008-11-12 10:03:55 -08001460 */
1461static uint32_t
Chris Wilsone28f8712011-07-18 13:11:49 -07001462i915_gem_get_gtt_alignment(struct drm_device *dev,
1463 uint32_t size,
1464 int tiling_mode)
Jesse Barnesde151cf2008-11-12 10:03:55 -08001465{
Jesse Barnesde151cf2008-11-12 10:03:55 -08001466 /*
1467 * Minimum alignment is 4k (GTT page size), but might be greater
1468 * if a fence register is needed for the object.
1469 */
Chris Wilsona00b10c2010-09-24 21:15:47 +01001470 if (INTEL_INFO(dev)->gen >= 4 ||
Chris Wilsone28f8712011-07-18 13:11:49 -07001471 tiling_mode == I915_TILING_NONE)
Jesse Barnesde151cf2008-11-12 10:03:55 -08001472 return 4096;
1473
1474 /*
1475 * Previous chips need to be aligned to the size of the smallest
1476 * fence register that can contain the object.
1477 */
Chris Wilsone28f8712011-07-18 13:11:49 -07001478 return i915_gem_get_gtt_size(dev, size, tiling_mode);
Chris Wilsona00b10c2010-09-24 21:15:47 +01001479}
1480
Daniel Vetter5e783302010-11-14 22:32:36 +01001481/**
1482 * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an
1483 * unfenced object
Chris Wilsone28f8712011-07-18 13:11:49 -07001484 * @dev: the device
1485 * @size: size of the object
1486 * @tiling_mode: tiling mode of the object
Daniel Vetter5e783302010-11-14 22:32:36 +01001487 *
1488 * Return the required GTT alignment for an object, only taking into account
1489 * unfenced tiled surface requirements.
1490 */
Chris Wilson467cffb2011-03-07 10:42:03 +00001491uint32_t
Chris Wilsone28f8712011-07-18 13:11:49 -07001492i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev,
1493 uint32_t size,
1494 int tiling_mode)
Daniel Vetter5e783302010-11-14 22:32:36 +01001495{
Daniel Vetter5e783302010-11-14 22:32:36 +01001496 /*
1497 * Minimum alignment is 4k (GTT page size) for sane hw.
1498 */
1499 if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) ||
Chris Wilsone28f8712011-07-18 13:11:49 -07001500 tiling_mode == I915_TILING_NONE)
Daniel Vetter5e783302010-11-14 22:32:36 +01001501 return 4096;
1502
Chris Wilsone28f8712011-07-18 13:11:49 -07001503 /* Previous hardware however needs to be aligned to a power-of-two
1504 * tile height. The simplest method for determining this is to reuse
1505 * the power-of-tile object size.
Daniel Vetter5e783302010-11-14 22:32:36 +01001506 */
Chris Wilsone28f8712011-07-18 13:11:49 -07001507 return i915_gem_get_gtt_size(dev, size, tiling_mode);
Daniel Vetter5e783302010-11-14 22:32:36 +01001508}
1509
Chris Wilsond8cb5082012-08-11 15:41:03 +01001510static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
1511{
1512 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
1513 int ret;
1514
1515 if (obj->base.map_list.map)
1516 return 0;
1517
1518 ret = drm_gem_create_mmap_offset(&obj->base);
1519 if (ret != -ENOSPC)
1520 return ret;
1521
1522 /* Badly fragmented mmap space? The only way we can recover
1523 * space is by destroying unwanted objects. We can't randomly release
1524 * mmap_offsets as userspace expects them to be persistent for the
1525 * lifetime of the objects. The closest we can is to release the
1526 * offsets on purgeable objects by truncating it and marking it purged,
1527 * which prevents userspace from ever using that object again.
1528 */
1529 i915_gem_purge(dev_priv, obj->base.size >> PAGE_SHIFT);
1530 ret = drm_gem_create_mmap_offset(&obj->base);
1531 if (ret != -ENOSPC)
1532 return ret;
1533
1534 i915_gem_shrink_all(dev_priv);
1535 return drm_gem_create_mmap_offset(&obj->base);
1536}
1537
1538static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
1539{
1540 if (!obj->base.map_list.map)
1541 return;
1542
1543 drm_gem_free_mmap_offset(&obj->base);
1544}
1545
Jesse Barnesde151cf2008-11-12 10:03:55 -08001546int
Dave Airlieff72145b2011-02-07 12:16:14 +10001547i915_gem_mmap_gtt(struct drm_file *file,
1548 struct drm_device *dev,
1549 uint32_t handle,
1550 uint64_t *offset)
Jesse Barnesde151cf2008-11-12 10:03:55 -08001551{
Chris Wilsonda761a62010-10-27 17:37:08 +01001552 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilson05394f32010-11-08 19:18:58 +00001553 struct drm_i915_gem_object *obj;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001554 int ret;
1555
Chris Wilson76c1dec2010-09-25 11:22:51 +01001556 ret = i915_mutex_lock_interruptible(dev);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001557 if (ret)
Chris Wilson76c1dec2010-09-25 11:22:51 +01001558 return ret;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001559
Dave Airlieff72145b2011-02-07 12:16:14 +10001560 obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle));
Chris Wilsonc8725222011-02-19 11:31:06 +00001561 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001562 ret = -ENOENT;
1563 goto unlock;
1564 }
Jesse Barnesde151cf2008-11-12 10:03:55 -08001565
Chris Wilson05394f32010-11-08 19:18:58 +00001566 if (obj->base.size > dev_priv->mm.gtt_mappable_end) {
Chris Wilsonda761a62010-10-27 17:37:08 +01001567 ret = -E2BIG;
Eric Anholtff56b0b2011-10-31 23:16:21 -07001568 goto out;
Chris Wilsonda761a62010-10-27 17:37:08 +01001569 }
1570
Chris Wilson05394f32010-11-08 19:18:58 +00001571 if (obj->madv != I915_MADV_WILLNEED) {
Chris Wilsonab182822009-09-22 18:46:17 +01001572 DRM_ERROR("Attempting to mmap a purgeable buffer\n");
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001573 ret = -EINVAL;
1574 goto out;
Chris Wilsonab182822009-09-22 18:46:17 +01001575 }
1576
Chris Wilsond8cb5082012-08-11 15:41:03 +01001577 ret = i915_gem_object_create_mmap_offset(obj);
1578 if (ret)
1579 goto out;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001580
Dave Airlieff72145b2011-02-07 12:16:14 +10001581 *offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001582
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001583out:
Chris Wilson05394f32010-11-08 19:18:58 +00001584 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001585unlock:
Jesse Barnesde151cf2008-11-12 10:03:55 -08001586 mutex_unlock(&dev->struct_mutex);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01001587 return ret;
Jesse Barnesde151cf2008-11-12 10:03:55 -08001588}
1589
Dave Airlieff72145b2011-02-07 12:16:14 +10001590/**
1591 * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
1592 * @dev: DRM device
1593 * @data: GTT mapping ioctl data
1594 * @file: GEM object info
1595 *
1596 * Simply returns the fake offset to userspace so it can mmap it.
1597 * The mmap call will end up in drm_gem_mmap(), which will set things
1598 * up so we can get faults in the handler above.
1599 *
1600 * The fault handler will take care of binding the object into the GTT
1601 * (since it may have been evicted to make room for something), allocating
1602 * a fence register, and mapping the appropriate aperture address into
1603 * userspace.
1604 */
1605int
1606i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
1607 struct drm_file *file)
1608{
1609 struct drm_i915_gem_mmap_gtt *args = data;
1610
Dave Airlieff72145b2011-02-07 12:16:14 +10001611 return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
1612}
1613
Daniel Vetter225067e2012-08-20 10:23:20 +02001614/* Immediately discard the backing storage */
1615static void
1616i915_gem_object_truncate(struct drm_i915_gem_object *obj)
Chris Wilsone5281cc2010-10-28 13:45:36 +01001617{
Chris Wilsone5281cc2010-10-28 13:45:36 +01001618 struct inode *inode;
Chris Wilsone5281cc2010-10-28 13:45:36 +01001619
Chris Wilson4d6294bf2012-08-11 15:41:05 +01001620 i915_gem_object_free_mmap_offset(obj);
Daniel Vetter1286ff72012-05-10 15:25:09 +02001621
Chris Wilson4d6294bf2012-08-11 15:41:05 +01001622 if (obj->base.filp == NULL)
1623 return;
1624
Daniel Vetter225067e2012-08-20 10:23:20 +02001625 /* Our goal here is to return as much of the memory as
1626 * is possible back to the system as we are called from OOM.
1627 * To do this we must instruct the shmfs to drop all of its
1628 * backing pages, *now*.
Chris Wilsone5281cc2010-10-28 13:45:36 +01001629 */
Chris Wilson05394f32010-11-08 19:18:58 +00001630 inode = obj->base.filp->f_path.dentry->d_inode;
Daniel Vetter225067e2012-08-20 10:23:20 +02001631 shmem_truncate_range(inode, 0, (loff_t)-1);
Hugh Dickins5949eac2011-06-27 16:18:18 -07001632
Daniel Vetter225067e2012-08-20 10:23:20 +02001633 obj->madv = __I915_MADV_PURGED;
Chris Wilsone5281cc2010-10-28 13:45:36 +01001634}
1635
Daniel Vetter225067e2012-08-20 10:23:20 +02001636static inline int
1637i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj)
1638{
1639 return obj->madv == I915_MADV_DONTNEED;
1640}
1641
Chris Wilson37e680a2012-06-07 15:38:42 +01001642static void
Chris Wilson05394f32010-11-08 19:18:58 +00001643i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
Eric Anholt673a3942008-07-30 12:06:12 -07001644{
Chris Wilson05394f32010-11-08 19:18:58 +00001645 int page_count = obj->base.size / PAGE_SIZE;
Chris Wilson6c085a72012-08-20 11:40:46 +02001646 int ret, i;
Eric Anholt673a3942008-07-30 12:06:12 -07001647
Chris Wilson05394f32010-11-08 19:18:58 +00001648 BUG_ON(obj->madv == __I915_MADV_PURGED);
Eric Anholt856fa192009-03-19 14:10:50 -07001649
Chris Wilson6c085a72012-08-20 11:40:46 +02001650 ret = i915_gem_object_set_to_cpu_domain(obj, true);
1651 if (ret) {
1652 /* In the event of a disaster, abandon all caches and
1653 * hope for the best.
1654 */
1655 WARN_ON(ret != -EIO);
1656 i915_gem_clflush_object(obj);
1657 obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
1658 }
1659
Daniel Vetter6dacfd22011-09-12 21:30:02 +02001660 if (i915_gem_object_needs_bit17_swizzle(obj))
Eric Anholt280b7132009-03-12 16:56:27 -07001661 i915_gem_object_save_bit_17_swizzle(obj);
1662
Chris Wilson05394f32010-11-08 19:18:58 +00001663 if (obj->madv == I915_MADV_DONTNEED)
1664 obj->dirty = 0;
Chris Wilson3ef94da2009-09-14 16:50:29 +01001665
1666 for (i = 0; i < page_count; i++) {
Chris Wilson05394f32010-11-08 19:18:58 +00001667 if (obj->dirty)
1668 set_page_dirty(obj->pages[i]);
Chris Wilson3ef94da2009-09-14 16:50:29 +01001669
Chris Wilson05394f32010-11-08 19:18:58 +00001670 if (obj->madv == I915_MADV_WILLNEED)
1671 mark_page_accessed(obj->pages[i]);
Chris Wilson3ef94da2009-09-14 16:50:29 +01001672
Chris Wilson05394f32010-11-08 19:18:58 +00001673 page_cache_release(obj->pages[i]);
Chris Wilson3ef94da2009-09-14 16:50:29 +01001674 }
Chris Wilson05394f32010-11-08 19:18:58 +00001675 obj->dirty = 0;
Eric Anholt673a3942008-07-30 12:06:12 -07001676
Chris Wilson05394f32010-11-08 19:18:58 +00001677 drm_free_large(obj->pages);
1678 obj->pages = NULL;
Chris Wilson37e680a2012-06-07 15:38:42 +01001679}
1680
1681static int
1682i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
1683{
1684 const struct drm_i915_gem_object_ops *ops = obj->ops;
1685
1686 if (obj->sg_table || obj->pages == NULL)
1687 return 0;
1688
1689 BUG_ON(obj->gtt_space);
1690
Chris Wilsona5570172012-09-04 21:02:54 +01001691 if (obj->pages_pin_count)
1692 return -EBUSY;
1693
Chris Wilson37e680a2012-06-07 15:38:42 +01001694 ops->put_pages(obj);
Chris Wilson6c085a72012-08-20 11:40:46 +02001695
1696 list_del(&obj->gtt_list);
Chris Wilson6c085a72012-08-20 11:40:46 +02001697 if (i915_gem_object_is_purgeable(obj))
1698 i915_gem_object_truncate(obj);
1699
1700 return 0;
1701}
1702
1703static long
1704i915_gem_purge(struct drm_i915_private *dev_priv, long target)
1705{
1706 struct drm_i915_gem_object *obj, *next;
1707 long count = 0;
1708
1709 list_for_each_entry_safe(obj, next,
1710 &dev_priv->mm.unbound_list,
1711 gtt_list) {
1712 if (i915_gem_object_is_purgeable(obj) &&
Chris Wilson37e680a2012-06-07 15:38:42 +01001713 i915_gem_object_put_pages(obj) == 0) {
Chris Wilson6c085a72012-08-20 11:40:46 +02001714 count += obj->base.size >> PAGE_SHIFT;
1715 if (count >= target)
1716 return count;
1717 }
1718 }
1719
1720 list_for_each_entry_safe(obj, next,
1721 &dev_priv->mm.inactive_list,
1722 mm_list) {
1723 if (i915_gem_object_is_purgeable(obj) &&
1724 i915_gem_object_unbind(obj) == 0 &&
Chris Wilson37e680a2012-06-07 15:38:42 +01001725 i915_gem_object_put_pages(obj) == 0) {
Chris Wilson6c085a72012-08-20 11:40:46 +02001726 count += obj->base.size >> PAGE_SHIFT;
1727 if (count >= target)
1728 return count;
1729 }
1730 }
1731
1732 return count;
1733}
1734
1735static void
1736i915_gem_shrink_all(struct drm_i915_private *dev_priv)
1737{
1738 struct drm_i915_gem_object *obj, *next;
1739
1740 i915_gem_evict_everything(dev_priv->dev);
1741
1742 list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, gtt_list)
Chris Wilson37e680a2012-06-07 15:38:42 +01001743 i915_gem_object_put_pages(obj);
Daniel Vetter225067e2012-08-20 10:23:20 +02001744}
1745
Chris Wilson37e680a2012-06-07 15:38:42 +01001746static int
Chris Wilson6c085a72012-08-20 11:40:46 +02001747i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
Eric Anholt673a3942008-07-30 12:06:12 -07001748{
Chris Wilson6c085a72012-08-20 11:40:46 +02001749 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
Eric Anholt673a3942008-07-30 12:06:12 -07001750 int page_count, i;
1751 struct address_space *mapping;
Eric Anholt673a3942008-07-30 12:06:12 -07001752 struct page *page;
Chris Wilson6c085a72012-08-20 11:40:46 +02001753 gfp_t gfp;
Eric Anholt673a3942008-07-30 12:06:12 -07001754
Chris Wilson6c085a72012-08-20 11:40:46 +02001755 /* Assert that the object is not currently in any GPU domain. As it
1756 * wasn't in the GTT, there shouldn't be any way it could have been in
1757 * a GPU cache
1758 */
1759 BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
1760 BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
1761
Eric Anholt673a3942008-07-30 12:06:12 -07001762 /* Get the list of pages out of our struct file. They'll be pinned
1763 * at this point until we release them.
1764 */
1765 page_count = obj->base.size / PAGE_SIZE;
Eric Anholt673a3942008-07-30 12:06:12 -07001766 obj->pages = drm_malloc_ab(page_count, sizeof(struct page *));
1767 if (obj->pages == NULL)
1768 return -ENOMEM;
1769
Chris Wilson6c085a72012-08-20 11:40:46 +02001770 /* Fail silently without starting the shrinker */
1771 mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
1772 gfp = mapping_gfp_mask(mapping);
Sedat Dilekd7c3b932012-08-27 14:02:37 +02001773 gfp |= __GFP_NORETRY | __GFP_NOWARN;
Chris Wilson6c085a72012-08-20 11:40:46 +02001774 gfp &= ~(__GFP_IO | __GFP_WAIT);
Eric Anholt673a3942008-07-30 12:06:12 -07001775 for (i = 0; i < page_count; i++) {
Chris Wilson6c085a72012-08-20 11:40:46 +02001776 page = shmem_read_mapping_page_gfp(mapping, i, gfp);
1777 if (IS_ERR(page)) {
1778 i915_gem_purge(dev_priv, page_count);
1779 page = shmem_read_mapping_page_gfp(mapping, i, gfp);
1780 }
1781 if (IS_ERR(page)) {
1782 /* We've tried hard to allocate the memory by reaping
1783 * our own buffer, now let the real VM do its job and
1784 * go down in flames if truly OOM.
1785 */
Sedat Dilekd7c3b932012-08-27 14:02:37 +02001786 gfp &= ~(__GFP_NORETRY | __GFP_NOWARN);
Chris Wilson6c085a72012-08-20 11:40:46 +02001787 gfp |= __GFP_IO | __GFP_WAIT;
1788
1789 i915_gem_shrink_all(dev_priv);
1790 page = shmem_read_mapping_page_gfp(mapping, i, gfp);
1791 if (IS_ERR(page))
1792 goto err_pages;
1793
Sedat Dilekd7c3b932012-08-27 14:02:37 +02001794 gfp |= __GFP_NORETRY | __GFP_NOWARN;
Chris Wilson6c085a72012-08-20 11:40:46 +02001795 gfp &= ~(__GFP_IO | __GFP_WAIT);
1796 }
Eric Anholt673a3942008-07-30 12:06:12 -07001797
1798 obj->pages[i] = page;
1799 }
1800
1801 if (i915_gem_object_needs_bit17_swizzle(obj))
1802 i915_gem_object_do_bit_17_swizzle(obj);
1803
1804 return 0;
1805
1806err_pages:
1807 while (i--)
1808 page_cache_release(obj->pages[i]);
1809
1810 drm_free_large(obj->pages);
1811 obj->pages = NULL;
1812 return PTR_ERR(page);
Eric Anholt673a3942008-07-30 12:06:12 -07001813}
1814
Chris Wilson37e680a2012-06-07 15:38:42 +01001815/* Ensure that the associated pages are gathered from the backing storage
1816 * and pinned into our object. i915_gem_object_get_pages() may be called
1817 * multiple times before they are released by a single call to
1818 * i915_gem_object_put_pages() - once the pages are no longer referenced
1819 * either as a result of memory pressure (reaping pages under the shrinker)
1820 * or as the object is itself released.
1821 */
1822int
1823i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
1824{
1825 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
1826 const struct drm_i915_gem_object_ops *ops = obj->ops;
1827 int ret;
1828
1829 if (obj->sg_table || obj->pages)
1830 return 0;
1831
Chris Wilsona5570172012-09-04 21:02:54 +01001832 BUG_ON(obj->pages_pin_count);
1833
Chris Wilson37e680a2012-06-07 15:38:42 +01001834 ret = ops->get_pages(obj);
1835 if (ret)
1836 return ret;
1837
1838 list_add_tail(&obj->gtt_list, &dev_priv->mm.unbound_list);
1839 return 0;
1840}
1841
Chris Wilson54cf91d2010-11-25 18:00:26 +00001842void
Chris Wilson05394f32010-11-08 19:18:58 +00001843i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
Chris Wilson1ec14ad2010-12-04 11:30:53 +00001844 struct intel_ring_buffer *ring,
1845 u32 seqno)
Eric Anholt673a3942008-07-30 12:06:12 -07001846{
Chris Wilson05394f32010-11-08 19:18:58 +00001847 struct drm_device *dev = obj->base.dev;
Chris Wilson69dc4982010-10-19 10:36:51 +01001848 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter617dbe22010-02-11 22:16:02 +01001849
Zou Nan hai852835f2010-05-21 09:08:56 +08001850 BUG_ON(ring == NULL);
Chris Wilson05394f32010-11-08 19:18:58 +00001851 obj->ring = ring;
Eric Anholt673a3942008-07-30 12:06:12 -07001852
1853 /* Add a reference if we're newly entering the active list. */
Chris Wilson05394f32010-11-08 19:18:58 +00001854 if (!obj->active) {
1855 drm_gem_object_reference(&obj->base);
1856 obj->active = 1;
Eric Anholt673a3942008-07-30 12:06:12 -07001857 }
Daniel Vettere35a41d2010-02-11 22:13:59 +01001858
Eric Anholt673a3942008-07-30 12:06:12 -07001859 /* Move from whatever list we were on to the tail of execution. */
Chris Wilson05394f32010-11-08 19:18:58 +00001860 list_move_tail(&obj->mm_list, &dev_priv->mm.active_list);
1861 list_move_tail(&obj->ring_list, &ring->active_list);
Chris Wilsoncaea7472010-11-12 13:53:37 +00001862
Chris Wilson0201f1e2012-07-20 12:41:01 +01001863 obj->last_read_seqno = seqno;
Chris Wilson7dd49062012-03-21 10:48:18 +00001864
Chris Wilsoncaea7472010-11-12 13:53:37 +00001865 if (obj->fenced_gpu_access) {
Chris Wilsoncaea7472010-11-12 13:53:37 +00001866 obj->last_fenced_seqno = seqno;
Chris Wilsoncaea7472010-11-12 13:53:37 +00001867
Chris Wilson7dd49062012-03-21 10:48:18 +00001868 /* Bump MRU to take account of the delayed flush */
1869 if (obj->fence_reg != I915_FENCE_REG_NONE) {
1870 struct drm_i915_fence_reg *reg;
1871
1872 reg = &dev_priv->fence_regs[obj->fence_reg];
1873 list_move_tail(&reg->lru_list,
1874 &dev_priv->mm.fence_list);
1875 }
Chris Wilsoncaea7472010-11-12 13:53:37 +00001876 }
1877}
1878
1879static void
Chris Wilsoncaea7472010-11-12 13:53:37 +00001880i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
1881{
1882 struct drm_device *dev = obj->base.dev;
1883 struct drm_i915_private *dev_priv = dev->dev_private;
1884
Chris Wilson65ce3022012-07-20 12:41:02 +01001885 BUG_ON(obj->base.write_domain & ~I915_GEM_GPU_DOMAINS);
Chris Wilsoncaea7472010-11-12 13:53:37 +00001886 BUG_ON(!obj->active);
Chris Wilson65ce3022012-07-20 12:41:02 +01001887
Chris Wilsonf047e392012-07-21 12:31:41 +01001888 if (obj->pin_count) /* are we a framebuffer? */
1889 intel_mark_fb_idle(obj);
1890
1891 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
1892
Chris Wilson65ce3022012-07-20 12:41:02 +01001893 list_del_init(&obj->ring_list);
Chris Wilsoncaea7472010-11-12 13:53:37 +00001894 obj->ring = NULL;
1895
Chris Wilson65ce3022012-07-20 12:41:02 +01001896 obj->last_read_seqno = 0;
1897 obj->last_write_seqno = 0;
1898 obj->base.write_domain = 0;
1899
1900 obj->last_fenced_seqno = 0;
Chris Wilsoncaea7472010-11-12 13:53:37 +00001901 obj->fenced_gpu_access = false;
Chris Wilsoncaea7472010-11-12 13:53:37 +00001902
1903 obj->active = 0;
1904 drm_gem_object_unreference(&obj->base);
1905
1906 WARN_ON(i915_verify_lists(dev));
Eric Anholtce44b0e2008-11-06 16:00:31 -08001907}
Eric Anholt673a3942008-07-30 12:06:12 -07001908
Daniel Vetter53d227f2012-01-25 16:32:49 +01001909static u32
1910i915_gem_get_seqno(struct drm_device *dev)
1911{
1912 drm_i915_private_t *dev_priv = dev->dev_private;
1913 u32 seqno = dev_priv->next_seqno;
1914
1915 /* reserve 0 for non-seqno */
1916 if (++dev_priv->next_seqno == 0)
1917 dev_priv->next_seqno = 1;
1918
1919 return seqno;
1920}
1921
1922u32
1923i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
1924{
1925 if (ring->outstanding_lazy_request == 0)
1926 ring->outstanding_lazy_request = i915_gem_get_seqno(ring->dev);
1927
1928 return ring->outstanding_lazy_request;
1929}
1930
Chris Wilson3cce4692010-10-27 16:11:02 +01001931int
Chris Wilsondb53a302011-02-03 11:57:46 +00001932i915_add_request(struct intel_ring_buffer *ring,
Chris Wilsonf787a5f2010-09-24 16:02:42 +01001933 struct drm_file *file,
Chris Wilsondb53a302011-02-03 11:57:46 +00001934 struct drm_i915_gem_request *request)
Eric Anholt673a3942008-07-30 12:06:12 -07001935{
Chris Wilsondb53a302011-02-03 11:57:46 +00001936 drm_i915_private_t *dev_priv = ring->dev->dev_private;
Eric Anholt673a3942008-07-30 12:06:12 -07001937 uint32_t seqno;
Chris Wilsona71d8d92012-02-15 11:25:36 +00001938 u32 request_ring_position;
Eric Anholt673a3942008-07-30 12:06:12 -07001939 int was_empty;
Chris Wilson3cce4692010-10-27 16:11:02 +01001940 int ret;
1941
Daniel Vettercc889e02012-06-13 20:45:19 +02001942 /*
1943 * Emit any outstanding flushes - execbuf can fail to emit the flush
1944 * after having emitted the batchbuffer command. Hence we need to fix
1945 * things up similar to emitting the lazy request. The difference here
1946 * is that the flush _must_ happen before the next request, no matter
1947 * what.
1948 */
Chris Wilsona7b97612012-07-20 12:41:08 +01001949 ret = intel_ring_flush_all_caches(ring);
1950 if (ret)
1951 return ret;
Daniel Vettercc889e02012-06-13 20:45:19 +02001952
Chris Wilson3bb73ab2012-07-20 12:40:59 +01001953 if (request == NULL) {
1954 request = kmalloc(sizeof(*request), GFP_KERNEL);
1955 if (request == NULL)
1956 return -ENOMEM;
1957 }
1958
Daniel Vetter53d227f2012-01-25 16:32:49 +01001959 seqno = i915_gem_next_request_seqno(ring);
Eric Anholt673a3942008-07-30 12:06:12 -07001960
Chris Wilsona71d8d92012-02-15 11:25:36 +00001961 /* Record the position of the start of the request so that
1962 * should we detect the updated seqno part-way through the
1963 * GPU processing the request, we never over-estimate the
1964 * position of the head.
1965 */
1966 request_ring_position = intel_ring_get_tail(ring);
1967
Chris Wilson3cce4692010-10-27 16:11:02 +01001968 ret = ring->add_request(ring, &seqno);
Chris Wilson3bb73ab2012-07-20 12:40:59 +01001969 if (ret) {
1970 kfree(request);
1971 return ret;
1972 }
Eric Anholt673a3942008-07-30 12:06:12 -07001973
Chris Wilsondb53a302011-02-03 11:57:46 +00001974 trace_i915_gem_request_add(ring, seqno);
Eric Anholt673a3942008-07-30 12:06:12 -07001975
1976 request->seqno = seqno;
Zou Nan hai852835f2010-05-21 09:08:56 +08001977 request->ring = ring;
Chris Wilsona71d8d92012-02-15 11:25:36 +00001978 request->tail = request_ring_position;
Eric Anholt673a3942008-07-30 12:06:12 -07001979 request->emitted_jiffies = jiffies;
Zou Nan hai852835f2010-05-21 09:08:56 +08001980 was_empty = list_empty(&ring->request_list);
1981 list_add_tail(&request->list, &ring->request_list);
Chris Wilson3bb73ab2012-07-20 12:40:59 +01001982 request->file_priv = NULL;
Zou Nan hai852835f2010-05-21 09:08:56 +08001983
Chris Wilsondb53a302011-02-03 11:57:46 +00001984 if (file) {
1985 struct drm_i915_file_private *file_priv = file->driver_priv;
1986
Chris Wilson1c255952010-09-26 11:03:27 +01001987 spin_lock(&file_priv->mm.lock);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01001988 request->file_priv = file_priv;
Eric Anholtb9624422009-06-03 07:27:35 +00001989 list_add_tail(&request->client_list,
Chris Wilsonf787a5f2010-09-24 16:02:42 +01001990 &file_priv->mm.request_list);
Chris Wilson1c255952010-09-26 11:03:27 +01001991 spin_unlock(&file_priv->mm.lock);
Eric Anholtb9624422009-06-03 07:27:35 +00001992 }
Eric Anholt673a3942008-07-30 12:06:12 -07001993
Daniel Vetter5391d0c2012-01-25 14:03:57 +01001994 ring->outstanding_lazy_request = 0;
Chris Wilsondb53a302011-02-03 11:57:46 +00001995
Ben Gamarif65d9422009-09-14 17:48:44 -04001996 if (!dev_priv->mm.suspended) {
Ben Widawsky3e0dc6b2011-06-29 10:26:42 -07001997 if (i915_enable_hangcheck) {
1998 mod_timer(&dev_priv->hangcheck_timer,
1999 jiffies +
2000 msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
2001 }
Chris Wilsonf047e392012-07-21 12:31:41 +01002002 if (was_empty) {
Chris Wilsonb3b079d2010-09-13 23:44:34 +01002003 queue_delayed_work(dev_priv->wq,
2004 &dev_priv->mm.retire_work, HZ);
Chris Wilsonf047e392012-07-21 12:31:41 +01002005 intel_mark_busy(dev_priv->dev);
2006 }
Ben Gamarif65d9422009-09-14 17:48:44 -04002007 }
Daniel Vettercc889e02012-06-13 20:45:19 +02002008
Chris Wilson3cce4692010-10-27 16:11:02 +01002009 return 0;
Eric Anholt673a3942008-07-30 12:06:12 -07002010}
2011
Chris Wilsonf787a5f2010-09-24 16:02:42 +01002012static inline void
2013i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
Eric Anholt673a3942008-07-30 12:06:12 -07002014{
Chris Wilson1c255952010-09-26 11:03:27 +01002015 struct drm_i915_file_private *file_priv = request->file_priv;
Eric Anholt673a3942008-07-30 12:06:12 -07002016
Chris Wilson1c255952010-09-26 11:03:27 +01002017 if (!file_priv)
2018 return;
Chris Wilson1c5d22f2009-08-25 11:15:50 +01002019
Chris Wilson1c255952010-09-26 11:03:27 +01002020 spin_lock(&file_priv->mm.lock);
Herton Ronaldo Krzesinski09bfa512011-03-17 13:45:12 +00002021 if (request->file_priv) {
2022 list_del(&request->client_list);
2023 request->file_priv = NULL;
2024 }
Chris Wilson1c255952010-09-26 11:03:27 +01002025 spin_unlock(&file_priv->mm.lock);
Eric Anholt673a3942008-07-30 12:06:12 -07002026}
2027
Chris Wilsondfaae392010-09-22 10:31:52 +01002028static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
2029 struct intel_ring_buffer *ring)
Chris Wilson9375e442010-09-19 12:21:28 +01002030{
Chris Wilsondfaae392010-09-22 10:31:52 +01002031 while (!list_empty(&ring->request_list)) {
2032 struct drm_i915_gem_request *request;
Chris Wilson9375e442010-09-19 12:21:28 +01002033
Chris Wilsondfaae392010-09-22 10:31:52 +01002034 request = list_first_entry(&ring->request_list,
2035 struct drm_i915_gem_request,
2036 list);
2037
2038 list_del(&request->list);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01002039 i915_gem_request_remove_from_client(request);
Chris Wilsondfaae392010-09-22 10:31:52 +01002040 kfree(request);
2041 }
2042
2043 while (!list_empty(&ring->active_list)) {
Chris Wilson05394f32010-11-08 19:18:58 +00002044 struct drm_i915_gem_object *obj;
Eric Anholt673a3942008-07-30 12:06:12 -07002045
Chris Wilson05394f32010-11-08 19:18:58 +00002046 obj = list_first_entry(&ring->active_list,
2047 struct drm_i915_gem_object,
2048 ring_list);
Eric Anholt673a3942008-07-30 12:06:12 -07002049
Chris Wilson05394f32010-11-08 19:18:58 +00002050 i915_gem_object_move_to_inactive(obj);
Eric Anholt673a3942008-07-30 12:06:12 -07002051 }
Eric Anholt673a3942008-07-30 12:06:12 -07002052}
2053
Chris Wilson312817a2010-11-22 11:50:11 +00002054static void i915_gem_reset_fences(struct drm_device *dev)
2055{
2056 struct drm_i915_private *dev_priv = dev->dev_private;
2057 int i;
2058
Daniel Vetter4b9de732011-10-09 21:52:02 +02002059 for (i = 0; i < dev_priv->num_fence_regs; i++) {
Chris Wilson312817a2010-11-22 11:50:11 +00002060 struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
Chris Wilson7d2cb392010-11-27 17:38:29 +00002061
Chris Wilsonada726c2012-04-17 15:31:32 +01002062 i915_gem_write_fence(dev, i, NULL);
Chris Wilson7d2cb392010-11-27 17:38:29 +00002063
Chris Wilsonada726c2012-04-17 15:31:32 +01002064 if (reg->obj)
2065 i915_gem_object_fence_lost(reg->obj);
Chris Wilson7d2cb392010-11-27 17:38:29 +00002066
Chris Wilsonada726c2012-04-17 15:31:32 +01002067 reg->pin_count = 0;
2068 reg->obj = NULL;
2069 INIT_LIST_HEAD(&reg->lru_list);
Chris Wilson312817a2010-11-22 11:50:11 +00002070 }
Chris Wilsonada726c2012-04-17 15:31:32 +01002071
2072 INIT_LIST_HEAD(&dev_priv->mm.fence_list);
Chris Wilson312817a2010-11-22 11:50:11 +00002073}
2074
Chris Wilson069efc12010-09-30 16:53:18 +01002075void i915_gem_reset(struct drm_device *dev)
Eric Anholt673a3942008-07-30 12:06:12 -07002076{
Chris Wilsondfaae392010-09-22 10:31:52 +01002077 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilson05394f32010-11-08 19:18:58 +00002078 struct drm_i915_gem_object *obj;
Chris Wilsonb4519512012-05-11 14:29:30 +01002079 struct intel_ring_buffer *ring;
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002080 int i;
Eric Anholt673a3942008-07-30 12:06:12 -07002081
Chris Wilsonb4519512012-05-11 14:29:30 +01002082 for_each_ring(ring, dev_priv, i)
2083 i915_gem_reset_ring_lists(dev_priv, ring);
Chris Wilsondfaae392010-09-22 10:31:52 +01002084
Chris Wilsondfaae392010-09-22 10:31:52 +01002085 /* Move everything out of the GPU domains to ensure we do any
2086 * necessary invalidation upon reuse.
2087 */
Chris Wilson05394f32010-11-08 19:18:58 +00002088 list_for_each_entry(obj,
Chris Wilson77f01232010-09-19 12:31:36 +01002089 &dev_priv->mm.inactive_list,
Chris Wilson69dc4982010-10-19 10:36:51 +01002090 mm_list)
Chris Wilson77f01232010-09-19 12:31:36 +01002091 {
Chris Wilson05394f32010-11-08 19:18:58 +00002092 obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS;
Chris Wilson77f01232010-09-19 12:31:36 +01002093 }
Chris Wilson069efc12010-09-30 16:53:18 +01002094
2095 /* The fence registers are invalidated so clear them out */
Chris Wilson312817a2010-11-22 11:50:11 +00002096 i915_gem_reset_fences(dev);
Eric Anholt673a3942008-07-30 12:06:12 -07002097}
2098
2099/**
2100 * This function clears the request list as sequence numbers are passed.
2101 */
Chris Wilsona71d8d92012-02-15 11:25:36 +00002102void
Chris Wilsondb53a302011-02-03 11:57:46 +00002103i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
Eric Anholt673a3942008-07-30 12:06:12 -07002104{
Eric Anholt673a3942008-07-30 12:06:12 -07002105 uint32_t seqno;
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002106 int i;
Eric Anholt673a3942008-07-30 12:06:12 -07002107
Chris Wilsondb53a302011-02-03 11:57:46 +00002108 if (list_empty(&ring->request_list))
Karsten Wiese6c0594a2009-02-23 15:07:57 +01002109 return;
2110
Chris Wilsondb53a302011-02-03 11:57:46 +00002111 WARN_ON(i915_verify_lists(ring->dev));
Eric Anholt673a3942008-07-30 12:06:12 -07002112
Chris Wilsonb2eadbc2012-08-09 10:58:30 +01002113 seqno = ring->get_seqno(ring, true);
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002114
Chris Wilson076e2c02011-01-21 10:07:18 +00002115 for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002116 if (seqno >= ring->sync_seqno[i])
2117 ring->sync_seqno[i] = 0;
2118
Zou Nan hai852835f2010-05-21 09:08:56 +08002119 while (!list_empty(&ring->request_list)) {
Eric Anholt673a3942008-07-30 12:06:12 -07002120 struct drm_i915_gem_request *request;
Eric Anholt673a3942008-07-30 12:06:12 -07002121
Zou Nan hai852835f2010-05-21 09:08:56 +08002122 request = list_first_entry(&ring->request_list,
Eric Anholt673a3942008-07-30 12:06:12 -07002123 struct drm_i915_gem_request,
2124 list);
Eric Anholt673a3942008-07-30 12:06:12 -07002125
Chris Wilsondfaae392010-09-22 10:31:52 +01002126 if (!i915_seqno_passed(seqno, request->seqno))
Eric Anholt673a3942008-07-30 12:06:12 -07002127 break;
Chris Wilsonb84d5f02010-09-18 01:38:04 +01002128
Chris Wilsondb53a302011-02-03 11:57:46 +00002129 trace_i915_gem_request_retire(ring, request->seqno);
Chris Wilsona71d8d92012-02-15 11:25:36 +00002130 /* We know the GPU must have read the request to have
2131 * sent us the seqno + interrupt, so use the position
2132 * of tail of the request to update the last known position
2133 * of the GPU head.
2134 */
2135 ring->last_retired_head = request->tail;
Chris Wilsonb84d5f02010-09-18 01:38:04 +01002136
2137 list_del(&request->list);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01002138 i915_gem_request_remove_from_client(request);
Chris Wilsonb84d5f02010-09-18 01:38:04 +01002139 kfree(request);
2140 }
2141
2142 /* Move any buffers on the active list that are no longer referenced
2143 * by the ringbuffer to the flushing/inactive lists as appropriate.
2144 */
2145 while (!list_empty(&ring->active_list)) {
Chris Wilson05394f32010-11-08 19:18:58 +00002146 struct drm_i915_gem_object *obj;
Chris Wilsonb84d5f02010-09-18 01:38:04 +01002147
Akshay Joshi0206e352011-08-16 15:34:10 -04002148 obj = list_first_entry(&ring->active_list,
Chris Wilson05394f32010-11-08 19:18:58 +00002149 struct drm_i915_gem_object,
2150 ring_list);
Chris Wilsonb84d5f02010-09-18 01:38:04 +01002151
Chris Wilson0201f1e2012-07-20 12:41:01 +01002152 if (!i915_seqno_passed(seqno, obj->last_read_seqno))
Chris Wilsonb84d5f02010-09-18 01:38:04 +01002153 break;
2154
Chris Wilson65ce3022012-07-20 12:41:02 +01002155 i915_gem_object_move_to_inactive(obj);
Eric Anholt673a3942008-07-30 12:06:12 -07002156 }
Chris Wilson9d34e5d2009-09-24 05:26:06 +01002157
Chris Wilsondb53a302011-02-03 11:57:46 +00002158 if (unlikely(ring->trace_irq_seqno &&
2159 i915_seqno_passed(seqno, ring->trace_irq_seqno))) {
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002160 ring->irq_put(ring);
Chris Wilsondb53a302011-02-03 11:57:46 +00002161 ring->trace_irq_seqno = 0;
Chris Wilson9d34e5d2009-09-24 05:26:06 +01002162 }
Chris Wilson23bc5982010-09-29 16:10:57 +01002163
Chris Wilsondb53a302011-02-03 11:57:46 +00002164 WARN_ON(i915_verify_lists(ring->dev));
Eric Anholt673a3942008-07-30 12:06:12 -07002165}
2166
2167void
Chris Wilsonb09a1fe2010-07-23 23:18:49 +01002168i915_gem_retire_requests(struct drm_device *dev)
2169{
2170 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilsonb4519512012-05-11 14:29:30 +01002171 struct intel_ring_buffer *ring;
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002172 int i;
Chris Wilsonb09a1fe2010-07-23 23:18:49 +01002173
Chris Wilsonb4519512012-05-11 14:29:30 +01002174 for_each_ring(ring, dev_priv, i)
2175 i915_gem_retire_requests_ring(ring);
Chris Wilsonb09a1fe2010-07-23 23:18:49 +01002176}
2177
Daniel Vetter75ef9da2010-08-21 00:25:16 +02002178static void
Eric Anholt673a3942008-07-30 12:06:12 -07002179i915_gem_retire_work_handler(struct work_struct *work)
2180{
2181 drm_i915_private_t *dev_priv;
2182 struct drm_device *dev;
Chris Wilsonb4519512012-05-11 14:29:30 +01002183 struct intel_ring_buffer *ring;
Chris Wilson0a587052011-01-09 21:05:44 +00002184 bool idle;
2185 int i;
Eric Anholt673a3942008-07-30 12:06:12 -07002186
2187 dev_priv = container_of(work, drm_i915_private_t,
2188 mm.retire_work.work);
2189 dev = dev_priv->dev;
2190
Chris Wilson891b48c2010-09-29 12:26:37 +01002191 /* Come back later if the device is busy... */
2192 if (!mutex_trylock(&dev->struct_mutex)) {
2193 queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
2194 return;
2195 }
2196
Chris Wilsonb09a1fe2010-07-23 23:18:49 +01002197 i915_gem_retire_requests(dev);
Zou Nan haid1b851f2010-05-21 09:08:57 +08002198
Chris Wilson0a587052011-01-09 21:05:44 +00002199 /* Send a periodic flush down the ring so we don't hold onto GEM
2200 * objects indefinitely.
2201 */
2202 idle = true;
Chris Wilsonb4519512012-05-11 14:29:30 +01002203 for_each_ring(ring, dev_priv, i) {
Chris Wilson3bb73ab2012-07-20 12:40:59 +01002204 if (ring->gpu_caches_dirty)
2205 i915_add_request(ring, NULL, NULL);
Chris Wilson0a587052011-01-09 21:05:44 +00002206
2207 idle &= list_empty(&ring->request_list);
2208 }
2209
2210 if (!dev_priv->mm.suspended && !idle)
Eric Anholt9c9fe1f2009-08-03 16:09:16 -07002211 queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
Chris Wilsonf047e392012-07-21 12:31:41 +01002212 if (idle)
2213 intel_mark_idle(dev);
Chris Wilson0a587052011-01-09 21:05:44 +00002214
Eric Anholt673a3942008-07-30 12:06:12 -07002215 mutex_unlock(&dev->struct_mutex);
2216}
2217
Ben Widawsky5816d642012-04-11 11:18:19 -07002218/**
Daniel Vetter30dfebf2012-06-01 15:21:23 +02002219 * Ensures that an object will eventually get non-busy by flushing any required
2220 * write domains, emitting any outstanding lazy request and retiring and
2221 * completed requests.
2222 */
2223static int
2224i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
2225{
2226 int ret;
2227
2228 if (obj->active) {
Chris Wilson0201f1e2012-07-20 12:41:01 +01002229 ret = i915_gem_check_olr(obj->ring, obj->last_read_seqno);
Daniel Vetter30dfebf2012-06-01 15:21:23 +02002230 if (ret)
2231 return ret;
Chris Wilson0201f1e2012-07-20 12:41:01 +01002232
Daniel Vetter30dfebf2012-06-01 15:21:23 +02002233 i915_gem_retire_requests_ring(obj->ring);
2234 }
2235
2236 return 0;
2237}
2238
2239/**
Ben Widawsky23ba4fd2012-05-24 15:03:10 -07002240 * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT
2241 * @DRM_IOCTL_ARGS: standard ioctl arguments
2242 *
2243 * Returns 0 if successful, else an error is returned with the remaining time in
2244 * the timeout parameter.
2245 * -ETIME: object is still busy after timeout
2246 * -ERESTARTSYS: signal interrupted the wait
2247 * -ENONENT: object doesn't exist
2248 * Also possible, but rare:
2249 * -EAGAIN: GPU wedged
2250 * -ENOMEM: damn
2251 * -ENODEV: Internal IRQ fail
2252 * -E?: The add request failed
2253 *
2254 * The wait ioctl with a timeout of 0 reimplements the busy ioctl. With any
2255 * non-zero timeout parameter the wait ioctl will wait for the given number of
2256 * nanoseconds on an object becoming unbusy. Since the wait itself does so
2257 * without holding struct_mutex the object may become re-busied before this
2258 * function completes. A similar but shorter * race condition exists in the busy
2259 * ioctl
2260 */
2261int
2262i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
2263{
2264 struct drm_i915_gem_wait *args = data;
2265 struct drm_i915_gem_object *obj;
2266 struct intel_ring_buffer *ring = NULL;
Ben Widawskyeac1f142012-06-05 15:24:24 -07002267 struct timespec timeout_stack, *timeout = NULL;
Ben Widawsky23ba4fd2012-05-24 15:03:10 -07002268 u32 seqno = 0;
2269 int ret = 0;
2270
Ben Widawskyeac1f142012-06-05 15:24:24 -07002271 if (args->timeout_ns >= 0) {
2272 timeout_stack = ns_to_timespec(args->timeout_ns);
2273 timeout = &timeout_stack;
2274 }
Ben Widawsky23ba4fd2012-05-24 15:03:10 -07002275
2276 ret = i915_mutex_lock_interruptible(dev);
2277 if (ret)
2278 return ret;
2279
2280 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->bo_handle));
2281 if (&obj->base == NULL) {
2282 mutex_unlock(&dev->struct_mutex);
2283 return -ENOENT;
2284 }
2285
Daniel Vetter30dfebf2012-06-01 15:21:23 +02002286 /* Need to make sure the object gets inactive eventually. */
2287 ret = i915_gem_object_flush_active(obj);
Ben Widawsky23ba4fd2012-05-24 15:03:10 -07002288 if (ret)
2289 goto out;
2290
2291 if (obj->active) {
Chris Wilson0201f1e2012-07-20 12:41:01 +01002292 seqno = obj->last_read_seqno;
Ben Widawsky23ba4fd2012-05-24 15:03:10 -07002293 ring = obj->ring;
2294 }
2295
2296 if (seqno == 0)
2297 goto out;
2298
Ben Widawsky23ba4fd2012-05-24 15:03:10 -07002299 /* Do this after OLR check to make sure we make forward progress polling
2300 * on this IOCTL with a 0 timeout (like busy ioctl)
2301 */
2302 if (!args->timeout_ns) {
2303 ret = -ETIME;
2304 goto out;
2305 }
2306
2307 drm_gem_object_unreference(&obj->base);
2308 mutex_unlock(&dev->struct_mutex);
2309
Ben Widawskyeac1f142012-06-05 15:24:24 -07002310 ret = __wait_seqno(ring, seqno, true, timeout);
2311 if (timeout) {
2312 WARN_ON(!timespec_valid(timeout));
2313 args->timeout_ns = timespec_to_ns(timeout);
2314 }
Ben Widawsky23ba4fd2012-05-24 15:03:10 -07002315 return ret;
2316
2317out:
2318 drm_gem_object_unreference(&obj->base);
2319 mutex_unlock(&dev->struct_mutex);
2320 return ret;
2321}
2322
2323/**
Ben Widawsky5816d642012-04-11 11:18:19 -07002324 * i915_gem_object_sync - sync an object to a ring.
2325 *
2326 * @obj: object which may be in use on another ring.
2327 * @to: ring we wish to use the object on. May be NULL.
2328 *
2329 * This code is meant to abstract object synchronization with the GPU.
2330 * Calling with NULL implies synchronizing the object with the CPU
2331 * rather than a particular GPU ring.
2332 *
2333 * Returns 0 if successful, else propagates up the lower layer error.
2334 */
Ben Widawsky2911a352012-04-05 14:47:36 -07002335int
2336i915_gem_object_sync(struct drm_i915_gem_object *obj,
2337 struct intel_ring_buffer *to)
2338{
2339 struct intel_ring_buffer *from = obj->ring;
2340 u32 seqno;
2341 int ret, idx;
2342
2343 if (from == NULL || to == from)
2344 return 0;
2345
Ben Widawsky5816d642012-04-11 11:18:19 -07002346 if (to == NULL || !i915_semaphore_is_enabled(obj->base.dev))
Chris Wilson0201f1e2012-07-20 12:41:01 +01002347 return i915_gem_object_wait_rendering(obj, false);
Ben Widawsky2911a352012-04-05 14:47:36 -07002348
2349 idx = intel_ring_sync_index(from, to);
2350
Chris Wilson0201f1e2012-07-20 12:41:01 +01002351 seqno = obj->last_read_seqno;
Ben Widawsky2911a352012-04-05 14:47:36 -07002352 if (seqno <= from->sync_seqno[idx])
2353 return 0;
2354
Ben Widawskyb4aca012012-04-25 20:50:12 -07002355 ret = i915_gem_check_olr(obj->ring, seqno);
2356 if (ret)
2357 return ret;
Ben Widawsky2911a352012-04-05 14:47:36 -07002358
Ben Widawsky1500f7e2012-04-11 11:18:21 -07002359 ret = to->sync_to(to, from, seqno);
Ben Widawskye3a5a222012-04-11 11:18:20 -07002360 if (!ret)
2361 from->sync_seqno[idx] = seqno;
Ben Widawsky2911a352012-04-05 14:47:36 -07002362
Ben Widawskye3a5a222012-04-11 11:18:20 -07002363 return ret;
Ben Widawsky2911a352012-04-05 14:47:36 -07002364}
2365
Chris Wilsonb5ffc9b2011-04-13 22:06:03 +01002366static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj)
2367{
2368 u32 old_write_domain, old_read_domains;
2369
Chris Wilsonb5ffc9b2011-04-13 22:06:03 +01002370 /* Act a barrier for all accesses through the GTT */
2371 mb();
2372
2373 /* Force a pagefault for domain tracking on next user access */
2374 i915_gem_release_mmap(obj);
2375
Keith Packardb97c3d92011-06-24 21:02:59 -07002376 if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0)
2377 return;
2378
Chris Wilsonb5ffc9b2011-04-13 22:06:03 +01002379 old_read_domains = obj->base.read_domains;
2380 old_write_domain = obj->base.write_domain;
2381
2382 obj->base.read_domains &= ~I915_GEM_DOMAIN_GTT;
2383 obj->base.write_domain &= ~I915_GEM_DOMAIN_GTT;
2384
2385 trace_i915_gem_object_change_domain(obj,
2386 old_read_domains,
2387 old_write_domain);
2388}
2389
Eric Anholt673a3942008-07-30 12:06:12 -07002390/**
2391 * Unbinds an object from the GTT aperture.
2392 */
Jesse Barnes0f973f22009-01-26 17:10:45 -08002393int
Chris Wilson05394f32010-11-08 19:18:58 +00002394i915_gem_object_unbind(struct drm_i915_gem_object *obj)
Eric Anholt673a3942008-07-30 12:06:12 -07002395{
Daniel Vetter7bddb012012-02-09 17:15:47 +01002396 drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
Eric Anholt673a3942008-07-30 12:06:12 -07002397 int ret = 0;
2398
Chris Wilson05394f32010-11-08 19:18:58 +00002399 if (obj->gtt_space == NULL)
Eric Anholt673a3942008-07-30 12:06:12 -07002400 return 0;
2401
Chris Wilson31d8d652012-05-24 19:11:20 +01002402 if (obj->pin_count)
2403 return -EBUSY;
Eric Anholt673a3942008-07-30 12:06:12 -07002404
Chris Wilsonc4670ad2012-08-20 10:23:27 +01002405 BUG_ON(obj->pages == NULL);
2406
Chris Wilsona8198ee2011-04-13 22:04:09 +01002407 ret = i915_gem_object_finish_gpu(obj);
Chris Wilson1488fc02012-04-24 15:47:31 +01002408 if (ret)
Eric Anholt673a3942008-07-30 12:06:12 -07002409 return ret;
Chris Wilson8dc17752010-07-23 23:18:51 +01002410 /* Continue on if we fail due to EIO, the GPU is hung so we
2411 * should be safe and we need to cleanup or else we might
2412 * cause memory corruption through use-after-free.
2413 */
Chris Wilsona8198ee2011-04-13 22:04:09 +01002414
Chris Wilsonb5ffc9b2011-04-13 22:06:03 +01002415 i915_gem_object_finish_gtt(obj);
Chris Wilsona8198ee2011-04-13 22:04:09 +01002416
Daniel Vetter96b47b62009-12-15 17:50:00 +01002417 /* release the fence reg _after_ flushing */
Chris Wilsond9e86c02010-11-10 16:40:20 +00002418 ret = i915_gem_object_put_fence(obj);
Chris Wilson1488fc02012-04-24 15:47:31 +01002419 if (ret)
Chris Wilsond9e86c02010-11-10 16:40:20 +00002420 return ret;
Daniel Vetter96b47b62009-12-15 17:50:00 +01002421
Chris Wilsondb53a302011-02-03 11:57:46 +00002422 trace_i915_gem_object_unbind(obj);
2423
Daniel Vetter74898d72012-02-15 23:50:22 +01002424 if (obj->has_global_gtt_mapping)
2425 i915_gem_gtt_unbind_object(obj);
Daniel Vetter7bddb012012-02-09 17:15:47 +01002426 if (obj->has_aliasing_ppgtt_mapping) {
2427 i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj);
2428 obj->has_aliasing_ppgtt_mapping = 0;
2429 }
Daniel Vetter74163902012-02-15 23:50:21 +01002430 i915_gem_gtt_finish_object(obj);
Daniel Vetter7bddb012012-02-09 17:15:47 +01002431
Chris Wilson6c085a72012-08-20 11:40:46 +02002432 list_del(&obj->mm_list);
2433 list_move_tail(&obj->gtt_list, &dev_priv->mm.unbound_list);
Daniel Vetter75e9e912010-11-04 17:11:09 +01002434 /* Avoid an unnecessary call to unbind on rebind. */
Chris Wilson05394f32010-11-08 19:18:58 +00002435 obj->map_and_fenceable = true;
Eric Anholt673a3942008-07-30 12:06:12 -07002436
Chris Wilson05394f32010-11-08 19:18:58 +00002437 drm_mm_put_block(obj->gtt_space);
2438 obj->gtt_space = NULL;
2439 obj->gtt_offset = 0;
Eric Anholt673a3942008-07-30 12:06:12 -07002440
Chris Wilson6c085a72012-08-20 11:40:46 +02002441 return 0;
Eric Anholt673a3942008-07-30 12:06:12 -07002442}
2443
Ben Widawskyb2da9fe2012-04-26 16:02:58 -07002444static int i915_ring_idle(struct intel_ring_buffer *ring)
Chris Wilsona56ba562010-09-28 10:07:56 +01002445{
Chris Wilson69c2fc82012-07-20 12:41:03 +01002446 if (list_empty(&ring->active_list))
Chris Wilson64193402010-10-24 12:38:05 +01002447 return 0;
2448
Ben Widawsky199b2bc2012-05-24 15:03:11 -07002449 return i915_wait_seqno(ring, i915_gem_next_request_seqno(ring));
Chris Wilsona56ba562010-09-28 10:07:56 +01002450}
2451
Ben Widawskyb2da9fe2012-04-26 16:02:58 -07002452int i915_gpu_idle(struct drm_device *dev)
Daniel Vetter4df2faf2010-02-19 11:52:00 +01002453{
2454 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilsonb4519512012-05-11 14:29:30 +01002455 struct intel_ring_buffer *ring;
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002456 int ret, i;
Daniel Vetter4df2faf2010-02-19 11:52:00 +01002457
Daniel Vetter4df2faf2010-02-19 11:52:00 +01002458 /* Flush everything onto the inactive list. */
Chris Wilsonb4519512012-05-11 14:29:30 +01002459 for_each_ring(ring, dev_priv, i) {
Ben Widawskyb6c74882012-08-14 14:35:14 -07002460 ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID);
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002461 if (ret)
2462 return ret;
Chris Wilsonb4519512012-05-11 14:29:30 +01002463
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002464 ret = i915_ring_idle(ring);
Ben Widawskyf2ef6eb2012-06-04 14:42:53 -07002465 if (ret)
2466 return ret;
Chris Wilson1ec14ad2010-12-04 11:30:53 +00002467 }
Zou Nan haid1b851f2010-05-21 09:08:57 +08002468
Daniel Vetter8a1a49f2010-02-11 22:29:04 +01002469 return 0;
Daniel Vetter4df2faf2010-02-19 11:52:00 +01002470}
2471
Chris Wilson9ce079e2012-04-17 15:31:30 +01002472static void sandybridge_write_fence_reg(struct drm_device *dev, int reg,
2473 struct drm_i915_gem_object *obj)
Eric Anholt4e901fd2009-10-26 16:44:17 -07002474{
Eric Anholt4e901fd2009-10-26 16:44:17 -07002475 drm_i915_private_t *dev_priv = dev->dev_private;
Eric Anholt4e901fd2009-10-26 16:44:17 -07002476 uint64_t val;
2477
Chris Wilson9ce079e2012-04-17 15:31:30 +01002478 if (obj) {
2479 u32 size = obj->gtt_space->size;
Eric Anholt4e901fd2009-10-26 16:44:17 -07002480
Chris Wilson9ce079e2012-04-17 15:31:30 +01002481 val = (uint64_t)((obj->gtt_offset + size - 4096) &
2482 0xfffff000) << 32;
2483 val |= obj->gtt_offset & 0xfffff000;
2484 val |= (uint64_t)((obj->stride / 128) - 1) <<
2485 SANDYBRIDGE_FENCE_PITCH_SHIFT;
Eric Anholt4e901fd2009-10-26 16:44:17 -07002486
Chris Wilson9ce079e2012-04-17 15:31:30 +01002487 if (obj->tiling_mode == I915_TILING_Y)
2488 val |= 1 << I965_FENCE_TILING_Y_SHIFT;
2489 val |= I965_FENCE_REG_VALID;
2490 } else
2491 val = 0;
Daniel Vetterc6642782010-11-12 13:46:18 +00002492
Chris Wilson9ce079e2012-04-17 15:31:30 +01002493 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + reg * 8, val);
2494 POSTING_READ(FENCE_REG_SANDYBRIDGE_0 + reg * 8);
Eric Anholt4e901fd2009-10-26 16:44:17 -07002495}
2496
Chris Wilson9ce079e2012-04-17 15:31:30 +01002497static void i965_write_fence_reg(struct drm_device *dev, int reg,
2498 struct drm_i915_gem_object *obj)
Jesse Barnesde151cf2008-11-12 10:03:55 -08002499{
Jesse Barnesde151cf2008-11-12 10:03:55 -08002500 drm_i915_private_t *dev_priv = dev->dev_private;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002501 uint64_t val;
2502
Chris Wilson9ce079e2012-04-17 15:31:30 +01002503 if (obj) {
2504 u32 size = obj->gtt_space->size;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002505
Chris Wilson9ce079e2012-04-17 15:31:30 +01002506 val = (uint64_t)((obj->gtt_offset + size - 4096) &
2507 0xfffff000) << 32;
2508 val |= obj->gtt_offset & 0xfffff000;
2509 val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT;
2510 if (obj->tiling_mode == I915_TILING_Y)
2511 val |= 1 << I965_FENCE_TILING_Y_SHIFT;
2512 val |= I965_FENCE_REG_VALID;
2513 } else
2514 val = 0;
Daniel Vetterc6642782010-11-12 13:46:18 +00002515
Chris Wilson9ce079e2012-04-17 15:31:30 +01002516 I915_WRITE64(FENCE_REG_965_0 + reg * 8, val);
2517 POSTING_READ(FENCE_REG_965_0 + reg * 8);
Jesse Barnesde151cf2008-11-12 10:03:55 -08002518}
2519
Chris Wilson9ce079e2012-04-17 15:31:30 +01002520static void i915_write_fence_reg(struct drm_device *dev, int reg,
2521 struct drm_i915_gem_object *obj)
Jesse Barnesde151cf2008-11-12 10:03:55 -08002522{
Jesse Barnesde151cf2008-11-12 10:03:55 -08002523 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilson9ce079e2012-04-17 15:31:30 +01002524 u32 val;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002525
Chris Wilson9ce079e2012-04-17 15:31:30 +01002526 if (obj) {
2527 u32 size = obj->gtt_space->size;
2528 int pitch_val;
2529 int tile_width;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002530
Chris Wilson9ce079e2012-04-17 15:31:30 +01002531 WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) ||
2532 (size & -size) != size ||
2533 (obj->gtt_offset & (size - 1)),
2534 "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
2535 obj->gtt_offset, obj->map_and_fenceable, size);
2536
2537 if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
2538 tile_width = 128;
2539 else
2540 tile_width = 512;
2541
2542 /* Note: pitch better be a power of two tile widths */
2543 pitch_val = obj->stride / tile_width;
2544 pitch_val = ffs(pitch_val) - 1;
2545
2546 val = obj->gtt_offset;
2547 if (obj->tiling_mode == I915_TILING_Y)
2548 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
2549 val |= I915_FENCE_SIZE_BITS(size);
2550 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
2551 val |= I830_FENCE_REG_VALID;
2552 } else
2553 val = 0;
2554
2555 if (reg < 8)
2556 reg = FENCE_REG_830_0 + reg * 4;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002557 else
Chris Wilson9ce079e2012-04-17 15:31:30 +01002558 reg = FENCE_REG_945_8 + (reg - 8) * 4;
Jesse Barnes0f973f22009-01-26 17:10:45 -08002559
Chris Wilson9ce079e2012-04-17 15:31:30 +01002560 I915_WRITE(reg, val);
2561 POSTING_READ(reg);
Jesse Barnesde151cf2008-11-12 10:03:55 -08002562}
2563
Chris Wilson9ce079e2012-04-17 15:31:30 +01002564static void i830_write_fence_reg(struct drm_device *dev, int reg,
2565 struct drm_i915_gem_object *obj)
Jesse Barnesde151cf2008-11-12 10:03:55 -08002566{
Jesse Barnesde151cf2008-11-12 10:03:55 -08002567 drm_i915_private_t *dev_priv = dev->dev_private;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002568 uint32_t val;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002569
Chris Wilson9ce079e2012-04-17 15:31:30 +01002570 if (obj) {
2571 u32 size = obj->gtt_space->size;
2572 uint32_t pitch_val;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002573
Chris Wilson9ce079e2012-04-17 15:31:30 +01002574 WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) ||
2575 (size & -size) != size ||
2576 (obj->gtt_offset & (size - 1)),
2577 "object 0x%08x not 512K or pot-size 0x%08x aligned\n",
2578 obj->gtt_offset, size);
Eric Anholte76a16d2009-05-26 17:44:56 -07002579
Chris Wilson9ce079e2012-04-17 15:31:30 +01002580 pitch_val = obj->stride / 128;
2581 pitch_val = ffs(pitch_val) - 1;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002582
Chris Wilson9ce079e2012-04-17 15:31:30 +01002583 val = obj->gtt_offset;
2584 if (obj->tiling_mode == I915_TILING_Y)
2585 val |= 1 << I830_FENCE_TILING_Y_SHIFT;
2586 val |= I830_FENCE_SIZE_BITS(size);
2587 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
2588 val |= I830_FENCE_REG_VALID;
2589 } else
2590 val = 0;
Daniel Vetterc6642782010-11-12 13:46:18 +00002591
Chris Wilson9ce079e2012-04-17 15:31:30 +01002592 I915_WRITE(FENCE_REG_830_0 + reg * 4, val);
2593 POSTING_READ(FENCE_REG_830_0 + reg * 4);
2594}
2595
2596static void i915_gem_write_fence(struct drm_device *dev, int reg,
2597 struct drm_i915_gem_object *obj)
2598{
2599 switch (INTEL_INFO(dev)->gen) {
2600 case 7:
2601 case 6: sandybridge_write_fence_reg(dev, reg, obj); break;
2602 case 5:
2603 case 4: i965_write_fence_reg(dev, reg, obj); break;
2604 case 3: i915_write_fence_reg(dev, reg, obj); break;
2605 case 2: i830_write_fence_reg(dev, reg, obj); break;
2606 default: break;
2607 }
Jesse Barnesde151cf2008-11-12 10:03:55 -08002608}
2609
Chris Wilson61050802012-04-17 15:31:31 +01002610static inline int fence_number(struct drm_i915_private *dev_priv,
2611 struct drm_i915_fence_reg *fence)
2612{
2613 return fence - dev_priv->fence_regs;
2614}
2615
2616static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
2617 struct drm_i915_fence_reg *fence,
2618 bool enable)
2619{
2620 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
2621 int reg = fence_number(dev_priv, fence);
2622
2623 i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
2624
2625 if (enable) {
2626 obj->fence_reg = reg;
2627 fence->obj = obj;
2628 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
2629 } else {
2630 obj->fence_reg = I915_FENCE_REG_NONE;
2631 fence->obj = NULL;
2632 list_del_init(&fence->lru_list);
2633 }
2634}
2635
Chris Wilsond9e86c02010-11-10 16:40:20 +00002636static int
Chris Wilsona360bb12012-04-17 15:31:25 +01002637i915_gem_object_flush_fence(struct drm_i915_gem_object *obj)
Chris Wilsond9e86c02010-11-10 16:40:20 +00002638{
Chris Wilson1c293ea2012-04-17 15:31:27 +01002639 if (obj->last_fenced_seqno) {
Chris Wilson86d5bc32012-07-20 12:41:04 +01002640 int ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno);
Chris Wilson18991842012-04-17 15:31:29 +01002641 if (ret)
2642 return ret;
Chris Wilsond9e86c02010-11-10 16:40:20 +00002643
2644 obj->last_fenced_seqno = 0;
Chris Wilsond9e86c02010-11-10 16:40:20 +00002645 }
2646
Chris Wilson63256ec2011-01-04 18:42:07 +00002647 /* Ensure that all CPU reads are completed before installing a fence
2648 * and all writes before removing the fence.
2649 */
2650 if (obj->base.read_domains & I915_GEM_DOMAIN_GTT)
2651 mb();
2652
Chris Wilson86d5bc32012-07-20 12:41:04 +01002653 obj->fenced_gpu_access = false;
Chris Wilsond9e86c02010-11-10 16:40:20 +00002654 return 0;
2655}
2656
2657int
2658i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
2659{
Chris Wilson61050802012-04-17 15:31:31 +01002660 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
Chris Wilsond9e86c02010-11-10 16:40:20 +00002661 int ret;
2662
Chris Wilsona360bb12012-04-17 15:31:25 +01002663 ret = i915_gem_object_flush_fence(obj);
Chris Wilsond9e86c02010-11-10 16:40:20 +00002664 if (ret)
2665 return ret;
2666
Chris Wilson61050802012-04-17 15:31:31 +01002667 if (obj->fence_reg == I915_FENCE_REG_NONE)
2668 return 0;
Chris Wilson1690e1e2011-12-14 13:57:08 +01002669
Chris Wilson61050802012-04-17 15:31:31 +01002670 i915_gem_object_update_fence(obj,
2671 &dev_priv->fence_regs[obj->fence_reg],
2672 false);
2673 i915_gem_object_fence_lost(obj);
Chris Wilsond9e86c02010-11-10 16:40:20 +00002674
2675 return 0;
2676}
2677
2678static struct drm_i915_fence_reg *
Chris Wilsona360bb12012-04-17 15:31:25 +01002679i915_find_fence_reg(struct drm_device *dev)
Daniel Vetterae3db242010-02-19 11:51:58 +01002680{
Daniel Vetterae3db242010-02-19 11:51:58 +01002681 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilson8fe301a2012-04-17 15:31:28 +01002682 struct drm_i915_fence_reg *reg, *avail;
Chris Wilsond9e86c02010-11-10 16:40:20 +00002683 int i;
Daniel Vetterae3db242010-02-19 11:51:58 +01002684
2685 /* First try to find a free reg */
Chris Wilsond9e86c02010-11-10 16:40:20 +00002686 avail = NULL;
Daniel Vetterae3db242010-02-19 11:51:58 +01002687 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
2688 reg = &dev_priv->fence_regs[i];
2689 if (!reg->obj)
Chris Wilsond9e86c02010-11-10 16:40:20 +00002690 return reg;
Daniel Vetterae3db242010-02-19 11:51:58 +01002691
Chris Wilson1690e1e2011-12-14 13:57:08 +01002692 if (!reg->pin_count)
Chris Wilsond9e86c02010-11-10 16:40:20 +00002693 avail = reg;
Daniel Vetterae3db242010-02-19 11:51:58 +01002694 }
2695
Chris Wilsond9e86c02010-11-10 16:40:20 +00002696 if (avail == NULL)
2697 return NULL;
Daniel Vetterae3db242010-02-19 11:51:58 +01002698
2699 /* None available, try to steal one or wait for a user to finish */
Chris Wilsond9e86c02010-11-10 16:40:20 +00002700 list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) {
Chris Wilson1690e1e2011-12-14 13:57:08 +01002701 if (reg->pin_count)
Daniel Vetterae3db242010-02-19 11:51:58 +01002702 continue;
2703
Chris Wilson8fe301a2012-04-17 15:31:28 +01002704 return reg;
Daniel Vetterae3db242010-02-19 11:51:58 +01002705 }
2706
Chris Wilson8fe301a2012-04-17 15:31:28 +01002707 return NULL;
Daniel Vetterae3db242010-02-19 11:51:58 +01002708}
2709
Jesse Barnesde151cf2008-11-12 10:03:55 -08002710/**
Chris Wilson9a5a53b2012-03-22 15:10:00 +00002711 * i915_gem_object_get_fence - set up fencing for an object
Jesse Barnesde151cf2008-11-12 10:03:55 -08002712 * @obj: object to map through a fence reg
2713 *
2714 * When mapping objects through the GTT, userspace wants to be able to write
2715 * to them without having to worry about swizzling if the object is tiled.
Jesse Barnesde151cf2008-11-12 10:03:55 -08002716 * This function walks the fence regs looking for a free one for @obj,
2717 * stealing one if it can't find any.
2718 *
2719 * It then sets up the reg based on the object's properties: address, pitch
2720 * and tiling format.
Chris Wilson9a5a53b2012-03-22 15:10:00 +00002721 *
2722 * For an untiled surface, this removes any existing fence.
Jesse Barnesde151cf2008-11-12 10:03:55 -08002723 */
Chris Wilson8c4b8c32009-06-17 22:08:52 +01002724int
Chris Wilson06d98132012-04-17 15:31:24 +01002725i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
Jesse Barnesde151cf2008-11-12 10:03:55 -08002726{
Chris Wilson05394f32010-11-08 19:18:58 +00002727 struct drm_device *dev = obj->base.dev;
Jesse Barnes79e53942008-11-07 14:24:08 -08002728 struct drm_i915_private *dev_priv = dev->dev_private;
Chris Wilson14415742012-04-17 15:31:33 +01002729 bool enable = obj->tiling_mode != I915_TILING_NONE;
Chris Wilsond9e86c02010-11-10 16:40:20 +00002730 struct drm_i915_fence_reg *reg;
Daniel Vetterae3db242010-02-19 11:51:58 +01002731 int ret;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002732
Chris Wilson14415742012-04-17 15:31:33 +01002733 /* Have we updated the tiling parameters upon the object and so
2734 * will need to serialise the write to the associated fence register?
2735 */
Chris Wilson5d82e3e2012-04-21 16:23:23 +01002736 if (obj->fence_dirty) {
Chris Wilson14415742012-04-17 15:31:33 +01002737 ret = i915_gem_object_flush_fence(obj);
2738 if (ret)
2739 return ret;
2740 }
Chris Wilson9a5a53b2012-03-22 15:10:00 +00002741
Chris Wilsond9e86c02010-11-10 16:40:20 +00002742 /* Just update our place in the LRU if our fence is getting reused. */
Chris Wilson05394f32010-11-08 19:18:58 +00002743 if (obj->fence_reg != I915_FENCE_REG_NONE) {
2744 reg = &dev_priv->fence_regs[obj->fence_reg];
Chris Wilson5d82e3e2012-04-21 16:23:23 +01002745 if (!obj->fence_dirty) {
Chris Wilson14415742012-04-17 15:31:33 +01002746 list_move_tail(&reg->lru_list,
2747 &dev_priv->mm.fence_list);
2748 return 0;
2749 }
2750 } else if (enable) {
2751 reg = i915_find_fence_reg(dev);
2752 if (reg == NULL)
2753 return -EDEADLK;
Chris Wilsond9e86c02010-11-10 16:40:20 +00002754
Chris Wilson14415742012-04-17 15:31:33 +01002755 if (reg->obj) {
2756 struct drm_i915_gem_object *old = reg->obj;
2757
2758 ret = i915_gem_object_flush_fence(old);
Chris Wilson29c5a582011-03-17 15:23:22 +00002759 if (ret)
2760 return ret;
2761
Chris Wilson14415742012-04-17 15:31:33 +01002762 i915_gem_object_fence_lost(old);
Chris Wilson29c5a582011-03-17 15:23:22 +00002763 }
Chris Wilson14415742012-04-17 15:31:33 +01002764 } else
Eric Anholta09ba7f2009-08-29 12:49:51 -07002765 return 0;
Eric Anholta09ba7f2009-08-29 12:49:51 -07002766
Chris Wilson14415742012-04-17 15:31:33 +01002767 i915_gem_object_update_fence(obj, reg, enable);
Chris Wilson5d82e3e2012-04-21 16:23:23 +01002768 obj->fence_dirty = false;
Chris Wilson14415742012-04-17 15:31:33 +01002769
Chris Wilson9ce079e2012-04-17 15:31:30 +01002770 return 0;
Jesse Barnesde151cf2008-11-12 10:03:55 -08002771}
2772
Chris Wilson42d6ab42012-07-26 11:49:32 +01002773static bool i915_gem_valid_gtt_space(struct drm_device *dev,
2774 struct drm_mm_node *gtt_space,
2775 unsigned long cache_level)
2776{
2777 struct drm_mm_node *other;
2778
2779 /* On non-LLC machines we have to be careful when putting differing
2780 * types of snoopable memory together to avoid the prefetcher
2781 * crossing memory domains and dieing.
2782 */
2783 if (HAS_LLC(dev))
2784 return true;
2785
2786 if (gtt_space == NULL)
2787 return true;
2788
2789 if (list_empty(&gtt_space->node_list))
2790 return true;
2791
2792 other = list_entry(gtt_space->node_list.prev, struct drm_mm_node, node_list);
2793 if (other->allocated && !other->hole_follows && other->color != cache_level)
2794 return false;
2795
2796 other = list_entry(gtt_space->node_list.next, struct drm_mm_node, node_list);
2797 if (other->allocated && !gtt_space->hole_follows && other->color != cache_level)
2798 return false;
2799
2800 return true;
2801}
2802
2803static void i915_gem_verify_gtt(struct drm_device *dev)
2804{
2805#if WATCH_GTT
2806 struct drm_i915_private *dev_priv = dev->dev_private;
2807 struct drm_i915_gem_object *obj;
2808 int err = 0;
2809
2810 list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
2811 if (obj->gtt_space == NULL) {
2812 printk(KERN_ERR "object found on GTT list with no space reserved\n");
2813 err++;
2814 continue;
2815 }
2816
2817 if (obj->cache_level != obj->gtt_space->color) {
2818 printk(KERN_ERR "object reserved space [%08lx, %08lx] with wrong color, cache_level=%x, color=%lx\n",
2819 obj->gtt_space->start,
2820 obj->gtt_space->start + obj->gtt_space->size,
2821 obj->cache_level,
2822 obj->gtt_space->color);
2823 err++;
2824 continue;
2825 }
2826
2827 if (!i915_gem_valid_gtt_space(dev,
2828 obj->gtt_space,
2829 obj->cache_level)) {
2830 printk(KERN_ERR "invalid GTT space found at [%08lx, %08lx] - color=%x\n",
2831 obj->gtt_space->start,
2832 obj->gtt_space->start + obj->gtt_space->size,
2833 obj->cache_level);
2834 err++;
2835 continue;
2836 }
2837 }
2838
2839 WARN_ON(err);
2840#endif
2841}
2842
Jesse Barnesde151cf2008-11-12 10:03:55 -08002843/**
Eric Anholt673a3942008-07-30 12:06:12 -07002844 * Finds free space in the GTT aperture and binds the object there.
2845 */
2846static int
Chris Wilson05394f32010-11-08 19:18:58 +00002847i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
Daniel Vetter920afa72010-09-16 17:54:23 +02002848 unsigned alignment,
Chris Wilson86a1ee22012-08-11 15:41:04 +01002849 bool map_and_fenceable,
2850 bool nonblocking)
Eric Anholt673a3942008-07-30 12:06:12 -07002851{
Chris Wilson05394f32010-11-08 19:18:58 +00002852 struct drm_device *dev = obj->base.dev;
Eric Anholt673a3942008-07-30 12:06:12 -07002853 drm_i915_private_t *dev_priv = dev->dev_private;
Eric Anholt673a3942008-07-30 12:06:12 -07002854 struct drm_mm_node *free_space;
Daniel Vetter5e783302010-11-14 22:32:36 +01002855 u32 size, fence_size, fence_alignment, unfenced_alignment;
Daniel Vetter75e9e912010-11-04 17:11:09 +01002856 bool mappable, fenceable;
Chris Wilson07f73f62009-09-14 16:50:30 +01002857 int ret;
Eric Anholt673a3942008-07-30 12:06:12 -07002858
Chris Wilson05394f32010-11-08 19:18:58 +00002859 if (obj->madv != I915_MADV_WILLNEED) {
Chris Wilson3ef94da2009-09-14 16:50:29 +01002860 DRM_ERROR("Attempting to bind a purgeable object\n");
2861 return -EINVAL;
2862 }
2863
Chris Wilsone28f8712011-07-18 13:11:49 -07002864 fence_size = i915_gem_get_gtt_size(dev,
2865 obj->base.size,
2866 obj->tiling_mode);
2867 fence_alignment = i915_gem_get_gtt_alignment(dev,
2868 obj->base.size,
2869 obj->tiling_mode);
2870 unfenced_alignment =
2871 i915_gem_get_unfenced_gtt_alignment(dev,
2872 obj->base.size,
2873 obj->tiling_mode);
Chris Wilsona00b10c2010-09-24 21:15:47 +01002874
Eric Anholt673a3942008-07-30 12:06:12 -07002875 if (alignment == 0)
Daniel Vetter5e783302010-11-14 22:32:36 +01002876 alignment = map_and_fenceable ? fence_alignment :
2877 unfenced_alignment;
Daniel Vetter75e9e912010-11-04 17:11:09 +01002878 if (map_and_fenceable && alignment & (fence_alignment - 1)) {
Eric Anholt673a3942008-07-30 12:06:12 -07002879 DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2880 return -EINVAL;
2881 }
2882
Chris Wilson05394f32010-11-08 19:18:58 +00002883 size = map_and_fenceable ? fence_size : obj->base.size;
Chris Wilsona00b10c2010-09-24 21:15:47 +01002884
Chris Wilson654fc602010-05-27 13:18:21 +01002885 /* If the object is bigger than the entire aperture, reject it early
2886 * before evicting everything in a vain attempt to find space.
2887 */
Chris Wilson05394f32010-11-08 19:18:58 +00002888 if (obj->base.size >
Daniel Vetter75e9e912010-11-04 17:11:09 +01002889 (map_and_fenceable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) {
Chris Wilson654fc602010-05-27 13:18:21 +01002890 DRM_ERROR("Attempting to bind an object larger than the aperture\n");
2891 return -E2BIG;
2892 }
2893
Chris Wilson37e680a2012-06-07 15:38:42 +01002894 ret = i915_gem_object_get_pages(obj);
Chris Wilson6c085a72012-08-20 11:40:46 +02002895 if (ret)
2896 return ret;
2897
Eric Anholt673a3942008-07-30 12:06:12 -07002898 search_free:
Daniel Vetter75e9e912010-11-04 17:11:09 +01002899 if (map_and_fenceable)
Daniel Vetter920afa72010-09-16 17:54:23 +02002900 free_space =
Chris Wilson42d6ab42012-07-26 11:49:32 +01002901 drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space,
2902 size, alignment, obj->cache_level,
2903 0, dev_priv->mm.gtt_mappable_end,
2904 false);
Daniel Vetter920afa72010-09-16 17:54:23 +02002905 else
Chris Wilson42d6ab42012-07-26 11:49:32 +01002906 free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space,
2907 size, alignment, obj->cache_level,
2908 false);
Daniel Vetter920afa72010-09-16 17:54:23 +02002909
2910 if (free_space != NULL) {
Daniel Vetter75e9e912010-11-04 17:11:09 +01002911 if (map_and_fenceable)
Chris Wilson05394f32010-11-08 19:18:58 +00002912 obj->gtt_space =
Daniel Vetter920afa72010-09-16 17:54:23 +02002913 drm_mm_get_block_range_generic(free_space,
Chris Wilson42d6ab42012-07-26 11:49:32 +01002914 size, alignment, obj->cache_level,
Chris Wilson6b9d89b2012-07-10 11:15:23 +01002915 0, dev_priv->mm.gtt_mappable_end,
Chris Wilson42d6ab42012-07-26 11:49:32 +01002916 false);
Daniel Vetter920afa72010-09-16 17:54:23 +02002917 else
Chris Wilson05394f32010-11-08 19:18:58 +00002918 obj->gtt_space =
Chris Wilson42d6ab42012-07-26 11:49:32 +01002919 drm_mm_get_block_generic(free_space,
2920 size, alignment, obj->cache_level,
2921 false);
Daniel Vetter920afa72010-09-16 17:54:23 +02002922 }
Chris Wilson05394f32010-11-08 19:18:58 +00002923 if (obj->gtt_space == NULL) {
Daniel Vetter75e9e912010-11-04 17:11:09 +01002924 ret = i915_gem_evict_something(dev, size, alignment,
Chris Wilson42d6ab42012-07-26 11:49:32 +01002925 obj->cache_level,
Chris Wilson86a1ee22012-08-11 15:41:04 +01002926 map_and_fenceable,
2927 nonblocking);
Chris Wilson97311292009-09-21 00:22:34 +01002928 if (ret)
Eric Anholt673a3942008-07-30 12:06:12 -07002929 return ret;
Chris Wilson97311292009-09-21 00:22:34 +01002930
Eric Anholt673a3942008-07-30 12:06:12 -07002931 goto search_free;
2932 }
Chris Wilson42d6ab42012-07-26 11:49:32 +01002933 if (WARN_ON(!i915_gem_valid_gtt_space(dev,
2934 obj->gtt_space,
2935 obj->cache_level))) {
2936 drm_mm_put_block(obj->gtt_space);
2937 obj->gtt_space = NULL;
2938 return -EINVAL;
2939 }
Eric Anholt673a3942008-07-30 12:06:12 -07002940
Eric Anholt673a3942008-07-30 12:06:12 -07002941
Daniel Vetter74163902012-02-15 23:50:21 +01002942 ret = i915_gem_gtt_prepare_object(obj);
Daniel Vetter7c2e6fd2010-11-06 10:10:47 +01002943 if (ret) {
Chris Wilson05394f32010-11-08 19:18:58 +00002944 drm_mm_put_block(obj->gtt_space);
2945 obj->gtt_space = NULL;
Chris Wilson6c085a72012-08-20 11:40:46 +02002946 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07002947 }
Eric Anholt673a3942008-07-30 12:06:12 -07002948
Daniel Vetter0ebb9822012-02-15 23:50:24 +01002949 if (!dev_priv->mm.aliasing_ppgtt)
2950 i915_gem_gtt_bind_object(obj, obj->cache_level);
Eric Anholt673a3942008-07-30 12:06:12 -07002951
Chris Wilson6c085a72012-08-20 11:40:46 +02002952 list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list);
Chris Wilson05394f32010-11-08 19:18:58 +00002953 list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
Chris Wilsonbf1a1092010-08-07 11:01:20 +01002954
Chris Wilson6299f992010-11-24 12:23:44 +00002955 obj->gtt_offset = obj->gtt_space->start;
Chris Wilson1c5d22f2009-08-25 11:15:50 +01002956
Daniel Vetter75e9e912010-11-04 17:11:09 +01002957 fenceable =
Chris Wilson05394f32010-11-08 19:18:58 +00002958 obj->gtt_space->size == fence_size &&
Akshay Joshi0206e352011-08-16 15:34:10 -04002959 (obj->gtt_space->start & (fence_alignment - 1)) == 0;
Chris Wilsona00b10c2010-09-24 21:15:47 +01002960
Daniel Vetter75e9e912010-11-04 17:11:09 +01002961 mappable =
Chris Wilson05394f32010-11-08 19:18:58 +00002962 obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end;
Chris Wilsona00b10c2010-09-24 21:15:47 +01002963
Chris Wilson05394f32010-11-08 19:18:58 +00002964 obj->map_and_fenceable = mappable && fenceable;
Daniel Vetter75e9e912010-11-04 17:11:09 +01002965
Chris Wilsondb53a302011-02-03 11:57:46 +00002966 trace_i915_gem_object_bind(obj, map_and_fenceable);
Chris Wilson42d6ab42012-07-26 11:49:32 +01002967 i915_gem_verify_gtt(dev);
Eric Anholt673a3942008-07-30 12:06:12 -07002968 return 0;
2969}
2970
2971void
Chris Wilson05394f32010-11-08 19:18:58 +00002972i915_gem_clflush_object(struct drm_i915_gem_object *obj)
Eric Anholt673a3942008-07-30 12:06:12 -07002973{
Eric Anholt673a3942008-07-30 12:06:12 -07002974 /* If we don't have a page list set up, then we're not pinned
2975 * to GPU, and we can ignore the cache flush because it'll happen
2976 * again at bind time.
2977 */
Chris Wilson05394f32010-11-08 19:18:58 +00002978 if (obj->pages == NULL)
Eric Anholt673a3942008-07-30 12:06:12 -07002979 return;
2980
Chris Wilson9c23f7f2011-03-29 16:59:52 -07002981 /* If the GPU is snooping the contents of the CPU cache,
2982 * we do not need to manually clear the CPU cache lines. However,
2983 * the caches are only snooped when the render cache is
2984 * flushed/invalidated. As we always have to emit invalidations
2985 * and flushes when moving into and out of the RENDER domain, correct
2986 * snooping behaviour occurs naturally as the result of our domain
2987 * tracking.
2988 */
2989 if (obj->cache_level != I915_CACHE_NONE)
2990 return;
2991
Chris Wilson1c5d22f2009-08-25 11:15:50 +01002992 trace_i915_gem_object_clflush(obj);
Eric Anholtcfa16a02009-05-26 18:46:16 -07002993
Chris Wilson05394f32010-11-08 19:18:58 +00002994 drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE);
Eric Anholt673a3942008-07-30 12:06:12 -07002995}
2996
Eric Anholte47c68e2008-11-14 13:35:19 -08002997/** Flushes the GTT write domain for the object if it's dirty. */
2998static void
Chris Wilson05394f32010-11-08 19:18:58 +00002999i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj)
Eric Anholte47c68e2008-11-14 13:35:19 -08003000{
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003001 uint32_t old_write_domain;
3002
Chris Wilson05394f32010-11-08 19:18:58 +00003003 if (obj->base.write_domain != I915_GEM_DOMAIN_GTT)
Eric Anholte47c68e2008-11-14 13:35:19 -08003004 return;
3005
Chris Wilson63256ec2011-01-04 18:42:07 +00003006 /* No actual flushing is required for the GTT write domain. Writes
Eric Anholte47c68e2008-11-14 13:35:19 -08003007 * to it immediately go to main memory as far as we know, so there's
3008 * no chipset flush. It also doesn't land in render cache.
Chris Wilson63256ec2011-01-04 18:42:07 +00003009 *
3010 * However, we do have to enforce the order so that all writes through
3011 * the GTT land before any writes to the device, such as updates to
3012 * the GATT itself.
Eric Anholte47c68e2008-11-14 13:35:19 -08003013 */
Chris Wilson63256ec2011-01-04 18:42:07 +00003014 wmb();
3015
Chris Wilson05394f32010-11-08 19:18:58 +00003016 old_write_domain = obj->base.write_domain;
3017 obj->base.write_domain = 0;
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003018
3019 trace_i915_gem_object_change_domain(obj,
Chris Wilson05394f32010-11-08 19:18:58 +00003020 obj->base.read_domains,
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003021 old_write_domain);
Eric Anholte47c68e2008-11-14 13:35:19 -08003022}
3023
3024/** Flushes the CPU write domain for the object if it's dirty. */
3025static void
Chris Wilson05394f32010-11-08 19:18:58 +00003026i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj)
Eric Anholte47c68e2008-11-14 13:35:19 -08003027{
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003028 uint32_t old_write_domain;
Eric Anholte47c68e2008-11-14 13:35:19 -08003029
Chris Wilson05394f32010-11-08 19:18:58 +00003030 if (obj->base.write_domain != I915_GEM_DOMAIN_CPU)
Eric Anholte47c68e2008-11-14 13:35:19 -08003031 return;
3032
3033 i915_gem_clflush_object(obj);
Daniel Vetter40ce6572010-11-05 18:12:18 +01003034 intel_gtt_chipset_flush();
Chris Wilson05394f32010-11-08 19:18:58 +00003035 old_write_domain = obj->base.write_domain;
3036 obj->base.write_domain = 0;
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003037
3038 trace_i915_gem_object_change_domain(obj,
Chris Wilson05394f32010-11-08 19:18:58 +00003039 obj->base.read_domains,
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003040 old_write_domain);
Eric Anholte47c68e2008-11-14 13:35:19 -08003041}
3042
Eric Anholt2ef7eea2008-11-10 10:53:25 -08003043/**
3044 * Moves a single object to the GTT read, and possibly write domain.
3045 *
3046 * This function returns when the move is complete, including waiting on
3047 * flushes to occur.
3048 */
Jesse Barnes79e53942008-11-07 14:24:08 -08003049int
Chris Wilson20217462010-11-23 15:26:33 +00003050i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
Eric Anholt2ef7eea2008-11-10 10:53:25 -08003051{
Chris Wilson8325a092012-04-24 15:52:35 +01003052 drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003053 uint32_t old_write_domain, old_read_domains;
Eric Anholte47c68e2008-11-14 13:35:19 -08003054 int ret;
Eric Anholt2ef7eea2008-11-10 10:53:25 -08003055
Eric Anholt02354392008-11-26 13:58:13 -08003056 /* Not valid to be called on unbound objects. */
Chris Wilson05394f32010-11-08 19:18:58 +00003057 if (obj->gtt_space == NULL)
Eric Anholt02354392008-11-26 13:58:13 -08003058 return -EINVAL;
3059
Chris Wilson8d7e3de2011-02-07 15:23:02 +00003060 if (obj->base.write_domain == I915_GEM_DOMAIN_GTT)
3061 return 0;
3062
Chris Wilson0201f1e2012-07-20 12:41:01 +01003063 ret = i915_gem_object_wait_rendering(obj, !write);
3064 if (ret)
3065 return ret;
Chris Wilson2dafb1e2010-06-07 14:03:05 +01003066
Chris Wilson72133422010-09-13 23:56:38 +01003067 i915_gem_object_flush_cpu_write_domain(obj);
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003068
Chris Wilson05394f32010-11-08 19:18:58 +00003069 old_write_domain = obj->base.write_domain;
3070 old_read_domains = obj->base.read_domains;
Eric Anholt2ef7eea2008-11-10 10:53:25 -08003071
Eric Anholt2ef7eea2008-11-10 10:53:25 -08003072 /* It should now be out of any other write domains, and we can update
3073 * the domain values for our changes.
3074 */
Chris Wilson05394f32010-11-08 19:18:58 +00003075 BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
3076 obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
Eric Anholte47c68e2008-11-14 13:35:19 -08003077 if (write) {
Chris Wilson05394f32010-11-08 19:18:58 +00003078 obj->base.read_domains = I915_GEM_DOMAIN_GTT;
3079 obj->base.write_domain = I915_GEM_DOMAIN_GTT;
3080 obj->dirty = 1;
Eric Anholte47c68e2008-11-14 13:35:19 -08003081 }
3082
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003083 trace_i915_gem_object_change_domain(obj,
3084 old_read_domains,
3085 old_write_domain);
3086
Chris Wilson8325a092012-04-24 15:52:35 +01003087 /* And bump the LRU for this access */
3088 if (i915_gem_object_is_inactive(obj))
3089 list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
3090
Eric Anholte47c68e2008-11-14 13:35:19 -08003091 return 0;
3092}
3093
Chris Wilsone4ffd172011-04-04 09:44:39 +01003094int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
3095 enum i915_cache_level cache_level)
3096{
Daniel Vetter7bddb012012-02-09 17:15:47 +01003097 struct drm_device *dev = obj->base.dev;
3098 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilsone4ffd172011-04-04 09:44:39 +01003099 int ret;
3100
3101 if (obj->cache_level == cache_level)
3102 return 0;
3103
3104 if (obj->pin_count) {
3105 DRM_DEBUG("can not change the cache level of pinned objects\n");
3106 return -EBUSY;
3107 }
3108
Chris Wilson42d6ab42012-07-26 11:49:32 +01003109 if (!i915_gem_valid_gtt_space(dev, obj->gtt_space, cache_level)) {
3110 ret = i915_gem_object_unbind(obj);
3111 if (ret)
3112 return ret;
3113 }
3114
Chris Wilsone4ffd172011-04-04 09:44:39 +01003115 if (obj->gtt_space) {
3116 ret = i915_gem_object_finish_gpu(obj);
3117 if (ret)
3118 return ret;
3119
3120 i915_gem_object_finish_gtt(obj);
3121
3122 /* Before SandyBridge, you could not use tiling or fence
3123 * registers with snooped memory, so relinquish any fences
3124 * currently pointing to our region in the aperture.
3125 */
Chris Wilson42d6ab42012-07-26 11:49:32 +01003126 if (INTEL_INFO(dev)->gen < 6) {
Chris Wilsone4ffd172011-04-04 09:44:39 +01003127 ret = i915_gem_object_put_fence(obj);
3128 if (ret)
3129 return ret;
3130 }
3131
Daniel Vetter74898d72012-02-15 23:50:22 +01003132 if (obj->has_global_gtt_mapping)
3133 i915_gem_gtt_bind_object(obj, cache_level);
Daniel Vetter7bddb012012-02-09 17:15:47 +01003134 if (obj->has_aliasing_ppgtt_mapping)
3135 i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
3136 obj, cache_level);
Chris Wilson42d6ab42012-07-26 11:49:32 +01003137
3138 obj->gtt_space->color = cache_level;
Chris Wilsone4ffd172011-04-04 09:44:39 +01003139 }
3140
3141 if (cache_level == I915_CACHE_NONE) {
3142 u32 old_read_domains, old_write_domain;
3143
3144 /* If we're coming from LLC cached, then we haven't
3145 * actually been tracking whether the data is in the
3146 * CPU cache or not, since we only allow one bit set
3147 * in obj->write_domain and have been skipping the clflushes.
3148 * Just set it to the CPU cache for now.
3149 */
3150 WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU);
3151 WARN_ON(obj->base.read_domains & ~I915_GEM_DOMAIN_CPU);
3152
3153 old_read_domains = obj->base.read_domains;
3154 old_write_domain = obj->base.write_domain;
3155
3156 obj->base.read_domains = I915_GEM_DOMAIN_CPU;
3157 obj->base.write_domain = I915_GEM_DOMAIN_CPU;
3158
3159 trace_i915_gem_object_change_domain(obj,
3160 old_read_domains,
3161 old_write_domain);
3162 }
3163
3164 obj->cache_level = cache_level;
Chris Wilson42d6ab42012-07-26 11:49:32 +01003165 i915_gem_verify_gtt(dev);
Chris Wilsone4ffd172011-04-04 09:44:39 +01003166 return 0;
3167}
3168
Chris Wilsone6994ae2012-07-10 10:27:08 +01003169int i915_gem_get_cacheing_ioctl(struct drm_device *dev, void *data,
3170 struct drm_file *file)
3171{
3172 struct drm_i915_gem_cacheing *args = data;
3173 struct drm_i915_gem_object *obj;
3174 int ret;
3175
3176 ret = i915_mutex_lock_interruptible(dev);
3177 if (ret)
3178 return ret;
3179
3180 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
3181 if (&obj->base == NULL) {
3182 ret = -ENOENT;
3183 goto unlock;
3184 }
3185
3186 args->cacheing = obj->cache_level != I915_CACHE_NONE;
3187
3188 drm_gem_object_unreference(&obj->base);
3189unlock:
3190 mutex_unlock(&dev->struct_mutex);
3191 return ret;
3192}
3193
3194int i915_gem_set_cacheing_ioctl(struct drm_device *dev, void *data,
3195 struct drm_file *file)
3196{
3197 struct drm_i915_gem_cacheing *args = data;
3198 struct drm_i915_gem_object *obj;
3199 enum i915_cache_level level;
3200 int ret;
3201
3202 ret = i915_mutex_lock_interruptible(dev);
3203 if (ret)
3204 return ret;
3205
3206 switch (args->cacheing) {
3207 case I915_CACHEING_NONE:
3208 level = I915_CACHE_NONE;
3209 break;
3210 case I915_CACHEING_CACHED:
3211 level = I915_CACHE_LLC;
3212 break;
3213 default:
3214 return -EINVAL;
3215 }
3216
3217 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
3218 if (&obj->base == NULL) {
3219 ret = -ENOENT;
3220 goto unlock;
3221 }
3222
3223 ret = i915_gem_object_set_cache_level(obj, level);
3224
3225 drm_gem_object_unreference(&obj->base);
3226unlock:
3227 mutex_unlock(&dev->struct_mutex);
3228 return ret;
3229}
3230
Zhenyu Wangb9241ea2009-11-25 13:09:39 +08003231/*
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003232 * Prepare buffer for display plane (scanout, cursors, etc).
3233 * Can be called from an uninterruptible phase (modesetting) and allows
3234 * any flushes to be pipelined (for pageflips).
Zhenyu Wangb9241ea2009-11-25 13:09:39 +08003235 */
3236int
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003237i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
3238 u32 alignment,
Chris Wilson919926a2010-11-12 13:42:53 +00003239 struct intel_ring_buffer *pipelined)
Zhenyu Wangb9241ea2009-11-25 13:09:39 +08003240{
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003241 u32 old_read_domains, old_write_domain;
Zhenyu Wangb9241ea2009-11-25 13:09:39 +08003242 int ret;
3243
Chris Wilson0be73282010-12-06 14:36:27 +00003244 if (pipelined != obj->ring) {
Ben Widawsky2911a352012-04-05 14:47:36 -07003245 ret = i915_gem_object_sync(obj, pipelined);
3246 if (ret)
Zhenyu Wangb9241ea2009-11-25 13:09:39 +08003247 return ret;
3248 }
3249
Eric Anholta7ef0642011-03-29 16:59:54 -07003250 /* The display engine is not coherent with the LLC cache on gen6. As
3251 * a result, we make sure that the pinning that is about to occur is
3252 * done with uncached PTEs. This is lowest common denominator for all
3253 * chipsets.
3254 *
3255 * However for gen6+, we could do better by using the GFDT bit instead
3256 * of uncaching, which would allow us to flush all the LLC-cached data
3257 * with that bit in the PTE to main memory with just one PIPE_CONTROL.
3258 */
3259 ret = i915_gem_object_set_cache_level(obj, I915_CACHE_NONE);
3260 if (ret)
3261 return ret;
3262
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003263 /* As the user may map the buffer once pinned in the display plane
3264 * (e.g. libkms for the bootup splash), we have to ensure that we
3265 * always use map_and_fenceable for all scanout buffers.
3266 */
Chris Wilson86a1ee22012-08-11 15:41:04 +01003267 ret = i915_gem_object_pin(obj, alignment, true, false);
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003268 if (ret)
3269 return ret;
3270
Chris Wilsonb118c1e2010-05-27 13:18:14 +01003271 i915_gem_object_flush_cpu_write_domain(obj);
3272
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003273 old_write_domain = obj->base.write_domain;
Chris Wilson05394f32010-11-08 19:18:58 +00003274 old_read_domains = obj->base.read_domains;
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003275
3276 /* It should now be out of any other write domains, and we can update
3277 * the domain values for our changes.
3278 */
Chris Wilsone5f1d962012-07-20 12:41:00 +01003279 obj->base.write_domain = 0;
Chris Wilson05394f32010-11-08 19:18:58 +00003280 obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
Zhenyu Wangb9241ea2009-11-25 13:09:39 +08003281
3282 trace_i915_gem_object_change_domain(obj,
3283 old_read_domains,
Chris Wilson2da3b9b2011-04-14 09:41:17 +01003284 old_write_domain);
Zhenyu Wangb9241ea2009-11-25 13:09:39 +08003285
3286 return 0;
3287}
3288
Chris Wilson85345512010-11-13 09:49:11 +00003289int
Chris Wilsona8198ee2011-04-13 22:04:09 +01003290i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj)
Chris Wilson85345512010-11-13 09:49:11 +00003291{
Chris Wilson88241782011-01-07 17:09:48 +00003292 int ret;
3293
Chris Wilsona8198ee2011-04-13 22:04:09 +01003294 if ((obj->base.read_domains & I915_GEM_GPU_DOMAINS) == 0)
Chris Wilson85345512010-11-13 09:49:11 +00003295 return 0;
3296
Chris Wilson0201f1e2012-07-20 12:41:01 +01003297 ret = i915_gem_object_wait_rendering(obj, false);
Chris Wilsonc501ae72011-12-14 13:57:23 +01003298 if (ret)
3299 return ret;
3300
Chris Wilsona8198ee2011-04-13 22:04:09 +01003301 /* Ensure that we invalidate the GPU's caches and TLBs. */
3302 obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS;
Chris Wilsonc501ae72011-12-14 13:57:23 +01003303 return 0;
Chris Wilson85345512010-11-13 09:49:11 +00003304}
3305
Eric Anholte47c68e2008-11-14 13:35:19 -08003306/**
3307 * Moves a single object to the CPU read, and possibly write domain.
3308 *
3309 * This function returns when the move is complete, including waiting on
3310 * flushes to occur.
3311 */
Chris Wilsondabdfe02012-03-26 10:10:27 +02003312int
Chris Wilson919926a2010-11-12 13:42:53 +00003313i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
Eric Anholte47c68e2008-11-14 13:35:19 -08003314{
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003315 uint32_t old_write_domain, old_read_domains;
Eric Anholte47c68e2008-11-14 13:35:19 -08003316 int ret;
3317
Chris Wilson8d7e3de2011-02-07 15:23:02 +00003318 if (obj->base.write_domain == I915_GEM_DOMAIN_CPU)
3319 return 0;
3320
Chris Wilson0201f1e2012-07-20 12:41:01 +01003321 ret = i915_gem_object_wait_rendering(obj, !write);
3322 if (ret)
3323 return ret;
Eric Anholte47c68e2008-11-14 13:35:19 -08003324
3325 i915_gem_object_flush_gtt_write_domain(obj);
3326
Chris Wilson05394f32010-11-08 19:18:58 +00003327 old_write_domain = obj->base.write_domain;
3328 old_read_domains = obj->base.read_domains;
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003329
Eric Anholte47c68e2008-11-14 13:35:19 -08003330 /* Flush the CPU cache if it's still invalid. */
Chris Wilson05394f32010-11-08 19:18:58 +00003331 if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) {
Eric Anholte47c68e2008-11-14 13:35:19 -08003332 i915_gem_clflush_object(obj);
Eric Anholte47c68e2008-11-14 13:35:19 -08003333
Chris Wilson05394f32010-11-08 19:18:58 +00003334 obj->base.read_domains |= I915_GEM_DOMAIN_CPU;
Eric Anholte47c68e2008-11-14 13:35:19 -08003335 }
3336
3337 /* It should now be out of any other write domains, and we can update
3338 * the domain values for our changes.
3339 */
Chris Wilson05394f32010-11-08 19:18:58 +00003340 BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0);
Eric Anholte47c68e2008-11-14 13:35:19 -08003341
3342 /* If we're writing through the CPU, then the GPU read domains will
3343 * need to be invalidated at next use.
3344 */
3345 if (write) {
Chris Wilson05394f32010-11-08 19:18:58 +00003346 obj->base.read_domains = I915_GEM_DOMAIN_CPU;
3347 obj->base.write_domain = I915_GEM_DOMAIN_CPU;
Eric Anholte47c68e2008-11-14 13:35:19 -08003348 }
Eric Anholt2ef7eea2008-11-10 10:53:25 -08003349
Chris Wilson1c5d22f2009-08-25 11:15:50 +01003350 trace_i915_gem_object_change_domain(obj,
3351 old_read_domains,
3352 old_write_domain);
3353
Eric Anholt2ef7eea2008-11-10 10:53:25 -08003354 return 0;
3355}
3356
Eric Anholt673a3942008-07-30 12:06:12 -07003357/* Throttle our rendering by waiting until the ring has completed our requests
3358 * emitted over 20 msec ago.
3359 *
Eric Anholtb9624422009-06-03 07:27:35 +00003360 * Note that if we were to use the current jiffies each time around the loop,
3361 * we wouldn't escape the function with any frames outstanding if the time to
3362 * render a frame was over 20ms.
3363 *
Eric Anholt673a3942008-07-30 12:06:12 -07003364 * This should get us reasonable parallelism between CPU and GPU but also
3365 * relatively low latency when blocking on a particular request to finish.
3366 */
3367static int
Chris Wilsonf787a5f2010-09-24 16:02:42 +01003368i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -07003369{
Chris Wilsonf787a5f2010-09-24 16:02:42 +01003370 struct drm_i915_private *dev_priv = dev->dev_private;
3371 struct drm_i915_file_private *file_priv = file->driver_priv;
Eric Anholtb9624422009-06-03 07:27:35 +00003372 unsigned long recent_enough = jiffies - msecs_to_jiffies(20);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01003373 struct drm_i915_gem_request *request;
3374 struct intel_ring_buffer *ring = NULL;
3375 u32 seqno = 0;
3376 int ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003377
Chris Wilsone110e8d2011-01-26 15:39:14 +00003378 if (atomic_read(&dev_priv->mm.wedged))
3379 return -EIO;
3380
Chris Wilson1c255952010-09-26 11:03:27 +01003381 spin_lock(&file_priv->mm.lock);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01003382 list_for_each_entry(request, &file_priv->mm.request_list, client_list) {
Eric Anholtb9624422009-06-03 07:27:35 +00003383 if (time_after_eq(request->emitted_jiffies, recent_enough))
3384 break;
3385
Chris Wilsonf787a5f2010-09-24 16:02:42 +01003386 ring = request->ring;
3387 seqno = request->seqno;
Eric Anholtb9624422009-06-03 07:27:35 +00003388 }
Chris Wilson1c255952010-09-26 11:03:27 +01003389 spin_unlock(&file_priv->mm.lock);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01003390
3391 if (seqno == 0)
3392 return 0;
3393
Ben Widawsky5c81fe852012-05-24 15:03:08 -07003394 ret = __wait_seqno(ring, seqno, true, NULL);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01003395 if (ret == 0)
3396 queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
Eric Anholtb9624422009-06-03 07:27:35 +00003397
Eric Anholt673a3942008-07-30 12:06:12 -07003398 return ret;
3399}
3400
Eric Anholt673a3942008-07-30 12:06:12 -07003401int
Chris Wilson05394f32010-11-08 19:18:58 +00003402i915_gem_object_pin(struct drm_i915_gem_object *obj,
3403 uint32_t alignment,
Chris Wilson86a1ee22012-08-11 15:41:04 +01003404 bool map_and_fenceable,
3405 bool nonblocking)
Eric Anholt673a3942008-07-30 12:06:12 -07003406{
Eric Anholt673a3942008-07-30 12:06:12 -07003407 int ret;
3408
Chris Wilson05394f32010-11-08 19:18:58 +00003409 BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT);
Chris Wilsonac0c6b52010-05-27 13:18:18 +01003410
Chris Wilson05394f32010-11-08 19:18:58 +00003411 if (obj->gtt_space != NULL) {
3412 if ((alignment && obj->gtt_offset & (alignment - 1)) ||
3413 (map_and_fenceable && !obj->map_and_fenceable)) {
3414 WARN(obj->pin_count,
Chris Wilsonae7d49d2010-08-04 12:37:41 +01003415 "bo is already pinned with incorrect alignment:"
Daniel Vetter75e9e912010-11-04 17:11:09 +01003416 " offset=%x, req.alignment=%x, req.map_and_fenceable=%d,"
3417 " obj->map_and_fenceable=%d\n",
Chris Wilson05394f32010-11-08 19:18:58 +00003418 obj->gtt_offset, alignment,
Daniel Vetter75e9e912010-11-04 17:11:09 +01003419 map_and_fenceable,
Chris Wilson05394f32010-11-08 19:18:58 +00003420 obj->map_and_fenceable);
Chris Wilsonac0c6b52010-05-27 13:18:18 +01003421 ret = i915_gem_object_unbind(obj);
3422 if (ret)
3423 return ret;
3424 }
3425 }
3426
Chris Wilson05394f32010-11-08 19:18:58 +00003427 if (obj->gtt_space == NULL) {
Chris Wilsona00b10c2010-09-24 21:15:47 +01003428 ret = i915_gem_object_bind_to_gtt(obj, alignment,
Chris Wilson86a1ee22012-08-11 15:41:04 +01003429 map_and_fenceable,
3430 nonblocking);
Chris Wilson97311292009-09-21 00:22:34 +01003431 if (ret)
Eric Anholt673a3942008-07-30 12:06:12 -07003432 return ret;
Chris Wilson22c344e2009-02-11 14:26:45 +00003433 }
Jesse Barnes76446ca2009-12-17 22:05:42 -05003434
Daniel Vetter74898d72012-02-15 23:50:22 +01003435 if (!obj->has_global_gtt_mapping && map_and_fenceable)
3436 i915_gem_gtt_bind_object(obj, obj->cache_level);
3437
Chris Wilson1b502472012-04-24 15:47:30 +01003438 obj->pin_count++;
Chris Wilson6299f992010-11-24 12:23:44 +00003439 obj->pin_mappable |= map_and_fenceable;
Eric Anholt673a3942008-07-30 12:06:12 -07003440
3441 return 0;
3442}
3443
3444void
Chris Wilson05394f32010-11-08 19:18:58 +00003445i915_gem_object_unpin(struct drm_i915_gem_object *obj)
Eric Anholt673a3942008-07-30 12:06:12 -07003446{
Chris Wilson05394f32010-11-08 19:18:58 +00003447 BUG_ON(obj->pin_count == 0);
3448 BUG_ON(obj->gtt_space == NULL);
Eric Anholt673a3942008-07-30 12:06:12 -07003449
Chris Wilson1b502472012-04-24 15:47:30 +01003450 if (--obj->pin_count == 0)
Chris Wilson6299f992010-11-24 12:23:44 +00003451 obj->pin_mappable = false;
Eric Anholt673a3942008-07-30 12:06:12 -07003452}
3453
3454int
3455i915_gem_pin_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +00003456 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -07003457{
3458 struct drm_i915_gem_pin *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +00003459 struct drm_i915_gem_object *obj;
Eric Anholt673a3942008-07-30 12:06:12 -07003460 int ret;
3461
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003462 ret = i915_mutex_lock_interruptible(dev);
3463 if (ret)
3464 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003465
Chris Wilson05394f32010-11-08 19:18:58 +00003466 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +00003467 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003468 ret = -ENOENT;
3469 goto unlock;
Eric Anholt673a3942008-07-30 12:06:12 -07003470 }
Eric Anholt673a3942008-07-30 12:06:12 -07003471
Chris Wilson05394f32010-11-08 19:18:58 +00003472 if (obj->madv != I915_MADV_WILLNEED) {
Chris Wilsonbb6baf72009-09-22 14:24:13 +01003473 DRM_ERROR("Attempting to pin a purgeable buffer\n");
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003474 ret = -EINVAL;
3475 goto out;
Chris Wilson3ef94da2009-09-14 16:50:29 +01003476 }
3477
Chris Wilson05394f32010-11-08 19:18:58 +00003478 if (obj->pin_filp != NULL && obj->pin_filp != file) {
Jesse Barnes79e53942008-11-07 14:24:08 -08003479 DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
3480 args->handle);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003481 ret = -EINVAL;
3482 goto out;
Jesse Barnes79e53942008-11-07 14:24:08 -08003483 }
3484
Chris Wilson05394f32010-11-08 19:18:58 +00003485 obj->user_pin_count++;
3486 obj->pin_filp = file;
3487 if (obj->user_pin_count == 1) {
Chris Wilson86a1ee22012-08-11 15:41:04 +01003488 ret = i915_gem_object_pin(obj, args->alignment, true, false);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003489 if (ret)
3490 goto out;
Eric Anholt673a3942008-07-30 12:06:12 -07003491 }
3492
3493 /* XXX - flush the CPU caches for pinned objects
3494 * as the X server doesn't manage domains yet
3495 */
Eric Anholte47c68e2008-11-14 13:35:19 -08003496 i915_gem_object_flush_cpu_write_domain(obj);
Chris Wilson05394f32010-11-08 19:18:58 +00003497 args->offset = obj->gtt_offset;
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003498out:
Chris Wilson05394f32010-11-08 19:18:58 +00003499 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003500unlock:
Eric Anholt673a3942008-07-30 12:06:12 -07003501 mutex_unlock(&dev->struct_mutex);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003502 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003503}
3504
3505int
3506i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +00003507 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -07003508{
3509 struct drm_i915_gem_pin *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +00003510 struct drm_i915_gem_object *obj;
Chris Wilson76c1dec2010-09-25 11:22:51 +01003511 int ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003512
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003513 ret = i915_mutex_lock_interruptible(dev);
3514 if (ret)
3515 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003516
Chris Wilson05394f32010-11-08 19:18:58 +00003517 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +00003518 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003519 ret = -ENOENT;
3520 goto unlock;
Eric Anholt673a3942008-07-30 12:06:12 -07003521 }
Chris Wilson76c1dec2010-09-25 11:22:51 +01003522
Chris Wilson05394f32010-11-08 19:18:58 +00003523 if (obj->pin_filp != file) {
Jesse Barnes79e53942008-11-07 14:24:08 -08003524 DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
3525 args->handle);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003526 ret = -EINVAL;
3527 goto out;
Jesse Barnes79e53942008-11-07 14:24:08 -08003528 }
Chris Wilson05394f32010-11-08 19:18:58 +00003529 obj->user_pin_count--;
3530 if (obj->user_pin_count == 0) {
3531 obj->pin_filp = NULL;
Jesse Barnes79e53942008-11-07 14:24:08 -08003532 i915_gem_object_unpin(obj);
3533 }
Eric Anholt673a3942008-07-30 12:06:12 -07003534
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003535out:
Chris Wilson05394f32010-11-08 19:18:58 +00003536 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003537unlock:
Eric Anholt673a3942008-07-30 12:06:12 -07003538 mutex_unlock(&dev->struct_mutex);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003539 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003540}
3541
3542int
3543i915_gem_busy_ioctl(struct drm_device *dev, void *data,
Chris Wilson05394f32010-11-08 19:18:58 +00003544 struct drm_file *file)
Eric Anholt673a3942008-07-30 12:06:12 -07003545{
3546 struct drm_i915_gem_busy *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +00003547 struct drm_i915_gem_object *obj;
Chris Wilson30dbf0c2010-09-25 10:19:17 +01003548 int ret;
3549
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003550 ret = i915_mutex_lock_interruptible(dev);
3551 if (ret)
3552 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003553
Chris Wilson05394f32010-11-08 19:18:58 +00003554 obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +00003555 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003556 ret = -ENOENT;
3557 goto unlock;
Eric Anholt673a3942008-07-30 12:06:12 -07003558 }
Zou Nan haid1b851f2010-05-21 09:08:57 +08003559
Chris Wilson0be555b2010-08-04 15:36:30 +01003560 /* Count all active objects as busy, even if they are currently not used
3561 * by the gpu. Users of this interface expect objects to eventually
3562 * become non-busy without any further actions, therefore emit any
3563 * necessary flushes here.
Eric Anholtc4de0a52008-12-14 19:05:04 -08003564 */
Daniel Vetter30dfebf2012-06-01 15:21:23 +02003565 ret = i915_gem_object_flush_active(obj);
3566
Chris Wilson05394f32010-11-08 19:18:58 +00003567 args->busy = obj->active;
Chris Wilsone9808ed2012-07-04 12:25:08 +01003568 if (obj->ring) {
3569 BUILD_BUG_ON(I915_NUM_RINGS > 16);
3570 args->busy |= intel_ring_flag(obj->ring) << 16;
3571 }
Eric Anholt673a3942008-07-30 12:06:12 -07003572
Chris Wilson05394f32010-11-08 19:18:58 +00003573 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003574unlock:
Eric Anholt673a3942008-07-30 12:06:12 -07003575 mutex_unlock(&dev->struct_mutex);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003576 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003577}
3578
3579int
3580i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
3581 struct drm_file *file_priv)
3582{
Akshay Joshi0206e352011-08-16 15:34:10 -04003583 return i915_gem_ring_throttle(dev, file_priv);
Eric Anholt673a3942008-07-30 12:06:12 -07003584}
3585
Chris Wilson3ef94da2009-09-14 16:50:29 +01003586int
3587i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
3588 struct drm_file *file_priv)
3589{
3590 struct drm_i915_gem_madvise *args = data;
Chris Wilson05394f32010-11-08 19:18:58 +00003591 struct drm_i915_gem_object *obj;
Chris Wilson76c1dec2010-09-25 11:22:51 +01003592 int ret;
Chris Wilson3ef94da2009-09-14 16:50:29 +01003593
3594 switch (args->madv) {
3595 case I915_MADV_DONTNEED:
3596 case I915_MADV_WILLNEED:
3597 break;
3598 default:
3599 return -EINVAL;
3600 }
3601
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003602 ret = i915_mutex_lock_interruptible(dev);
3603 if (ret)
3604 return ret;
3605
Chris Wilson05394f32010-11-08 19:18:58 +00003606 obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle));
Chris Wilsonc8725222011-02-19 11:31:06 +00003607 if (&obj->base == NULL) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003608 ret = -ENOENT;
3609 goto unlock;
Chris Wilson3ef94da2009-09-14 16:50:29 +01003610 }
Chris Wilson3ef94da2009-09-14 16:50:29 +01003611
Chris Wilson05394f32010-11-08 19:18:58 +00003612 if (obj->pin_count) {
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003613 ret = -EINVAL;
3614 goto out;
Chris Wilson3ef94da2009-09-14 16:50:29 +01003615 }
3616
Chris Wilson05394f32010-11-08 19:18:58 +00003617 if (obj->madv != __I915_MADV_PURGED)
3618 obj->madv = args->madv;
Chris Wilson3ef94da2009-09-14 16:50:29 +01003619
Chris Wilson6c085a72012-08-20 11:40:46 +02003620 /* if the object is no longer attached, discard its backing storage */
3621 if (i915_gem_object_is_purgeable(obj) && obj->pages == NULL)
Chris Wilson2d7ef392009-09-20 23:13:10 +01003622 i915_gem_object_truncate(obj);
3623
Chris Wilson05394f32010-11-08 19:18:58 +00003624 args->retained = obj->madv != __I915_MADV_PURGED;
Chris Wilsonbb6baf72009-09-22 14:24:13 +01003625
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003626out:
Chris Wilson05394f32010-11-08 19:18:58 +00003627 drm_gem_object_unreference(&obj->base);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003628unlock:
Chris Wilson3ef94da2009-09-14 16:50:29 +01003629 mutex_unlock(&dev->struct_mutex);
Chris Wilson1d7cfea2010-10-17 09:45:41 +01003630 return ret;
Chris Wilson3ef94da2009-09-14 16:50:29 +01003631}
3632
Chris Wilson37e680a2012-06-07 15:38:42 +01003633void i915_gem_object_init(struct drm_i915_gem_object *obj,
3634 const struct drm_i915_gem_object_ops *ops)
Chris Wilson0327d6b2012-08-11 15:41:06 +01003635{
Chris Wilson0327d6b2012-08-11 15:41:06 +01003636 INIT_LIST_HEAD(&obj->mm_list);
3637 INIT_LIST_HEAD(&obj->gtt_list);
3638 INIT_LIST_HEAD(&obj->ring_list);
3639 INIT_LIST_HEAD(&obj->exec_list);
3640
Chris Wilson37e680a2012-06-07 15:38:42 +01003641 obj->ops = ops;
3642
Chris Wilson0327d6b2012-08-11 15:41:06 +01003643 obj->fence_reg = I915_FENCE_REG_NONE;
3644 obj->madv = I915_MADV_WILLNEED;
3645 /* Avoid an unnecessary call to unbind on the first bind. */
3646 obj->map_and_fenceable = true;
3647
3648 i915_gem_info_add_obj(obj->base.dev->dev_private, obj->base.size);
3649}
3650
Chris Wilson37e680a2012-06-07 15:38:42 +01003651static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
3652 .get_pages = i915_gem_object_get_pages_gtt,
3653 .put_pages = i915_gem_object_put_pages_gtt,
3654};
3655
Chris Wilson05394f32010-11-08 19:18:58 +00003656struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
3657 size_t size)
Daniel Vetterac52bc52010-04-09 19:05:06 +00003658{
Daniel Vetterc397b902010-04-09 19:05:07 +00003659 struct drm_i915_gem_object *obj;
Hugh Dickins5949eac2011-06-27 16:18:18 -07003660 struct address_space *mapping;
Chris Wilsonbed1ea92012-05-24 20:48:12 +01003661 u32 mask;
Daniel Vetterc397b902010-04-09 19:05:07 +00003662
3663 obj = kzalloc(sizeof(*obj), GFP_KERNEL);
3664 if (obj == NULL)
3665 return NULL;
3666
3667 if (drm_gem_object_init(dev, &obj->base, size) != 0) {
3668 kfree(obj);
3669 return NULL;
3670 }
3671
Chris Wilsonbed1ea92012-05-24 20:48:12 +01003672 mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
3673 if (IS_CRESTLINE(dev) || IS_BROADWATER(dev)) {
3674 /* 965gm cannot relocate objects above 4GiB. */
3675 mask &= ~__GFP_HIGHMEM;
3676 mask |= __GFP_DMA32;
3677 }
3678
Hugh Dickins5949eac2011-06-27 16:18:18 -07003679 mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
Chris Wilsonbed1ea92012-05-24 20:48:12 +01003680 mapping_set_gfp_mask(mapping, mask);
Hugh Dickins5949eac2011-06-27 16:18:18 -07003681
Chris Wilson37e680a2012-06-07 15:38:42 +01003682 i915_gem_object_init(obj, &i915_gem_object_ops);
Chris Wilson73aa8082010-09-30 11:46:12 +01003683
Daniel Vetterc397b902010-04-09 19:05:07 +00003684 obj->base.write_domain = I915_GEM_DOMAIN_CPU;
3685 obj->base.read_domains = I915_GEM_DOMAIN_CPU;
3686
Eugeni Dodonov3d29b842012-01-17 14:43:53 -02003687 if (HAS_LLC(dev)) {
3688 /* On some devices, we can have the GPU use the LLC (the CPU
Eric Anholta1871112011-03-29 16:59:55 -07003689 * cache) for about a 10% performance improvement
3690 * compared to uncached. Graphics requests other than
3691 * display scanout are coherent with the CPU in
3692 * accessing this cache. This means in this mode we
3693 * don't need to clflush on the CPU side, and on the
3694 * GPU side we only need to flush internal caches to
3695 * get data visible to the CPU.
3696 *
3697 * However, we maintain the display planes as UC, and so
3698 * need to rebind when first used as such.
3699 */
3700 obj->cache_level = I915_CACHE_LLC;
3701 } else
3702 obj->cache_level = I915_CACHE_NONE;
3703
Chris Wilson05394f32010-11-08 19:18:58 +00003704 return obj;
Daniel Vetterac52bc52010-04-09 19:05:06 +00003705}
3706
Eric Anholt673a3942008-07-30 12:06:12 -07003707int i915_gem_init_object(struct drm_gem_object *obj)
3708{
Daniel Vetterc397b902010-04-09 19:05:07 +00003709 BUG();
Jesse Barnesde151cf2008-11-12 10:03:55 -08003710
Eric Anholt673a3942008-07-30 12:06:12 -07003711 return 0;
3712}
3713
Chris Wilson1488fc02012-04-24 15:47:31 +01003714void i915_gem_free_object(struct drm_gem_object *gem_obj)
Chris Wilsonbe726152010-07-23 23:18:50 +01003715{
Chris Wilson1488fc02012-04-24 15:47:31 +01003716 struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
Chris Wilson05394f32010-11-08 19:18:58 +00003717 struct drm_device *dev = obj->base.dev;
Chris Wilsonbe726152010-07-23 23:18:50 +01003718 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilsonbe726152010-07-23 23:18:50 +01003719
Chris Wilson26e12f892011-03-20 11:20:19 +00003720 trace_i915_gem_object_destroy(obj);
3721
Daniel Vetter1286ff72012-05-10 15:25:09 +02003722 if (gem_obj->import_attach)
3723 drm_prime_gem_destroy(gem_obj, obj->sg_table);
3724
Chris Wilson1488fc02012-04-24 15:47:31 +01003725 if (obj->phys_obj)
3726 i915_gem_detach_phys_object(dev, obj);
3727
3728 obj->pin_count = 0;
3729 if (WARN_ON(i915_gem_object_unbind(obj) == -ERESTARTSYS)) {
3730 bool was_interruptible;
3731
3732 was_interruptible = dev_priv->mm.interruptible;
3733 dev_priv->mm.interruptible = false;
3734
3735 WARN_ON(i915_gem_object_unbind(obj));
3736
3737 dev_priv->mm.interruptible = was_interruptible;
3738 }
3739
Chris Wilsona5570172012-09-04 21:02:54 +01003740 obj->pages_pin_count = 0;
Chris Wilson37e680a2012-06-07 15:38:42 +01003741 i915_gem_object_put_pages(obj);
Chris Wilsond8cb5082012-08-11 15:41:03 +01003742 i915_gem_object_free_mmap_offset(obj);
Chris Wilsonbe726152010-07-23 23:18:50 +01003743
Chris Wilson05394f32010-11-08 19:18:58 +00003744 drm_gem_object_release(&obj->base);
3745 i915_gem_info_remove_obj(dev_priv, obj->base.size);
Chris Wilsonbe726152010-07-23 23:18:50 +01003746
Chris Wilson05394f32010-11-08 19:18:58 +00003747 kfree(obj->bit_17);
3748 kfree(obj);
Chris Wilsonbe726152010-07-23 23:18:50 +01003749}
3750
Jesse Barnes5669fca2009-02-17 15:13:31 -08003751int
Eric Anholt673a3942008-07-30 12:06:12 -07003752i915_gem_idle(struct drm_device *dev)
3753{
3754 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilson29105cc2010-01-07 10:39:13 +00003755 int ret;
Eric Anholt673a3942008-07-30 12:06:12 -07003756
Keith Packard6dbe2772008-10-14 21:41:13 -07003757 mutex_lock(&dev->struct_mutex);
3758
Chris Wilson87acb0a2010-10-19 10:13:00 +01003759 if (dev_priv->mm.suspended) {
Keith Packard6dbe2772008-10-14 21:41:13 -07003760 mutex_unlock(&dev->struct_mutex);
Eric Anholt673a3942008-07-30 12:06:12 -07003761 return 0;
Keith Packard6dbe2772008-10-14 21:41:13 -07003762 }
Eric Anholt673a3942008-07-30 12:06:12 -07003763
Ben Widawskyb2da9fe2012-04-26 16:02:58 -07003764 ret = i915_gpu_idle(dev);
Keith Packard6dbe2772008-10-14 21:41:13 -07003765 if (ret) {
3766 mutex_unlock(&dev->struct_mutex);
Eric Anholt673a3942008-07-30 12:06:12 -07003767 return ret;
Keith Packard6dbe2772008-10-14 21:41:13 -07003768 }
Ben Widawskyb2da9fe2012-04-26 16:02:58 -07003769 i915_gem_retire_requests(dev);
Eric Anholt673a3942008-07-30 12:06:12 -07003770
Chris Wilson29105cc2010-01-07 10:39:13 +00003771 /* Under UMS, be paranoid and evict. */
Chris Wilsona39d7ef2012-04-24 18:22:52 +01003772 if (!drm_core_check_feature(dev, DRIVER_MODESET))
Chris Wilson6c085a72012-08-20 11:40:46 +02003773 i915_gem_evict_everything(dev);
Chris Wilson29105cc2010-01-07 10:39:13 +00003774
Chris Wilson312817a2010-11-22 11:50:11 +00003775 i915_gem_reset_fences(dev);
3776
Chris Wilson29105cc2010-01-07 10:39:13 +00003777 /* Hack! Don't let anybody do execbuf while we don't control the chip.
3778 * We need to replace this with a semaphore, or something.
3779 * And not confound mm.suspended!
3780 */
3781 dev_priv->mm.suspended = 1;
Daniel Vetterbc0c7f12010-08-20 18:18:48 +02003782 del_timer_sync(&dev_priv->hangcheck_timer);
Chris Wilson29105cc2010-01-07 10:39:13 +00003783
3784 i915_kernel_lost_context(dev);
Keith Packard6dbe2772008-10-14 21:41:13 -07003785 i915_gem_cleanup_ringbuffer(dev);
Chris Wilson29105cc2010-01-07 10:39:13 +00003786
Keith Packard6dbe2772008-10-14 21:41:13 -07003787 mutex_unlock(&dev->struct_mutex);
3788
Chris Wilson29105cc2010-01-07 10:39:13 +00003789 /* Cancel the retire work handler, which should be idle now. */
3790 cancel_delayed_work_sync(&dev_priv->mm.retire_work);
3791
Eric Anholt673a3942008-07-30 12:06:12 -07003792 return 0;
3793}
3794
Ben Widawskyb9524a12012-05-25 16:56:24 -07003795void i915_gem_l3_remap(struct drm_device *dev)
3796{
3797 drm_i915_private_t *dev_priv = dev->dev_private;
3798 u32 misccpctl;
3799 int i;
3800
3801 if (!IS_IVYBRIDGE(dev))
3802 return;
3803
3804 if (!dev_priv->mm.l3_remap_info)
3805 return;
3806
3807 misccpctl = I915_READ(GEN7_MISCCPCTL);
3808 I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
3809 POSTING_READ(GEN7_MISCCPCTL);
3810
3811 for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) {
3812 u32 remap = I915_READ(GEN7_L3LOG_BASE + i);
3813 if (remap && remap != dev_priv->mm.l3_remap_info[i/4])
3814 DRM_DEBUG("0x%x was already programmed to %x\n",
3815 GEN7_L3LOG_BASE + i, remap);
3816 if (remap && !dev_priv->mm.l3_remap_info[i/4])
3817 DRM_DEBUG_DRIVER("Clearing remapped register\n");
3818 I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->mm.l3_remap_info[i/4]);
3819 }
3820
3821 /* Make sure all the writes land before disabling dop clock gating */
3822 POSTING_READ(GEN7_L3LOG_BASE);
3823
3824 I915_WRITE(GEN7_MISCCPCTL, misccpctl);
3825}
3826
Daniel Vetterf691e2f2012-02-02 09:58:12 +01003827void i915_gem_init_swizzling(struct drm_device *dev)
3828{
3829 drm_i915_private_t *dev_priv = dev->dev_private;
3830
Daniel Vetter11782b02012-01-31 16:47:55 +01003831 if (INTEL_INFO(dev)->gen < 5 ||
Daniel Vetterf691e2f2012-02-02 09:58:12 +01003832 dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
3833 return;
3834
3835 I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
3836 DISP_TILE_SURFACE_SWIZZLING);
3837
Daniel Vetter11782b02012-01-31 16:47:55 +01003838 if (IS_GEN5(dev))
3839 return;
3840
Daniel Vetterf691e2f2012-02-02 09:58:12 +01003841 I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL);
3842 if (IS_GEN6(dev))
Daniel Vetter6b26c862012-04-24 14:04:12 +02003843 I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB));
Daniel Vetterf691e2f2012-02-02 09:58:12 +01003844 else
Daniel Vetter6b26c862012-04-24 14:04:12 +02003845 I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB));
Daniel Vetterf691e2f2012-02-02 09:58:12 +01003846}
Daniel Vettere21af882012-02-09 20:53:27 +01003847
3848void i915_gem_init_ppgtt(struct drm_device *dev)
3849{
3850 drm_i915_private_t *dev_priv = dev->dev_private;
3851 uint32_t pd_offset;
3852 struct intel_ring_buffer *ring;
Daniel Vetter55a254a2012-03-22 00:14:43 +01003853 struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
3854 uint32_t __iomem *pd_addr;
3855 uint32_t pd_entry;
Daniel Vettere21af882012-02-09 20:53:27 +01003856 int i;
3857
3858 if (!dev_priv->mm.aliasing_ppgtt)
3859 return;
3860
Daniel Vetter55a254a2012-03-22 00:14:43 +01003861
3862 pd_addr = dev_priv->mm.gtt->gtt + ppgtt->pd_offset/sizeof(uint32_t);
3863 for (i = 0; i < ppgtt->num_pd_entries; i++) {
3864 dma_addr_t pt_addr;
3865
3866 if (dev_priv->mm.gtt->needs_dmar)
3867 pt_addr = ppgtt->pt_dma_addr[i];
3868 else
3869 pt_addr = page_to_phys(ppgtt->pt_pages[i]);
3870
3871 pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
3872 pd_entry |= GEN6_PDE_VALID;
3873
3874 writel(pd_entry, pd_addr + i);
3875 }
3876 readl(pd_addr);
3877
3878 pd_offset = ppgtt->pd_offset;
Daniel Vettere21af882012-02-09 20:53:27 +01003879 pd_offset /= 64; /* in cachelines, */
3880 pd_offset <<= 16;
3881
3882 if (INTEL_INFO(dev)->gen == 6) {
Daniel Vetter48ecfa12012-04-11 20:42:40 +02003883 uint32_t ecochk, gab_ctl, ecobits;
3884
3885 ecobits = I915_READ(GAC_ECO_BITS);
3886 I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B);
Daniel Vetterbe901a52012-04-11 20:42:39 +02003887
3888 gab_ctl = I915_READ(GAB_CTL);
3889 I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT);
3890
3891 ecochk = I915_READ(GAM_ECOCHK);
Daniel Vettere21af882012-02-09 20:53:27 +01003892 I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT |
3893 ECOCHK_PPGTT_CACHE64B);
Daniel Vetter6b26c862012-04-24 14:04:12 +02003894 I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
Daniel Vettere21af882012-02-09 20:53:27 +01003895 } else if (INTEL_INFO(dev)->gen >= 7) {
3896 I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B);
3897 /* GFX_MODE is per-ring on gen7+ */
3898 }
3899
Chris Wilsonb4519512012-05-11 14:29:30 +01003900 for_each_ring(ring, dev_priv, i) {
Daniel Vettere21af882012-02-09 20:53:27 +01003901 if (INTEL_INFO(dev)->gen >= 7)
3902 I915_WRITE(RING_MODE_GEN7(ring),
Daniel Vetter6b26c862012-04-24 14:04:12 +02003903 _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
Daniel Vettere21af882012-02-09 20:53:27 +01003904
3905 I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
3906 I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset);
3907 }
3908}
3909
Chris Wilson67b1b572012-07-05 23:49:40 +01003910static bool
3911intel_enable_blt(struct drm_device *dev)
3912{
3913 if (!HAS_BLT(dev))
3914 return false;
3915
3916 /* The blitter was dysfunctional on early prototypes */
3917 if (IS_GEN6(dev) && dev->pdev->revision < 8) {
3918 DRM_INFO("BLT not supported on this pre-production hardware;"
3919 " graphics performance will be degraded.\n");
3920 return false;
3921 }
3922
3923 return true;
3924}
3925
Eric Anholt673a3942008-07-30 12:06:12 -07003926int
Daniel Vetterf691e2f2012-02-02 09:58:12 +01003927i915_gem_init_hw(struct drm_device *dev)
Zou Nan hai8187a2b2010-05-21 09:08:55 +08003928{
3929 drm_i915_private_t *dev_priv = dev->dev_private;
3930 int ret;
Chris Wilson68f95ba2010-05-27 13:18:22 +01003931
Daniel Vetter8ecd1a62012-06-07 15:56:03 +02003932 if (!intel_enable_gtt())
3933 return -EIO;
3934
Ben Widawskyb9524a12012-05-25 16:56:24 -07003935 i915_gem_l3_remap(dev);
3936
Daniel Vetterf691e2f2012-02-02 09:58:12 +01003937 i915_gem_init_swizzling(dev);
3938
Xiang, Haihao5c1143b2010-09-16 10:43:11 +08003939 ret = intel_init_render_ring_buffer(dev);
Chris Wilson68f95ba2010-05-27 13:18:22 +01003940 if (ret)
Chris Wilsonb6913e42010-11-12 10:46:37 +00003941 return ret;
Chris Wilson68f95ba2010-05-27 13:18:22 +01003942
3943 if (HAS_BSD(dev)) {
Xiang, Haihao5c1143b2010-09-16 10:43:11 +08003944 ret = intel_init_bsd_ring_buffer(dev);
Chris Wilson68f95ba2010-05-27 13:18:22 +01003945 if (ret)
3946 goto cleanup_render_ring;
Zou Nan haid1b851f2010-05-21 09:08:57 +08003947 }
Chris Wilson68f95ba2010-05-27 13:18:22 +01003948
Chris Wilson67b1b572012-07-05 23:49:40 +01003949 if (intel_enable_blt(dev)) {
Chris Wilson549f7362010-10-19 11:19:32 +01003950 ret = intel_init_blt_ring_buffer(dev);
3951 if (ret)
3952 goto cleanup_bsd_ring;
3953 }
3954
Chris Wilson6f392d5482010-08-07 11:01:22 +01003955 dev_priv->next_seqno = 1;
3956
Ben Widawsky254f9652012-06-04 14:42:42 -07003957 /*
3958 * XXX: There was some w/a described somewhere suggesting loading
3959 * contexts before PPGTT.
3960 */
3961 i915_gem_context_init(dev);
Daniel Vettere21af882012-02-09 20:53:27 +01003962 i915_gem_init_ppgtt(dev);
3963
Chris Wilson68f95ba2010-05-27 13:18:22 +01003964 return 0;
3965
Chris Wilson549f7362010-10-19 11:19:32 +01003966cleanup_bsd_ring:
Chris Wilson1ec14ad2010-12-04 11:30:53 +00003967 intel_cleanup_ring_buffer(&dev_priv->ring[VCS]);
Chris Wilson68f95ba2010-05-27 13:18:22 +01003968cleanup_render_ring:
Chris Wilson1ec14ad2010-12-04 11:30:53 +00003969 intel_cleanup_ring_buffer(&dev_priv->ring[RCS]);
Zou Nan hai8187a2b2010-05-21 09:08:55 +08003970 return ret;
3971}
3972
Chris Wilson1070a422012-04-24 15:47:41 +01003973static bool
3974intel_enable_ppgtt(struct drm_device *dev)
3975{
3976 if (i915_enable_ppgtt >= 0)
3977 return i915_enable_ppgtt;
3978
3979#ifdef CONFIG_INTEL_IOMMU
3980 /* Disable ppgtt on SNB if VT-d is on. */
3981 if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
3982 return false;
3983#endif
3984
3985 return true;
3986}
3987
3988int i915_gem_init(struct drm_device *dev)
3989{
3990 struct drm_i915_private *dev_priv = dev->dev_private;
3991 unsigned long gtt_size, mappable_size;
3992 int ret;
3993
3994 gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT;
3995 mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
3996
3997 mutex_lock(&dev->struct_mutex);
3998 if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) {
3999 /* PPGTT pdes are stolen from global gtt ptes, so shrink the
4000 * aperture accordingly when using aliasing ppgtt. */
4001 gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE;
4002
4003 i915_gem_init_global_gtt(dev, 0, mappable_size, gtt_size);
4004
4005 ret = i915_gem_init_aliasing_ppgtt(dev);
4006 if (ret) {
4007 mutex_unlock(&dev->struct_mutex);
4008 return ret;
4009 }
4010 } else {
4011 /* Let GEM Manage all of the aperture.
4012 *
4013 * However, leave one page at the end still bound to the scratch
4014 * page. There are a number of places where the hardware
4015 * apparently prefetches past the end of the object, and we've
4016 * seen multiple hangs with the GPU head pointer stuck in a
4017 * batchbuffer bound at the last page of the aperture. One page
4018 * should be enough to keep any prefetching inside of the
4019 * aperture.
4020 */
4021 i915_gem_init_global_gtt(dev, 0, mappable_size,
4022 gtt_size);
4023 }
4024
4025 ret = i915_gem_init_hw(dev);
4026 mutex_unlock(&dev->struct_mutex);
4027 if (ret) {
4028 i915_gem_cleanup_aliasing_ppgtt(dev);
4029 return ret;
4030 }
4031
Daniel Vetter53ca26c2012-04-26 23:28:03 +02004032 /* Allow hardware batchbuffers unless told otherwise, but not for KMS. */
4033 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4034 dev_priv->dri1.allow_batchbuffer = 1;
Chris Wilson1070a422012-04-24 15:47:41 +01004035 return 0;
4036}
4037
Zou Nan hai8187a2b2010-05-21 09:08:55 +08004038void
4039i915_gem_cleanup_ringbuffer(struct drm_device *dev)
4040{
4041 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilsonb4519512012-05-11 14:29:30 +01004042 struct intel_ring_buffer *ring;
Chris Wilson1ec14ad2010-12-04 11:30:53 +00004043 int i;
Zou Nan hai8187a2b2010-05-21 09:08:55 +08004044
Chris Wilsonb4519512012-05-11 14:29:30 +01004045 for_each_ring(ring, dev_priv, i)
4046 intel_cleanup_ring_buffer(ring);
Zou Nan hai8187a2b2010-05-21 09:08:55 +08004047}
4048
4049int
Eric Anholt673a3942008-07-30 12:06:12 -07004050i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
4051 struct drm_file *file_priv)
4052{
4053 drm_i915_private_t *dev_priv = dev->dev_private;
Chris Wilsonb4519512012-05-11 14:29:30 +01004054 int ret;
Eric Anholt673a3942008-07-30 12:06:12 -07004055
Jesse Barnes79e53942008-11-07 14:24:08 -08004056 if (drm_core_check_feature(dev, DRIVER_MODESET))
4057 return 0;
4058
Ben Gamariba1234d2009-09-14 17:48:47 -04004059 if (atomic_read(&dev_priv->mm.wedged)) {
Eric Anholt673a3942008-07-30 12:06:12 -07004060 DRM_ERROR("Reenabling wedged hardware, good luck\n");
Ben Gamariba1234d2009-09-14 17:48:47 -04004061 atomic_set(&dev_priv->mm.wedged, 0);
Eric Anholt673a3942008-07-30 12:06:12 -07004062 }
4063
Eric Anholt673a3942008-07-30 12:06:12 -07004064 mutex_lock(&dev->struct_mutex);
Eric Anholt9bb2d6f2008-12-23 18:42:32 -08004065 dev_priv->mm.suspended = 0;
4066
Daniel Vetterf691e2f2012-02-02 09:58:12 +01004067 ret = i915_gem_init_hw(dev);
Wu Fengguangd816f6a2009-04-18 10:43:32 +08004068 if (ret != 0) {
4069 mutex_unlock(&dev->struct_mutex);
Eric Anholt9bb2d6f2008-12-23 18:42:32 -08004070 return ret;
Wu Fengguangd816f6a2009-04-18 10:43:32 +08004071 }
Eric Anholt9bb2d6f2008-12-23 18:42:32 -08004072
Chris Wilson69dc4982010-10-19 10:36:51 +01004073 BUG_ON(!list_empty(&dev_priv->mm.active_list));
Eric Anholt673a3942008-07-30 12:06:12 -07004074 BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
Eric Anholt673a3942008-07-30 12:06:12 -07004075 mutex_unlock(&dev->struct_mutex);
Kristian Høgsbergdbb19d32008-08-20 11:04:27 -04004076
Chris Wilson5f353082010-06-07 14:03:03 +01004077 ret = drm_irq_install(dev);
4078 if (ret)
4079 goto cleanup_ringbuffer;
Kristian Høgsbergdbb19d32008-08-20 11:04:27 -04004080
Eric Anholt673a3942008-07-30 12:06:12 -07004081 return 0;
Chris Wilson5f353082010-06-07 14:03:03 +01004082
4083cleanup_ringbuffer:
4084 mutex_lock(&dev->struct_mutex);
4085 i915_gem_cleanup_ringbuffer(dev);
4086 dev_priv->mm.suspended = 1;
4087 mutex_unlock(&dev->struct_mutex);
4088
4089 return ret;
Eric Anholt673a3942008-07-30 12:06:12 -07004090}
4091
4092int
4093i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
4094 struct drm_file *file_priv)
4095{
Jesse Barnes79e53942008-11-07 14:24:08 -08004096 if (drm_core_check_feature(dev, DRIVER_MODESET))
4097 return 0;
4098
Kristian Høgsbergdbb19d32008-08-20 11:04:27 -04004099 drm_irq_uninstall(dev);
Linus Torvaldse6890f62009-09-08 17:09:24 -07004100 return i915_gem_idle(dev);
Eric Anholt673a3942008-07-30 12:06:12 -07004101}
4102
4103void
4104i915_gem_lastclose(struct drm_device *dev)
4105{
4106 int ret;
Eric Anholt673a3942008-07-30 12:06:12 -07004107
Eric Anholte806b492009-01-22 09:56:58 -08004108 if (drm_core_check_feature(dev, DRIVER_MODESET))
4109 return;
4110
Keith Packard6dbe2772008-10-14 21:41:13 -07004111 ret = i915_gem_idle(dev);
4112 if (ret)
4113 DRM_ERROR("failed to idle hardware: %d\n", ret);
Eric Anholt673a3942008-07-30 12:06:12 -07004114}
4115
Chris Wilson64193402010-10-24 12:38:05 +01004116static void
4117init_ring_lists(struct intel_ring_buffer *ring)
4118{
4119 INIT_LIST_HEAD(&ring->active_list);
4120 INIT_LIST_HEAD(&ring->request_list);
Chris Wilson64193402010-10-24 12:38:05 +01004121}
4122
Eric Anholt673a3942008-07-30 12:06:12 -07004123void
4124i915_gem_load(struct drm_device *dev)
4125{
Grégoire Henryb5aa8a02009-06-23 15:41:02 +02004126 int i;
Eric Anholt673a3942008-07-30 12:06:12 -07004127 drm_i915_private_t *dev_priv = dev->dev_private;
4128
Chris Wilson69dc4982010-10-19 10:36:51 +01004129 INIT_LIST_HEAD(&dev_priv->mm.active_list);
Eric Anholt673a3942008-07-30 12:06:12 -07004130 INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
Chris Wilson6c085a72012-08-20 11:40:46 +02004131 INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
4132 INIT_LIST_HEAD(&dev_priv->mm.bound_list);
Eric Anholta09ba7f2009-08-29 12:49:51 -07004133 INIT_LIST_HEAD(&dev_priv->mm.fence_list);
Chris Wilson1ec14ad2010-12-04 11:30:53 +00004134 for (i = 0; i < I915_NUM_RINGS; i++)
4135 init_ring_lists(&dev_priv->ring[i]);
Daniel Vetter4b9de732011-10-09 21:52:02 +02004136 for (i = 0; i < I915_MAX_NUM_FENCES; i++)
Daniel Vetter007cc8a2010-04-28 11:02:31 +02004137 INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
Eric Anholt673a3942008-07-30 12:06:12 -07004138 INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
4139 i915_gem_retire_work_handler);
Chris Wilson30dbf0c2010-09-25 10:19:17 +01004140 init_completion(&dev_priv->error_completion);
Chris Wilson31169712009-09-14 16:50:28 +01004141
Dave Airlie94400122010-07-20 13:15:31 +10004142 /* On GEN3 we really need to make sure the ARB C3 LP bit is set */
4143 if (IS_GEN3(dev)) {
Daniel Vetter50743292012-04-26 22:02:54 +02004144 I915_WRITE(MI_ARB_STATE,
4145 _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE));
Dave Airlie94400122010-07-20 13:15:31 +10004146 }
4147
Chris Wilson72bfa192010-12-19 11:42:05 +00004148 dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL;
4149
Jesse Barnesde151cf2008-11-12 10:03:55 -08004150 /* Old X drivers will take 0-2 for front, back, depth buffers */
Eric Anholtb397c832010-01-26 09:43:10 -08004151 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4152 dev_priv->fence_reg_start = 3;
Jesse Barnesde151cf2008-11-12 10:03:55 -08004153
Chris Wilsona6c45cf2010-09-17 00:32:17 +01004154 if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
Jesse Barnesde151cf2008-11-12 10:03:55 -08004155 dev_priv->num_fence_regs = 16;
4156 else
4157 dev_priv->num_fence_regs = 8;
4158
Grégoire Henryb5aa8a02009-06-23 15:41:02 +02004159 /* Initialize fence registers to zero */
Chris Wilsonada726c2012-04-17 15:31:32 +01004160 i915_gem_reset_fences(dev);
Eric Anholt10ed13e2011-05-06 13:53:49 -07004161
Eric Anholt673a3942008-07-30 12:06:12 -07004162 i915_gem_detect_bit_6_swizzle(dev);
Kristian Høgsberg6b95a202009-11-18 11:25:18 -05004163 init_waitqueue_head(&dev_priv->pending_flip_queue);
Chris Wilson17250b72010-10-28 12:51:39 +01004164
Chris Wilsonce453d82011-02-21 14:43:56 +00004165 dev_priv->mm.interruptible = true;
4166
Chris Wilson17250b72010-10-28 12:51:39 +01004167 dev_priv->mm.inactive_shrinker.shrink = i915_gem_inactive_shrink;
4168 dev_priv->mm.inactive_shrinker.seeks = DEFAULT_SEEKS;
4169 register_shrinker(&dev_priv->mm.inactive_shrinker);
Eric Anholt673a3942008-07-30 12:06:12 -07004170}
Dave Airlie71acb5e2008-12-30 20:31:46 +10004171
4172/*
4173 * Create a physically contiguous memory object for this object
4174 * e.g. for cursor + overlay regs
4175 */
Chris Wilson995b6762010-08-20 13:23:26 +01004176static int i915_gem_init_phys_object(struct drm_device *dev,
4177 int id, int size, int align)
Dave Airlie71acb5e2008-12-30 20:31:46 +10004178{
4179 drm_i915_private_t *dev_priv = dev->dev_private;
4180 struct drm_i915_gem_phys_object *phys_obj;
4181 int ret;
4182
4183 if (dev_priv->mm.phys_objs[id - 1] || !size)
4184 return 0;
4185
Eric Anholt9a298b22009-03-24 12:23:04 -07004186 phys_obj = kzalloc(sizeof(struct drm_i915_gem_phys_object), GFP_KERNEL);
Dave Airlie71acb5e2008-12-30 20:31:46 +10004187 if (!phys_obj)
4188 return -ENOMEM;
4189
4190 phys_obj->id = id;
4191
Chris Wilson6eeefaf2010-08-07 11:01:39 +01004192 phys_obj->handle = drm_pci_alloc(dev, size, align);
Dave Airlie71acb5e2008-12-30 20:31:46 +10004193 if (!phys_obj->handle) {
4194 ret = -ENOMEM;
4195 goto kfree_obj;
4196 }
4197#ifdef CONFIG_X86
4198 set_memory_wc((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE);
4199#endif
4200
4201 dev_priv->mm.phys_objs[id - 1] = phys_obj;
4202
4203 return 0;
4204kfree_obj:
Eric Anholt9a298b22009-03-24 12:23:04 -07004205 kfree(phys_obj);
Dave Airlie71acb5e2008-12-30 20:31:46 +10004206 return ret;
4207}
4208
Chris Wilson995b6762010-08-20 13:23:26 +01004209static void i915_gem_free_phys_object(struct drm_device *dev, int id)
Dave Airlie71acb5e2008-12-30 20:31:46 +10004210{
4211 drm_i915_private_t *dev_priv = dev->dev_private;
4212 struct drm_i915_gem_phys_object *phys_obj;
4213
4214 if (!dev_priv->mm.phys_objs[id - 1])
4215 return;
4216
4217 phys_obj = dev_priv->mm.phys_objs[id - 1];
4218 if (phys_obj->cur_obj) {
4219 i915_gem_detach_phys_object(dev, phys_obj->cur_obj);
4220 }
4221
4222#ifdef CONFIG_X86
4223 set_memory_wb((unsigned long)phys_obj->handle->vaddr, phys_obj->handle->size / PAGE_SIZE);
4224#endif
4225 drm_pci_free(dev, phys_obj->handle);
4226 kfree(phys_obj);
4227 dev_priv->mm.phys_objs[id - 1] = NULL;
4228}
4229
4230void i915_gem_free_all_phys_object(struct drm_device *dev)
4231{
4232 int i;
4233
Dave Airlie260883c2009-01-22 17:58:49 +10004234 for (i = I915_GEM_PHYS_CURSOR_0; i <= I915_MAX_PHYS_OBJECT; i++)
Dave Airlie71acb5e2008-12-30 20:31:46 +10004235 i915_gem_free_phys_object(dev, i);
4236}
4237
4238void i915_gem_detach_phys_object(struct drm_device *dev,
Chris Wilson05394f32010-11-08 19:18:58 +00004239 struct drm_i915_gem_object *obj)
Dave Airlie71acb5e2008-12-30 20:31:46 +10004240{
Chris Wilson05394f32010-11-08 19:18:58 +00004241 struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
Chris Wilsone5281cc2010-10-28 13:45:36 +01004242 char *vaddr;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004243 int i;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004244 int page_count;
4245
Chris Wilson05394f32010-11-08 19:18:58 +00004246 if (!obj->phys_obj)
Dave Airlie71acb5e2008-12-30 20:31:46 +10004247 return;
Chris Wilson05394f32010-11-08 19:18:58 +00004248 vaddr = obj->phys_obj->handle->vaddr;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004249
Chris Wilson05394f32010-11-08 19:18:58 +00004250 page_count = obj->base.size / PAGE_SIZE;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004251 for (i = 0; i < page_count; i++) {
Hugh Dickins5949eac2011-06-27 16:18:18 -07004252 struct page *page = shmem_read_mapping_page(mapping, i);
Chris Wilsone5281cc2010-10-28 13:45:36 +01004253 if (!IS_ERR(page)) {
4254 char *dst = kmap_atomic(page);
4255 memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE);
4256 kunmap_atomic(dst);
Dave Airlie71acb5e2008-12-30 20:31:46 +10004257
Chris Wilsone5281cc2010-10-28 13:45:36 +01004258 drm_clflush_pages(&page, 1);
4259
4260 set_page_dirty(page);
4261 mark_page_accessed(page);
4262 page_cache_release(page);
4263 }
Dave Airlie71acb5e2008-12-30 20:31:46 +10004264 }
Daniel Vetter40ce6572010-11-05 18:12:18 +01004265 intel_gtt_chipset_flush();
Chris Wilsond78b47b2009-06-17 21:52:49 +01004266
Chris Wilson05394f32010-11-08 19:18:58 +00004267 obj->phys_obj->cur_obj = NULL;
4268 obj->phys_obj = NULL;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004269}
4270
4271int
4272i915_gem_attach_phys_object(struct drm_device *dev,
Chris Wilson05394f32010-11-08 19:18:58 +00004273 struct drm_i915_gem_object *obj,
Chris Wilson6eeefaf2010-08-07 11:01:39 +01004274 int id,
4275 int align)
Dave Airlie71acb5e2008-12-30 20:31:46 +10004276{
Chris Wilson05394f32010-11-08 19:18:58 +00004277 struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004278 drm_i915_private_t *dev_priv = dev->dev_private;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004279 int ret = 0;
4280 int page_count;
4281 int i;
4282
4283 if (id > I915_MAX_PHYS_OBJECT)
4284 return -EINVAL;
4285
Chris Wilson05394f32010-11-08 19:18:58 +00004286 if (obj->phys_obj) {
4287 if (obj->phys_obj->id == id)
Dave Airlie71acb5e2008-12-30 20:31:46 +10004288 return 0;
4289 i915_gem_detach_phys_object(dev, obj);
4290 }
4291
Dave Airlie71acb5e2008-12-30 20:31:46 +10004292 /* create a new object */
4293 if (!dev_priv->mm.phys_objs[id - 1]) {
4294 ret = i915_gem_init_phys_object(dev, id,
Chris Wilson05394f32010-11-08 19:18:58 +00004295 obj->base.size, align);
Dave Airlie71acb5e2008-12-30 20:31:46 +10004296 if (ret) {
Chris Wilson05394f32010-11-08 19:18:58 +00004297 DRM_ERROR("failed to init phys object %d size: %zu\n",
4298 id, obj->base.size);
Chris Wilsone5281cc2010-10-28 13:45:36 +01004299 return ret;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004300 }
4301 }
4302
4303 /* bind to the object */
Chris Wilson05394f32010-11-08 19:18:58 +00004304 obj->phys_obj = dev_priv->mm.phys_objs[id - 1];
4305 obj->phys_obj->cur_obj = obj;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004306
Chris Wilson05394f32010-11-08 19:18:58 +00004307 page_count = obj->base.size / PAGE_SIZE;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004308
4309 for (i = 0; i < page_count; i++) {
Chris Wilsone5281cc2010-10-28 13:45:36 +01004310 struct page *page;
4311 char *dst, *src;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004312
Hugh Dickins5949eac2011-06-27 16:18:18 -07004313 page = shmem_read_mapping_page(mapping, i);
Chris Wilsone5281cc2010-10-28 13:45:36 +01004314 if (IS_ERR(page))
4315 return PTR_ERR(page);
4316
Chris Wilsonff75b9b2010-10-30 22:52:31 +01004317 src = kmap_atomic(page);
Chris Wilson05394f32010-11-08 19:18:58 +00004318 dst = obj->phys_obj->handle->vaddr + (i * PAGE_SIZE);
Dave Airlie71acb5e2008-12-30 20:31:46 +10004319 memcpy(dst, src, PAGE_SIZE);
Peter Zijlstra3e4d3af2010-10-26 14:21:51 -07004320 kunmap_atomic(src);
Chris Wilsone5281cc2010-10-28 13:45:36 +01004321
4322 mark_page_accessed(page);
4323 page_cache_release(page);
Dave Airlie71acb5e2008-12-30 20:31:46 +10004324 }
4325
4326 return 0;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004327}
4328
4329static int
Chris Wilson05394f32010-11-08 19:18:58 +00004330i915_gem_phys_pwrite(struct drm_device *dev,
4331 struct drm_i915_gem_object *obj,
Dave Airlie71acb5e2008-12-30 20:31:46 +10004332 struct drm_i915_gem_pwrite *args,
4333 struct drm_file *file_priv)
4334{
Chris Wilson05394f32010-11-08 19:18:58 +00004335 void *vaddr = obj->phys_obj->handle->vaddr + args->offset;
Chris Wilsonb47b30c2010-11-08 01:12:29 +00004336 char __user *user_data = (char __user *) (uintptr_t) args->data_ptr;
Dave Airlie71acb5e2008-12-30 20:31:46 +10004337
Chris Wilsonb47b30c2010-11-08 01:12:29 +00004338 if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) {
4339 unsigned long unwritten;
4340
4341 /* The physical object once assigned is fixed for the lifetime
4342 * of the obj, so we can safely drop the lock and continue
4343 * to access vaddr.
4344 */
4345 mutex_unlock(&dev->struct_mutex);
4346 unwritten = copy_from_user(vaddr, user_data, args->size);
4347 mutex_lock(&dev->struct_mutex);
4348 if (unwritten)
4349 return -EFAULT;
4350 }
Dave Airlie71acb5e2008-12-30 20:31:46 +10004351
Daniel Vetter40ce6572010-11-05 18:12:18 +01004352 intel_gtt_chipset_flush();
Dave Airlie71acb5e2008-12-30 20:31:46 +10004353 return 0;
4354}
Eric Anholtb9624422009-06-03 07:27:35 +00004355
Chris Wilsonf787a5f2010-09-24 16:02:42 +01004356void i915_gem_release(struct drm_device *dev, struct drm_file *file)
Eric Anholtb9624422009-06-03 07:27:35 +00004357{
Chris Wilsonf787a5f2010-09-24 16:02:42 +01004358 struct drm_i915_file_private *file_priv = file->driver_priv;
Eric Anholtb9624422009-06-03 07:27:35 +00004359
4360 /* Clean up our request list when the client is going away, so that
4361 * later retire_requests won't dereference our soon-to-be-gone
4362 * file_priv.
4363 */
Chris Wilson1c255952010-09-26 11:03:27 +01004364 spin_lock(&file_priv->mm.lock);
Chris Wilsonf787a5f2010-09-24 16:02:42 +01004365 while (!list_empty(&file_priv->mm.request_list)) {
4366 struct drm_i915_gem_request *request;
4367
4368 request = list_first_entry(&file_priv->mm.request_list,
4369 struct drm_i915_gem_request,
4370 client_list);
4371 list_del(&request->client_list);
4372 request->file_priv = NULL;
4373 }
Chris Wilson1c255952010-09-26 11:03:27 +01004374 spin_unlock(&file_priv->mm.lock);
Eric Anholtb9624422009-06-03 07:27:35 +00004375}
Chris Wilson31169712009-09-14 16:50:28 +01004376
Chris Wilson31169712009-09-14 16:50:28 +01004377static int
Ying Han1495f232011-05-24 17:12:27 -07004378i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
Chris Wilson31169712009-09-14 16:50:28 +01004379{
Chris Wilson17250b72010-10-28 12:51:39 +01004380 struct drm_i915_private *dev_priv =
4381 container_of(shrinker,
4382 struct drm_i915_private,
4383 mm.inactive_shrinker);
4384 struct drm_device *dev = dev_priv->dev;
Chris Wilson6c085a72012-08-20 11:40:46 +02004385 struct drm_i915_gem_object *obj;
Ying Han1495f232011-05-24 17:12:27 -07004386 int nr_to_scan = sc->nr_to_scan;
Chris Wilson17250b72010-10-28 12:51:39 +01004387 int cnt;
4388
4389 if (!mutex_trylock(&dev->struct_mutex))
Chris Wilsonbbe2e112010-10-28 22:35:07 +01004390 return 0;
Chris Wilson31169712009-09-14 16:50:28 +01004391
Chris Wilson6c085a72012-08-20 11:40:46 +02004392 if (nr_to_scan) {
4393 nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
4394 if (nr_to_scan > 0)
4395 i915_gem_shrink_all(dev_priv);
Chris Wilson31169712009-09-14 16:50:28 +01004396 }
4397
Chris Wilson17250b72010-10-28 12:51:39 +01004398 cnt = 0;
Chris Wilson6c085a72012-08-20 11:40:46 +02004399 list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
Chris Wilsona5570172012-09-04 21:02:54 +01004400 if (obj->pages_pin_count == 0)
4401 cnt += obj->base.size >> PAGE_SHIFT;
Chris Wilson6c085a72012-08-20 11:40:46 +02004402 list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
Chris Wilsona5570172012-09-04 21:02:54 +01004403 if (obj->pin_count == 0 && obj->pages_pin_count == 0)
Chris Wilson6c085a72012-08-20 11:40:46 +02004404 cnt += obj->base.size >> PAGE_SHIFT;
Chris Wilson31169712009-09-14 16:50:28 +01004405
Chris Wilson17250b72010-10-28 12:51:39 +01004406 mutex_unlock(&dev->struct_mutex);
Chris Wilson6c085a72012-08-20 11:40:46 +02004407 return cnt;
Chris Wilson31169712009-09-14 16:50:28 +01004408}