blob: 82a274b336c5b206e3e08e96552860093fc3204a [file] [log] [blame]
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +01001/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25#include "i915_drv.h"
26#include "intel_ringbuffer.h"
27#include "intel_lrc.h"
28
Oscar Mateob8400f02017-04-10 07:34:32 -070029struct engine_class_info {
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010030 const char *name;
Oscar Mateob8400f02017-04-10 07:34:32 -070031 int (*init_legacy)(struct intel_engine_cs *engine);
32 int (*init_execlists)(struct intel_engine_cs *engine);
33};
34
35static const struct engine_class_info intel_engine_classes[] = {
36 [RENDER_CLASS] = {
37 .name = "rcs",
38 .init_execlists = logical_render_ring_init,
39 .init_legacy = intel_init_render_ring_buffer,
40 },
41 [COPY_ENGINE_CLASS] = {
42 .name = "bcs",
43 .init_execlists = logical_xcs_ring_init,
44 .init_legacy = intel_init_blt_ring_buffer,
45 },
46 [VIDEO_DECODE_CLASS] = {
47 .name = "vcs",
48 .init_execlists = logical_xcs_ring_init,
49 .init_legacy = intel_init_bsd_ring_buffer,
50 },
51 [VIDEO_ENHANCEMENT_CLASS] = {
52 .name = "vecs",
53 .init_execlists = logical_xcs_ring_init,
54 .init_legacy = intel_init_vebox_ring_buffer,
55 },
56};
57
58struct engine_info {
Michal Wajdeczko237ae7c2017-03-01 20:26:15 +000059 unsigned int hw_id;
Chris Wilson1d39f282017-04-11 13:43:06 +010060 unsigned int uabi_id;
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070061 u8 class;
62 u8 instance;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010063 u32 mmio_base;
64 unsigned irq_shift;
Oscar Mateob8400f02017-04-10 07:34:32 -070065};
66
67static const struct engine_info intel_engines[] = {
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010068 [RCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +010069 .hw_id = RCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +010070 .uabi_id = I915_EXEC_RENDER,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070071 .class = RENDER_CLASS,
72 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010073 .mmio_base = RENDER_RING_BASE,
74 .irq_shift = GEN8_RCS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010075 },
76 [BCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +010077 .hw_id = BCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +010078 .uabi_id = I915_EXEC_BLT,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070079 .class = COPY_ENGINE_CLASS,
80 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010081 .mmio_base = BLT_RING_BASE,
82 .irq_shift = GEN8_BCS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010083 },
84 [VCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +010085 .hw_id = VCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +010086 .uabi_id = I915_EXEC_BSD,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070087 .class = VIDEO_DECODE_CLASS,
88 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010089 .mmio_base = GEN6_BSD_RING_BASE,
90 .irq_shift = GEN8_VCS1_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010091 },
92 [VCS2] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +010093 .hw_id = VCS2_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +010094 .uabi_id = I915_EXEC_BSD,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070095 .class = VIDEO_DECODE_CLASS,
96 .instance = 1,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010097 .mmio_base = GEN8_BSD2_RING_BASE,
98 .irq_shift = GEN8_VCS2_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010099 },
100 [VECS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100101 .hw_id = VECS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100102 .uabi_id = I915_EXEC_VEBOX,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700103 .class = VIDEO_ENHANCEMENT_CLASS,
104 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100105 .mmio_base = VEBOX_RING_BASE,
106 .irq_shift = GEN8_VECS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100107 },
108};
109
Akash Goel3b3f1652016-10-13 22:44:48 +0530110static int
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100111intel_engine_setup(struct drm_i915_private *dev_priv,
112 enum intel_engine_id id)
113{
114 const struct engine_info *info = &intel_engines[id];
Oscar Mateob8400f02017-04-10 07:34:32 -0700115 const struct engine_class_info *class_info;
Akash Goel3b3f1652016-10-13 22:44:48 +0530116 struct intel_engine_cs *engine;
117
Oscar Mateob8400f02017-04-10 07:34:32 -0700118 GEM_BUG_ON(info->class >= ARRAY_SIZE(intel_engine_classes));
119 class_info = &intel_engine_classes[info->class];
120
Akash Goel3b3f1652016-10-13 22:44:48 +0530121 GEM_BUG_ON(dev_priv->engine[id]);
122 engine = kzalloc(sizeof(*engine), GFP_KERNEL);
123 if (!engine)
124 return -ENOMEM;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100125
126 engine->id = id;
127 engine->i915 = dev_priv;
Oscar Mateo6e516142017-04-10 07:34:31 -0700128 WARN_ON(snprintf(engine->name, sizeof(engine->name), "%s%u",
Oscar Mateob8400f02017-04-10 07:34:32 -0700129 class_info->name, info->instance) >=
130 sizeof(engine->name));
Chris Wilson1d39f282017-04-11 13:43:06 +0100131 engine->uabi_id = info->uabi_id;
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100132 engine->hw_id = engine->guc_id = info->hw_id;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100133 engine->mmio_base = info->mmio_base;
134 engine->irq_shift = info->irq_shift;
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700135 engine->class = info->class;
136 engine->instance = info->instance;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100137
Chris Wilson0de91362016-11-14 20:41:01 +0000138 /* Nothing to do here, execute in order of dependencies */
139 engine->schedule = NULL;
140
Changbin Du3fc03062017-03-13 10:47:11 +0800141 ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
142
Akash Goel3b3f1652016-10-13 22:44:48 +0530143 dev_priv->engine[id] = engine;
144 return 0;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100145}
146
147/**
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000148 * intel_engines_init_early() - allocate the Engine Command Streamers
Tvrtko Ursulinbf9e8422016-12-01 14:16:38 +0000149 * @dev_priv: i915 device private
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100150 *
151 * Return: non-zero if the initialization failed.
152 */
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000153int intel_engines_init_early(struct drm_i915_private *dev_priv)
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100154{
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100155 struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
Chris Wilson5f9be052017-04-11 17:56:58 +0100156 const unsigned int ring_mask = INTEL_INFO(dev_priv)->ring_mask;
Akash Goel3b3f1652016-10-13 22:44:48 +0530157 struct intel_engine_cs *engine;
158 enum intel_engine_id id;
Chris Wilson5f9be052017-04-11 17:56:58 +0100159 unsigned int mask = 0;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100160 unsigned int i;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000161 int err;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100162
Tvrtko Ursulin70006ad2016-10-13 11:02:56 +0100163 WARN_ON(ring_mask == 0);
164 WARN_ON(ring_mask &
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100165 GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES));
166
167 for (i = 0; i < ARRAY_SIZE(intel_engines); i++) {
168 if (!HAS_ENGINE(dev_priv, i))
169 continue;
170
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000171 err = intel_engine_setup(dev_priv, i);
172 if (err)
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100173 goto cleanup;
174
175 mask |= ENGINE_MASK(i);
176 }
177
178 /*
179 * Catch failures to update intel_engines table when the new engines
180 * are added to the driver by a warning and disabling the forgotten
181 * engines.
182 */
Tvrtko Ursulin70006ad2016-10-13 11:02:56 +0100183 if (WARN_ON(mask != ring_mask))
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100184 device_info->ring_mask = mask;
185
Chris Wilson5f9be052017-04-11 17:56:58 +0100186 /* We always presume we have at least RCS available for later probing */
187 if (WARN_ON(!HAS_ENGINE(dev_priv, RCS))) {
188 err = -ENODEV;
189 goto cleanup;
190 }
191
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100192 device_info->num_rings = hweight32(mask);
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100193
194 return 0;
195
196cleanup:
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000197 for_each_engine(engine, dev_priv, id)
198 kfree(engine);
199 return err;
200}
201
202/**
203 * intel_engines_init() - allocate, populate and init the Engine Command Streamers
204 * @dev_priv: i915 device private
205 *
206 * Return: non-zero if the initialization failed.
207 */
208int intel_engines_init(struct drm_i915_private *dev_priv)
209{
210 struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
211 struct intel_engine_cs *engine;
212 enum intel_engine_id id, err_id;
213 unsigned int mask = 0;
214 int err = 0;
215
Akash Goel3b3f1652016-10-13 22:44:48 +0530216 for_each_engine(engine, dev_priv, id) {
Oscar Mateob8400f02017-04-10 07:34:32 -0700217 const struct engine_class_info *class_info =
218 &intel_engine_classes[engine->class];
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000219 int (*init)(struct intel_engine_cs *engine);
220
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100221 if (i915.enable_execlists)
Oscar Mateob8400f02017-04-10 07:34:32 -0700222 init = class_info->init_execlists;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000223 else
Oscar Mateob8400f02017-04-10 07:34:32 -0700224 init = class_info->init_legacy;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000225 if (!init) {
226 kfree(engine);
227 dev_priv->engine[id] = NULL;
228 continue;
229 }
230
231 err = init(engine);
232 if (err) {
233 err_id = id;
234 goto cleanup;
235 }
236
Chris Wilsonff44ad52017-03-16 17:13:03 +0000237 GEM_BUG_ON(!engine->submit_request);
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000238 mask |= ENGINE_MASK(id);
239 }
240
241 /*
242 * Catch failures to update intel_engines table when the new engines
243 * are added to the driver by a warning and disabling the forgotten
244 * engines.
245 */
246 if (WARN_ON(mask != INTEL_INFO(dev_priv)->ring_mask))
247 device_info->ring_mask = mask;
248
249 device_info->num_rings = hweight32(mask);
250
251 return 0;
252
253cleanup:
254 for_each_engine(engine, dev_priv, id) {
255 if (id >= err_id)
256 kfree(engine);
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100257 else
Tvrtko Ursulin8ee7c6e2017-02-16 12:23:22 +0000258 dev_priv->gt.cleanup_engine(engine);
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100259 }
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000260 return err;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100261}
262
Chris Wilson73cb9702016-10-28 13:58:46 +0100263void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
Chris Wilson57f275a2016-08-15 10:49:00 +0100264{
265 struct drm_i915_private *dev_priv = engine->i915;
266
Chris Wilson2ca9faa2017-04-05 16:30:54 +0100267 GEM_BUG_ON(!intel_engine_is_idle(engine));
Chris Wilson546cdbc2017-04-21 09:31:13 +0100268 GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
Chris Wilson2ca9faa2017-04-05 16:30:54 +0100269
Chris Wilson57f275a2016-08-15 10:49:00 +0100270 /* Our semaphore implementation is strictly monotonic (i.e. we proceed
271 * so long as the semaphore value in the register/page is greater
272 * than the sync value), so whenever we reset the seqno,
273 * so long as we reset the tracking semaphore value to 0, it will
274 * always be before the next request's seqno. If we don't reset
275 * the semaphore value, then when the seqno moves backwards all
276 * future waits will complete instantly (causing rendering corruption).
277 */
278 if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv)) {
279 I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
280 I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
281 if (HAS_VEBOX(dev_priv))
282 I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
283 }
Chris Wilson51d545d2016-08-15 10:49:02 +0100284 if (dev_priv->semaphore) {
285 struct page *page = i915_vma_first_page(dev_priv->semaphore);
286 void *semaphores;
287
288 /* Semaphores are in noncoherent memory, flush to be safe */
Chris Wilson24caf652017-03-20 14:56:09 +0000289 semaphores = kmap_atomic(page);
Chris Wilson57f275a2016-08-15 10:49:00 +0100290 memset(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
291 0, I915_NUM_ENGINES * gen8_semaphore_seqno_size);
Chris Wilson51d545d2016-08-15 10:49:02 +0100292 drm_clflush_virt_range(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
293 I915_NUM_ENGINES * gen8_semaphore_seqno_size);
Chris Wilson24caf652017-03-20 14:56:09 +0000294 kunmap_atomic(semaphores);
Chris Wilson57f275a2016-08-15 10:49:00 +0100295 }
Chris Wilson57f275a2016-08-15 10:49:00 +0100296
297 intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
Chris Wilson14a6bbf2017-03-14 11:14:52 +0000298 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
Chris Wilson73cb9702016-10-28 13:58:46 +0100299
Chris Wilson57f275a2016-08-15 10:49:00 +0100300 /* After manually advancing the seqno, fake the interrupt in case
301 * there are any waiters for that seqno.
302 */
303 intel_engine_wakeup(engine);
Chris Wilson2ca9faa2017-04-05 16:30:54 +0100304
305 GEM_BUG_ON(intel_engine_get_seqno(engine) != seqno);
Chris Wilson57f275a2016-08-15 10:49:00 +0100306}
307
Chris Wilson73cb9702016-10-28 13:58:46 +0100308static void intel_engine_init_timeline(struct intel_engine_cs *engine)
Chris Wilsondcff85c2016-08-05 10:14:11 +0100309{
Chris Wilson73cb9702016-10-28 13:58:46 +0100310 engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id];
Chris Wilsondcff85c2016-08-05 10:14:11 +0100311}
312
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100313/**
314 * intel_engines_setup_common - setup engine state not requiring hw access
315 * @engine: Engine to setup.
316 *
317 * Initializes @engine@ structure members shared between legacy and execlists
318 * submission modes which do not require hardware access.
319 *
320 * Typically done early in the submission mode specific engine setup stage.
321 */
322void intel_engine_setup_common(struct intel_engine_cs *engine)
323{
Chris Wilson20311bd2016-11-14 20:41:03 +0000324 engine->execlist_queue = RB_ROOT;
325 engine->execlist_first = NULL;
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100326
Chris Wilson73cb9702016-10-28 13:58:46 +0100327 intel_engine_init_timeline(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100328 intel_engine_init_hangcheck(engine);
Chris Wilson115003e92016-08-04 16:32:19 +0100329 i915_gem_batch_pool_init(engine, &engine->batch_pool);
Chris Wilson7756e452016-08-18 17:17:10 +0100330
331 intel_engine_init_cmd_parser(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100332}
333
Chris Wilsonadc320c2016-08-15 10:48:59 +0100334int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
335{
336 struct drm_i915_gem_object *obj;
337 struct i915_vma *vma;
338 int ret;
339
340 WARN_ON(engine->scratch);
341
Tvrtko Ursulin187685c2016-12-01 14:16:36 +0000342 obj = i915_gem_object_create_stolen(engine->i915, size);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100343 if (!obj)
Chris Wilson920cf412016-10-28 13:58:30 +0100344 obj = i915_gem_object_create_internal(engine->i915, size);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100345 if (IS_ERR(obj)) {
346 DRM_ERROR("Failed to allocate scratch page\n");
347 return PTR_ERR(obj);
348 }
349
Chris Wilsona01cb372017-01-16 15:21:30 +0000350 vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100351 if (IS_ERR(vma)) {
352 ret = PTR_ERR(vma);
353 goto err_unref;
354 }
355
356 ret = i915_vma_pin(vma, 0, 4096, PIN_GLOBAL | PIN_HIGH);
357 if (ret)
358 goto err_unref;
359
360 engine->scratch = vma;
Chris Wilsonbde13eb2016-08-15 10:49:07 +0100361 DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
362 engine->name, i915_ggtt_offset(vma));
Chris Wilsonadc320c2016-08-15 10:48:59 +0100363 return 0;
364
365err_unref:
366 i915_gem_object_put(obj);
367 return ret;
368}
369
370static void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
371{
Chris Wilson19880c42016-08-15 10:49:05 +0100372 i915_vma_unpin_and_release(&engine->scratch);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100373}
374
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100375/**
376 * intel_engines_init_common - initialize cengine state which might require hw access
377 * @engine: Engine to initialize.
378 *
379 * Initializes @engine@ structure members shared between legacy and execlists
380 * submission modes which do require hardware access.
381 *
382 * Typcally done at later stages of submission mode specific engine setup.
383 *
384 * Returns zero on success or an error code on failure.
385 */
386int intel_engine_init_common(struct intel_engine_cs *engine)
387{
388 int ret;
389
Chris Wilsonff44ad52017-03-16 17:13:03 +0000390 engine->set_default_submission(engine);
391
Chris Wilsone8a9c582016-12-18 15:37:20 +0000392 /* We may need to do things with the shrinker which
393 * require us to immediately switch back to the default
394 * context. This can cause a problem as pinning the
395 * default context also requires GTT space which may not
396 * be available. To avoid this we always pin the default
397 * context.
398 */
399 ret = engine->context_pin(engine, engine->i915->kernel_context);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100400 if (ret)
401 return ret;
402
Chris Wilsone8a9c582016-12-18 15:37:20 +0000403 ret = intel_engine_init_breadcrumbs(engine);
404 if (ret)
405 goto err_unpin;
406
Chris Wilson4e50f082016-10-28 13:58:31 +0100407 ret = i915_gem_render_state_init(engine);
408 if (ret)
Chris Wilsone8a9c582016-12-18 15:37:20 +0000409 goto err_unpin;
Chris Wilson4e50f082016-10-28 13:58:31 +0100410
Chris Wilson7756e452016-08-18 17:17:10 +0100411 return 0;
Chris Wilsone8a9c582016-12-18 15:37:20 +0000412
413err_unpin:
414 engine->context_unpin(engine, engine->i915->kernel_context);
415 return ret;
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100416}
Chris Wilson96a945a2016-08-03 13:19:16 +0100417
418/**
419 * intel_engines_cleanup_common - cleans up the engine state created by
420 * the common initiailizers.
421 * @engine: Engine to cleanup.
422 *
423 * This cleans up everything created by the common helpers.
424 */
425void intel_engine_cleanup_common(struct intel_engine_cs *engine)
426{
Chris Wilsonadc320c2016-08-15 10:48:59 +0100427 intel_engine_cleanup_scratch(engine);
428
Chris Wilson4e50f082016-10-28 13:58:31 +0100429 i915_gem_render_state_fini(engine);
Chris Wilson96a945a2016-08-03 13:19:16 +0100430 intel_engine_fini_breadcrumbs(engine);
Chris Wilson7756e452016-08-18 17:17:10 +0100431 intel_engine_cleanup_cmd_parser(engine);
Chris Wilson96a945a2016-08-03 13:19:16 +0100432 i915_gem_batch_pool_fini(&engine->batch_pool);
Chris Wilsone8a9c582016-12-18 15:37:20 +0000433
434 engine->context_unpin(engine, engine->i915->kernel_context);
Chris Wilson96a945a2016-08-03 13:19:16 +0100435}
Chris Wilson1b365952016-10-04 21:11:31 +0100436
437u64 intel_engine_get_active_head(struct intel_engine_cs *engine)
438{
439 struct drm_i915_private *dev_priv = engine->i915;
440 u64 acthd;
441
442 if (INTEL_GEN(dev_priv) >= 8)
443 acthd = I915_READ64_2x32(RING_ACTHD(engine->mmio_base),
444 RING_ACTHD_UDW(engine->mmio_base));
445 else if (INTEL_GEN(dev_priv) >= 4)
446 acthd = I915_READ(RING_ACTHD(engine->mmio_base));
447 else
448 acthd = I915_READ(ACTHD);
449
450 return acthd;
451}
452
453u64 intel_engine_get_last_batch_head(struct intel_engine_cs *engine)
454{
455 struct drm_i915_private *dev_priv = engine->i915;
456 u64 bbaddr;
457
458 if (INTEL_GEN(dev_priv) >= 8)
459 bbaddr = I915_READ64_2x32(RING_BBADDR(engine->mmio_base),
460 RING_BBADDR_UDW(engine->mmio_base));
461 else
462 bbaddr = I915_READ(RING_BBADDR(engine->mmio_base));
463
464 return bbaddr;
465}
Chris Wilson0e704472016-10-12 10:05:17 +0100466
467const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
468{
469 switch (type) {
470 case I915_CACHE_NONE: return " uncached";
471 case I915_CACHE_LLC: return HAS_LLC(i915) ? " LLC" : " snooped";
472 case I915_CACHE_L3_LLC: return " L3+LLC";
473 case I915_CACHE_WT: return " WT";
474 default: return "";
475 }
476}
477
478static inline uint32_t
479read_subslice_reg(struct drm_i915_private *dev_priv, int slice,
480 int subslice, i915_reg_t reg)
481{
482 uint32_t mcr;
483 uint32_t ret;
484 enum forcewake_domains fw_domains;
485
486 fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg,
487 FW_REG_READ);
488 fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
489 GEN8_MCR_SELECTOR,
490 FW_REG_READ | FW_REG_WRITE);
491
492 spin_lock_irq(&dev_priv->uncore.lock);
493 intel_uncore_forcewake_get__locked(dev_priv, fw_domains);
494
495 mcr = I915_READ_FW(GEN8_MCR_SELECTOR);
496 /*
497 * The HW expects the slice and sublice selectors to be reset to 0
498 * after reading out the registers.
499 */
500 WARN_ON_ONCE(mcr & (GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK));
501 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
502 mcr |= GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice);
503 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
504
505 ret = I915_READ_FW(reg);
506
507 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
508 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
509
510 intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
511 spin_unlock_irq(&dev_priv->uncore.lock);
512
513 return ret;
514}
515
516/* NB: please notice the memset */
517void intel_engine_get_instdone(struct intel_engine_cs *engine,
518 struct intel_instdone *instdone)
519{
520 struct drm_i915_private *dev_priv = engine->i915;
521 u32 mmio_base = engine->mmio_base;
522 int slice;
523 int subslice;
524
525 memset(instdone, 0, sizeof(*instdone));
526
527 switch (INTEL_GEN(dev_priv)) {
528 default:
529 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
530
531 if (engine->id != RCS)
532 break;
533
534 instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
535 for_each_instdone_slice_subslice(dev_priv, slice, subslice) {
536 instdone->sampler[slice][subslice] =
537 read_subslice_reg(dev_priv, slice, subslice,
538 GEN7_SAMPLER_INSTDONE);
539 instdone->row[slice][subslice] =
540 read_subslice_reg(dev_priv, slice, subslice,
541 GEN7_ROW_INSTDONE);
542 }
543 break;
544 case 7:
545 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
546
547 if (engine->id != RCS)
548 break;
549
550 instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
551 instdone->sampler[0][0] = I915_READ(GEN7_SAMPLER_INSTDONE);
552 instdone->row[0][0] = I915_READ(GEN7_ROW_INSTDONE);
553
554 break;
555 case 6:
556 case 5:
557 case 4:
558 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
559
560 if (engine->id == RCS)
561 /* HACK: Using the wrong struct member */
562 instdone->slice_common = I915_READ(GEN4_INSTDONE1);
563 break;
564 case 3:
565 case 2:
566 instdone->instdone = I915_READ(GEN2_INSTDONE);
567 break;
568 }
569}
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000570
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000571static int wa_add(struct drm_i915_private *dev_priv,
572 i915_reg_t addr,
573 const u32 mask, const u32 val)
574{
575 const u32 idx = dev_priv->workarounds.count;
576
577 if (WARN_ON(idx >= I915_MAX_WA_REGS))
578 return -ENOSPC;
579
580 dev_priv->workarounds.reg[idx].addr = addr;
581 dev_priv->workarounds.reg[idx].value = val;
582 dev_priv->workarounds.reg[idx].mask = mask;
583
584 dev_priv->workarounds.count++;
585
586 return 0;
587}
588
589#define WA_REG(addr, mask, val) do { \
590 const int r = wa_add(dev_priv, (addr), (mask), (val)); \
591 if (r) \
592 return r; \
593 } while (0)
594
595#define WA_SET_BIT_MASKED(addr, mask) \
596 WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
597
598#define WA_CLR_BIT_MASKED(addr, mask) \
599 WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
600
601#define WA_SET_FIELD_MASKED(addr, mask, value) \
602 WA_REG(addr, mask, _MASKED_FIELD(mask, value))
603
604#define WA_SET_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) | (mask))
605#define WA_CLR_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) & ~(mask))
606
607#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val)
608
609static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
610 i915_reg_t reg)
611{
612 struct drm_i915_private *dev_priv = engine->i915;
613 struct i915_workarounds *wa = &dev_priv->workarounds;
614 const uint32_t index = wa->hw_whitelist_count[engine->id];
615
616 if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
617 return -EINVAL;
618
619 WA_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
620 i915_mmio_reg_offset(reg));
621 wa->hw_whitelist_count[engine->id]++;
622
623 return 0;
624}
625
626static int gen8_init_workarounds(struct intel_engine_cs *engine)
627{
628 struct drm_i915_private *dev_priv = engine->i915;
629
630 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
631
632 /* WaDisableAsyncFlipPerfMode:bdw,chv */
633 WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
634
635 /* WaDisablePartialInstShootdown:bdw,chv */
636 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
637 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
638
639 /* Use Force Non-Coherent whenever executing a 3D context. This is a
640 * workaround for for a possible hang in the unlikely event a TLB
641 * invalidation occurs during a PSD flush.
642 */
643 /* WaForceEnableNonCoherent:bdw,chv */
644 /* WaHdcDisableFetchWhenMasked:bdw,chv */
645 WA_SET_BIT_MASKED(HDC_CHICKEN0,
646 HDC_DONOT_FETCH_MEM_WHEN_MASKED |
647 HDC_FORCE_NON_COHERENT);
648
649 /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
650 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
651 * polygons in the same 8x4 pixel/sample area to be processed without
652 * stalling waiting for the earlier ones to write to Hierarchical Z
653 * buffer."
654 *
655 * This optimization is off by default for BDW and CHV; turn it on.
656 */
657 WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
658
659 /* Wa4x4STCOptimizationDisable:bdw,chv */
660 WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
661
662 /*
663 * BSpec recommends 8x4 when MSAA is used,
664 * however in practice 16x4 seems fastest.
665 *
666 * Note that PS/WM thread counts depend on the WIZ hashing
667 * disable bit, which we don't touch here, but it's good
668 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
669 */
670 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
671 GEN6_WIZ_HASHING_MASK,
672 GEN6_WIZ_HASHING_16x4);
673
674 return 0;
675}
676
677static int bdw_init_workarounds(struct intel_engine_cs *engine)
678{
679 struct drm_i915_private *dev_priv = engine->i915;
680 int ret;
681
682 ret = gen8_init_workarounds(engine);
683 if (ret)
684 return ret;
685
686 /* WaDisableThreadStallDopClockGating:bdw (pre-production) */
687 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
688
689 /* WaDisableDopClockGating:bdw
690 *
691 * Also see the related UCGTCL1 write in broadwell_init_clock_gating()
692 * to disable EUTC clock gating.
693 */
694 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
695 DOP_CLOCK_GATING_DISABLE);
696
697 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
698 GEN8_SAMPLER_POWER_BYPASS_DIS);
699
700 WA_SET_BIT_MASKED(HDC_CHICKEN0,
701 /* WaForceContextSaveRestoreNonCoherent:bdw */
702 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
703 /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
704 (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
705
706 return 0;
707}
708
709static int chv_init_workarounds(struct intel_engine_cs *engine)
710{
711 struct drm_i915_private *dev_priv = engine->i915;
712 int ret;
713
714 ret = gen8_init_workarounds(engine);
715 if (ret)
716 return ret;
717
718 /* WaDisableThreadStallDopClockGating:chv */
719 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
720
721 /* Improve HiZ throughput on CHV. */
722 WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
723
724 return 0;
725}
726
727static int gen9_init_workarounds(struct intel_engine_cs *engine)
728{
729 struct drm_i915_private *dev_priv = engine->i915;
730 int ret;
731
732 /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk */
733 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
734
735 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk */
736 I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
737 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
738
739 /* WaDisableKillLogic:bxt,skl,kbl */
740 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
741 ECOCHK_DIS_TLB);
742
743 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk */
744 /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk */
745 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
746 FLOW_CONTROL_ENABLE |
747 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
748
749 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
750 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
751 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
752
753 /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */
754 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
755 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
756 GEN9_DG_MIRROR_FIX_ENABLE);
757
758 /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */
759 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
760 WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1,
761 GEN9_RHWO_OPTIMIZATION_DISABLE);
762 /*
763 * WA also requires GEN9_SLICE_COMMON_ECO_CHICKEN0[14:14] to be set
764 * but we do that in per ctx batchbuffer as there is an issue
765 * with this register not getting restored on ctx restore
766 */
767 }
768
769 /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl */
770 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
771 GEN9_ENABLE_GPGPU_PREEMPTION);
772
773 /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk */
774 /* WaDisablePartialResolveInVc:skl,bxt,kbl */
775 WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
776 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
777
778 /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk */
779 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
780 GEN9_CCS_TLB_PREFETCH_ENABLE);
781
782 /* WaDisableMaskBasedCammingInRCC:bxt */
783 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
784 WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0,
785 PIXEL_MASK_CAMMING_DISABLE);
786
787 /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl */
788 WA_SET_BIT_MASKED(HDC_CHICKEN0,
789 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
790 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
791
792 /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
793 * both tied to WaForceContextSaveRestoreNonCoherent
794 * in some hsds for skl. We keep the tie for all gen9. The
795 * documentation is a bit hazy and so we want to get common behaviour,
796 * even though there is no clear evidence we would need both on kbl/bxt.
797 * This area has been source of system hangs so we play it safe
798 * and mimic the skl regardless of what bspec says.
799 *
800 * Use Force Non-Coherent whenever executing a 3D context. This
801 * is a workaround for a possible hang in the unlikely event
802 * a TLB invalidation occurs during a PSD flush.
803 */
804
805 /* WaForceEnableNonCoherent:skl,bxt,kbl */
806 WA_SET_BIT_MASKED(HDC_CHICKEN0,
807 HDC_FORCE_NON_COHERENT);
808
809 /* WaDisableHDCInvalidation:skl,bxt,kbl */
810 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
811 BDW_DISABLE_HDC_INVALIDATION);
812
813 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl */
814 if (IS_SKYLAKE(dev_priv) ||
815 IS_KABYLAKE(dev_priv) ||
816 IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
817 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
818 GEN8_SAMPLER_POWER_BYPASS_DIS);
819
820 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk */
821 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
822
823 /* WaOCLCoherentLineFlush:skl,bxt,kbl */
824 I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
825 GEN8_LQSC_FLUSH_COHERENT_LINES));
826
827 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk */
828 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
829 if (ret)
830 return ret;
831
832 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl */
833 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
834 if (ret)
835 return ret;
836
837 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk */
838 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
839 if (ret)
840 return ret;
841
842 return 0;
843}
844
845static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
846{
847 struct drm_i915_private *dev_priv = engine->i915;
848 u8 vals[3] = { 0, 0, 0 };
849 unsigned int i;
850
851 for (i = 0; i < 3; i++) {
852 u8 ss;
853
854 /*
855 * Only consider slices where one, and only one, subslice has 7
856 * EUs
857 */
858 if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
859 continue;
860
861 /*
862 * subslice_7eu[i] != 0 (because of the check above) and
863 * ss_max == 4 (maximum number of subslices possible per slice)
864 *
865 * -> 0 <= ss <= 3;
866 */
867 ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
868 vals[i] = 3 - ss;
869 }
870
871 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
872 return 0;
873
874 /* Tune IZ hashing. See intel_device_info_runtime_init() */
875 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
876 GEN9_IZ_HASHING_MASK(2) |
877 GEN9_IZ_HASHING_MASK(1) |
878 GEN9_IZ_HASHING_MASK(0),
879 GEN9_IZ_HASHING(2, vals[2]) |
880 GEN9_IZ_HASHING(1, vals[1]) |
881 GEN9_IZ_HASHING(0, vals[0]));
882
883 return 0;
884}
885
886static int skl_init_workarounds(struct intel_engine_cs *engine)
887{
888 struct drm_i915_private *dev_priv = engine->i915;
889 int ret;
890
891 ret = gen9_init_workarounds(engine);
892 if (ret)
893 return ret;
894
895 /*
896 * Actual WA is to disable percontext preemption granularity control
897 * until D0 which is the default case so this is equivalent to
898 * !WaDisablePerCtxtPreemptionGranularityControl:skl
899 */
900 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
901 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
902
903 /* WaEnableGapsTsvCreditFix:skl */
904 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
905 GEN9_GAPS_TSV_CREDIT_DISABLE));
906
907 /* WaDisableGafsUnitClkGating:skl */
908 WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
909
910 /* WaInPlaceDecompressionHang:skl */
911 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
912 WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA,
913 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
914
915 /* WaDisableLSQCROPERFforOCL:skl */
916 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
917 if (ret)
918 return ret;
919
920 return skl_tune_iz_hashing(engine);
921}
922
923static int bxt_init_workarounds(struct intel_engine_cs *engine)
924{
925 struct drm_i915_private *dev_priv = engine->i915;
926 int ret;
927
928 ret = gen9_init_workarounds(engine);
929 if (ret)
930 return ret;
931
932 /* WaStoreMultiplePTEenable:bxt */
933 /* This is a requirement according to Hardware specification */
934 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
935 I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
936
937 /* WaSetClckGatingDisableMedia:bxt */
938 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
939 I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
940 ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
941 }
942
943 /* WaDisableThreadStallDopClockGating:bxt */
944 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
945 STALL_DOP_GATING_DISABLE);
946
947 /* WaDisablePooledEuLoadBalancingFix:bxt */
948 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
949 WA_SET_BIT_MASKED(FF_SLICE_CS_CHICKEN2,
950 GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE);
951 }
952
953 /* WaDisableSbeCacheDispatchPortSharing:bxt */
954 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) {
955 WA_SET_BIT_MASKED(
956 GEN7_HALF_SLICE_CHICKEN1,
957 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
958 }
959
960 /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */
961 /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */
962 /* WaDisableObjectLevelPreemtionForInstanceId:bxt */
963 /* WaDisableLSQCROPERFforOCL:bxt */
964 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
965 ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1);
966 if (ret)
967 return ret;
968
969 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
970 if (ret)
971 return ret;
972 }
973
974 /* WaProgramL3SqcReg1DefaultForPerf:bxt */
975 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
976 I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
977 L3_HIGH_PRIO_CREDITS(2));
978
979 /* WaToEnableHwFixForPushConstHWBug:bxt */
980 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
981 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
982 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
983
984 /* WaInPlaceDecompressionHang:bxt */
985 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
986 WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA,
987 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
988
989 return 0;
990}
991
992static int kbl_init_workarounds(struct intel_engine_cs *engine)
993{
994 struct drm_i915_private *dev_priv = engine->i915;
995 int ret;
996
997 ret = gen9_init_workarounds(engine);
998 if (ret)
999 return ret;
1000
1001 /* WaEnableGapsTsvCreditFix:kbl */
1002 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1003 GEN9_GAPS_TSV_CREDIT_DISABLE));
1004
1005 /* WaDisableDynamicCreditSharing:kbl */
1006 if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
1007 WA_SET_BIT(GAMT_CHKN_BIT_REG,
1008 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
1009
1010 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
1011 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
1012 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1013 HDC_FENCE_DEST_SLM_DISABLE);
1014
1015 /* WaToEnableHwFixForPushConstHWBug:kbl */
1016 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
1017 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1018 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1019
1020 /* WaDisableGafsUnitClkGating:kbl */
1021 WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
1022
1023 /* WaDisableSbeCacheDispatchPortSharing:kbl */
1024 WA_SET_BIT_MASKED(
1025 GEN7_HALF_SLICE_CHICKEN1,
1026 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1027
1028 /* WaInPlaceDecompressionHang:kbl */
1029 WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA,
1030 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
1031
1032 /* WaDisableLSQCROPERFforOCL:kbl */
1033 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1034 if (ret)
1035 return ret;
1036
1037 return 0;
1038}
1039
1040static int glk_init_workarounds(struct intel_engine_cs *engine)
1041{
1042 struct drm_i915_private *dev_priv = engine->i915;
1043 int ret;
1044
1045 ret = gen9_init_workarounds(engine);
1046 if (ret)
1047 return ret;
1048
1049 /* WaToEnableHwFixForPushConstHWBug:glk */
1050 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1051 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1052
1053 return 0;
1054}
1055
1056int init_workarounds_ring(struct intel_engine_cs *engine)
1057{
1058 struct drm_i915_private *dev_priv = engine->i915;
Chris Wilson02e012f2017-03-01 12:11:31 +00001059 int err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001060
1061 WARN_ON(engine->id != RCS);
1062
1063 dev_priv->workarounds.count = 0;
Chris Wilson02e012f2017-03-01 12:11:31 +00001064 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001065
1066 if (IS_BROADWELL(dev_priv))
Chris Wilson02e012f2017-03-01 12:11:31 +00001067 err = bdw_init_workarounds(engine);
1068 else if (IS_CHERRYVIEW(dev_priv))
1069 err = chv_init_workarounds(engine);
1070 else if (IS_SKYLAKE(dev_priv))
1071 err = skl_init_workarounds(engine);
1072 else if (IS_BROXTON(dev_priv))
1073 err = bxt_init_workarounds(engine);
1074 else if (IS_KABYLAKE(dev_priv))
1075 err = kbl_init_workarounds(engine);
1076 else if (IS_GEMINILAKE(dev_priv))
1077 err = glk_init_workarounds(engine);
1078 else
1079 err = 0;
1080 if (err)
1081 return err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001082
Chris Wilson02e012f2017-03-01 12:11:31 +00001083 DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n",
1084 engine->name, dev_priv->workarounds.count);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001085 return 0;
1086}
1087
1088int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)
1089{
1090 struct i915_workarounds *w = &req->i915->workarounds;
1091 u32 *cs;
1092 int ret, i;
1093
1094 if (w->count == 0)
1095 return 0;
1096
1097 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1098 if (ret)
1099 return ret;
1100
1101 cs = intel_ring_begin(req, (w->count * 2 + 2));
1102 if (IS_ERR(cs))
1103 return PTR_ERR(cs);
1104
1105 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
1106 for (i = 0; i < w->count; i++) {
1107 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
1108 *cs++ = w->reg[i].value;
1109 }
1110 *cs++ = MI_NOOP;
1111
1112 intel_ring_advance(req, cs);
1113
1114 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1115 if (ret)
1116 return ret;
1117
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001118 return 0;
1119}
1120
Chris Wilson54003672017-03-03 12:19:46 +00001121/**
1122 * intel_engine_is_idle() - Report if the engine has finished process all work
1123 * @engine: the intel_engine_cs
1124 *
1125 * Return true if there are no requests pending, nothing left to be submitted
1126 * to hardware, and that the engine is idle.
1127 */
1128bool intel_engine_is_idle(struct intel_engine_cs *engine)
1129{
1130 struct drm_i915_private *dev_priv = engine->i915;
1131
Chris Wilsona8e9a412017-04-11 20:00:42 +01001132 /* More white lies, if wedged, hw state is inconsistent */
1133 if (i915_terminally_wedged(&dev_priv->gpu_error))
1134 return true;
1135
Chris Wilson54003672017-03-03 12:19:46 +00001136 /* Any inflight/incomplete requests? */
1137 if (!i915_seqno_passed(intel_engine_get_seqno(engine),
1138 intel_engine_last_submit(engine)))
1139 return false;
1140
Chris Wilson8968a362017-04-12 00:44:26 +01001141 if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))
1142 return true;
1143
Chris Wilson54003672017-03-03 12:19:46 +00001144 /* Interrupt/tasklet pending? */
1145 if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
1146 return false;
1147
1148 /* Both ports drained, no more ELSP submission? */
1149 if (engine->execlist_port[0].request)
1150 return false;
1151
1152 /* Ring stopped? */
1153 if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE))
1154 return false;
1155
1156 return true;
1157}
1158
Chris Wilson05425242017-03-03 12:19:47 +00001159bool intel_engines_are_idle(struct drm_i915_private *dev_priv)
1160{
1161 struct intel_engine_cs *engine;
1162 enum intel_engine_id id;
1163
Chris Wilson8490ae202017-03-30 15:50:37 +01001164 if (READ_ONCE(dev_priv->gt.active_requests))
1165 return false;
1166
1167 /* If the driver is wedged, HW state may be very inconsistent and
1168 * report that it is still busy, even though we have stopped using it.
1169 */
1170 if (i915_terminally_wedged(&dev_priv->gpu_error))
1171 return true;
1172
Chris Wilson05425242017-03-03 12:19:47 +00001173 for_each_engine(engine, dev_priv, id) {
1174 if (!intel_engine_is_idle(engine))
1175 return false;
1176 }
1177
1178 return true;
1179}
1180
Chris Wilsonff44ad52017-03-16 17:13:03 +00001181void intel_engines_reset_default_submission(struct drm_i915_private *i915)
1182{
1183 struct intel_engine_cs *engine;
1184 enum intel_engine_id id;
1185
1186 for_each_engine(engine, i915, id)
1187 engine->set_default_submission(engine);
1188}
1189
Chris Wilsonf97fbf92017-02-13 17:15:14 +00001190#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
1191#include "selftests/mock_engine.c"
1192#endif