diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 292 |
1 files changed, 133 insertions, 159 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9b285da4449b..742206e45103 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -845,12 +845,12 @@ out: | |||
845 | * domain anymore. */ | 845 | * domain anymore. */ |
846 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) { | 846 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) { |
847 | i915_gem_clflush_object(obj); | 847 | i915_gem_clflush_object(obj); |
848 | intel_gtt_chipset_flush(); | 848 | i915_gem_chipset_flush(dev); |
849 | } | 849 | } |
850 | } | 850 | } |
851 | 851 | ||
852 | if (needs_clflush_after) | 852 | if (needs_clflush_after) |
853 | intel_gtt_chipset_flush(); | 853 | i915_gem_chipset_flush(dev); |
854 | 854 | ||
855 | return ret; | 855 | return ret; |
856 | } | 856 | } |
@@ -1345,30 +1345,17 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1345 | trace_i915_gem_object_fault(obj, page_offset, true, write); | 1345 | trace_i915_gem_object_fault(obj, page_offset, true, write); |
1346 | 1346 | ||
1347 | /* Now bind it into the GTT if needed */ | 1347 | /* Now bind it into the GTT if needed */ |
1348 | if (!obj->map_and_fenceable) { | 1348 | ret = i915_gem_object_pin(obj, 0, true, false); |
1349 | ret = i915_gem_object_unbind(obj); | 1349 | if (ret) |
1350 | if (ret) | 1350 | goto unlock; |
1351 | goto unlock; | ||
1352 | } | ||
1353 | if (!obj->gtt_space) { | ||
1354 | ret = i915_gem_object_bind_to_gtt(obj, 0, true, false); | ||
1355 | if (ret) | ||
1356 | goto unlock; | ||
1357 | |||
1358 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | ||
1359 | if (ret) | ||
1360 | goto unlock; | ||
1361 | } | ||
1362 | 1351 | ||
1363 | if (!obj->has_global_gtt_mapping) | 1352 | ret = i915_gem_object_set_to_gtt_domain(obj, write); |
1364 | i915_gem_gtt_bind_object(obj, obj->cache_level); | 1353 | if (ret) |
1354 | goto unpin; | ||
1365 | 1355 | ||
1366 | ret = i915_gem_object_get_fence(obj); | 1356 | ret = i915_gem_object_get_fence(obj); |
1367 | if (ret) | 1357 | if (ret) |
1368 | goto unlock; | 1358 | goto unpin; |
1369 | |||
1370 | if (i915_gem_object_is_inactive(obj)) | ||
1371 | list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); | ||
1372 | 1359 | ||
1373 | obj->fault_mappable = true; | 1360 | obj->fault_mappable = true; |
1374 | 1361 | ||
@@ -1377,6 +1364,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1377 | 1364 | ||
1378 | /* Finally, remap it using the new GTT offset */ | 1365 | /* Finally, remap it using the new GTT offset */ |
1379 | ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); | 1366 | ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); |
1367 | unpin: | ||
1368 | i915_gem_object_unpin(obj); | ||
1380 | unlock: | 1369 | unlock: |
1381 | mutex_unlock(&dev->struct_mutex); | 1370 | mutex_unlock(&dev->struct_mutex); |
1382 | out: | 1371 | out: |
@@ -1707,10 +1696,14 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) | |||
1707 | if (obj->pages_pin_count) | 1696 | if (obj->pages_pin_count) |
1708 | return -EBUSY; | 1697 | return -EBUSY; |
1709 | 1698 | ||
1699 | /* ->put_pages might need to allocate memory for the bit17 swizzle | ||
1700 | * array, hence protect them from being reaped by removing them from gtt | ||
1701 | * lists early. */ | ||
1702 | list_del(&obj->gtt_list); | ||
1703 | |||
1710 | ops->put_pages(obj); | 1704 | ops->put_pages(obj); |
1711 | obj->pages = NULL; | 1705 | obj->pages = NULL; |
1712 | 1706 | ||
1713 | list_del(&obj->gtt_list); | ||
1714 | if (i915_gem_object_is_purgeable(obj)) | 1707 | if (i915_gem_object_is_purgeable(obj)) |
1715 | i915_gem_object_truncate(obj); | 1708 | i915_gem_object_truncate(obj); |
1716 | 1709 | ||
@@ -1868,11 +1861,11 @@ i915_gem_object_get_pages(struct drm_i915_gem_object *obj) | |||
1868 | 1861 | ||
1869 | void | 1862 | void |
1870 | i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, | 1863 | i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, |
1871 | struct intel_ring_buffer *ring, | 1864 | struct intel_ring_buffer *ring) |
1872 | u32 seqno) | ||
1873 | { | 1865 | { |
1874 | struct drm_device *dev = obj->base.dev; | 1866 | struct drm_device *dev = obj->base.dev; |
1875 | struct drm_i915_private *dev_priv = dev->dev_private; | 1867 | struct drm_i915_private *dev_priv = dev->dev_private; |
1868 | u32 seqno = intel_ring_get_seqno(ring); | ||
1876 | 1869 | ||
1877 | BUG_ON(ring == NULL); | 1870 | BUG_ON(ring == NULL); |
1878 | obj->ring = ring; | 1871 | obj->ring = ring; |
@@ -1933,26 +1926,54 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) | |||
1933 | WARN_ON(i915_verify_lists(dev)); | 1926 | WARN_ON(i915_verify_lists(dev)); |
1934 | } | 1927 | } |
1935 | 1928 | ||
1936 | static u32 | 1929 | static int |
1937 | i915_gem_get_seqno(struct drm_device *dev) | 1930 | i915_gem_handle_seqno_wrap(struct drm_device *dev) |
1938 | { | 1931 | { |
1939 | drm_i915_private_t *dev_priv = dev->dev_private; | 1932 | struct drm_i915_private *dev_priv = dev->dev_private; |
1940 | u32 seqno = dev_priv->next_seqno; | 1933 | struct intel_ring_buffer *ring; |
1934 | int ret, i, j; | ||
1941 | 1935 | ||
1942 | /* reserve 0 for non-seqno */ | 1936 | /* The hardware uses various monotonic 32-bit counters, if we |
1943 | if (++dev_priv->next_seqno == 0) | 1937 | * detect that they will wraparound we need to idle the GPU |
1944 | dev_priv->next_seqno = 1; | 1938 | * and reset those counters. |
1939 | */ | ||
1940 | ret = 0; | ||
1941 | for_each_ring(ring, dev_priv, i) { | ||
1942 | for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++) | ||
1943 | ret |= ring->sync_seqno[j] != 0; | ||
1944 | } | ||
1945 | if (ret == 0) | ||
1946 | return ret; | ||
1947 | |||
1948 | ret = i915_gpu_idle(dev); | ||
1949 | if (ret) | ||
1950 | return ret; | ||
1951 | |||
1952 | i915_gem_retire_requests(dev); | ||
1953 | for_each_ring(ring, dev_priv, i) { | ||
1954 | for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++) | ||
1955 | ring->sync_seqno[j] = 0; | ||
1956 | } | ||
1945 | 1957 | ||
1946 | return seqno; | 1958 | return 0; |
1947 | } | 1959 | } |
1948 | 1960 | ||
1949 | u32 | 1961 | int |
1950 | i915_gem_next_request_seqno(struct intel_ring_buffer *ring) | 1962 | i915_gem_get_seqno(struct drm_device *dev, u32 *seqno) |
1951 | { | 1963 | { |
1952 | if (ring->outstanding_lazy_request == 0) | 1964 | struct drm_i915_private *dev_priv = dev->dev_private; |
1953 | ring->outstanding_lazy_request = i915_gem_get_seqno(ring->dev); | 1965 | |
1966 | /* reserve 0 for non-seqno */ | ||
1967 | if (dev_priv->next_seqno == 0) { | ||
1968 | int ret = i915_gem_handle_seqno_wrap(dev); | ||
1969 | if (ret) | ||
1970 | return ret; | ||
1954 | 1971 | ||
1955 | return ring->outstanding_lazy_request; | 1972 | dev_priv->next_seqno = 1; |
1973 | } | ||
1974 | |||
1975 | *seqno = dev_priv->next_seqno++; | ||
1976 | return 0; | ||
1956 | } | 1977 | } |
1957 | 1978 | ||
1958 | int | 1979 | int |
@@ -1963,7 +1984,6 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1963 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1984 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1964 | struct drm_i915_gem_request *request; | 1985 | struct drm_i915_gem_request *request; |
1965 | u32 request_ring_position; | 1986 | u32 request_ring_position; |
1966 | u32 seqno; | ||
1967 | int was_empty; | 1987 | int was_empty; |
1968 | int ret; | 1988 | int ret; |
1969 | 1989 | ||
@@ -1982,7 +2002,6 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1982 | if (request == NULL) | 2002 | if (request == NULL) |
1983 | return -ENOMEM; | 2003 | return -ENOMEM; |
1984 | 2004 | ||
1985 | seqno = i915_gem_next_request_seqno(ring); | ||
1986 | 2005 | ||
1987 | /* Record the position of the start of the request so that | 2006 | /* Record the position of the start of the request so that |
1988 | * should we detect the updated seqno part-way through the | 2007 | * should we detect the updated seqno part-way through the |
@@ -1991,15 +2010,13 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
1991 | */ | 2010 | */ |
1992 | request_ring_position = intel_ring_get_tail(ring); | 2011 | request_ring_position = intel_ring_get_tail(ring); |
1993 | 2012 | ||
1994 | ret = ring->add_request(ring, &seqno); | 2013 | ret = ring->add_request(ring); |
1995 | if (ret) { | 2014 | if (ret) { |
1996 | kfree(request); | 2015 | kfree(request); |
1997 | return ret; | 2016 | return ret; |
1998 | } | 2017 | } |
1999 | 2018 | ||
2000 | trace_i915_gem_request_add(ring, seqno); | 2019 | request->seqno = intel_ring_get_seqno(ring); |
2001 | |||
2002 | request->seqno = seqno; | ||
2003 | request->ring = ring; | 2020 | request->ring = ring; |
2004 | request->tail = request_ring_position; | 2021 | request->tail = request_ring_position; |
2005 | request->emitted_jiffies = jiffies; | 2022 | request->emitted_jiffies = jiffies; |
@@ -2017,23 +2034,24 @@ i915_add_request(struct intel_ring_buffer *ring, | |||
2017 | spin_unlock(&file_priv->mm.lock); | 2034 | spin_unlock(&file_priv->mm.lock); |
2018 | } | 2035 | } |
2019 | 2036 | ||
2037 | trace_i915_gem_request_add(ring, request->seqno); | ||
2020 | ring->outstanding_lazy_request = 0; | 2038 | ring->outstanding_lazy_request = 0; |
2021 | 2039 | ||
2022 | if (!dev_priv->mm.suspended) { | 2040 | if (!dev_priv->mm.suspended) { |
2023 | if (i915_enable_hangcheck) { | 2041 | if (i915_enable_hangcheck) { |
2024 | mod_timer(&dev_priv->hangcheck_timer, | 2042 | mod_timer(&dev_priv->hangcheck_timer, |
2025 | jiffies + | 2043 | round_jiffies_up(jiffies + DRM_I915_HANGCHECK_JIFFIES)); |
2026 | msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); | ||
2027 | } | 2044 | } |
2028 | if (was_empty) { | 2045 | if (was_empty) { |
2029 | queue_delayed_work(dev_priv->wq, | 2046 | queue_delayed_work(dev_priv->wq, |
2030 | &dev_priv->mm.retire_work, HZ); | 2047 | &dev_priv->mm.retire_work, |
2048 | round_jiffies_up_relative(HZ)); | ||
2031 | intel_mark_busy(dev_priv->dev); | 2049 | intel_mark_busy(dev_priv->dev); |
2032 | } | 2050 | } |
2033 | } | 2051 | } |
2034 | 2052 | ||
2035 | if (out_seqno) | 2053 | if (out_seqno) |
2036 | *out_seqno = seqno; | 2054 | *out_seqno = request->seqno; |
2037 | return 0; | 2055 | return 0; |
2038 | } | 2056 | } |
2039 | 2057 | ||
@@ -2131,7 +2149,6 @@ void | |||
2131 | i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) | 2149 | i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) |
2132 | { | 2150 | { |
2133 | uint32_t seqno; | 2151 | uint32_t seqno; |
2134 | int i; | ||
2135 | 2152 | ||
2136 | if (list_empty(&ring->request_list)) | 2153 | if (list_empty(&ring->request_list)) |
2137 | return; | 2154 | return; |
@@ -2140,10 +2157,6 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring) | |||
2140 | 2157 | ||
2141 | seqno = ring->get_seqno(ring, true); | 2158 | seqno = ring->get_seqno(ring, true); |
2142 | 2159 | ||
2143 | for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) | ||
2144 | if (seqno >= ring->sync_seqno[i]) | ||
2145 | ring->sync_seqno[i] = 0; | ||
2146 | |||
2147 | while (!list_empty(&ring->request_list)) { | 2160 | while (!list_empty(&ring->request_list)) { |
2148 | struct drm_i915_gem_request *request; | 2161 | struct drm_i915_gem_request *request; |
2149 | 2162 | ||
@@ -2218,7 +2231,8 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
2218 | 2231 | ||
2219 | /* Come back later if the device is busy... */ | 2232 | /* Come back later if the device is busy... */ |
2220 | if (!mutex_trylock(&dev->struct_mutex)) { | 2233 | if (!mutex_trylock(&dev->struct_mutex)) { |
2221 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); | 2234 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, |
2235 | round_jiffies_up_relative(HZ)); | ||
2222 | return; | 2236 | return; |
2223 | } | 2237 | } |
2224 | 2238 | ||
@@ -2236,7 +2250,8 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
2236 | } | 2250 | } |
2237 | 2251 | ||
2238 | if (!dev_priv->mm.suspended && !idle) | 2252 | if (!dev_priv->mm.suspended && !idle) |
2239 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); | 2253 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, |
2254 | round_jiffies_up_relative(HZ)); | ||
2240 | if (idle) | 2255 | if (idle) |
2241 | intel_mark_idle(dev); | 2256 | intel_mark_idle(dev); |
2242 | 2257 | ||
@@ -2386,7 +2401,11 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj, | |||
2386 | 2401 | ||
2387 | ret = to->sync_to(to, from, seqno); | 2402 | ret = to->sync_to(to, from, seqno); |
2388 | if (!ret) | 2403 | if (!ret) |
2389 | from->sync_seqno[idx] = seqno; | 2404 | /* We use last_read_seqno because sync_to() |
2405 | * might have just caused seqno wrap under | ||
2406 | * the radar. | ||
2407 | */ | ||
2408 | from->sync_seqno[idx] = obj->last_read_seqno; | ||
2390 | 2409 | ||
2391 | return ret; | 2410 | return ret; |
2392 | } | 2411 | } |
@@ -2469,14 +2488,6 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
2469 | return 0; | 2488 | return 0; |
2470 | } | 2489 | } |
2471 | 2490 | ||
2472 | static int i915_ring_idle(struct intel_ring_buffer *ring) | ||
2473 | { | ||
2474 | if (list_empty(&ring->active_list)) | ||
2475 | return 0; | ||
2476 | |||
2477 | return i915_wait_seqno(ring, i915_gem_next_request_seqno(ring)); | ||
2478 | } | ||
2479 | |||
2480 | int i915_gpu_idle(struct drm_device *dev) | 2491 | int i915_gpu_idle(struct drm_device *dev) |
2481 | { | 2492 | { |
2482 | drm_i915_private_t *dev_priv = dev->dev_private; | 2493 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -2489,7 +2500,7 @@ int i915_gpu_idle(struct drm_device *dev) | |||
2489 | if (ret) | 2500 | if (ret) |
2490 | return ret; | 2501 | return ret; |
2491 | 2502 | ||
2492 | ret = i915_ring_idle(ring); | 2503 | ret = intel_ring_idle(ring); |
2493 | if (ret) | 2504 | if (ret) |
2494 | return ret; | 2505 | return ret; |
2495 | } | 2506 | } |
@@ -2923,13 +2934,14 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2923 | if (ret) | 2934 | if (ret) |
2924 | return ret; | 2935 | return ret; |
2925 | 2936 | ||
2937 | i915_gem_object_pin_pages(obj); | ||
2938 | |||
2926 | search_free: | 2939 | search_free: |
2927 | if (map_and_fenceable) | 2940 | if (map_and_fenceable) |
2928 | free_space = | 2941 | free_space = drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space, |
2929 | drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space, | 2942 | size, alignment, obj->cache_level, |
2930 | size, alignment, obj->cache_level, | 2943 | 0, dev_priv->mm.gtt_mappable_end, |
2931 | 0, dev_priv->mm.gtt_mappable_end, | 2944 | false); |
2932 | false); | ||
2933 | else | 2945 | else |
2934 | free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space, | 2946 | free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space, |
2935 | size, alignment, obj->cache_level, | 2947 | size, alignment, obj->cache_level, |
@@ -2937,60 +2949,60 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, | |||
2937 | 2949 | ||
2938 | if (free_space != NULL) { | 2950 | if (free_space != NULL) { |
2939 | if (map_and_fenceable) | 2951 | if (map_and_fenceable) |
2940 | obj->gtt_space = | 2952 | free_space = |
2941 | drm_mm_get_block_range_generic(free_space, | 2953 | drm_mm_get_block_range_generic(free_space, |
2942 | size, alignment, obj->cache_level, | 2954 | size, alignment, obj->cache_level, |
2943 | 0, dev_priv->mm.gtt_mappable_end, | 2955 | 0, dev_priv->mm.gtt_mappable_end, |
2944 | false); | 2956 | false); |
2945 | else | 2957 | else |
2946 | obj->gtt_space = | 2958 | free_space = |
2947 | drm_mm_get_block_generic(free_space, | 2959 | drm_mm_get_block_generic(free_space, |
2948 | size, alignment, obj->cache_level, | 2960 | size, alignment, obj->cache_level, |
2949 | false); | 2961 | false); |
2950 | } | 2962 | } |
2951 | if (obj->gtt_space == NULL) { | 2963 | if (free_space == NULL) { |
2952 | ret = i915_gem_evict_something(dev, size, alignment, | 2964 | ret = i915_gem_evict_something(dev, size, alignment, |
2953 | obj->cache_level, | 2965 | obj->cache_level, |
2954 | map_and_fenceable, | 2966 | map_and_fenceable, |
2955 | nonblocking); | 2967 | nonblocking); |
2956 | if (ret) | 2968 | if (ret) { |
2969 | i915_gem_object_unpin_pages(obj); | ||
2957 | return ret; | 2970 | return ret; |
2971 | } | ||
2958 | 2972 | ||
2959 | goto search_free; | 2973 | goto search_free; |
2960 | } | 2974 | } |
2961 | if (WARN_ON(!i915_gem_valid_gtt_space(dev, | 2975 | if (WARN_ON(!i915_gem_valid_gtt_space(dev, |
2962 | obj->gtt_space, | 2976 | free_space, |
2963 | obj->cache_level))) { | 2977 | obj->cache_level))) { |
2964 | drm_mm_put_block(obj->gtt_space); | 2978 | i915_gem_object_unpin_pages(obj); |
2965 | obj->gtt_space = NULL; | 2979 | drm_mm_put_block(free_space); |
2966 | return -EINVAL; | 2980 | return -EINVAL; |
2967 | } | 2981 | } |
2968 | 2982 | ||
2969 | |||
2970 | ret = i915_gem_gtt_prepare_object(obj); | 2983 | ret = i915_gem_gtt_prepare_object(obj); |
2971 | if (ret) { | 2984 | if (ret) { |
2972 | drm_mm_put_block(obj->gtt_space); | 2985 | i915_gem_object_unpin_pages(obj); |
2973 | obj->gtt_space = NULL; | 2986 | drm_mm_put_block(free_space); |
2974 | return ret; | 2987 | return ret; |
2975 | } | 2988 | } |
2976 | 2989 | ||
2977 | if (!dev_priv->mm.aliasing_ppgtt) | ||
2978 | i915_gem_gtt_bind_object(obj, obj->cache_level); | ||
2979 | |||
2980 | list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list); | 2990 | list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list); |
2981 | list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); | 2991 | list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); |
2982 | 2992 | ||
2983 | obj->gtt_offset = obj->gtt_space->start; | 2993 | obj->gtt_space = free_space; |
2994 | obj->gtt_offset = free_space->start; | ||
2984 | 2995 | ||
2985 | fenceable = | 2996 | fenceable = |
2986 | obj->gtt_space->size == fence_size && | 2997 | free_space->size == fence_size && |
2987 | (obj->gtt_space->start & (fence_alignment - 1)) == 0; | 2998 | (free_space->start & (fence_alignment - 1)) == 0; |
2988 | 2999 | ||
2989 | mappable = | 3000 | mappable = |
2990 | obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; | 3001 | obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; |
2991 | 3002 | ||
2992 | obj->map_and_fenceable = mappable && fenceable; | 3003 | obj->map_and_fenceable = mappable && fenceable; |
2993 | 3004 | ||
3005 | i915_gem_object_unpin_pages(obj); | ||
2994 | trace_i915_gem_object_bind(obj, map_and_fenceable); | 3006 | trace_i915_gem_object_bind(obj, map_and_fenceable); |
2995 | i915_gem_verify_gtt(dev); | 3007 | i915_gem_verify_gtt(dev); |
2996 | return 0; | 3008 | return 0; |
@@ -3059,7 +3071,7 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) | |||
3059 | return; | 3071 | return; |
3060 | 3072 | ||
3061 | i915_gem_clflush_object(obj); | 3073 | i915_gem_clflush_object(obj); |
3062 | intel_gtt_chipset_flush(); | 3074 | i915_gem_chipset_flush(obj->base.dev); |
3063 | old_write_domain = obj->base.write_domain; | 3075 | old_write_domain = obj->base.write_domain; |
3064 | obj->base.write_domain = 0; | 3076 | obj->base.write_domain = 0; |
3065 | 3077 | ||
@@ -3454,11 +3466,16 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, | |||
3454 | } | 3466 | } |
3455 | 3467 | ||
3456 | if (obj->gtt_space == NULL) { | 3468 | if (obj->gtt_space == NULL) { |
3469 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
3470 | |||
3457 | ret = i915_gem_object_bind_to_gtt(obj, alignment, | 3471 | ret = i915_gem_object_bind_to_gtt(obj, alignment, |
3458 | map_and_fenceable, | 3472 | map_and_fenceable, |
3459 | nonblocking); | 3473 | nonblocking); |
3460 | if (ret) | 3474 | if (ret) |
3461 | return ret; | 3475 | return ret; |
3476 | |||
3477 | if (!dev_priv->mm.aliasing_ppgtt) | ||
3478 | i915_gem_gtt_bind_object(obj, obj->cache_level); | ||
3462 | } | 3479 | } |
3463 | 3480 | ||
3464 | if (!obj->has_global_gtt_mapping && map_and_fenceable) | 3481 | if (!obj->has_global_gtt_mapping && map_and_fenceable) |
@@ -3832,7 +3849,7 @@ void i915_gem_l3_remap(struct drm_device *dev) | |||
3832 | if (!IS_IVYBRIDGE(dev)) | 3849 | if (!IS_IVYBRIDGE(dev)) |
3833 | return; | 3850 | return; |
3834 | 3851 | ||
3835 | if (!dev_priv->mm.l3_remap_info) | 3852 | if (!dev_priv->l3_parity.remap_info) |
3836 | return; | 3853 | return; |
3837 | 3854 | ||
3838 | misccpctl = I915_READ(GEN7_MISCCPCTL); | 3855 | misccpctl = I915_READ(GEN7_MISCCPCTL); |
@@ -3841,12 +3858,12 @@ void i915_gem_l3_remap(struct drm_device *dev) | |||
3841 | 3858 | ||
3842 | for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) { | 3859 | for (i = 0; i < GEN7_L3LOG_SIZE; i += 4) { |
3843 | u32 remap = I915_READ(GEN7_L3LOG_BASE + i); | 3860 | u32 remap = I915_READ(GEN7_L3LOG_BASE + i); |
3844 | if (remap && remap != dev_priv->mm.l3_remap_info[i/4]) | 3861 | if (remap && remap != dev_priv->l3_parity.remap_info[i/4]) |
3845 | DRM_DEBUG("0x%x was already programmed to %x\n", | 3862 | DRM_DEBUG("0x%x was already programmed to %x\n", |
3846 | GEN7_L3LOG_BASE + i, remap); | 3863 | GEN7_L3LOG_BASE + i, remap); |
3847 | if (remap && !dev_priv->mm.l3_remap_info[i/4]) | 3864 | if (remap && !dev_priv->l3_parity.remap_info[i/4]) |
3848 | DRM_DEBUG_DRIVER("Clearing remapped register\n"); | 3865 | DRM_DEBUG_DRIVER("Clearing remapped register\n"); |
3849 | I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->mm.l3_remap_info[i/4]); | 3866 | I915_WRITE(GEN7_L3LOG_BASE + i, dev_priv->l3_parity.remap_info[i/4]); |
3850 | } | 3867 | } |
3851 | 3868 | ||
3852 | /* Make sure all the writes land before disabling dop clock gating */ | 3869 | /* Make sure all the writes land before disabling dop clock gating */ |
@@ -3876,68 +3893,6 @@ void i915_gem_init_swizzling(struct drm_device *dev) | |||
3876 | I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); | 3893 | I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); |
3877 | } | 3894 | } |
3878 | 3895 | ||
3879 | void i915_gem_init_ppgtt(struct drm_device *dev) | ||
3880 | { | ||
3881 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3882 | uint32_t pd_offset; | ||
3883 | struct intel_ring_buffer *ring; | ||
3884 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; | ||
3885 | uint32_t __iomem *pd_addr; | ||
3886 | uint32_t pd_entry; | ||
3887 | int i; | ||
3888 | |||
3889 | if (!dev_priv->mm.aliasing_ppgtt) | ||
3890 | return; | ||
3891 | |||
3892 | |||
3893 | pd_addr = dev_priv->mm.gtt->gtt + ppgtt->pd_offset/sizeof(uint32_t); | ||
3894 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | ||
3895 | dma_addr_t pt_addr; | ||
3896 | |||
3897 | if (dev_priv->mm.gtt->needs_dmar) | ||
3898 | pt_addr = ppgtt->pt_dma_addr[i]; | ||
3899 | else | ||
3900 | pt_addr = page_to_phys(ppgtt->pt_pages[i]); | ||
3901 | |||
3902 | pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); | ||
3903 | pd_entry |= GEN6_PDE_VALID; | ||
3904 | |||
3905 | writel(pd_entry, pd_addr + i); | ||
3906 | } | ||
3907 | readl(pd_addr); | ||
3908 | |||
3909 | pd_offset = ppgtt->pd_offset; | ||
3910 | pd_offset /= 64; /* in cachelines, */ | ||
3911 | pd_offset <<= 16; | ||
3912 | |||
3913 | if (INTEL_INFO(dev)->gen == 6) { | ||
3914 | uint32_t ecochk, gab_ctl, ecobits; | ||
3915 | |||
3916 | ecobits = I915_READ(GAC_ECO_BITS); | ||
3917 | I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B); | ||
3918 | |||
3919 | gab_ctl = I915_READ(GAB_CTL); | ||
3920 | I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT); | ||
3921 | |||
3922 | ecochk = I915_READ(GAM_ECOCHK); | ||
3923 | I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | | ||
3924 | ECOCHK_PPGTT_CACHE64B); | ||
3925 | I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); | ||
3926 | } else if (INTEL_INFO(dev)->gen >= 7) { | ||
3927 | I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); | ||
3928 | /* GFX_MODE is per-ring on gen7+ */ | ||
3929 | } | ||
3930 | |||
3931 | for_each_ring(ring, dev_priv, i) { | ||
3932 | if (INTEL_INFO(dev)->gen >= 7) | ||
3933 | I915_WRITE(RING_MODE_GEN7(ring), | ||
3934 | _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); | ||
3935 | |||
3936 | I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); | ||
3937 | I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); | ||
3938 | } | ||
3939 | } | ||
3940 | |||
3941 | static bool | 3896 | static bool |
3942 | intel_enable_blt(struct drm_device *dev) | 3897 | intel_enable_blt(struct drm_device *dev) |
3943 | { | 3898 | { |
@@ -3960,7 +3915,7 @@ i915_gem_init_hw(struct drm_device *dev) | |||
3960 | drm_i915_private_t *dev_priv = dev->dev_private; | 3915 | drm_i915_private_t *dev_priv = dev->dev_private; |
3961 | int ret; | 3916 | int ret; |
3962 | 3917 | ||
3963 | if (!intel_enable_gtt()) | 3918 | if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) |
3964 | return -EIO; | 3919 | return -EIO; |
3965 | 3920 | ||
3966 | if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) | 3921 | if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) |
@@ -4295,7 +4250,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, | |||
4295 | page_cache_release(page); | 4250 | page_cache_release(page); |
4296 | } | 4251 | } |
4297 | } | 4252 | } |
4298 | intel_gtt_chipset_flush(); | 4253 | i915_gem_chipset_flush(dev); |
4299 | 4254 | ||
4300 | obj->phys_obj->cur_obj = NULL; | 4255 | obj->phys_obj->cur_obj = NULL; |
4301 | obj->phys_obj = NULL; | 4256 | obj->phys_obj = NULL; |
@@ -4382,7 +4337,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, | |||
4382 | return -EFAULT; | 4337 | return -EFAULT; |
4383 | } | 4338 | } |
4384 | 4339 | ||
4385 | intel_gtt_chipset_flush(); | 4340 | i915_gem_chipset_flush(dev); |
4386 | return 0; | 4341 | return 0; |
4387 | } | 4342 | } |
4388 | 4343 | ||
@@ -4407,6 +4362,19 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file) | |||
4407 | spin_unlock(&file_priv->mm.lock); | 4362 | spin_unlock(&file_priv->mm.lock); |
4408 | } | 4363 | } |
4409 | 4364 | ||
4365 | static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) | ||
4366 | { | ||
4367 | if (!mutex_is_locked(mutex)) | ||
4368 | return false; | ||
4369 | |||
4370 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) | ||
4371 | return mutex->owner == task; | ||
4372 | #else | ||
4373 | /* Since UP may be pre-empted, we cannot assume that we own the lock */ | ||
4374 | return false; | ||
4375 | #endif | ||
4376 | } | ||
4377 | |||
4410 | static int | 4378 | static int |
4411 | i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) | 4379 | i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) |
4412 | { | 4380 | { |
@@ -4417,10 +4385,15 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) | |||
4417 | struct drm_device *dev = dev_priv->dev; | 4385 | struct drm_device *dev = dev_priv->dev; |
4418 | struct drm_i915_gem_object *obj; | 4386 | struct drm_i915_gem_object *obj; |
4419 | int nr_to_scan = sc->nr_to_scan; | 4387 | int nr_to_scan = sc->nr_to_scan; |
4388 | bool unlock = true; | ||
4420 | int cnt; | 4389 | int cnt; |
4421 | 4390 | ||
4422 | if (!mutex_trylock(&dev->struct_mutex)) | 4391 | if (!mutex_trylock(&dev->struct_mutex)) { |
4423 | return 0; | 4392 | if (!mutex_is_locked_by(&dev->struct_mutex, current)) |
4393 | return 0; | ||
4394 | |||
4395 | unlock = false; | ||
4396 | } | ||
4424 | 4397 | ||
4425 | if (nr_to_scan) { | 4398 | if (nr_to_scan) { |
4426 | nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan); | 4399 | nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan); |
@@ -4436,6 +4409,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc) | |||
4436 | if (obj->pin_count == 0 && obj->pages_pin_count == 0) | 4409 | if (obj->pin_count == 0 && obj->pages_pin_count == 0) |
4437 | cnt += obj->base.size >> PAGE_SHIFT; | 4410 | cnt += obj->base.size >> PAGE_SHIFT; |
4438 | 4411 | ||
4439 | mutex_unlock(&dev->struct_mutex); | 4412 | if (unlock) |
4413 | mutex_unlock(&dev->struct_mutex); | ||
4440 | return cnt; | 4414 | return cnt; |
4441 | } | 4415 | } |