aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-04-04 04:44:39 -0400
committerKeith Packard <keithp@keithp.com>2011-06-10 00:51:16 -0400
commite4ffd173a1c2f96b43127c2537dd99d89e759bba (patch)
tree932a67f5eebb7884ba6b28a4ebf0893d84a44eec /drivers/gpu/drm/i915/i915_gem.c
parentd5bd144959e639443f387c34989cec7c9efff091 (diff)
drm/i915: Add an interface to dynamically change the cache level
[anholt v2: Don't forget that when going from cached to uncached, we haven't been tracking the write domain from the CPU perspective, since we haven't needed it for GPU coherency.] [ickle v3: We also need to make sure we relinquish any fences on older chipsets and clear the GTT for sane domain tracking.] Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e78a7ef634d9..e6915072ba72 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3034,6 +3034,66 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
3034 return 0; 3034 return 0;
3035} 3035}
3036 3036
3037int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
3038 enum i915_cache_level cache_level)
3039{
3040 int ret;
3041
3042 if (obj->cache_level == cache_level)
3043 return 0;
3044
3045 if (obj->pin_count) {
3046 DRM_DEBUG("can not change the cache level of pinned objects\n");
3047 return -EBUSY;
3048 }
3049
3050 if (obj->gtt_space) {
3051 ret = i915_gem_object_finish_gpu(obj);
3052 if (ret)
3053 return ret;
3054
3055 i915_gem_object_finish_gtt(obj);
3056
3057 /* Before SandyBridge, you could not use tiling or fence
3058 * registers with snooped memory, so relinquish any fences
3059 * currently pointing to our region in the aperture.
3060 */
3061 if (INTEL_INFO(obj->base.dev)->gen < 6) {
3062 ret = i915_gem_object_put_fence(obj);
3063 if (ret)
3064 return ret;
3065 }
3066
3067 i915_gem_gtt_rebind_object(obj, cache_level);
3068 }
3069
3070 if (cache_level == I915_CACHE_NONE) {
3071 u32 old_read_domains, old_write_domain;
3072
3073 /* If we're coming from LLC cached, then we haven't
3074 * actually been tracking whether the data is in the
3075 * CPU cache or not, since we only allow one bit set
3076 * in obj->write_domain and have been skipping the clflushes.
3077 * Just set it to the CPU cache for now.
3078 */
3079 WARN_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU);
3080 WARN_ON(obj->base.read_domains & ~I915_GEM_DOMAIN_CPU);
3081
3082 old_read_domains = obj->base.read_domains;
3083 old_write_domain = obj->base.write_domain;
3084
3085 obj->base.read_domains = I915_GEM_DOMAIN_CPU;
3086 obj->base.write_domain = I915_GEM_DOMAIN_CPU;
3087
3088 trace_i915_gem_object_change_domain(obj,
3089 old_read_domains,
3090 old_write_domain);
3091 }
3092
3093 obj->cache_level = cache_level;
3094 return 0;
3095}
3096
3037/* 3097/*
3038 * Prepare buffer for display plane. Use uninterruptible for possible flush 3098 * Prepare buffer for display plane. Use uninterruptible for possible flush
3039 * wait, as in modesetting process we're not supposed to be interrupted. 3099 * wait, as in modesetting process we're not supposed to be interrupted.