aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c430
1 files changed, 208 insertions, 222 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ec8a0d7ffa39..fba37e9f775d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -128,9 +128,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
128 return -ENOMEM; 128 return -ENOMEM;
129 129
130 ret = drm_gem_handle_create(file_priv, obj, &handle); 130 ret = drm_gem_handle_create(file_priv, obj, &handle);
131 mutex_lock(&dev->struct_mutex); 131 drm_gem_object_handle_unreference_unlocked(obj);
132 drm_gem_object_handle_unreference(obj);
133 mutex_unlock(&dev->struct_mutex);
134 132
135 if (ret) 133 if (ret)
136 return ret; 134 return ret;
@@ -488,7 +486,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
488 */ 486 */
489 if (args->offset > obj->size || args->size > obj->size || 487 if (args->offset > obj->size || args->size > obj->size ||
490 args->offset + args->size > obj->size) { 488 args->offset + args->size > obj->size) {
491 drm_gem_object_unreference(obj); 489 drm_gem_object_unreference_unlocked(obj);
492 return -EINVAL; 490 return -EINVAL;
493 } 491 }
494 492
@@ -501,7 +499,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
501 file_priv); 499 file_priv);
502 } 500 }
503 501
504 drm_gem_object_unreference(obj); 502 drm_gem_object_unreference_unlocked(obj);
505 503
506 return ret; 504 return ret;
507} 505}
@@ -961,7 +959,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
961 */ 959 */
962 if (args->offset > obj->size || args->size > obj->size || 960 if (args->offset > obj->size || args->size > obj->size ||
963 args->offset + args->size > obj->size) { 961 args->offset + args->size > obj->size) {
964 drm_gem_object_unreference(obj); 962 drm_gem_object_unreference_unlocked(obj);
965 return -EINVAL; 963 return -EINVAL;
966 } 964 }
967 965
@@ -995,7 +993,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
995 DRM_INFO("pwrite failed %d\n", ret); 993 DRM_INFO("pwrite failed %d\n", ret);
996#endif 994#endif
997 995
998 drm_gem_object_unreference(obj); 996 drm_gem_object_unreference_unlocked(obj);
999 997
1000 return ret; 998 return ret;
1001} 999}
@@ -1138,9 +1136,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1138 PROT_READ | PROT_WRITE, MAP_SHARED, 1136 PROT_READ | PROT_WRITE, MAP_SHARED,
1139 args->offset); 1137 args->offset);
1140 up_write(&current->mm->mmap_sem); 1138 up_write(&current->mm->mmap_sem);
1141 mutex_lock(&dev->struct_mutex); 1139 drm_gem_object_unreference_unlocked(obj);
1142 drm_gem_object_unreference(obj);
1143 mutex_unlock(&dev->struct_mutex);
1144 if (IS_ERR((void *)addr)) 1140 if (IS_ERR((void *)addr))
1145 return addr; 1141 return addr;
1146 1142
@@ -1562,6 +1558,38 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
1562 i915_verify_inactive(dev, __FILE__, __LINE__); 1558 i915_verify_inactive(dev, __FILE__, __LINE__);
1563} 1559}
1564 1560
1561static void
1562i915_gem_process_flushing_list(struct drm_device *dev,
1563 uint32_t flush_domains, uint32_t seqno)
1564{
1565 drm_i915_private_t *dev_priv = dev->dev_private;
1566 struct drm_i915_gem_object *obj_priv, *next;
1567
1568 list_for_each_entry_safe(obj_priv, next,
1569 &dev_priv->mm.gpu_write_list,
1570 gpu_write_list) {
1571 struct drm_gem_object *obj = obj_priv->obj;
1572
1573 if ((obj->write_domain & flush_domains) ==
1574 obj->write_domain) {
1575 uint32_t old_write_domain = obj->write_domain;
1576
1577 obj->write_domain = 0;
1578 list_del_init(&obj_priv->gpu_write_list);
1579 i915_gem_object_move_to_active(obj, seqno);
1580
1581 /* update the fence lru list */
1582 if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
1583 list_move_tail(&obj_priv->fence_list,
1584 &dev_priv->mm.fence_list);
1585
1586 trace_i915_gem_object_change_domain(obj,
1587 obj->read_domains,
1588 old_write_domain);
1589 }
1590 }
1591}
1592
1565/** 1593/**
1566 * Creates a new sequence number, emitting a write of it to the status page 1594 * Creates a new sequence number, emitting a write of it to the status page
1567 * plus an interrupt, which will trigger i915_user_interrupt_handler. 1595 * plus an interrupt, which will trigger i915_user_interrupt_handler.
@@ -1620,29 +1648,8 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
1620 /* Associate any objects on the flushing list matching the write 1648 /* Associate any objects on the flushing list matching the write
1621 * domain we're flushing with our flush. 1649 * domain we're flushing with our flush.
1622 */ 1650 */
1623 if (flush_domains != 0) { 1651 if (flush_domains != 0)
1624 struct drm_i915_gem_object *obj_priv, *next; 1652 i915_gem_process_flushing_list(dev, flush_domains, seqno);
1625
1626 list_for_each_entry_safe(obj_priv, next,
1627 &dev_priv->mm.gpu_write_list,
1628 gpu_write_list) {
1629 struct drm_gem_object *obj = obj_priv->obj;
1630
1631 if ((obj->write_domain & flush_domains) ==
1632 obj->write_domain) {
1633 uint32_t old_write_domain = obj->write_domain;
1634
1635 obj->write_domain = 0;
1636 list_del_init(&obj_priv->gpu_write_list);
1637 i915_gem_object_move_to_active(obj, seqno);
1638
1639 trace_i915_gem_object_change_domain(obj,
1640 obj->read_domains,
1641 old_write_domain);
1642 }
1643 }
1644
1645 }
1646 1653
1647 if (!dev_priv->mm.suspended) { 1654 if (!dev_priv->mm.suspended) {
1648 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); 1655 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
@@ -1822,7 +1829,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
1822 return -EIO; 1829 return -EIO;
1823 1830
1824 if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { 1831 if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
1825 if (IS_IRONLAKE(dev)) 1832 if (HAS_PCH_SPLIT(dev))
1826 ier = I915_READ(DEIER) | I915_READ(GTIER); 1833 ier = I915_READ(DEIER) | I915_READ(GTIER);
1827 else 1834 else
1828 ier = I915_READ(IER); 1835 ier = I915_READ(IER);
@@ -1991,6 +1998,7 @@ int
1991i915_gem_object_unbind(struct drm_gem_object *obj) 1998i915_gem_object_unbind(struct drm_gem_object *obj)
1992{ 1999{
1993 struct drm_device *dev = obj->dev; 2000 struct drm_device *dev = obj->dev;
2001 drm_i915_private_t *dev_priv = dev->dev_private;
1994 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2002 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1995 int ret = 0; 2003 int ret = 0;
1996 2004
@@ -2046,8 +2054,10 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
2046 } 2054 }
2047 2055
2048 /* Remove ourselves from the LRU list if present. */ 2056 /* Remove ourselves from the LRU list if present. */
2057 spin_lock(&dev_priv->mm.active_list_lock);
2049 if (!list_empty(&obj_priv->list)) 2058 if (!list_empty(&obj_priv->list))
2050 list_del_init(&obj_priv->list); 2059 list_del_init(&obj_priv->list);
2060 spin_unlock(&dev_priv->mm.active_list_lock);
2051 2061
2052 if (i915_gem_object_is_purgeable(obj_priv)) 2062 if (i915_gem_object_is_purgeable(obj_priv))
2053 i915_gem_object_truncate(obj); 2063 i915_gem_object_truncate(obj);
@@ -2085,11 +2095,34 @@ i915_gem_find_inactive_object(struct drm_device *dev, int min_size)
2085} 2095}
2086 2096
2087static int 2097static int
2098i915_gpu_idle(struct drm_device *dev)
2099{
2100 drm_i915_private_t *dev_priv = dev->dev_private;
2101 bool lists_empty;
2102 uint32_t seqno;
2103
2104 spin_lock(&dev_priv->mm.active_list_lock);
2105 lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
2106 list_empty(&dev_priv->mm.active_list);
2107 spin_unlock(&dev_priv->mm.active_list_lock);
2108
2109 if (lists_empty)
2110 return 0;
2111
2112 /* Flush everything onto the inactive list. */
2113 i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
2114 seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS);
2115 if (seqno == 0)
2116 return -ENOMEM;
2117
2118 return i915_wait_request(dev, seqno);
2119}
2120
2121static int
2088i915_gem_evict_everything(struct drm_device *dev) 2122i915_gem_evict_everything(struct drm_device *dev)
2089{ 2123{
2090 drm_i915_private_t *dev_priv = dev->dev_private; 2124 drm_i915_private_t *dev_priv = dev->dev_private;
2091 int ret; 2125 int ret;
2092 uint32_t seqno;
2093 bool lists_empty; 2126 bool lists_empty;
2094 2127
2095 spin_lock(&dev_priv->mm.active_list_lock); 2128 spin_lock(&dev_priv->mm.active_list_lock);
@@ -2102,12 +2135,7 @@ i915_gem_evict_everything(struct drm_device *dev)
2102 return -ENOSPC; 2135 return -ENOSPC;
2103 2136
2104 /* Flush everything (on to the inactive lists) and evict */ 2137 /* Flush everything (on to the inactive lists) and evict */
2105 i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); 2138 ret = i915_gpu_idle(dev);
2106 seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS);
2107 if (seqno == 0)
2108 return -ENOMEM;
2109
2110 ret = i915_wait_request(dev, seqno);
2111 if (ret) 2139 if (ret)
2112 return ret; 2140 return ret;
2113 2141
@@ -2265,6 +2293,28 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,
2265 return 0; 2293 return 0;
2266} 2294}
2267 2295
2296static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
2297{
2298 struct drm_gem_object *obj = reg->obj;
2299 struct drm_device *dev = obj->dev;
2300 drm_i915_private_t *dev_priv = dev->dev_private;
2301 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2302 int regnum = obj_priv->fence_reg;
2303 uint64_t val;
2304
2305 val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) &
2306 0xfffff000) << 32;
2307 val |= obj_priv->gtt_offset & 0xfffff000;
2308 val |= (uint64_t)((obj_priv->stride / 128) - 1) <<
2309 SANDYBRIDGE_FENCE_PITCH_SHIFT;
2310
2311 if (obj_priv->tiling_mode == I915_TILING_Y)
2312 val |= 1 << I965_FENCE_TILING_Y_SHIFT;
2313 val |= I965_FENCE_REG_VALID;
2314
2315 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val);
2316}
2317
2268static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) 2318static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
2269{ 2319{
2270 struct drm_gem_object *obj = reg->obj; 2320 struct drm_gem_object *obj = reg->obj;
@@ -2361,6 +2411,58 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
2361 I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); 2411 I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val);
2362} 2412}
2363 2413
2414static int i915_find_fence_reg(struct drm_device *dev)
2415{
2416 struct drm_i915_fence_reg *reg = NULL;
2417 struct drm_i915_gem_object *obj_priv = NULL;
2418 struct drm_i915_private *dev_priv = dev->dev_private;
2419 struct drm_gem_object *obj = NULL;
2420 int i, avail, ret;
2421
2422 /* First try to find a free reg */
2423 avail = 0;
2424 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
2425 reg = &dev_priv->fence_regs[i];
2426 if (!reg->obj)
2427 return i;
2428
2429 obj_priv = reg->obj->driver_private;
2430 if (!obj_priv->pin_count)
2431 avail++;
2432 }
2433
2434 if (avail == 0)
2435 return -ENOSPC;
2436
2437 /* None available, try to steal one or wait for a user to finish */
2438 i = I915_FENCE_REG_NONE;
2439 list_for_each_entry(obj_priv, &dev_priv->mm.fence_list,
2440 fence_list) {
2441 obj = obj_priv->obj;
2442
2443 if (obj_priv->pin_count)
2444 continue;
2445
2446 /* found one! */
2447 i = obj_priv->fence_reg;
2448 break;
2449 }
2450
2451 BUG_ON(i == I915_FENCE_REG_NONE);
2452
2453 /* We only have a reference on obj from the active list. put_fence_reg
2454 * might drop that one, causing a use-after-free in it. So hold a
2455 * private reference to obj like the other callers of put_fence_reg
2456 * (set_tiling ioctl) do. */
2457 drm_gem_object_reference(obj);
2458 ret = i915_gem_object_put_fence_reg(obj);
2459 drm_gem_object_unreference(obj);
2460 if (ret != 0)
2461 return ret;
2462
2463 return i;
2464}
2465
2364/** 2466/**
2365 * i915_gem_object_get_fence_reg - set up a fence reg for an object 2467 * i915_gem_object_get_fence_reg - set up a fence reg for an object
2366 * @obj: object to map through a fence reg 2468 * @obj: object to map through a fence reg
@@ -2381,8 +2483,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
2381 struct drm_i915_private *dev_priv = dev->dev_private; 2483 struct drm_i915_private *dev_priv = dev->dev_private;
2382 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2484 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2383 struct drm_i915_fence_reg *reg = NULL; 2485 struct drm_i915_fence_reg *reg = NULL;
2384 struct drm_i915_gem_object *old_obj_priv = NULL; 2486 int ret;
2385 int i, ret, avail;
2386 2487
2387 /* Just update our place in the LRU if our fence is getting used. */ 2488 /* Just update our place in the LRU if our fence is getting used. */
2388 if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { 2489 if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
@@ -2410,86 +2511,27 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
2410 break; 2511 break;
2411 } 2512 }
2412 2513
2413 /* First try to find a free reg */ 2514 ret = i915_find_fence_reg(dev);
2414 avail = 0; 2515 if (ret < 0)
2415 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { 2516 return ret;
2416 reg = &dev_priv->fence_regs[i];
2417 if (!reg->obj)
2418 break;
2419
2420 old_obj_priv = reg->obj->driver_private;
2421 if (!old_obj_priv->pin_count)
2422 avail++;
2423 }
2424
2425 /* None available, try to steal one or wait for a user to finish */
2426 if (i == dev_priv->num_fence_regs) {
2427 struct drm_gem_object *old_obj = NULL;
2428
2429 if (avail == 0)
2430 return -ENOSPC;
2431
2432 list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list,
2433 fence_list) {
2434 old_obj = old_obj_priv->obj;
2435
2436 if (old_obj_priv->pin_count)
2437 continue;
2438
2439 /* Take a reference, as otherwise the wait_rendering
2440 * below may cause the object to get freed out from
2441 * under us.
2442 */
2443 drm_gem_object_reference(old_obj);
2444
2445 /* i915 uses fences for GPU access to tiled buffers */
2446 if (IS_I965G(dev) || !old_obj_priv->active)
2447 break;
2448
2449 /* This brings the object to the head of the LRU if it
2450 * had been written to. The only way this should
2451 * result in us waiting longer than the expected
2452 * optimal amount of time is if there was a
2453 * fence-using buffer later that was read-only.
2454 */
2455 i915_gem_object_flush_gpu_write_domain(old_obj);
2456 ret = i915_gem_object_wait_rendering(old_obj);
2457 if (ret != 0) {
2458 drm_gem_object_unreference(old_obj);
2459 return ret;
2460 }
2461
2462 break;
2463 }
2464
2465 /*
2466 * Zap this virtual mapping so we can set up a fence again
2467 * for this object next time we need it.
2468 */
2469 i915_gem_release_mmap(old_obj);
2470
2471 i = old_obj_priv->fence_reg;
2472 reg = &dev_priv->fence_regs[i];
2473
2474 old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
2475 list_del_init(&old_obj_priv->fence_list);
2476
2477 drm_gem_object_unreference(old_obj);
2478 }
2479 2517
2480 obj_priv->fence_reg = i; 2518 obj_priv->fence_reg = ret;
2519 reg = &dev_priv->fence_regs[obj_priv->fence_reg];
2481 list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); 2520 list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
2482 2521
2483 reg->obj = obj; 2522 reg->obj = obj;
2484 2523
2485 if (IS_I965G(dev)) 2524 if (IS_GEN6(dev))
2525 sandybridge_write_fence_reg(reg);
2526 else if (IS_I965G(dev))
2486 i965_write_fence_reg(reg); 2527 i965_write_fence_reg(reg);
2487 else if (IS_I9XX(dev)) 2528 else if (IS_I9XX(dev))
2488 i915_write_fence_reg(reg); 2529 i915_write_fence_reg(reg);
2489 else 2530 else
2490 i830_write_fence_reg(reg); 2531 i830_write_fence_reg(reg);
2491 2532
2492 trace_i915_gem_object_get_fence(obj, i, obj_priv->tiling_mode); 2533 trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg,
2534 obj_priv->tiling_mode);
2493 2535
2494 return 0; 2536 return 0;
2495} 2537}
@@ -2508,9 +2550,12 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
2508 drm_i915_private_t *dev_priv = dev->dev_private; 2550 drm_i915_private_t *dev_priv = dev->dev_private;
2509 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2551 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2510 2552
2511 if (IS_I965G(dev)) 2553 if (IS_GEN6(dev)) {
2554 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
2555 (obj_priv->fence_reg * 8), 0);
2556 } else if (IS_I965G(dev)) {
2512 I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); 2557 I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0);
2513 else { 2558 } else {
2514 uint32_t fence_reg; 2559 uint32_t fence_reg;
2515 2560
2516 if (obj_priv->fence_reg < 8) 2561 if (obj_priv->fence_reg < 8)
@@ -2544,6 +2589,12 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
2544 if (obj_priv->fence_reg == I915_FENCE_REG_NONE) 2589 if (obj_priv->fence_reg == I915_FENCE_REG_NONE)
2545 return 0; 2590 return 0;
2546 2591
2592 /* If we've changed tiling, GTT-mappings of the object
2593 * need to re-fault to ensure that the correct fence register
2594 * setup is in place.
2595 */
2596 i915_gem_release_mmap(obj);
2597
2547 /* On the i915, GPU access to tiled buffers is via a fence, 2598 /* On the i915, GPU access to tiled buffers is via a fence,
2548 * therefore we must wait for any outstanding access to complete 2599 * therefore we must wait for any outstanding access to complete
2549 * before clearing the fence. 2600 * before clearing the fence.
@@ -2552,12 +2603,12 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
2552 int ret; 2603 int ret;
2553 2604
2554 i915_gem_object_flush_gpu_write_domain(obj); 2605 i915_gem_object_flush_gpu_write_domain(obj);
2555 i915_gem_object_flush_gtt_write_domain(obj);
2556 ret = i915_gem_object_wait_rendering(obj); 2606 ret = i915_gem_object_wait_rendering(obj);
2557 if (ret != 0) 2607 if (ret != 0)
2558 return ret; 2608 return ret;
2559 } 2609 }
2560 2610
2611 i915_gem_object_flush_gtt_write_domain(obj);
2561 i915_gem_clear_fence_reg (obj); 2612 i915_gem_clear_fence_reg (obj);
2562 2613
2563 return 0; 2614 return 0;
@@ -2697,7 +2748,6 @@ static void
2697i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) 2748i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
2698{ 2749{
2699 struct drm_device *dev = obj->dev; 2750 struct drm_device *dev = obj->dev;
2700 uint32_t seqno;
2701 uint32_t old_write_domain; 2751 uint32_t old_write_domain;
2702 2752
2703 if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) 2753 if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0)
@@ -2706,9 +2756,8 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj)
2706 /* Queue the GPU write cache flushing we need. */ 2756 /* Queue the GPU write cache flushing we need. */
2707 old_write_domain = obj->write_domain; 2757 old_write_domain = obj->write_domain;
2708 i915_gem_flush(dev, 0, obj->write_domain); 2758 i915_gem_flush(dev, 0, obj->write_domain);
2709 seqno = i915_add_request(dev, NULL, obj->write_domain); 2759 (void) i915_add_request(dev, NULL, obj->write_domain);
2710 BUG_ON(obj->write_domain); 2760 BUG_ON(obj->write_domain);
2711 i915_gem_object_move_to_active(obj, seqno);
2712 2761
2713 trace_i915_gem_object_change_domain(obj, 2762 trace_i915_gem_object_change_domain(obj,
2714 obj->read_domains, 2763 obj->read_domains,
@@ -3247,7 +3296,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
3247 obj_priv->tiling_mode != I915_TILING_NONE; 3296 obj_priv->tiling_mode != I915_TILING_NONE;
3248 3297
3249 /* Check fence reg constraints and rebind if necessary */ 3298 /* Check fence reg constraints and rebind if necessary */
3250 if (need_fence && !i915_obj_fenceable(dev, obj)) 3299 if (need_fence && !i915_gem_object_fence_offset_ok(obj,
3300 obj_priv->tiling_mode))
3251 i915_gem_object_unbind(obj); 3301 i915_gem_object_unbind(obj);
3252 3302
3253 /* Choose the GTT offset for our buffer and put it there. */ 3303 /* Choose the GTT offset for our buffer and put it there. */
@@ -3317,6 +3367,16 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
3317 } 3367 }
3318 3368
3319 /* Validate that the target is in a valid r/w GPU domain */ 3369 /* Validate that the target is in a valid r/w GPU domain */
3370 if (reloc->write_domain & (reloc->write_domain - 1)) {
3371 DRM_ERROR("reloc with multiple write domains: "
3372 "obj %p target %d offset %d "
3373 "read %08x write %08x",
3374 obj, reloc->target_handle,
3375 (int) reloc->offset,
3376 reloc->read_domains,
3377 reloc->write_domain);
3378 return -EINVAL;
3379 }
3320 if (reloc->write_domain & I915_GEM_DOMAIN_CPU || 3380 if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
3321 reloc->read_domains & I915_GEM_DOMAIN_CPU) { 3381 reloc->read_domains & I915_GEM_DOMAIN_CPU) {
3322 DRM_ERROR("reloc with read/write CPU domains: " 3382 DRM_ERROR("reloc with read/write CPU domains: "
@@ -4445,8 +4505,7 @@ int
4445i915_gem_idle(struct drm_device *dev) 4505i915_gem_idle(struct drm_device *dev)
4446{ 4506{
4447 drm_i915_private_t *dev_priv = dev->dev_private; 4507 drm_i915_private_t *dev_priv = dev->dev_private;
4448 uint32_t seqno, cur_seqno, last_seqno; 4508 int ret;
4449 int stuck, ret;
4450 4509
4451 mutex_lock(&dev->struct_mutex); 4510 mutex_lock(&dev->struct_mutex);
4452 4511
@@ -4455,115 +4514,36 @@ i915_gem_idle(struct drm_device *dev)
4455 return 0; 4514 return 0;
4456 } 4515 }
4457 4516
4458 /* Hack! Don't let anybody do execbuf while we don't control the chip. 4517 ret = i915_gpu_idle(dev);
4459 * We need to replace this with a semaphore, or something. 4518 if (ret) {
4460 */
4461 dev_priv->mm.suspended = 1;
4462 del_timer(&dev_priv->hangcheck_timer);
4463
4464 /* Cancel the retire work handler, wait for it to finish if running
4465 */
4466 mutex_unlock(&dev->struct_mutex);
4467 cancel_delayed_work_sync(&dev_priv->mm.retire_work);
4468 mutex_lock(&dev->struct_mutex);
4469
4470 i915_kernel_lost_context(dev);
4471
4472 /* Flush the GPU along with all non-CPU write domains
4473 */
4474 i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS);
4475 seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS);
4476
4477 if (seqno == 0) {
4478 mutex_unlock(&dev->struct_mutex); 4519 mutex_unlock(&dev->struct_mutex);
4479 return -ENOMEM; 4520 return ret;
4480 } 4521 }
4481 4522
4482 dev_priv->mm.waiting_gem_seqno = seqno; 4523 /* Under UMS, be paranoid and evict. */
4483 last_seqno = 0; 4524 if (!drm_core_check_feature(dev, DRIVER_MODESET)) {
4484 stuck = 0; 4525 ret = i915_gem_evict_from_inactive_list(dev);
4485 for (;;) { 4526 if (ret) {
4486 cur_seqno = i915_get_gem_seqno(dev); 4527 mutex_unlock(&dev->struct_mutex);
4487 if (i915_seqno_passed(cur_seqno, seqno)) 4528 return ret;
4488 break;
4489 if (last_seqno == cur_seqno) {
4490 if (stuck++ > 100) {
4491 DRM_ERROR("hardware wedged\n");
4492 atomic_set(&dev_priv->mm.wedged, 1);
4493 DRM_WAKEUP(&dev_priv->irq_queue);
4494 break;
4495 }
4496 } 4529 }
4497 msleep(10);
4498 last_seqno = cur_seqno;
4499 }
4500 dev_priv->mm.waiting_gem_seqno = 0;
4501
4502 i915_gem_retire_requests(dev);
4503
4504 spin_lock(&dev_priv->mm.active_list_lock);
4505 if (!atomic_read(&dev_priv->mm.wedged)) {
4506 /* Active and flushing should now be empty as we've
4507 * waited for a sequence higher than any pending execbuffer
4508 */
4509 WARN_ON(!list_empty(&dev_priv->mm.active_list));
4510 WARN_ON(!list_empty(&dev_priv->mm.flushing_list));
4511 /* Request should now be empty as we've also waited
4512 * for the last request in the list
4513 */
4514 WARN_ON(!list_empty(&dev_priv->mm.request_list));
4515 } 4530 }
4516 4531
4517 /* Empty the active and flushing lists to inactive. If there's 4532 /* Hack! Don't let anybody do execbuf while we don't control the chip.
4518 * anything left at this point, it means that we're wedged and 4533 * We need to replace this with a semaphore, or something.
4519 * nothing good's going to happen by leaving them there. So strip 4534 * And not confound mm.suspended!
4520 * the GPU domains and just stuff them onto inactive.
4521 */ 4535 */
4522 while (!list_empty(&dev_priv->mm.active_list)) { 4536 dev_priv->mm.suspended = 1;
4523 struct drm_gem_object *obj; 4537 del_timer(&dev_priv->hangcheck_timer);
4524 uint32_t old_write_domain;
4525
4526 obj = list_first_entry(&dev_priv->mm.active_list,
4527 struct drm_i915_gem_object,
4528 list)->obj;
4529 old_write_domain = obj->write_domain;
4530 obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
4531 i915_gem_object_move_to_inactive(obj);
4532
4533 trace_i915_gem_object_change_domain(obj,
4534 obj->read_domains,
4535 old_write_domain);
4536 }
4537 spin_unlock(&dev_priv->mm.active_list_lock);
4538
4539 while (!list_empty(&dev_priv->mm.flushing_list)) {
4540 struct drm_gem_object *obj;
4541 uint32_t old_write_domain;
4542
4543 obj = list_first_entry(&dev_priv->mm.flushing_list,
4544 struct drm_i915_gem_object,
4545 list)->obj;
4546 old_write_domain = obj->write_domain;
4547 obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
4548 i915_gem_object_move_to_inactive(obj);
4549
4550 trace_i915_gem_object_change_domain(obj,
4551 obj->read_domains,
4552 old_write_domain);
4553 }
4554
4555
4556 /* Move all inactive buffers out of the GTT. */
4557 ret = i915_gem_evict_from_inactive_list(dev);
4558 WARN_ON(!list_empty(&dev_priv->mm.inactive_list));
4559 if (ret) {
4560 mutex_unlock(&dev->struct_mutex);
4561 return ret;
4562 }
4563 4538
4539 i915_kernel_lost_context(dev);
4564 i915_gem_cleanup_ringbuffer(dev); 4540 i915_gem_cleanup_ringbuffer(dev);
4541
4565 mutex_unlock(&dev->struct_mutex); 4542 mutex_unlock(&dev->struct_mutex);
4566 4543
4544 /* Cancel the retire work handler, which should be idle now. */
4545 cancel_delayed_work_sync(&dev_priv->mm.retire_work);
4546
4567 return 0; 4547 return 0;
4568} 4548}
4569 4549
@@ -4607,8 +4587,13 @@ i915_gem_init_hws(struct drm_device *dev)
4607 } 4587 }
4608 dev_priv->hws_obj = obj; 4588 dev_priv->hws_obj = obj;
4609 memset(dev_priv->hw_status_page, 0, PAGE_SIZE); 4589 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
4610 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); 4590 if (IS_GEN6(dev)) {
4611 I915_READ(HWS_PGA); /* posting read */ 4591 I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr);
4592 I915_READ(HWS_PGA_GEN6); /* posting read */
4593 } else {
4594 I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
4595 I915_READ(HWS_PGA); /* posting read */
4596 }
4612 DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); 4597 DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
4613 4598
4614 return 0; 4599 return 0;
@@ -4850,7 +4835,8 @@ i915_gem_load(struct drm_device *dev)
4850 spin_unlock(&shrink_list_lock); 4835 spin_unlock(&shrink_list_lock);
4851 4836
4852 /* Old X drivers will take 0-2 for front, back, depth buffers */ 4837 /* Old X drivers will take 0-2 for front, back, depth buffers */
4853 dev_priv->fence_reg_start = 3; 4838 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4839 dev_priv->fence_reg_start = 3;
4854 4840
4855 if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 4841 if (IS_I965G(dev) || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
4856 dev_priv->num_fence_regs = 16; 4842 dev_priv->num_fence_regs = 16;