1*87df8fc6SFrançois Tigeot /* 2*87df8fc6SFrançois Tigeot * Copyright © 2016 Intel Corporation 3*87df8fc6SFrançois Tigeot * 4*87df8fc6SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 5*87df8fc6SFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 6*87df8fc6SFrançois Tigeot * to deal in the Software without restriction, including without limitation 7*87df8fc6SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*87df8fc6SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 9*87df8fc6SFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 10*87df8fc6SFrançois Tigeot * 11*87df8fc6SFrançois Tigeot * The above copyright notice and this permission notice (including the next 12*87df8fc6SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 13*87df8fc6SFrançois Tigeot * Software. 14*87df8fc6SFrançois Tigeot * 15*87df8fc6SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*87df8fc6SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*87df8fc6SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18*87df8fc6SFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*87df8fc6SFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20*87df8fc6SFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21*87df8fc6SFrançois Tigeot * IN THE SOFTWARE. 22*87df8fc6SFrançois Tigeot * 23*87df8fc6SFrançois Tigeot */ 24*87df8fc6SFrançois Tigeot 25*87df8fc6SFrançois Tigeot #include "i915_drv.h" 26*87df8fc6SFrançois Tigeot #include "intel_ringbuffer.h" 27*87df8fc6SFrançois Tigeot #include "intel_lrc.h" 28*87df8fc6SFrançois Tigeot 29*87df8fc6SFrançois Tigeot static const struct engine_info { 30*87df8fc6SFrançois Tigeot const char *name; 31*87df8fc6SFrançois Tigeot unsigned exec_id; 32*87df8fc6SFrançois Tigeot unsigned guc_id; 33*87df8fc6SFrançois Tigeot u32 mmio_base; 34*87df8fc6SFrançois Tigeot unsigned irq_shift; 35*87df8fc6SFrançois Tigeot int (*init_legacy)(struct intel_engine_cs *engine); 36*87df8fc6SFrançois Tigeot int (*init_execlists)(struct intel_engine_cs *engine); 37*87df8fc6SFrançois Tigeot } intel_engines[] = { 38*87df8fc6SFrançois Tigeot [RCS] = { 39*87df8fc6SFrançois Tigeot .name = "render ring", 40*87df8fc6SFrançois Tigeot .exec_id = I915_EXEC_RENDER, 41*87df8fc6SFrançois Tigeot .guc_id = GUC_RENDER_ENGINE, 42*87df8fc6SFrançois Tigeot .mmio_base = RENDER_RING_BASE, 43*87df8fc6SFrançois Tigeot .irq_shift = GEN8_RCS_IRQ_SHIFT, 44*87df8fc6SFrançois Tigeot .init_execlists = logical_render_ring_init, 45*87df8fc6SFrançois Tigeot .init_legacy = intel_init_render_ring_buffer, 46*87df8fc6SFrançois Tigeot }, 47*87df8fc6SFrançois Tigeot [BCS] = { 48*87df8fc6SFrançois Tigeot .name = "blitter ring", 49*87df8fc6SFrançois Tigeot .exec_id = I915_EXEC_BLT, 50*87df8fc6SFrançois Tigeot .guc_id = GUC_BLITTER_ENGINE, 51*87df8fc6SFrançois Tigeot .mmio_base = BLT_RING_BASE, 52*87df8fc6SFrançois Tigeot .irq_shift = GEN8_BCS_IRQ_SHIFT, 53*87df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 54*87df8fc6SFrançois Tigeot .init_legacy = intel_init_blt_ring_buffer, 55*87df8fc6SFrançois Tigeot }, 56*87df8fc6SFrançois Tigeot [VCS] = { 57*87df8fc6SFrançois Tigeot .name = "bsd ring", 58*87df8fc6SFrançois Tigeot .exec_id = I915_EXEC_BSD, 59*87df8fc6SFrançois Tigeot .guc_id = GUC_VIDEO_ENGINE, 60*87df8fc6SFrançois Tigeot .mmio_base = GEN6_BSD_RING_BASE, 61*87df8fc6SFrançois Tigeot .irq_shift = GEN8_VCS1_IRQ_SHIFT, 62*87df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 63*87df8fc6SFrançois Tigeot .init_legacy = intel_init_bsd_ring_buffer, 64*87df8fc6SFrançois Tigeot }, 65*87df8fc6SFrançois Tigeot [VCS2] = { 66*87df8fc6SFrançois Tigeot .name = "bsd2 ring", 67*87df8fc6SFrançois Tigeot .exec_id = I915_EXEC_BSD, 68*87df8fc6SFrançois Tigeot .guc_id = GUC_VIDEO_ENGINE2, 69*87df8fc6SFrançois Tigeot .mmio_base = GEN8_BSD2_RING_BASE, 70*87df8fc6SFrançois Tigeot .irq_shift = GEN8_VCS2_IRQ_SHIFT, 71*87df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 72*87df8fc6SFrançois Tigeot .init_legacy = intel_init_bsd2_ring_buffer, 73*87df8fc6SFrançois Tigeot }, 74*87df8fc6SFrançois Tigeot [VECS] = { 75*87df8fc6SFrançois Tigeot .name = "video enhancement ring", 76*87df8fc6SFrançois Tigeot .exec_id = I915_EXEC_VEBOX, 77*87df8fc6SFrançois Tigeot .guc_id = GUC_VIDEOENHANCE_ENGINE, 78*87df8fc6SFrançois Tigeot .mmio_base = VEBOX_RING_BASE, 79*87df8fc6SFrançois Tigeot .irq_shift = GEN8_VECS_IRQ_SHIFT, 80*87df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 81*87df8fc6SFrançois Tigeot .init_legacy = intel_init_vebox_ring_buffer, 82*87df8fc6SFrançois Tigeot }, 83*87df8fc6SFrançois Tigeot }; 84*87df8fc6SFrançois Tigeot 85*87df8fc6SFrançois Tigeot static struct intel_engine_cs * 86*87df8fc6SFrançois Tigeot intel_engine_setup(struct drm_i915_private *dev_priv, 87*87df8fc6SFrançois Tigeot enum intel_engine_id id) 88*87df8fc6SFrançois Tigeot { 89*87df8fc6SFrançois Tigeot const struct engine_info *info = &intel_engines[id]; 90*87df8fc6SFrançois Tigeot struct intel_engine_cs *engine = &dev_priv->engine[id]; 91*87df8fc6SFrançois Tigeot 92*87df8fc6SFrançois Tigeot engine->id = id; 93*87df8fc6SFrançois Tigeot engine->i915 = dev_priv; 94*87df8fc6SFrançois Tigeot engine->name = info->name; 95*87df8fc6SFrançois Tigeot engine->exec_id = info->exec_id; 96*87df8fc6SFrançois Tigeot engine->hw_id = engine->guc_id = info->guc_id; 97*87df8fc6SFrançois Tigeot engine->mmio_base = info->mmio_base; 98*87df8fc6SFrançois Tigeot engine->irq_shift = info->irq_shift; 99*87df8fc6SFrançois Tigeot 100*87df8fc6SFrançois Tigeot return engine; 101*87df8fc6SFrançois Tigeot } 102*87df8fc6SFrançois Tigeot 103*87df8fc6SFrançois Tigeot /** 104*87df8fc6SFrançois Tigeot * intel_engines_init() - allocate, populate and init the Engine Command Streamers 105*87df8fc6SFrançois Tigeot * @dev: DRM device. 106*87df8fc6SFrançois Tigeot * 107*87df8fc6SFrançois Tigeot * Return: non-zero if the initialization failed. 108*87df8fc6SFrançois Tigeot */ 109*87df8fc6SFrançois Tigeot int intel_engines_init(struct drm_device *dev) 110*87df8fc6SFrançois Tigeot { 111*87df8fc6SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev); 112*87df8fc6SFrançois Tigeot unsigned int mask = 0; 113*87df8fc6SFrançois Tigeot int (*init)(struct intel_engine_cs *engine); 114*87df8fc6SFrançois Tigeot unsigned int i; 115*87df8fc6SFrançois Tigeot int ret; 116*87df8fc6SFrançois Tigeot 117*87df8fc6SFrançois Tigeot WARN_ON(INTEL_INFO(dev_priv)->ring_mask & 118*87df8fc6SFrançois Tigeot GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES)); 119*87df8fc6SFrançois Tigeot 120*87df8fc6SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(intel_engines); i++) { 121*87df8fc6SFrançois Tigeot if (!HAS_ENGINE(dev_priv, i)) 122*87df8fc6SFrançois Tigeot continue; 123*87df8fc6SFrançois Tigeot 124*87df8fc6SFrançois Tigeot if (i915.enable_execlists) 125*87df8fc6SFrançois Tigeot init = intel_engines[i].init_execlists; 126*87df8fc6SFrançois Tigeot else 127*87df8fc6SFrançois Tigeot init = intel_engines[i].init_legacy; 128*87df8fc6SFrançois Tigeot 129*87df8fc6SFrançois Tigeot if (!init) 130*87df8fc6SFrançois Tigeot continue; 131*87df8fc6SFrançois Tigeot 132*87df8fc6SFrançois Tigeot ret = init(intel_engine_setup(dev_priv, i)); 133*87df8fc6SFrançois Tigeot if (ret) 134*87df8fc6SFrançois Tigeot goto cleanup; 135*87df8fc6SFrançois Tigeot 136*87df8fc6SFrançois Tigeot mask |= ENGINE_MASK(i); 137*87df8fc6SFrançois Tigeot } 138*87df8fc6SFrançois Tigeot 139*87df8fc6SFrançois Tigeot /* 140*87df8fc6SFrançois Tigeot * Catch failures to update intel_engines table when the new engines 141*87df8fc6SFrançois Tigeot * are added to the driver by a warning and disabling the forgotten 142*87df8fc6SFrançois Tigeot * engines. 143*87df8fc6SFrançois Tigeot */ 144*87df8fc6SFrançois Tigeot if (WARN_ON(mask != INTEL_INFO(dev_priv)->ring_mask)) { 145*87df8fc6SFrançois Tigeot struct intel_device_info *info = 146*87df8fc6SFrançois Tigeot (struct intel_device_info *)&dev_priv->info; 147*87df8fc6SFrançois Tigeot info->ring_mask = mask; 148*87df8fc6SFrançois Tigeot } 149*87df8fc6SFrançois Tigeot 150*87df8fc6SFrançois Tigeot return 0; 151*87df8fc6SFrançois Tigeot 152*87df8fc6SFrançois Tigeot cleanup: 153*87df8fc6SFrançois Tigeot for (i = 0; i < I915_NUM_ENGINES; i++) { 154*87df8fc6SFrançois Tigeot if (i915.enable_execlists) 155*87df8fc6SFrançois Tigeot intel_logical_ring_cleanup(&dev_priv->engine[i]); 156*87df8fc6SFrançois Tigeot else 157*87df8fc6SFrançois Tigeot intel_cleanup_engine(&dev_priv->engine[i]); 158*87df8fc6SFrançois Tigeot } 159*87df8fc6SFrançois Tigeot 160*87df8fc6SFrançois Tigeot return ret; 161*87df8fc6SFrançois Tigeot } 162*87df8fc6SFrançois Tigeot 163*87df8fc6SFrançois Tigeot void intel_engine_init_hangcheck(struct intel_engine_cs *engine) 164*87df8fc6SFrançois Tigeot { 165*87df8fc6SFrançois Tigeot memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); 166*87df8fc6SFrançois Tigeot } 167*87df8fc6SFrançois Tigeot 168*87df8fc6SFrançois Tigeot /** 169*87df8fc6SFrançois Tigeot * intel_engines_setup_common - setup engine state not requiring hw access 170*87df8fc6SFrançois Tigeot * @engine: Engine to setup. 171*87df8fc6SFrançois Tigeot * 172*87df8fc6SFrançois Tigeot * Initializes @engine@ structure members shared between legacy and execlists 173*87df8fc6SFrançois Tigeot * submission modes which do not require hardware access. 174*87df8fc6SFrançois Tigeot * 175*87df8fc6SFrançois Tigeot * Typically done early in the submission mode specific engine setup stage. 176*87df8fc6SFrançois Tigeot */ 177*87df8fc6SFrançois Tigeot void intel_engine_setup_common(struct intel_engine_cs *engine) 178*87df8fc6SFrançois Tigeot { 179*87df8fc6SFrançois Tigeot INIT_LIST_HEAD(&engine->active_list); 180*87df8fc6SFrançois Tigeot INIT_LIST_HEAD(&engine->request_list); 181*87df8fc6SFrançois Tigeot INIT_LIST_HEAD(&engine->buffers); 182*87df8fc6SFrançois Tigeot INIT_LIST_HEAD(&engine->execlist_queue); 183*87df8fc6SFrançois Tigeot lockinit(&engine->execlist_lock, "i915el", 0, LK_CANRECURSE); 184*87df8fc6SFrançois Tigeot 185*87df8fc6SFrançois Tigeot engine->fence_context = fence_context_alloc(1); 186*87df8fc6SFrançois Tigeot 187*87df8fc6SFrançois Tigeot intel_engine_init_hangcheck(engine); 188*87df8fc6SFrançois Tigeot i915_gem_batch_pool_init(&engine->i915->drm, &engine->batch_pool); 189*87df8fc6SFrançois Tigeot } 190*87df8fc6SFrançois Tigeot 191*87df8fc6SFrançois Tigeot /** 192*87df8fc6SFrançois Tigeot * intel_engines_init_common - initialize cengine state which might require hw access 193*87df8fc6SFrançois Tigeot * @engine: Engine to initialize. 194*87df8fc6SFrançois Tigeot * 195*87df8fc6SFrançois Tigeot * Initializes @engine@ structure members shared between legacy and execlists 196*87df8fc6SFrançois Tigeot * submission modes which do require hardware access. 197*87df8fc6SFrançois Tigeot * 198*87df8fc6SFrançois Tigeot * Typcally done at later stages of submission mode specific engine setup. 199*87df8fc6SFrançois Tigeot * 200*87df8fc6SFrançois Tigeot * Returns zero on success or an error code on failure. 201*87df8fc6SFrançois Tigeot */ 202*87df8fc6SFrançois Tigeot int intel_engine_init_common(struct intel_engine_cs *engine) 203*87df8fc6SFrançois Tigeot { 204*87df8fc6SFrançois Tigeot int ret; 205*87df8fc6SFrançois Tigeot 206*87df8fc6SFrançois Tigeot ret = intel_engine_init_breadcrumbs(engine); 207*87df8fc6SFrançois Tigeot if (ret) 208*87df8fc6SFrançois Tigeot return ret; 209*87df8fc6SFrançois Tigeot 210*87df8fc6SFrançois Tigeot return i915_cmd_parser_init_ring(engine); 211*87df8fc6SFrançois Tigeot } 212