1e555d299SFrançois Tigeot /* 2e555d299SFrançois Tigeot * Copyright © 2011-2012 Intel Corporation 3e555d299SFrançois Tigeot * 4e555d299SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 5e555d299SFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 6e555d299SFrançois Tigeot * to deal in the Software without restriction, including without limitation 7e555d299SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8e555d299SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 9e555d299SFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 10e555d299SFrançois Tigeot * 11e555d299SFrançois Tigeot * The above copyright notice and this permission notice (including the next 12e555d299SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 13e555d299SFrançois Tigeot * Software. 14e555d299SFrançois Tigeot * 15e555d299SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16e555d299SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17e555d299SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18e555d299SFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19e555d299SFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20e555d299SFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21e555d299SFrançois Tigeot * IN THE SOFTWARE. 22e555d299SFrançois Tigeot * 23e555d299SFrançois Tigeot * Authors: 24e555d299SFrançois Tigeot * Ben Widawsky <ben@bwidawsk.net> 25e555d299SFrançois Tigeot * 26e555d299SFrançois Tigeot */ 27e555d299SFrançois Tigeot 28e555d299SFrançois Tigeot /* 29e555d299SFrançois Tigeot * This file implements HW context support. On gen5+ a HW context consists of an 30e555d299SFrançois Tigeot * opaque GPU object which is referenced at times of context saves and restores. 31e555d299SFrançois Tigeot * With RC6 enabled, the context is also referenced as the GPU enters and exists 32e555d299SFrançois Tigeot * from RC6 (GPU has it's own internal power context, except on gen5). Though 33e555d299SFrançois Tigeot * something like a context does exist for the media ring, the code only 34e555d299SFrançois Tigeot * supports contexts for the render ring. 35e555d299SFrançois Tigeot * 36e555d299SFrançois Tigeot * In software, there is a distinction between contexts created by the user, 37e555d299SFrançois Tigeot * and the default HW context. The default HW context is used by GPU clients 38e555d299SFrançois Tigeot * that do not request setup of their own hardware context. The default 39e555d299SFrançois Tigeot * context's state is never restored to help prevent programming errors. This 40e555d299SFrançois Tigeot * would happen if a client ran and piggy-backed off another clients GPU state. 41e555d299SFrançois Tigeot * The default context only exists to give the GPU some offset to load as the 42e555d299SFrançois Tigeot * current to invoke a save of the context we actually care about. In fact, the 43e555d299SFrançois Tigeot * code could likely be constructed, albeit in a more complicated fashion, to 44e555d299SFrançois Tigeot * never use the default context, though that limits the driver's ability to 45e555d299SFrançois Tigeot * swap out, and/or destroy other contexts. 46e555d299SFrançois Tigeot * 47e555d299SFrançois Tigeot * All other contexts are created as a request by the GPU client. These contexts 48e555d299SFrançois Tigeot * store GPU state, and thus allow GPU clients to not re-emit state (and 49e555d299SFrançois Tigeot * potentially query certain state) at any time. The kernel driver makes 50e555d299SFrançois Tigeot * certain that the appropriate commands are inserted. 51e555d299SFrançois Tigeot * 52e555d299SFrançois Tigeot * The context life cycle is semi-complicated in that context BOs may live 53e555d299SFrançois Tigeot * longer than the context itself because of the way the hardware, and object 54e555d299SFrançois Tigeot * tracking works. Below is a very crude representation of the state machine 55e555d299SFrançois Tigeot * describing the context life. 56e555d299SFrançois Tigeot * refcount pincount active 57e555d299SFrançois Tigeot * S0: initial state 0 0 0 58e555d299SFrançois Tigeot * S1: context created 1 0 0 59e555d299SFrançois Tigeot * S2: context is currently running 2 1 X 60e555d299SFrançois Tigeot * S3: GPU referenced, but not current 2 0 1 61e555d299SFrançois Tigeot * S4: context is current, but destroyed 1 1 0 62e555d299SFrançois Tigeot * S5: like S3, but destroyed 1 0 1 63e555d299SFrançois Tigeot * 64e555d299SFrançois Tigeot * The most common (but not all) transitions: 65e555d299SFrançois Tigeot * S0->S1: client creates a context 66e555d299SFrançois Tigeot * S1->S2: client submits execbuf with context 67e555d299SFrançois Tigeot * S2->S3: other clients submits execbuf with context 68e555d299SFrançois Tigeot * S3->S1: context object was retired 69e555d299SFrançois Tigeot * S3->S2: clients submits another execbuf 70e555d299SFrançois Tigeot * S2->S4: context destroy called with current context 71e555d299SFrançois Tigeot * S3->S5->S0: destroy path 72e555d299SFrançois Tigeot * S4->S5->S0: destroy path on current context 73e555d299SFrançois Tigeot * 74e555d299SFrançois Tigeot * There are two confusing terms used above: 75e555d299SFrançois Tigeot * The "current context" means the context which is currently running on the 769edbd4a0SFrançois Tigeot * GPU. The GPU has loaded its state already and has stored away the gtt 77e555d299SFrançois Tigeot * offset of the BO. The GPU is not actively referencing the data at this 78e555d299SFrançois Tigeot * offset, but it will on the next context switch. The only way to avoid this 79e555d299SFrançois Tigeot * is to do a GPU reset. 80e555d299SFrançois Tigeot * 81e555d299SFrançois Tigeot * An "active context' is one which was previously the "current context" and is 82e555d299SFrançois Tigeot * on the active list waiting for the next context switch to occur. Until this 83e555d299SFrançois Tigeot * happens, the object must remain at the same gtt offset. It is therefore 84e555d299SFrançois Tigeot * possible to destroy a context, but it is still active. 85e555d299SFrançois Tigeot * 86e555d299SFrançois Tigeot */ 87e555d299SFrançois Tigeot 88e555d299SFrançois Tigeot #include <drm/drmP.h> 89e555d299SFrançois Tigeot #include <drm/i915_drm.h> 90e555d299SFrançois Tigeot #include "i915_drv.h" 91e555d299SFrançois Tigeot 92e555d299SFrançois Tigeot /* This is a HW constraint. The value below is the largest known requirement 93e555d299SFrançois Tigeot * I've seen in a spec to date, and that was a workaround for a non-shipping 94e555d299SFrançois Tigeot * part. It should be safe to decrease this, but it's more future proof as is. 95e555d299SFrançois Tigeot */ 96ba55f2f5SFrançois Tigeot #define GEN6_CONTEXT_ALIGN (64<<10) 97ba55f2f5SFrançois Tigeot #define GEN7_CONTEXT_ALIGN 4096 98e555d299SFrançois Tigeot 99ba55f2f5SFrançois Tigeot static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) 100ba55f2f5SFrançois Tigeot { 101ba55f2f5SFrançois Tigeot struct drm_device *dev = ppgtt->base.dev; 102ba55f2f5SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 103ba55f2f5SFrançois Tigeot struct i915_address_space *vm = &ppgtt->base; 104ba55f2f5SFrançois Tigeot 105ba55f2f5SFrançois Tigeot if (ppgtt == dev_priv->mm.aliasing_ppgtt || 106ba55f2f5SFrançois Tigeot (list_empty(&vm->active_list) && list_empty(&vm->inactive_list))) { 107ba55f2f5SFrançois Tigeot ppgtt->base.cleanup(&ppgtt->base); 108ba55f2f5SFrançois Tigeot return; 109ba55f2f5SFrançois Tigeot } 110ba55f2f5SFrançois Tigeot 111ba55f2f5SFrançois Tigeot /* 112ba55f2f5SFrançois Tigeot * Make sure vmas are unbound before we take down the drm_mm 113ba55f2f5SFrançois Tigeot * 114ba55f2f5SFrançois Tigeot * FIXME: Proper refcounting should take care of this, this shouldn't be 115ba55f2f5SFrançois Tigeot * needed at all. 116ba55f2f5SFrançois Tigeot */ 117ba55f2f5SFrançois Tigeot if (!list_empty(&vm->active_list)) { 118ba55f2f5SFrançois Tigeot struct i915_vma *vma; 119ba55f2f5SFrançois Tigeot 120ba55f2f5SFrançois Tigeot list_for_each_entry(vma, &vm->active_list, mm_list) 121ba55f2f5SFrançois Tigeot if (WARN_ON(list_empty(&vma->vma_link) || 122ba55f2f5SFrançois Tigeot list_is_singular(&vma->vma_link))) 123ba55f2f5SFrançois Tigeot break; 124ba55f2f5SFrançois Tigeot 125ba55f2f5SFrançois Tigeot i915_gem_evict_vm(&ppgtt->base, true); 126ba55f2f5SFrançois Tigeot } else { 127ba55f2f5SFrançois Tigeot i915_gem_retire_requests(dev); 128ba55f2f5SFrançois Tigeot i915_gem_evict_vm(&ppgtt->base, false); 129ba55f2f5SFrançois Tigeot } 130ba55f2f5SFrançois Tigeot 131ba55f2f5SFrançois Tigeot ppgtt->base.cleanup(&ppgtt->base); 132ba55f2f5SFrançois Tigeot } 133ba55f2f5SFrançois Tigeot 134ba55f2f5SFrançois Tigeot static void ppgtt_release(struct kref *kref) 135ba55f2f5SFrançois Tigeot { 136ba55f2f5SFrançois Tigeot struct i915_hw_ppgtt *ppgtt = 137ba55f2f5SFrançois Tigeot container_of(kref, struct i915_hw_ppgtt, ref); 138ba55f2f5SFrançois Tigeot 139ba55f2f5SFrançois Tigeot do_ppgtt_cleanup(ppgtt); 140ba55f2f5SFrançois Tigeot kfree(ppgtt); 141ba55f2f5SFrançois Tigeot } 142ba55f2f5SFrançois Tigeot 143ba55f2f5SFrançois Tigeot static size_t get_context_alignment(struct drm_device *dev) 144ba55f2f5SFrançois Tigeot { 145ba55f2f5SFrançois Tigeot if (IS_GEN6(dev)) 146ba55f2f5SFrançois Tigeot return GEN6_CONTEXT_ALIGN; 147ba55f2f5SFrançois Tigeot 148ba55f2f5SFrançois Tigeot return GEN7_CONTEXT_ALIGN; 149ba55f2f5SFrançois Tigeot } 150e555d299SFrançois Tigeot 151e555d299SFrançois Tigeot static int get_context_size(struct drm_device *dev) 152e555d299SFrançois Tigeot { 153e555d299SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 154e555d299SFrançois Tigeot int ret; 155e555d299SFrançois Tigeot u32 reg; 156e555d299SFrançois Tigeot 157e555d299SFrançois Tigeot switch (INTEL_INFO(dev)->gen) { 158e555d299SFrançois Tigeot case 6: 159e555d299SFrançois Tigeot reg = I915_READ(CXT_SIZE); 160e555d299SFrançois Tigeot ret = GEN6_CXT_TOTAL_SIZE(reg) * 64; 161e555d299SFrançois Tigeot break; 162e555d299SFrançois Tigeot case 7: 163e555d299SFrançois Tigeot reg = I915_READ(GEN7_CXT_SIZE); 164e555d299SFrançois Tigeot if (IS_HASWELL(dev)) 1655d0b1887SFrançois Tigeot ret = HSW_CXT_TOTAL_SIZE; 166e555d299SFrançois Tigeot else 167e555d299SFrançois Tigeot ret = GEN7_CXT_TOTAL_SIZE(reg) * 64; 168e555d299SFrançois Tigeot break; 1699edbd4a0SFrançois Tigeot case 8: 1709edbd4a0SFrançois Tigeot ret = GEN8_CXT_TOTAL_SIZE; 1719edbd4a0SFrançois Tigeot break; 172e555d299SFrançois Tigeot default: 173e555d299SFrançois Tigeot BUG(); 174e555d299SFrançois Tigeot } 175e555d299SFrançois Tigeot 176e555d299SFrançois Tigeot return ret; 177e555d299SFrançois Tigeot } 178e555d299SFrançois Tigeot 1795d0b1887SFrançois Tigeot void i915_gem_context_free(struct kref *ctx_ref) 180e555d299SFrançois Tigeot { 181ba55f2f5SFrançois Tigeot struct intel_context *ctx = container_of(ctx_ref, 1825d0b1887SFrançois Tigeot typeof(*ctx), ref); 183ba55f2f5SFrançois Tigeot struct i915_hw_ppgtt *ppgtt = NULL; 184e555d299SFrançois Tigeot 185*24edb884SFrançois Tigeot if (ctx->legacy_hw_ctx.rcs_state) { 186ba55f2f5SFrançois Tigeot /* We refcount even the aliasing PPGTT to keep the code symmetric */ 187*24edb884SFrançois Tigeot if (USES_PPGTT(ctx->legacy_hw_ctx.rcs_state->base.dev)) 188ba55f2f5SFrançois Tigeot ppgtt = ctx_to_ppgtt(ctx); 189ba55f2f5SFrançois Tigeot } 190ba55f2f5SFrançois Tigeot 191ba55f2f5SFrançois Tigeot if (ppgtt) 192ba55f2f5SFrançois Tigeot kref_put(&ppgtt->ref, ppgtt_release); 193*24edb884SFrançois Tigeot if (ctx->legacy_hw_ctx.rcs_state) 194*24edb884SFrançois Tigeot drm_gem_object_unreference(&ctx->legacy_hw_ctx.rcs_state->base); 195ba55f2f5SFrançois Tigeot list_del(&ctx->link); 196158486a6SFrançois Tigeot kfree(ctx); 197e555d299SFrançois Tigeot } 198e555d299SFrançois Tigeot 199*24edb884SFrançois Tigeot static struct drm_i915_gem_object * 200*24edb884SFrançois Tigeot i915_gem_alloc_context_obj(struct drm_device *dev, size_t size) 201*24edb884SFrançois Tigeot { 202*24edb884SFrançois Tigeot struct drm_i915_gem_object *obj; 203*24edb884SFrançois Tigeot int ret; 204*24edb884SFrançois Tigeot 205*24edb884SFrançois Tigeot obj = i915_gem_alloc_object(dev, size); 206*24edb884SFrançois Tigeot if (obj == NULL) 207*24edb884SFrançois Tigeot return ERR_PTR(-ENOMEM); 208*24edb884SFrançois Tigeot 209*24edb884SFrançois Tigeot /* 210*24edb884SFrançois Tigeot * Try to make the context utilize L3 as well as LLC. 211*24edb884SFrançois Tigeot * 212*24edb884SFrançois Tigeot * On VLV we don't have L3 controls in the PTEs so we 213*24edb884SFrançois Tigeot * shouldn't touch the cache level, especially as that 214*24edb884SFrançois Tigeot * would make the object snooped which might have a 215*24edb884SFrançois Tigeot * negative performance impact. 216*24edb884SFrançois Tigeot */ 217*24edb884SFrançois Tigeot if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev)) { 218*24edb884SFrançois Tigeot ret = i915_gem_object_set_cache_level(obj, I915_CACHE_L3_LLC); 219*24edb884SFrançois Tigeot /* Failure shouldn't ever happen this early */ 220*24edb884SFrançois Tigeot if (WARN_ON(ret)) { 221*24edb884SFrançois Tigeot drm_gem_object_unreference(&obj->base); 222*24edb884SFrançois Tigeot return ERR_PTR(ret); 223*24edb884SFrançois Tigeot } 224*24edb884SFrançois Tigeot } 225*24edb884SFrançois Tigeot 226*24edb884SFrançois Tigeot return obj; 227*24edb884SFrançois Tigeot } 228*24edb884SFrançois Tigeot 229ba55f2f5SFrançois Tigeot static struct i915_hw_ppgtt * 230ba55f2f5SFrançois Tigeot create_vm_for_ctx(struct drm_device *dev, struct intel_context *ctx) 231ba55f2f5SFrançois Tigeot { 232ba55f2f5SFrançois Tigeot struct i915_hw_ppgtt *ppgtt; 233ba55f2f5SFrançois Tigeot int ret; 234ba55f2f5SFrançois Tigeot 235ba55f2f5SFrançois Tigeot ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); 236ba55f2f5SFrançois Tigeot if (!ppgtt) 237ba55f2f5SFrançois Tigeot return ERR_PTR(-ENOMEM); 238ba55f2f5SFrançois Tigeot 239ba55f2f5SFrançois Tigeot ret = i915_gem_init_ppgtt(dev, ppgtt); 240ba55f2f5SFrançois Tigeot if (ret) { 241ba55f2f5SFrançois Tigeot kfree(ppgtt); 242ba55f2f5SFrançois Tigeot return ERR_PTR(ret); 243ba55f2f5SFrançois Tigeot } 244ba55f2f5SFrançois Tigeot 245ba55f2f5SFrançois Tigeot ppgtt->ctx = ctx; 246ba55f2f5SFrançois Tigeot return ppgtt; 247ba55f2f5SFrançois Tigeot } 248ba55f2f5SFrançois Tigeot 249ba55f2f5SFrançois Tigeot static struct intel_context * 250ba55f2f5SFrançois Tigeot __create_hw_context(struct drm_device *dev, 251e555d299SFrançois Tigeot struct drm_i915_file_private *file_priv) 252e555d299SFrançois Tigeot { 253e555d299SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 254ba55f2f5SFrançois Tigeot struct intel_context *ctx; 2559f0f5970SFrançois Tigeot int ret; 256e555d299SFrançois Tigeot 257159fc1d7SFrançois Tigeot ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 258e555d299SFrançois Tigeot if (ctx == NULL) 259e555d299SFrançois Tigeot return ERR_PTR(-ENOMEM); 260e555d299SFrançois Tigeot 2615d0b1887SFrançois Tigeot kref_init(&ctx->ref); 262ba55f2f5SFrançois Tigeot list_add_tail(&ctx->link, &dev_priv->context_list); 263ba55f2f5SFrançois Tigeot 264ba55f2f5SFrançois Tigeot if (dev_priv->hw_context_size) { 265*24edb884SFrançois Tigeot struct drm_i915_gem_object *obj = 266*24edb884SFrançois Tigeot i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size); 267*24edb884SFrançois Tigeot if (IS_ERR(obj)) { 268*24edb884SFrançois Tigeot ret = PTR_ERR(obj); 269ba55f2f5SFrançois Tigeot goto err_out; 270e555d299SFrançois Tigeot } 271*24edb884SFrançois Tigeot ctx->legacy_hw_ctx.rcs_state = obj; 272ba55f2f5SFrançois Tigeot } 273e555d299SFrançois Tigeot 274e555d299SFrançois Tigeot /* Default context will never have a file_priv */ 275ba55f2f5SFrançois Tigeot if (file_priv != NULL) { 276ba55f2f5SFrançois Tigeot ret = idr_alloc(&file_priv->context_idr, ctx, 277*24edb884SFrançois Tigeot DEFAULT_CONTEXT_HANDLE, 0, GFP_KERNEL); 2789f0f5970SFrançois Tigeot if (ret < 0) 279e555d299SFrançois Tigeot goto err_out; 280ba55f2f5SFrançois Tigeot } else 281*24edb884SFrançois Tigeot ret = DEFAULT_CONTEXT_HANDLE; 2825d0b1887SFrançois Tigeot 2835d0b1887SFrançois Tigeot ctx->file_priv = file_priv; 284*24edb884SFrançois Tigeot ctx->user_handle = ret; 2859edbd4a0SFrançois Tigeot /* NB: Mark all slices as needing a remap so that when the context first 2869edbd4a0SFrançois Tigeot * loads it will restore whatever remap state already exists. If there 2879edbd4a0SFrançois Tigeot * is no remap info, it will be a NOP. */ 2889edbd4a0SFrançois Tigeot ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1; 289e555d299SFrançois Tigeot 290e555d299SFrançois Tigeot return ctx; 291e555d299SFrançois Tigeot 292e555d299SFrançois Tigeot err_out: 2935d0b1887SFrançois Tigeot i915_gem_context_unreference(ctx); 294e555d299SFrançois Tigeot return ERR_PTR(ret); 295e555d299SFrançois Tigeot } 296e555d299SFrançois Tigeot 297e555d299SFrançois Tigeot /** 298e555d299SFrançois Tigeot * The default context needs to exist per ring that uses contexts. It stores the 299e555d299SFrançois Tigeot * context state of the GPU for applications that don't utilize HW contexts, as 300e555d299SFrançois Tigeot * well as an idle case. 301e555d299SFrançois Tigeot */ 302ba55f2f5SFrançois Tigeot static struct intel_context * 303ba55f2f5SFrançois Tigeot i915_gem_create_context(struct drm_device *dev, 304ba55f2f5SFrançois Tigeot struct drm_i915_file_private *file_priv, 305ba55f2f5SFrançois Tigeot bool create_vm) 306e555d299SFrançois Tigeot { 307ba55f2f5SFrançois Tigeot const bool is_global_default_ctx = file_priv == NULL; 308ba55f2f5SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 309ba55f2f5SFrançois Tigeot struct intel_context *ctx; 310ba55f2f5SFrançois Tigeot int ret = 0; 311e555d299SFrançois Tigeot 312ba55f2f5SFrançois Tigeot BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 313e555d299SFrançois Tigeot 314ba55f2f5SFrançois Tigeot ctx = __create_hw_context(dev, file_priv); 315e555d299SFrançois Tigeot if (IS_ERR(ctx)) 316ba55f2f5SFrançois Tigeot return ctx; 317e555d299SFrançois Tigeot 318*24edb884SFrançois Tigeot if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) { 319ba55f2f5SFrançois Tigeot /* We may need to do things with the shrinker which 320ba55f2f5SFrançois Tigeot * require us to immediately switch back to the default 321ba55f2f5SFrançois Tigeot * context. This can cause a problem as pinning the 322ba55f2f5SFrançois Tigeot * default context also requires GTT space which may not 323ba55f2f5SFrançois Tigeot * be available. To avoid this we always pin the default 324ba55f2f5SFrançois Tigeot * context. 325e555d299SFrançois Tigeot */ 326*24edb884SFrançois Tigeot ret = i915_gem_obj_ggtt_pin(ctx->legacy_hw_ctx.rcs_state, 327ba55f2f5SFrançois Tigeot get_context_alignment(dev), 0); 3285d0b1887SFrançois Tigeot if (ret) { 3295d0b1887SFrançois Tigeot DRM_DEBUG_DRIVER("Couldn't pin %d\n", ret); 330e555d299SFrançois Tigeot goto err_destroy; 3315d0b1887SFrançois Tigeot } 332ba55f2f5SFrançois Tigeot } 333e555d299SFrançois Tigeot 334ba55f2f5SFrançois Tigeot if (create_vm) { 335ba55f2f5SFrançois Tigeot struct i915_hw_ppgtt *ppgtt = create_vm_for_ctx(dev, ctx); 336ba55f2f5SFrançois Tigeot 337ba55f2f5SFrançois Tigeot if (IS_ERR_OR_NULL(ppgtt)) { 338ba55f2f5SFrançois Tigeot DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", 339ba55f2f5SFrançois Tigeot PTR_ERR(ppgtt)); 340ba55f2f5SFrançois Tigeot ret = PTR_ERR(ppgtt); 341ba55f2f5SFrançois Tigeot goto err_unpin; 342ba55f2f5SFrançois Tigeot } else 343ba55f2f5SFrançois Tigeot ctx->vm = &ppgtt->base; 344ba55f2f5SFrançois Tigeot 345ba55f2f5SFrançois Tigeot /* This case is reserved for the global default context and 346ba55f2f5SFrançois Tigeot * should only happen once. */ 347ba55f2f5SFrançois Tigeot if (is_global_default_ctx) { 348ba55f2f5SFrançois Tigeot if (WARN_ON(dev_priv->mm.aliasing_ppgtt)) { 349ba55f2f5SFrançois Tigeot ret = -EEXIST; 350e555d299SFrançois Tigeot goto err_unpin; 3515d0b1887SFrançois Tigeot } 352e555d299SFrançois Tigeot 353ba55f2f5SFrançois Tigeot dev_priv->mm.aliasing_ppgtt = ppgtt; 354ba55f2f5SFrançois Tigeot } 355ba55f2f5SFrançois Tigeot } else if (USES_PPGTT(dev)) { 356ba55f2f5SFrançois Tigeot /* For platforms which only have aliasing PPGTT, we fake the 357ba55f2f5SFrançois Tigeot * address space and refcounting. */ 358ba55f2f5SFrançois Tigeot ctx->vm = &dev_priv->mm.aliasing_ppgtt->base; 359ba55f2f5SFrançois Tigeot kref_get(&dev_priv->mm.aliasing_ppgtt->ref); 360ba55f2f5SFrançois Tigeot } else 361ba55f2f5SFrançois Tigeot ctx->vm = &dev_priv->gtt.base; 3629edbd4a0SFrançois Tigeot 363ba55f2f5SFrançois Tigeot return ctx; 364e555d299SFrançois Tigeot 365e555d299SFrançois Tigeot err_unpin: 366*24edb884SFrançois Tigeot if (is_global_default_ctx && ctx->legacy_hw_ctx.rcs_state) 367*24edb884SFrançois Tigeot i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state); 368e555d299SFrançois Tigeot err_destroy: 3695d0b1887SFrançois Tigeot i915_gem_context_unreference(ctx); 370ba55f2f5SFrançois Tigeot return ERR_PTR(ret); 371ba55f2f5SFrançois Tigeot } 372ba55f2f5SFrançois Tigeot 373ba55f2f5SFrançois Tigeot void i915_gem_context_reset(struct drm_device *dev) 374ba55f2f5SFrançois Tigeot { 375ba55f2f5SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 376ba55f2f5SFrançois Tigeot int i; 377ba55f2f5SFrançois Tigeot 378ba55f2f5SFrançois Tigeot /* Prevent the hardware from restoring the last context (which hung) on 379ba55f2f5SFrançois Tigeot * the next switch */ 380ba55f2f5SFrançois Tigeot for (i = 0; i < I915_NUM_RINGS; i++) { 381ba55f2f5SFrançois Tigeot struct intel_engine_cs *ring = &dev_priv->ring[i]; 382ba55f2f5SFrançois Tigeot struct intel_context *dctx = ring->default_context; 383*24edb884SFrançois Tigeot struct intel_context *lctx = ring->last_context; 384ba55f2f5SFrançois Tigeot 385ba55f2f5SFrançois Tigeot /* Do a fake switch to the default context */ 386*24edb884SFrançois Tigeot if (lctx == dctx) 387ba55f2f5SFrançois Tigeot continue; 388ba55f2f5SFrançois Tigeot 389*24edb884SFrançois Tigeot if (!lctx) 390ba55f2f5SFrançois Tigeot continue; 391ba55f2f5SFrançois Tigeot 392*24edb884SFrançois Tigeot if (dctx->legacy_hw_ctx.rcs_state && i == RCS) { 393*24edb884SFrançois Tigeot WARN_ON(i915_gem_obj_ggtt_pin(dctx->legacy_hw_ctx.rcs_state, 394ba55f2f5SFrançois Tigeot get_context_alignment(dev), 0)); 395ba55f2f5SFrançois Tigeot /* Fake a finish/inactive */ 396*24edb884SFrançois Tigeot dctx->legacy_hw_ctx.rcs_state->base.write_domain = 0; 397*24edb884SFrançois Tigeot dctx->legacy_hw_ctx.rcs_state->active = 0; 398ba55f2f5SFrançois Tigeot } 399ba55f2f5SFrançois Tigeot 400*24edb884SFrançois Tigeot if (lctx->legacy_hw_ctx.rcs_state && i == RCS) 401*24edb884SFrançois Tigeot i915_gem_object_ggtt_unpin(lctx->legacy_hw_ctx.rcs_state); 402*24edb884SFrançois Tigeot 403*24edb884SFrançois Tigeot i915_gem_context_unreference(lctx); 404ba55f2f5SFrançois Tigeot i915_gem_context_reference(dctx); 405ba55f2f5SFrançois Tigeot ring->last_context = dctx; 406ba55f2f5SFrançois Tigeot } 407e555d299SFrançois Tigeot } 408e555d299SFrançois Tigeot 4099edbd4a0SFrançois Tigeot int i915_gem_context_init(struct drm_device *dev) 410e555d299SFrançois Tigeot { 411e555d299SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 412ba55f2f5SFrançois Tigeot struct intel_context *ctx; 413ba55f2f5SFrançois Tigeot int i; 414e555d299SFrançois Tigeot 415ba55f2f5SFrançois Tigeot /* Init should only be called once per module load. Eventually the 416ba55f2f5SFrançois Tigeot * restriction on the context_disabled check can be loosened. */ 417ba55f2f5SFrançois Tigeot if (WARN_ON(dev_priv->ring[RCS].default_context)) 4189edbd4a0SFrançois Tigeot return 0; 419e555d299SFrançois Tigeot 420ba55f2f5SFrançois Tigeot if (HAS_HW_CONTEXTS(dev)) { 421a2fdbec6SFrançois Tigeot dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); 422a2fdbec6SFrançois Tigeot if (dev_priv->hw_context_size > (1<<20)) { 423ba55f2f5SFrançois Tigeot DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n", 424ba55f2f5SFrançois Tigeot dev_priv->hw_context_size); 425ba55f2f5SFrançois Tigeot dev_priv->hw_context_size = 0; 426ba55f2f5SFrançois Tigeot } 427e555d299SFrançois Tigeot } 428e555d299SFrançois Tigeot 429ba55f2f5SFrançois Tigeot ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev)); 430ba55f2f5SFrançois Tigeot if (IS_ERR(ctx)) { 431ba55f2f5SFrançois Tigeot DRM_ERROR("Failed to create default global context (error %ld)\n", 432ba55f2f5SFrançois Tigeot PTR_ERR(ctx)); 433ba55f2f5SFrançois Tigeot return PTR_ERR(ctx); 434e555d299SFrançois Tigeot } 435e555d299SFrançois Tigeot 436ba55f2f5SFrançois Tigeot /* NB: RCS will hold a ref for all rings */ 437ba55f2f5SFrançois Tigeot for (i = 0; i < I915_NUM_RINGS; i++) 438ba55f2f5SFrançois Tigeot dev_priv->ring[i].default_context = ctx; 439ba55f2f5SFrançois Tigeot 440ba55f2f5SFrançois Tigeot DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake"); 4419edbd4a0SFrançois Tigeot return 0; 442e555d299SFrançois Tigeot } 443e555d299SFrançois Tigeot 444e555d299SFrançois Tigeot void i915_gem_context_fini(struct drm_device *dev) 445e555d299SFrançois Tigeot { 446e555d299SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 447ba55f2f5SFrançois Tigeot struct intel_context *dctx = dev_priv->ring[RCS].default_context; 448ba55f2f5SFrançois Tigeot int i; 449e555d299SFrançois Tigeot 450*24edb884SFrançois Tigeot if (dctx->legacy_hw_ctx.rcs_state) { 451e555d299SFrançois Tigeot /* The only known way to stop the gpu from accessing the hw context is 452e555d299SFrançois Tigeot * to reset it. Do this as the very last operation to avoid confusing 453e555d299SFrançois Tigeot * other code, leading to spurious errors. */ 454e555d299SFrançois Tigeot intel_gpu_reset(dev); 455e555d299SFrançois Tigeot 4565d0b1887SFrançois Tigeot /* When default context is created and switched to, base object refcount 4575d0b1887SFrançois Tigeot * will be 2 (+1 from object creation and +1 from do_switch()). 4585d0b1887SFrançois Tigeot * i915_gem_context_fini() will be called after gpu_idle() has switched 4595d0b1887SFrançois Tigeot * to default context. So we need to unreference the base object once 4605d0b1887SFrançois Tigeot * to offset the do_switch part, so that i915_gem_context_unreference() 4615d0b1887SFrançois Tigeot * can then free the base object correctly. */ 4629edbd4a0SFrançois Tigeot WARN_ON(!dev_priv->ring[RCS].last_context); 4639edbd4a0SFrançois Tigeot if (dev_priv->ring[RCS].last_context == dctx) { 4649edbd4a0SFrançois Tigeot /* Fake switch to NULL context */ 465*24edb884SFrançois Tigeot WARN_ON(dctx->legacy_hw_ctx.rcs_state->active); 466*24edb884SFrançois Tigeot i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state); 467ba55f2f5SFrançois Tigeot i915_gem_context_unreference(dctx); 468ba55f2f5SFrançois Tigeot dev_priv->ring[RCS].last_context = NULL; 469ba55f2f5SFrançois Tigeot } 470ba55f2f5SFrançois Tigeot 471*24edb884SFrançois Tigeot i915_gem_object_ggtt_unpin(dctx->legacy_hw_ctx.rcs_state); 472ba55f2f5SFrançois Tigeot } 473ba55f2f5SFrançois Tigeot 474ba55f2f5SFrançois Tigeot for (i = 0; i < I915_NUM_RINGS; i++) { 475ba55f2f5SFrançois Tigeot struct intel_engine_cs *ring = &dev_priv->ring[i]; 476ba55f2f5SFrançois Tigeot 477ba55f2f5SFrançois Tigeot if (ring->last_context) 478ba55f2f5SFrançois Tigeot i915_gem_context_unreference(ring->last_context); 479ba55f2f5SFrançois Tigeot 480ba55f2f5SFrançois Tigeot ring->default_context = NULL; 481ba55f2f5SFrançois Tigeot ring->last_context = NULL; 482ba55f2f5SFrançois Tigeot } 483ba55f2f5SFrançois Tigeot 4845d0b1887SFrançois Tigeot i915_gem_context_unreference(dctx); 485e555d299SFrançois Tigeot } 486e555d299SFrançois Tigeot 487ba55f2f5SFrançois Tigeot int i915_gem_context_enable(struct drm_i915_private *dev_priv) 488ba55f2f5SFrançois Tigeot { 489ba55f2f5SFrançois Tigeot struct intel_engine_cs *ring; 490ba55f2f5SFrançois Tigeot int ret, i; 491ba55f2f5SFrançois Tigeot 492ba55f2f5SFrançois Tigeot /* This is the only place the aliasing PPGTT gets enabled, which means 493ba55f2f5SFrançois Tigeot * it has to happen before we bail on reset */ 494ba55f2f5SFrançois Tigeot if (dev_priv->mm.aliasing_ppgtt) { 495ba55f2f5SFrançois Tigeot struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; 496ba55f2f5SFrançois Tigeot ppgtt->enable(ppgtt); 497ba55f2f5SFrançois Tigeot } 498ba55f2f5SFrançois Tigeot 499ba55f2f5SFrançois Tigeot /* FIXME: We should make this work, even in reset */ 500ba55f2f5SFrançois Tigeot if (i915_reset_in_progress(&dev_priv->gpu_error)) 501ba55f2f5SFrançois Tigeot return 0; 502ba55f2f5SFrançois Tigeot 503ba55f2f5SFrançois Tigeot BUG_ON(!dev_priv->ring[RCS].default_context); 504ba55f2f5SFrançois Tigeot 505ba55f2f5SFrançois Tigeot for_each_ring(ring, dev_priv, i) { 506ba55f2f5SFrançois Tigeot ret = i915_switch_context(ring, ring->default_context); 507ba55f2f5SFrançois Tigeot if (ret) 508ba55f2f5SFrançois Tigeot return ret; 509ba55f2f5SFrançois Tigeot } 510ba55f2f5SFrançois Tigeot 511ba55f2f5SFrançois Tigeot return 0; 5129edbd4a0SFrançois Tigeot } 5139edbd4a0SFrançois Tigeot 514e555d299SFrançois Tigeot static int context_idr_cleanup(int id, void *p, void *data) 515e555d299SFrançois Tigeot { 516ba55f2f5SFrançois Tigeot struct intel_context *ctx = p; 517e555d299SFrançois Tigeot 5185d0b1887SFrançois Tigeot i915_gem_context_unreference(ctx); 519e555d299SFrançois Tigeot return 0; 520e555d299SFrançois Tigeot } 521e555d299SFrançois Tigeot 522ba55f2f5SFrançois Tigeot int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) 5235d0b1887SFrançois Tigeot { 5245d0b1887SFrançois Tigeot struct drm_i915_file_private *file_priv = file->driver_priv; 525ba55f2f5SFrançois Tigeot struct intel_context *ctx; 5265d0b1887SFrançois Tigeot 527ba55f2f5SFrançois Tigeot idr_init(&file_priv->context_idr); 5285d0b1887SFrançois Tigeot 529ba55f2f5SFrançois Tigeot mutex_lock(&dev->struct_mutex); 530ba55f2f5SFrançois Tigeot ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev)); 531ba55f2f5SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 5325d0b1887SFrançois Tigeot 533ba55f2f5SFrançois Tigeot if (IS_ERR(ctx)) { 534ba55f2f5SFrançois Tigeot idr_destroy(&file_priv->context_idr); 535ba55f2f5SFrançois Tigeot return PTR_ERR(ctx); 536ba55f2f5SFrançois Tigeot } 5379edbd4a0SFrançois Tigeot 538ba55f2f5SFrançois Tigeot return 0; 5395d0b1887SFrançois Tigeot } 5405d0b1887SFrançois Tigeot 541e555d299SFrançois Tigeot void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) 542e555d299SFrançois Tigeot { 543e555d299SFrançois Tigeot struct drm_i915_file_private *file_priv = file->driver_priv; 544e555d299SFrançois Tigeot 545e555d299SFrançois Tigeot idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); 546e555d299SFrançois Tigeot idr_destroy(&file_priv->context_idr); 547e555d299SFrançois Tigeot } 548e555d299SFrançois Tigeot 549ba55f2f5SFrançois Tigeot struct intel_context * 550e555d299SFrançois Tigeot i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) 551e555d299SFrançois Tigeot { 552ba55f2f5SFrançois Tigeot struct intel_context *ctx; 553ba55f2f5SFrançois Tigeot 554ba55f2f5SFrançois Tigeot ctx = (struct intel_context *)idr_find(&file_priv->context_idr, id); 555ba55f2f5SFrançois Tigeot if (!ctx) 556ba55f2f5SFrançois Tigeot return ERR_PTR(-ENOENT); 557ba55f2f5SFrançois Tigeot 558ba55f2f5SFrançois Tigeot return ctx; 559e555d299SFrançois Tigeot } 560e555d299SFrançois Tigeot 561e555d299SFrançois Tigeot static inline int 562ba55f2f5SFrançois Tigeot mi_set_context(struct intel_engine_cs *ring, 563ba55f2f5SFrançois Tigeot struct intel_context *new_context, 564e555d299SFrançois Tigeot u32 hw_flags) 565e555d299SFrançois Tigeot { 5660dbf0ea8SMatthew Dillon const int num_rings = 5670dbf0ea8SMatthew Dillon /* Use an extended w/a on ivb+ if signalling from other rings */ 5680dbf0ea8SMatthew Dillon i915_semaphore_is_enabled(ring->dev) ? 5690dbf0ea8SMatthew Dillon hweight32(INTEL_INFO(ring->dev)->ring_mask) - 1 : 5700dbf0ea8SMatthew Dillon 0; 5710dbf0ea8SMatthew Dillon int len, i, ret; 572e555d299SFrançois Tigeot 573e555d299SFrançois Tigeot /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB 574e555d299SFrançois Tigeot * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value 575e555d299SFrançois Tigeot * explicitly, so we rely on the value at ring init, stored in 576e555d299SFrançois Tigeot * itlb_before_ctx_switch. 577e555d299SFrançois Tigeot */ 578ba55f2f5SFrançois Tigeot if (IS_GEN6(ring->dev)) { 579e555d299SFrançois Tigeot ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, 0); 580e555d299SFrançois Tigeot if (ret) 581e555d299SFrançois Tigeot return ret; 582e555d299SFrançois Tigeot } 583e555d299SFrançois Tigeot 5840dbf0ea8SMatthew Dillon 5850dbf0ea8SMatthew Dillon len = 4; 5860dbf0ea8SMatthew Dillon if (INTEL_INFO(ring->dev)->gen >= 7) 5870dbf0ea8SMatthew Dillon len += 2 + (num_rings ? 4*num_rings + 2 : 0); 5880dbf0ea8SMatthew Dillon 5890dbf0ea8SMatthew Dillon ret = intel_ring_begin(ring, len); 590e555d299SFrançois Tigeot if (ret) 591e555d299SFrançois Tigeot return ret; 592e555d299SFrançois Tigeot 593ba55f2f5SFrançois Tigeot /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ 5940dbf0ea8SMatthew Dillon if (INTEL_INFO(ring->dev)->gen >= 7) { 595e555d299SFrançois Tigeot intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); 5960dbf0ea8SMatthew Dillon if (num_rings) { 5970dbf0ea8SMatthew Dillon struct intel_engine_cs *signaller; 5980dbf0ea8SMatthew Dillon 5990dbf0ea8SMatthew Dillon intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); 6000dbf0ea8SMatthew Dillon for_each_ring(signaller, to_i915(ring->dev), i) { 6010dbf0ea8SMatthew Dillon if (signaller == ring) 6020dbf0ea8SMatthew Dillon continue; 6030dbf0ea8SMatthew Dillon 6040dbf0ea8SMatthew Dillon intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); 6050dbf0ea8SMatthew Dillon intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); 6060dbf0ea8SMatthew Dillon } 6070dbf0ea8SMatthew Dillon } 6080dbf0ea8SMatthew Dillon } 609e555d299SFrançois Tigeot 610e555d299SFrançois Tigeot intel_ring_emit(ring, MI_NOOP); 611e555d299SFrançois Tigeot intel_ring_emit(ring, MI_SET_CONTEXT); 612*24edb884SFrançois Tigeot intel_ring_emit(ring, i915_gem_obj_ggtt_offset(new_context->legacy_hw_ctx.rcs_state) | 613e555d299SFrançois Tigeot MI_MM_SPACE_GTT | 614e555d299SFrançois Tigeot MI_SAVE_EXT_STATE_EN | 615e555d299SFrançois Tigeot MI_RESTORE_EXT_STATE_EN | 616e555d299SFrançois Tigeot hw_flags); 617ba55f2f5SFrançois Tigeot /* 618ba55f2f5SFrançois Tigeot * w/a: MI_SET_CONTEXT must always be followed by MI_NOOP 619ba55f2f5SFrançois Tigeot * WaMiSetContext_Hang:snb,ivb,vlv 620ba55f2f5SFrançois Tigeot */ 621e555d299SFrançois Tigeot intel_ring_emit(ring, MI_NOOP); 622e555d299SFrançois Tigeot 6230dbf0ea8SMatthew Dillon if (INTEL_INFO(ring->dev)->gen >= 7) { 6240dbf0ea8SMatthew Dillon if (num_rings) { 6250dbf0ea8SMatthew Dillon struct intel_engine_cs *signaller; 6260dbf0ea8SMatthew Dillon 6270dbf0ea8SMatthew Dillon intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); 6280dbf0ea8SMatthew Dillon for_each_ring(signaller, to_i915(ring->dev), i) { 6290dbf0ea8SMatthew Dillon if (signaller == ring) 6300dbf0ea8SMatthew Dillon continue; 6310dbf0ea8SMatthew Dillon 6320dbf0ea8SMatthew Dillon intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); 6330dbf0ea8SMatthew Dillon intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); 6340dbf0ea8SMatthew Dillon } 6350dbf0ea8SMatthew Dillon } 636e555d299SFrançois Tigeot intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); 6370dbf0ea8SMatthew Dillon } 638e555d299SFrançois Tigeot 639e555d299SFrançois Tigeot intel_ring_advance(ring); 640e555d299SFrançois Tigeot 641e555d299SFrançois Tigeot return ret; 642e555d299SFrançois Tigeot } 643e555d299SFrançois Tigeot 644ba55f2f5SFrançois Tigeot static int do_switch(struct intel_engine_cs *ring, 645ba55f2f5SFrançois Tigeot struct intel_context *to) 646e555d299SFrançois Tigeot { 647ba55f2f5SFrançois Tigeot struct drm_i915_private *dev_priv = ring->dev->dev_private; 648ba55f2f5SFrançois Tigeot struct intel_context *from = ring->last_context; 649ba55f2f5SFrançois Tigeot struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to); 650e555d299SFrançois Tigeot u32 hw_flags = 0; 651ba55f2f5SFrançois Tigeot bool uninitialized = false; 6529edbd4a0SFrançois Tigeot int ret, i; 653e555d299SFrançois Tigeot 654ba55f2f5SFrançois Tigeot if (from != NULL && ring == &dev_priv->ring[RCS]) { 655*24edb884SFrançois Tigeot BUG_ON(from->legacy_hw_ctx.rcs_state == NULL); 656*24edb884SFrançois Tigeot BUG_ON(!i915_gem_obj_is_pinned(from->legacy_hw_ctx.rcs_state)); 657ba55f2f5SFrançois Tigeot } 658e555d299SFrançois Tigeot 659*24edb884SFrançois Tigeot if (from == to && !to->remap_slice) 660e555d299SFrançois Tigeot return 0; 661e555d299SFrançois Tigeot 662ba55f2f5SFrançois Tigeot /* Trying to pin first makes error handling easier. */ 663ba55f2f5SFrançois Tigeot if (ring == &dev_priv->ring[RCS]) { 664*24edb884SFrançois Tigeot ret = i915_gem_obj_ggtt_pin(to->legacy_hw_ctx.rcs_state, 665ba55f2f5SFrançois Tigeot get_context_alignment(ring->dev), 0); 666e555d299SFrançois Tigeot if (ret) 667e555d299SFrançois Tigeot return ret; 668ba55f2f5SFrançois Tigeot } 669e555d299SFrançois Tigeot 6709edbd4a0SFrançois Tigeot /* 6719edbd4a0SFrançois Tigeot * Pin can switch back to the default context if we end up calling into 6729edbd4a0SFrançois Tigeot * evict_everything - as a last ditch gtt defrag effort that also 6739edbd4a0SFrançois Tigeot * switches to the default context. Hence we need to reload from here. 6749edbd4a0SFrançois Tigeot */ 6759edbd4a0SFrançois Tigeot from = ring->last_context; 6769edbd4a0SFrançois Tigeot 677ba55f2f5SFrançois Tigeot if (USES_FULL_PPGTT(ring->dev)) { 678ba55f2f5SFrançois Tigeot ret = ppgtt->switch_mm(ppgtt, ring, false); 679ba55f2f5SFrançois Tigeot if (ret) 680ba55f2f5SFrançois Tigeot goto unpin_out; 681ba55f2f5SFrançois Tigeot } 682ba55f2f5SFrançois Tigeot 683ba55f2f5SFrançois Tigeot if (ring != &dev_priv->ring[RCS]) { 684ba55f2f5SFrançois Tigeot if (from) 685ba55f2f5SFrançois Tigeot i915_gem_context_unreference(from); 686ba55f2f5SFrançois Tigeot goto done; 687ba55f2f5SFrançois Tigeot } 688ba55f2f5SFrançois Tigeot 6899edbd4a0SFrançois Tigeot /* 6909edbd4a0SFrançois Tigeot * Clear this page out of any CPU caches for coherent swap-in/out. Note 691e555d299SFrançois Tigeot * that thanks to write = false in this call and us not setting any gpu 692e555d299SFrançois Tigeot * write domains when putting a context object onto the active list 693e555d299SFrançois Tigeot * (when switching away from it), this won't block. 6949edbd4a0SFrançois Tigeot * 6959edbd4a0SFrançois Tigeot * XXX: We need a real interface to do this instead of trickery. 6969edbd4a0SFrançois Tigeot */ 697*24edb884SFrançois Tigeot ret = i915_gem_object_set_to_gtt_domain(to->legacy_hw_ctx.rcs_state, false); 698ba55f2f5SFrançois Tigeot if (ret) 699ba55f2f5SFrançois Tigeot goto unpin_out; 700ba55f2f5SFrançois Tigeot 701*24edb884SFrançois Tigeot if (!to->legacy_hw_ctx.rcs_state->has_global_gtt_mapping) { 702*24edb884SFrançois Tigeot struct i915_vma *vma = i915_gem_obj_to_vma(to->legacy_hw_ctx.rcs_state, 703ba55f2f5SFrançois Tigeot &dev_priv->gtt.base); 704*24edb884SFrançois Tigeot vma->bind_vma(vma, to->legacy_hw_ctx.rcs_state->cache_level, GLOBAL_BIND); 705e555d299SFrançois Tigeot } 706e555d299SFrançois Tigeot 707*24edb884SFrançois Tigeot if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to)) 708e555d299SFrançois Tigeot hw_flags |= MI_RESTORE_INHIBIT; 709e555d299SFrançois Tigeot 710e555d299SFrançois Tigeot ret = mi_set_context(ring, to, hw_flags); 711ba55f2f5SFrançois Tigeot if (ret) 712ba55f2f5SFrançois Tigeot goto unpin_out; 713e555d299SFrançois Tigeot 7149edbd4a0SFrançois Tigeot for (i = 0; i < MAX_L3_SLICES; i++) { 7159edbd4a0SFrançois Tigeot if (!(to->remap_slice & (1<<i))) 7169edbd4a0SFrançois Tigeot continue; 7179edbd4a0SFrançois Tigeot 7189edbd4a0SFrançois Tigeot ret = i915_gem_l3_remap(ring, i); 7199edbd4a0SFrançois Tigeot /* If it failed, try again next round */ 7209edbd4a0SFrançois Tigeot if (ret) 7219edbd4a0SFrançois Tigeot DRM_DEBUG_DRIVER("L3 remapping failed\n"); 7229edbd4a0SFrançois Tigeot else 7239edbd4a0SFrançois Tigeot to->remap_slice &= ~(1<<i); 7249edbd4a0SFrançois Tigeot } 7259edbd4a0SFrançois Tigeot 726e555d299SFrançois Tigeot /* The backing object for the context is done after switching to the 727e555d299SFrançois Tigeot * *next* context. Therefore we cannot retire the previous context until 728e555d299SFrançois Tigeot * the next context has already started running. In fact, the below code 729e555d299SFrançois Tigeot * is a bit suboptimal because the retiring can occur simply after the 730e555d299SFrançois Tigeot * MI_SET_CONTEXT instead of when the next seqno has completed. 731e555d299SFrançois Tigeot */ 7325d0b1887SFrançois Tigeot if (from != NULL) { 733*24edb884SFrançois Tigeot from->legacy_hw_ctx.rcs_state->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION; 734*24edb884SFrançois Tigeot i915_vma_move_to_active(i915_gem_obj_to_ggtt(from->legacy_hw_ctx.rcs_state), ring); 735e555d299SFrançois Tigeot /* As long as MI_SET_CONTEXT is serializing, ie. it flushes the 736e555d299SFrançois Tigeot * whole damn pipeline, we don't need to explicitly mark the 737e555d299SFrançois Tigeot * object dirty. The only exception is that the context must be 738e555d299SFrançois Tigeot * correct in case the object gets swapped out. Ideally we'd be 739e555d299SFrançois Tigeot * able to defer doing this until we know the object would be 740e555d299SFrançois Tigeot * swapped, but there is no way to do that yet. 741e555d299SFrançois Tigeot */ 742*24edb884SFrançois Tigeot from->legacy_hw_ctx.rcs_state->dirty = 1; 743*24edb884SFrançois Tigeot BUG_ON(from->legacy_hw_ctx.rcs_state->ring != ring); 744e555d299SFrançois Tigeot 7459edbd4a0SFrançois Tigeot /* obj is kept alive until the next request by its active ref */ 746*24edb884SFrançois Tigeot i915_gem_object_ggtt_unpin(from->legacy_hw_ctx.rcs_state); 7475d0b1887SFrançois Tigeot i915_gem_context_unreference(from); 7485d0b1887SFrançois Tigeot } 7495d0b1887SFrançois Tigeot 750*24edb884SFrançois Tigeot uninitialized = !to->legacy_hw_ctx.initialized && from == NULL; 751*24edb884SFrançois Tigeot to->legacy_hw_ctx.initialized = true; 752e555d299SFrançois Tigeot 753ba55f2f5SFrançois Tigeot done: 754ba55f2f5SFrançois Tigeot i915_gem_context_reference(to); 755ba55f2f5SFrançois Tigeot ring->last_context = to; 756ba55f2f5SFrançois Tigeot 757ba55f2f5SFrançois Tigeot if (uninitialized) { 758ba55f2f5SFrançois Tigeot ret = i915_gem_render_state_init(ring); 759ba55f2f5SFrançois Tigeot if (ret) 760ba55f2f5SFrançois Tigeot DRM_ERROR("init render state: %d\n", ret); 761ba55f2f5SFrançois Tigeot } 762ba55f2f5SFrançois Tigeot 763e555d299SFrançois Tigeot return 0; 764ba55f2f5SFrançois Tigeot 765ba55f2f5SFrançois Tigeot unpin_out: 766ba55f2f5SFrançois Tigeot if (ring->id == RCS) 767*24edb884SFrançois Tigeot i915_gem_object_ggtt_unpin(to->legacy_hw_ctx.rcs_state); 768ba55f2f5SFrançois Tigeot return ret; 769e555d299SFrançois Tigeot } 770e555d299SFrançois Tigeot 771e555d299SFrançois Tigeot /** 772e555d299SFrançois Tigeot * i915_switch_context() - perform a GPU context switch. 773e555d299SFrançois Tigeot * @ring: ring for which we'll execute the context switch 774ba55f2f5SFrançois Tigeot * @to: the context to switch to 775e555d299SFrançois Tigeot * 776e555d299SFrançois Tigeot * The context life cycle is simple. The context refcount is incremented and 777e555d299SFrançois Tigeot * decremented by 1 and create and destroy. If the context is in use by the GPU, 778e555d299SFrançois Tigeot * it will have a refoucnt > 1. This allows us to destroy the context abstract 779e555d299SFrançois Tigeot * object while letting the normal object tracking destroy the backing BO. 780e555d299SFrançois Tigeot */ 781ba55f2f5SFrançois Tigeot int i915_switch_context(struct intel_engine_cs *ring, 782ba55f2f5SFrançois Tigeot struct intel_context *to) 783e555d299SFrançois Tigeot { 784e555d299SFrançois Tigeot struct drm_i915_private *dev_priv = ring->dev->dev_private; 785e555d299SFrançois Tigeot 7865d0b1887SFrançois Tigeot WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); 7875d0b1887SFrançois Tigeot 788*24edb884SFrançois Tigeot if (to->legacy_hw_ctx.rcs_state == NULL) { /* We have the fake context */ 789ba55f2f5SFrançois Tigeot if (to != ring->last_context) { 790ba55f2f5SFrançois Tigeot i915_gem_context_reference(to); 791ba55f2f5SFrançois Tigeot if (ring->last_context) 792ba55f2f5SFrançois Tigeot i915_gem_context_unreference(ring->last_context); 793ba55f2f5SFrançois Tigeot ring->last_context = to; 794ba55f2f5SFrançois Tigeot } 795e555d299SFrançois Tigeot return 0; 796e555d299SFrançois Tigeot } 797e555d299SFrançois Tigeot 798ba55f2f5SFrançois Tigeot return do_switch(ring, to); 799ba55f2f5SFrançois Tigeot } 800ba55f2f5SFrançois Tigeot 801ba55f2f5SFrançois Tigeot static bool hw_context_enabled(struct drm_device *dev) 802ba55f2f5SFrançois Tigeot { 803ba55f2f5SFrançois Tigeot return to_i915(dev)->hw_context_size; 804e555d299SFrançois Tigeot } 805e555d299SFrançois Tigeot 806e555d299SFrançois Tigeot int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, 807e555d299SFrançois Tigeot struct drm_file *file) 808e555d299SFrançois Tigeot { 809e555d299SFrançois Tigeot struct drm_i915_gem_context_create *args = data; 810e555d299SFrançois Tigeot struct drm_i915_file_private *file_priv = file->driver_priv; 811ba55f2f5SFrançois Tigeot struct intel_context *ctx; 812e555d299SFrançois Tigeot int ret; 813e555d299SFrançois Tigeot 814ba55f2f5SFrançois Tigeot if (!hw_context_enabled(dev)) 815e555d299SFrançois Tigeot return -ENODEV; 816e555d299SFrançois Tigeot 817e555d299SFrançois Tigeot ret = i915_mutex_lock_interruptible(dev); 818e555d299SFrançois Tigeot if (ret) 819e555d299SFrançois Tigeot return ret; 820e555d299SFrançois Tigeot 821ba55f2f5SFrançois Tigeot ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev)); 822a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 823e555d299SFrançois Tigeot if (IS_ERR(ctx)) 824e555d299SFrançois Tigeot return PTR_ERR(ctx); 825e555d299SFrançois Tigeot 826*24edb884SFrançois Tigeot args->ctx_id = ctx->user_handle; 827e555d299SFrançois Tigeot DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id); 828e555d299SFrançois Tigeot 829e555d299SFrançois Tigeot return 0; 830e555d299SFrançois Tigeot } 831e555d299SFrançois Tigeot 832e555d299SFrançois Tigeot int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, 833e555d299SFrançois Tigeot struct drm_file *file) 834e555d299SFrançois Tigeot { 835e555d299SFrançois Tigeot struct drm_i915_gem_context_destroy *args = data; 836e555d299SFrançois Tigeot struct drm_i915_file_private *file_priv = file->driver_priv; 837ba55f2f5SFrançois Tigeot struct intel_context *ctx; 838e555d299SFrançois Tigeot int ret; 839e555d299SFrançois Tigeot 840*24edb884SFrançois Tigeot if (args->ctx_id == DEFAULT_CONTEXT_HANDLE) 841ba55f2f5SFrançois Tigeot return -ENOENT; 842e555d299SFrançois Tigeot 843e555d299SFrançois Tigeot ret = i915_mutex_lock_interruptible(dev); 844e555d299SFrançois Tigeot if (ret) 845e555d299SFrançois Tigeot return ret; 846e555d299SFrançois Tigeot 847e555d299SFrançois Tigeot ctx = i915_gem_context_get(file_priv, args->ctx_id); 848ba55f2f5SFrançois Tigeot if (IS_ERR(ctx)) { 849a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 850ba55f2f5SFrançois Tigeot return PTR_ERR(ctx); 851e555d299SFrançois Tigeot } 852e555d299SFrançois Tigeot 853*24edb884SFrançois Tigeot idr_remove(&ctx->file_priv->context_idr, ctx->user_handle); 8545d0b1887SFrançois Tigeot i915_gem_context_unreference(ctx); 855a2fdbec6SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 856e555d299SFrançois Tigeot 857e555d299SFrançois Tigeot DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id); 858e555d299SFrançois Tigeot return 0; 859e555d299SFrançois Tigeot } 860