drm/i915: Extract i915_gem_fence.c
[linux-2.6-block.git] / drivers / gpu / drm / i915 / i915_gem_fence.c
1 /*
2  * Copyright © 2008-2015 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
24 #include <drm/drmP.h>
25 #include <drm/i915_drm.h>
26 #include "i915_drv.h"
27
28 static void i965_write_fence_reg(struct drm_device *dev, int reg,
29                                  struct drm_i915_gem_object *obj)
30 {
31         struct drm_i915_private *dev_priv = dev->dev_private;
32         int fence_reg;
33         int fence_pitch_shift;
34
35         if (INTEL_INFO(dev)->gen >= 6) {
36                 fence_reg = FENCE_REG_SANDYBRIDGE_0;
37                 fence_pitch_shift = SANDYBRIDGE_FENCE_PITCH_SHIFT;
38         } else {
39                 fence_reg = FENCE_REG_965_0;
40                 fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
41         }
42
43         fence_reg += reg * 8;
44
45         /* To w/a incoherency with non-atomic 64-bit register updates,
46          * we split the 64-bit update into two 32-bit writes. In order
47          * for a partial fence not to be evaluated between writes, we
48          * precede the update with write to turn off the fence register,
49          * and only enable the fence as the last step.
50          *
51          * For extra levels of paranoia, we make sure each step lands
52          * before applying the next step.
53          */
54         I915_WRITE(fence_reg, 0);
55         POSTING_READ(fence_reg);
56
57         if (obj) {
58                 u32 size = i915_gem_obj_ggtt_size(obj);
59                 uint64_t val;
60
61                 /* Adjust fence size to match tiled area */
62                 if (obj->tiling_mode != I915_TILING_NONE) {
63                         uint32_t row_size = obj->stride *
64                                 (obj->tiling_mode == I915_TILING_Y ? 32 : 8);
65                         size = (size / row_size) * row_size;
66                 }
67
68                 val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) &
69                                  0xfffff000) << 32;
70                 val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
71                 val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift;
72                 if (obj->tiling_mode == I915_TILING_Y)
73                         val |= 1 << I965_FENCE_TILING_Y_SHIFT;
74                 val |= I965_FENCE_REG_VALID;
75
76                 I915_WRITE(fence_reg + 4, val >> 32);
77                 POSTING_READ(fence_reg + 4);
78
79                 I915_WRITE(fence_reg + 0, val);
80                 POSTING_READ(fence_reg);
81         } else {
82                 I915_WRITE(fence_reg + 4, 0);
83                 POSTING_READ(fence_reg + 4);
84         }
85 }
86
87 static void i915_write_fence_reg(struct drm_device *dev, int reg,
88                                  struct drm_i915_gem_object *obj)
89 {
90         struct drm_i915_private *dev_priv = dev->dev_private;
91         u32 val;
92
93         if (obj) {
94                 u32 size = i915_gem_obj_ggtt_size(obj);
95                 int pitch_val;
96                 int tile_width;
97
98                 WARN((i915_gem_obj_ggtt_offset(obj) & ~I915_FENCE_START_MASK) ||
99                      (size & -size) != size ||
100                      (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
101                      "object 0x%08lx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
102                      i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size);
103
104                 if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
105                         tile_width = 128;
106                 else
107                         tile_width = 512;
108
109                 /* Note: pitch better be a power of two tile widths */
110                 pitch_val = obj->stride / tile_width;
111                 pitch_val = ffs(pitch_val) - 1;
112
113                 val = i915_gem_obj_ggtt_offset(obj);
114                 if (obj->tiling_mode == I915_TILING_Y)
115                         val |= 1 << I830_FENCE_TILING_Y_SHIFT;
116                 val |= I915_FENCE_SIZE_BITS(size);
117                 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
118                 val |= I830_FENCE_REG_VALID;
119         } else
120                 val = 0;
121
122         if (reg < 8)
123                 reg = FENCE_REG_830_0 + reg * 4;
124         else
125                 reg = FENCE_REG_945_8 + (reg - 8) * 4;
126
127         I915_WRITE(reg, val);
128         POSTING_READ(reg);
129 }
130
131 static void i830_write_fence_reg(struct drm_device *dev, int reg,
132                                 struct drm_i915_gem_object *obj)
133 {
134         struct drm_i915_private *dev_priv = dev->dev_private;
135         uint32_t val;
136
137         if (obj) {
138                 u32 size = i915_gem_obj_ggtt_size(obj);
139                 uint32_t pitch_val;
140
141                 WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) ||
142                      (size & -size) != size ||
143                      (i915_gem_obj_ggtt_offset(obj) & (size - 1)),
144                      "object 0x%08lx not 512K or pot-size 0x%08x aligned\n",
145                      i915_gem_obj_ggtt_offset(obj), size);
146
147                 pitch_val = obj->stride / 128;
148                 pitch_val = ffs(pitch_val) - 1;
149
150                 val = i915_gem_obj_ggtt_offset(obj);
151                 if (obj->tiling_mode == I915_TILING_Y)
152                         val |= 1 << I830_FENCE_TILING_Y_SHIFT;
153                 val |= I830_FENCE_SIZE_BITS(size);
154                 val |= pitch_val << I830_FENCE_PITCH_SHIFT;
155                 val |= I830_FENCE_REG_VALID;
156         } else
157                 val = 0;
158
159         I915_WRITE(FENCE_REG_830_0 + reg * 4, val);
160         POSTING_READ(FENCE_REG_830_0 + reg * 4);
161 }
162
163 inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj)
164 {
165         return obj && obj->base.read_domains & I915_GEM_DOMAIN_GTT;
166 }
167
168 static void i915_gem_write_fence(struct drm_device *dev, int reg,
169                                  struct drm_i915_gem_object *obj)
170 {
171         struct drm_i915_private *dev_priv = dev->dev_private;
172
173         /* Ensure that all CPU reads are completed before installing a fence
174          * and all writes before removing the fence.
175          */
176         if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj))
177                 mb();
178
179         WARN(obj && (!obj->stride || !obj->tiling_mode),
180              "bogus fence setup with stride: 0x%x, tiling mode: %i\n",
181              obj->stride, obj->tiling_mode);
182
183         if (IS_GEN2(dev))
184                 i830_write_fence_reg(dev, reg, obj);
185         else if (IS_GEN3(dev))
186                 i915_write_fence_reg(dev, reg, obj);
187         else if (INTEL_INFO(dev)->gen >= 4)
188                 i965_write_fence_reg(dev, reg, obj);
189
190         /* And similarly be paranoid that no direct access to this region
191          * is reordered to before the fence is installed.
192          */
193         if (i915_gem_object_needs_mb(obj))
194                 mb();
195 }
196
197 static inline int fence_number(struct drm_i915_private *dev_priv,
198                                struct drm_i915_fence_reg *fence)
199 {
200         return fence - dev_priv->fence_regs;
201 }
202
203 static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
204                                          struct drm_i915_fence_reg *fence,
205                                          bool enable)
206 {
207         struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
208         int reg = fence_number(dev_priv, fence);
209
210         i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
211
212         if (enable) {
213                 obj->fence_reg = reg;
214                 fence->obj = obj;
215                 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
216         } else {
217                 obj->fence_reg = I915_FENCE_REG_NONE;
218                 fence->obj = NULL;
219                 list_del_init(&fence->lru_list);
220         }
221         obj->fence_dirty = false;
222 }
223
224 static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
225 {
226         if (obj->tiling_mode)
227                 i915_gem_release_mmap(obj);
228
229         /* As we do not have an associated fence register, we will force
230          * a tiling change if we ever need to acquire one.
231          */
232         obj->fence_dirty = false;
233         obj->fence_reg = I915_FENCE_REG_NONE;
234 }
235
236 static int
237 i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
238 {
239         if (obj->last_fenced_req) {
240                 int ret = i915_wait_request(obj->last_fenced_req);
241                 if (ret)
242                         return ret;
243
244                 i915_gem_request_assign(&obj->last_fenced_req, NULL);
245         }
246
247         return 0;
248 }
249
250 int
251 i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
252 {
253         struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
254         struct drm_i915_fence_reg *fence;
255         int ret;
256
257         ret = i915_gem_object_wait_fence(obj);
258         if (ret)
259                 return ret;
260
261         if (obj->fence_reg == I915_FENCE_REG_NONE)
262                 return 0;
263
264         fence = &dev_priv->fence_regs[obj->fence_reg];
265
266         if (WARN_ON(fence->pin_count))
267                 return -EBUSY;
268
269         i915_gem_object_fence_lost(obj);
270         i915_gem_object_update_fence(obj, fence, false);
271
272         return 0;
273 }
274
275 static struct drm_i915_fence_reg *
276 i915_find_fence_reg(struct drm_device *dev)
277 {
278         struct drm_i915_private *dev_priv = dev->dev_private;
279         struct drm_i915_fence_reg *reg, *avail;
280         int i;
281
282         /* First try to find a free reg */
283         avail = NULL;
284         for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
285                 reg = &dev_priv->fence_regs[i];
286                 if (!reg->obj)
287                         return reg;
288
289                 if (!reg->pin_count)
290                         avail = reg;
291         }
292
293         if (avail == NULL)
294                 goto deadlock;
295
296         /* None available, try to steal one or wait for a user to finish */
297         list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) {
298                 if (reg->pin_count)
299                         continue;
300
301                 return reg;
302         }
303
304 deadlock:
305         /* Wait for completion of pending flips which consume fences */
306         if (intel_has_pending_fb_unpin(dev))
307                 return ERR_PTR(-EAGAIN);
308
309         return ERR_PTR(-EDEADLK);
310 }
311
312 /**
313  * i915_gem_object_get_fence - set up fencing for an object
314  * @obj: object to map through a fence reg
315  *
316  * When mapping objects through the GTT, userspace wants to be able to write
317  * to them without having to worry about swizzling if the object is tiled.
318  * This function walks the fence regs looking for a free one for @obj,
319  * stealing one if it can't find any.
320  *
321  * It then sets up the reg based on the object's properties: address, pitch
322  * and tiling format.
323  *
324  * For an untiled surface, this removes any existing fence.
325  */
326 int
327 i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
328 {
329         struct drm_device *dev = obj->base.dev;
330         struct drm_i915_private *dev_priv = dev->dev_private;
331         bool enable = obj->tiling_mode != I915_TILING_NONE;
332         struct drm_i915_fence_reg *reg;
333         int ret;
334
335         /* Have we updated the tiling parameters upon the object and so
336          * will need to serialise the write to the associated fence register?
337          */
338         if (obj->fence_dirty) {
339                 ret = i915_gem_object_wait_fence(obj);
340                 if (ret)
341                         return ret;
342         }
343
344         /* Just update our place in the LRU if our fence is getting reused. */
345         if (obj->fence_reg != I915_FENCE_REG_NONE) {
346                 reg = &dev_priv->fence_regs[obj->fence_reg];
347                 if (!obj->fence_dirty) {
348                         list_move_tail(&reg->lru_list,
349                                        &dev_priv->mm.fence_list);
350                         return 0;
351                 }
352         } else if (enable) {
353                 if (WARN_ON(!obj->map_and_fenceable))
354                         return -EINVAL;
355
356                 reg = i915_find_fence_reg(dev);
357                 if (IS_ERR(reg))
358                         return PTR_ERR(reg);
359
360                 if (reg->obj) {
361                         struct drm_i915_gem_object *old = reg->obj;
362
363                         ret = i915_gem_object_wait_fence(old);
364                         if (ret)
365                                 return ret;
366
367                         i915_gem_object_fence_lost(old);
368                 }
369         } else
370                 return 0;
371
372         i915_gem_object_update_fence(obj, reg, enable);
373
374         return 0;
375 }
376
377 bool
378 i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
379 {
380         if (obj->fence_reg != I915_FENCE_REG_NONE) {
381                 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
382                 struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj);
383
384                 WARN_ON(!ggtt_vma ||
385                         dev_priv->fence_regs[obj->fence_reg].pin_count >
386                         ggtt_vma->pin_count);
387                 dev_priv->fence_regs[obj->fence_reg].pin_count++;
388                 return true;
389         } else
390                 return false;
391 }
392
393 void
394 i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
395 {
396         if (obj->fence_reg != I915_FENCE_REG_NONE) {
397                 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
398                 WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count <= 0);
399                 dev_priv->fence_regs[obj->fence_reg].pin_count--;
400         }
401 }
402
403 void i915_gem_restore_fences(struct drm_device *dev)
404 {
405         struct drm_i915_private *dev_priv = dev->dev_private;
406         int i;
407
408         for (i = 0; i < dev_priv->num_fence_regs; i++) {
409                 struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
410
411                 /*
412                  * Commit delayed tiling changes if we have an object still
413                  * attached to the fence, otherwise just clear the fence.
414                  */
415                 if (reg->obj) {
416                         i915_gem_object_update_fence(reg->obj, reg,
417                                                      reg->obj->tiling_mode);
418                 } else {
419                         i915_gem_write_fence(dev, i, NULL);
420                 }
421         }
422 }