187df8fc6SFrançois Tigeot /* 287df8fc6SFrançois Tigeot * Copyright © 2016 Intel Corporation 387df8fc6SFrançois Tigeot * 487df8fc6SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 587df8fc6SFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 687df8fc6SFrançois Tigeot * to deal in the Software without restriction, including without limitation 787df8fc6SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 887df8fc6SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 987df8fc6SFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 1087df8fc6SFrançois Tigeot * 1187df8fc6SFrançois Tigeot * The above copyright notice and this permission notice (including the next 1287df8fc6SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 1387df8fc6SFrançois Tigeot * Software. 1487df8fc6SFrançois Tigeot * 1587df8fc6SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1687df8fc6SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1787df8fc6SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1887df8fc6SFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1987df8fc6SFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2087df8fc6SFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2187df8fc6SFrançois Tigeot * IN THE SOFTWARE. 2287df8fc6SFrançois Tigeot * 2387df8fc6SFrançois Tigeot */ 2487df8fc6SFrançois Tigeot 2587df8fc6SFrançois Tigeot #include "i915_drv.h" 2687df8fc6SFrançois Tigeot #include "intel_ringbuffer.h" 2787df8fc6SFrançois Tigeot #include "intel_lrc.h" 2887df8fc6SFrançois Tigeot 2987df8fc6SFrançois Tigeot static const struct engine_info { 3087df8fc6SFrançois Tigeot const char *name; 3187df8fc6SFrançois Tigeot unsigned exec_id; 3287df8fc6SFrançois Tigeot unsigned guc_id; 3387df8fc6SFrançois Tigeot u32 mmio_base; 3487df8fc6SFrançois Tigeot unsigned irq_shift; 3587df8fc6SFrançois Tigeot int (*init_legacy)(struct intel_engine_cs *engine); 3687df8fc6SFrançois Tigeot int (*init_execlists)(struct intel_engine_cs *engine); 3787df8fc6SFrançois Tigeot } intel_engines[] = { 3887df8fc6SFrançois Tigeot [RCS] = { 3987df8fc6SFrançois Tigeot .name = "render ring", 4087df8fc6SFrançois Tigeot .exec_id = I915_EXEC_RENDER, 4187df8fc6SFrançois Tigeot .guc_id = GUC_RENDER_ENGINE, 4287df8fc6SFrançois Tigeot .mmio_base = RENDER_RING_BASE, 4387df8fc6SFrançois Tigeot .irq_shift = GEN8_RCS_IRQ_SHIFT, 4487df8fc6SFrançois Tigeot .init_execlists = logical_render_ring_init, 4587df8fc6SFrançois Tigeot .init_legacy = intel_init_render_ring_buffer, 4687df8fc6SFrançois Tigeot }, 4787df8fc6SFrançois Tigeot [BCS] = { 4887df8fc6SFrançois Tigeot .name = "blitter ring", 4987df8fc6SFrançois Tigeot .exec_id = I915_EXEC_BLT, 5087df8fc6SFrançois Tigeot .guc_id = GUC_BLITTER_ENGINE, 5187df8fc6SFrançois Tigeot .mmio_base = BLT_RING_BASE, 5287df8fc6SFrançois Tigeot .irq_shift = GEN8_BCS_IRQ_SHIFT, 5387df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 5487df8fc6SFrançois Tigeot .init_legacy = intel_init_blt_ring_buffer, 5587df8fc6SFrançois Tigeot }, 5687df8fc6SFrançois Tigeot [VCS] = { 5787df8fc6SFrançois Tigeot .name = "bsd ring", 5887df8fc6SFrançois Tigeot .exec_id = I915_EXEC_BSD, 5987df8fc6SFrançois Tigeot .guc_id = GUC_VIDEO_ENGINE, 6087df8fc6SFrançois Tigeot .mmio_base = GEN6_BSD_RING_BASE, 6187df8fc6SFrançois Tigeot .irq_shift = GEN8_VCS1_IRQ_SHIFT, 6287df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 6387df8fc6SFrançois Tigeot .init_legacy = intel_init_bsd_ring_buffer, 6487df8fc6SFrançois Tigeot }, 6587df8fc6SFrançois Tigeot [VCS2] = { 6687df8fc6SFrançois Tigeot .name = "bsd2 ring", 6787df8fc6SFrançois Tigeot .exec_id = I915_EXEC_BSD, 6887df8fc6SFrançois Tigeot .guc_id = GUC_VIDEO_ENGINE2, 6987df8fc6SFrançois Tigeot .mmio_base = GEN8_BSD2_RING_BASE, 7087df8fc6SFrançois Tigeot .irq_shift = GEN8_VCS2_IRQ_SHIFT, 7187df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 7287df8fc6SFrançois Tigeot .init_legacy = intel_init_bsd2_ring_buffer, 7387df8fc6SFrançois Tigeot }, 7487df8fc6SFrançois Tigeot [VECS] = { 7587df8fc6SFrançois Tigeot .name = "video enhancement ring", 7687df8fc6SFrançois Tigeot .exec_id = I915_EXEC_VEBOX, 7787df8fc6SFrançois Tigeot .guc_id = GUC_VIDEOENHANCE_ENGINE, 7887df8fc6SFrançois Tigeot .mmio_base = VEBOX_RING_BASE, 7987df8fc6SFrançois Tigeot .irq_shift = GEN8_VECS_IRQ_SHIFT, 8087df8fc6SFrançois Tigeot .init_execlists = logical_xcs_ring_init, 8187df8fc6SFrançois Tigeot .init_legacy = intel_init_vebox_ring_buffer, 8287df8fc6SFrançois Tigeot }, 8387df8fc6SFrançois Tigeot }; 8487df8fc6SFrançois Tigeot 8587df8fc6SFrançois Tigeot static struct intel_engine_cs * 8687df8fc6SFrançois Tigeot intel_engine_setup(struct drm_i915_private *dev_priv, 8787df8fc6SFrançois Tigeot enum intel_engine_id id) 8887df8fc6SFrançois Tigeot { 8987df8fc6SFrançois Tigeot const struct engine_info *info = &intel_engines[id]; 9087df8fc6SFrançois Tigeot struct intel_engine_cs *engine = &dev_priv->engine[id]; 9187df8fc6SFrançois Tigeot 9287df8fc6SFrançois Tigeot engine->id = id; 9387df8fc6SFrançois Tigeot engine->i915 = dev_priv; 9487df8fc6SFrançois Tigeot engine->name = info->name; 9587df8fc6SFrançois Tigeot engine->exec_id = info->exec_id; 9687df8fc6SFrançois Tigeot engine->hw_id = engine->guc_id = info->guc_id; 9787df8fc6SFrançois Tigeot engine->mmio_base = info->mmio_base; 9887df8fc6SFrançois Tigeot engine->irq_shift = info->irq_shift; 9987df8fc6SFrançois Tigeot 10087df8fc6SFrançois Tigeot return engine; 10187df8fc6SFrançois Tigeot } 10287df8fc6SFrançois Tigeot 10387df8fc6SFrançois Tigeot /** 10487df8fc6SFrançois Tigeot * intel_engines_init() - allocate, populate and init the Engine Command Streamers 10587df8fc6SFrançois Tigeot * @dev: DRM device. 10687df8fc6SFrançois Tigeot * 10787df8fc6SFrançois Tigeot * Return: non-zero if the initialization failed. 10887df8fc6SFrançois Tigeot */ 10987df8fc6SFrançois Tigeot int intel_engines_init(struct drm_device *dev) 11087df8fc6SFrançois Tigeot { 11187df8fc6SFrançois Tigeot struct drm_i915_private *dev_priv = to_i915(dev); 11287df8fc6SFrançois Tigeot unsigned int mask = 0; 11387df8fc6SFrançois Tigeot int (*init)(struct intel_engine_cs *engine); 11487df8fc6SFrançois Tigeot unsigned int i; 11587df8fc6SFrançois Tigeot int ret; 11687df8fc6SFrançois Tigeot 117*71f41f3eSFrançois Tigeot WARN_ON(INTEL_INFO(dev_priv)->ring_mask == 0); 11887df8fc6SFrançois Tigeot WARN_ON(INTEL_INFO(dev_priv)->ring_mask & 11987df8fc6SFrançois Tigeot GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES)); 12087df8fc6SFrançois Tigeot 12187df8fc6SFrançois Tigeot for (i = 0; i < ARRAY_SIZE(intel_engines); i++) { 12287df8fc6SFrançois Tigeot if (!HAS_ENGINE(dev_priv, i)) 12387df8fc6SFrançois Tigeot continue; 12487df8fc6SFrançois Tigeot 12587df8fc6SFrançois Tigeot if (i915.enable_execlists) 12687df8fc6SFrançois Tigeot init = intel_engines[i].init_execlists; 12787df8fc6SFrançois Tigeot else 12887df8fc6SFrançois Tigeot init = intel_engines[i].init_legacy; 12987df8fc6SFrançois Tigeot 13087df8fc6SFrançois Tigeot if (!init) 13187df8fc6SFrançois Tigeot continue; 13287df8fc6SFrançois Tigeot 13387df8fc6SFrançois Tigeot ret = init(intel_engine_setup(dev_priv, i)); 13487df8fc6SFrançois Tigeot if (ret) 13587df8fc6SFrançois Tigeot goto cleanup; 13687df8fc6SFrançois Tigeot 13787df8fc6SFrançois Tigeot mask |= ENGINE_MASK(i); 13887df8fc6SFrançois Tigeot } 13987df8fc6SFrançois Tigeot 14087df8fc6SFrançois Tigeot /* 14187df8fc6SFrançois Tigeot * Catch failures to update intel_engines table when the new engines 14287df8fc6SFrançois Tigeot * are added to the driver by a warning and disabling the forgotten 14387df8fc6SFrançois Tigeot * engines. 14487df8fc6SFrançois Tigeot */ 14587df8fc6SFrançois Tigeot if (WARN_ON(mask != INTEL_INFO(dev_priv)->ring_mask)) { 14687df8fc6SFrançois Tigeot struct intel_device_info *info = 14787df8fc6SFrançois Tigeot (struct intel_device_info *)&dev_priv->info; 14887df8fc6SFrançois Tigeot info->ring_mask = mask; 14987df8fc6SFrançois Tigeot } 15087df8fc6SFrançois Tigeot 15187df8fc6SFrançois Tigeot return 0; 15287df8fc6SFrançois Tigeot 15387df8fc6SFrançois Tigeot cleanup: 15487df8fc6SFrançois Tigeot for (i = 0; i < I915_NUM_ENGINES; i++) { 15587df8fc6SFrançois Tigeot if (i915.enable_execlists) 15687df8fc6SFrançois Tigeot intel_logical_ring_cleanup(&dev_priv->engine[i]); 15787df8fc6SFrançois Tigeot else 158*71f41f3eSFrançois Tigeot intel_engine_cleanup(&dev_priv->engine[i]); 15987df8fc6SFrançois Tigeot } 16087df8fc6SFrançois Tigeot 16187df8fc6SFrançois Tigeot return ret; 16287df8fc6SFrançois Tigeot } 16387df8fc6SFrançois Tigeot 16487df8fc6SFrançois Tigeot void intel_engine_init_hangcheck(struct intel_engine_cs *engine) 16587df8fc6SFrançois Tigeot { 16687df8fc6SFrançois Tigeot memset(&engine->hangcheck, 0, sizeof(engine->hangcheck)); 16787df8fc6SFrançois Tigeot } 16887df8fc6SFrançois Tigeot 169*71f41f3eSFrançois Tigeot static void intel_engine_init_requests(struct intel_engine_cs *engine) 170*71f41f3eSFrançois Tigeot { 171*71f41f3eSFrançois Tigeot init_request_active(&engine->last_request, NULL); 172*71f41f3eSFrançois Tigeot INIT_LIST_HEAD(&engine->request_list); 173*71f41f3eSFrançois Tigeot } 174*71f41f3eSFrançois Tigeot 17587df8fc6SFrançois Tigeot /** 17687df8fc6SFrançois Tigeot * intel_engines_setup_common - setup engine state not requiring hw access 17787df8fc6SFrançois Tigeot * @engine: Engine to setup. 17887df8fc6SFrançois Tigeot * 17987df8fc6SFrançois Tigeot * Initializes @engine@ structure members shared between legacy and execlists 18087df8fc6SFrançois Tigeot * submission modes which do not require hardware access. 18187df8fc6SFrançois Tigeot * 18287df8fc6SFrançois Tigeot * Typically done early in the submission mode specific engine setup stage. 18387df8fc6SFrançois Tigeot */ 18487df8fc6SFrançois Tigeot void intel_engine_setup_common(struct intel_engine_cs *engine) 18587df8fc6SFrançois Tigeot { 18687df8fc6SFrançois Tigeot INIT_LIST_HEAD(&engine->buffers); 18787df8fc6SFrançois Tigeot INIT_LIST_HEAD(&engine->execlist_queue); 18887df8fc6SFrançois Tigeot lockinit(&engine->execlist_lock, "i915el", 0, LK_CANRECURSE); 18987df8fc6SFrançois Tigeot 19087df8fc6SFrançois Tigeot engine->fence_context = fence_context_alloc(1); 19187df8fc6SFrançois Tigeot 192*71f41f3eSFrançois Tigeot intel_engine_init_requests(engine); 19387df8fc6SFrançois Tigeot intel_engine_init_hangcheck(engine); 194*71f41f3eSFrançois Tigeot i915_gem_batch_pool_init(engine, &engine->batch_pool); 19587df8fc6SFrançois Tigeot } 19687df8fc6SFrançois Tigeot 19787df8fc6SFrançois Tigeot /** 19887df8fc6SFrançois Tigeot * intel_engines_init_common - initialize cengine state which might require hw access 19987df8fc6SFrançois Tigeot * @engine: Engine to initialize. 20087df8fc6SFrançois Tigeot * 20187df8fc6SFrançois Tigeot * Initializes @engine@ structure members shared between legacy and execlists 20287df8fc6SFrançois Tigeot * submission modes which do require hardware access. 20387df8fc6SFrançois Tigeot * 20487df8fc6SFrançois Tigeot * Typcally done at later stages of submission mode specific engine setup. 20587df8fc6SFrançois Tigeot * 20687df8fc6SFrançois Tigeot * Returns zero on success or an error code on failure. 20787df8fc6SFrançois Tigeot */ 20887df8fc6SFrançois Tigeot int intel_engine_init_common(struct intel_engine_cs *engine) 20987df8fc6SFrançois Tigeot { 21087df8fc6SFrançois Tigeot int ret; 21187df8fc6SFrançois Tigeot 21287df8fc6SFrançois Tigeot ret = intel_engine_init_breadcrumbs(engine); 21387df8fc6SFrançois Tigeot if (ret) 21487df8fc6SFrançois Tigeot return ret; 21587df8fc6SFrançois Tigeot 216*71f41f3eSFrançois Tigeot return intel_engine_init_cmd_parser(engine); 217*71f41f3eSFrançois Tigeot } 218*71f41f3eSFrançois Tigeot 219*71f41f3eSFrançois Tigeot /** 220*71f41f3eSFrançois Tigeot * intel_engines_cleanup_common - cleans up the engine state created by 221*71f41f3eSFrançois Tigeot * the common initiailizers. 222*71f41f3eSFrançois Tigeot * @engine: Engine to cleanup. 223*71f41f3eSFrançois Tigeot * 224*71f41f3eSFrançois Tigeot * This cleans up everything created by the common helpers. 225*71f41f3eSFrançois Tigeot */ 226*71f41f3eSFrançois Tigeot void intel_engine_cleanup_common(struct intel_engine_cs *engine) 227*71f41f3eSFrançois Tigeot { 228*71f41f3eSFrançois Tigeot intel_engine_cleanup_cmd_parser(engine); 229*71f41f3eSFrançois Tigeot intel_engine_fini_breadcrumbs(engine); 230*71f41f3eSFrançois Tigeot i915_gem_batch_pool_fini(&engine->batch_pool); 23187df8fc6SFrançois Tigeot } 232