blob: 8625feb0939e5bed849aa1e4a774209fd27b49fb [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
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +030029/* Haswell does have the CXT_SIZE register however it does not appear to be
30 * valid. Now, docs explain in dwords what is in the context object. The full
31 * size is 70720 bytes, however, the power context and execlist context will
32 * never be saved (power context is stored elsewhere, and execlists don't work
33 * on HSW) - so the final size, including the extra state required for the
34 * Resource Streamer, is 66944 bytes, which rounds to 17 pages.
35 */
36#define HSW_CXT_TOTAL_SIZE (17 * PAGE_SIZE)
37/* Same as Haswell, but 72064 bytes now. */
38#define GEN8_CXT_TOTAL_SIZE (18 * PAGE_SIZE)
39
40#define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE)
41#define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE)
Oscar Mateo7fd0b1a2017-09-21 16:19:49 -070042#define GEN10_LR_CONTEXT_RENDER_SIZE (19 * PAGE_SIZE)
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +030043
44#define GEN8_LR_CONTEXT_OTHER_SIZE ( 2 * PAGE_SIZE)
45
Oscar Mateob8400f02017-04-10 07:34:32 -070046struct engine_class_info {
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010047 const char *name;
Oscar Mateob8400f02017-04-10 07:34:32 -070048 int (*init_legacy)(struct intel_engine_cs *engine);
49 int (*init_execlists)(struct intel_engine_cs *engine);
50};
51
52static const struct engine_class_info intel_engine_classes[] = {
53 [RENDER_CLASS] = {
54 .name = "rcs",
55 .init_execlists = logical_render_ring_init,
56 .init_legacy = intel_init_render_ring_buffer,
57 },
58 [COPY_ENGINE_CLASS] = {
59 .name = "bcs",
60 .init_execlists = logical_xcs_ring_init,
61 .init_legacy = intel_init_blt_ring_buffer,
62 },
63 [VIDEO_DECODE_CLASS] = {
64 .name = "vcs",
65 .init_execlists = logical_xcs_ring_init,
66 .init_legacy = intel_init_bsd_ring_buffer,
67 },
68 [VIDEO_ENHANCEMENT_CLASS] = {
69 .name = "vecs",
70 .init_execlists = logical_xcs_ring_init,
71 .init_legacy = intel_init_vebox_ring_buffer,
72 },
73};
74
75struct engine_info {
Michal Wajdeczko237ae7c2017-03-01 20:26:15 +000076 unsigned int hw_id;
Chris Wilson1d39f282017-04-11 13:43:06 +010077 unsigned int uabi_id;
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070078 u8 class;
79 u8 instance;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010080 u32 mmio_base;
81 unsigned irq_shift;
Oscar Mateob8400f02017-04-10 07:34:32 -070082};
83
84static const struct engine_info intel_engines[] = {
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010085 [RCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +010086 .hw_id = RCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +010087 .uabi_id = I915_EXEC_RENDER,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070088 .class = RENDER_CLASS,
89 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010090 .mmio_base = RENDER_RING_BASE,
91 .irq_shift = GEN8_RCS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010092 },
93 [BCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +010094 .hw_id = BCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +010095 .uabi_id = I915_EXEC_BLT,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070096 .class = COPY_ENGINE_CLASS,
97 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010098 .mmio_base = BLT_RING_BASE,
99 .irq_shift = GEN8_BCS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100100 },
101 [VCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100102 .hw_id = VCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100103 .uabi_id = I915_EXEC_BSD,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700104 .class = VIDEO_DECODE_CLASS,
105 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100106 .mmio_base = GEN6_BSD_RING_BASE,
107 .irq_shift = GEN8_VCS1_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100108 },
109 [VCS2] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100110 .hw_id = VCS2_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100111 .uabi_id = I915_EXEC_BSD,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700112 .class = VIDEO_DECODE_CLASS,
113 .instance = 1,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100114 .mmio_base = GEN8_BSD2_RING_BASE,
115 .irq_shift = GEN8_VCS2_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100116 },
117 [VECS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100118 .hw_id = VECS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100119 .uabi_id = I915_EXEC_VEBOX,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700120 .class = VIDEO_ENHANCEMENT_CLASS,
121 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100122 .mmio_base = VEBOX_RING_BASE,
123 .irq_shift = GEN8_VECS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100124 },
125};
126
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300127/**
128 * ___intel_engine_context_size() - return the size of the context for an engine
129 * @dev_priv: i915 device private
130 * @class: engine class
131 *
132 * Each engine class may require a different amount of space for a context
133 * image.
134 *
135 * Return: size (in bytes) of an engine class specific context image
136 *
137 * Note: this size includes the HWSP, which is part of the context image
138 * in LRC mode, but does not include the "shared data page" used with
139 * GuC submission. The caller should account for this if using the GuC.
140 */
141static u32
142__intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class)
143{
144 u32 cxt_size;
145
146 BUILD_BUG_ON(I915_GTT_PAGE_SIZE != PAGE_SIZE);
147
148 switch (class) {
149 case RENDER_CLASS:
150 switch (INTEL_GEN(dev_priv)) {
151 default:
152 MISSING_CASE(INTEL_GEN(dev_priv));
Rodrigo Vivif65f8412017-07-06 14:06:24 -0700153 case 10:
Oscar Mateo7fd0b1a2017-09-21 16:19:49 -0700154 return GEN10_LR_CONTEXT_RENDER_SIZE;
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300155 case 9:
156 return GEN9_LR_CONTEXT_RENDER_SIZE;
157 case 8:
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000158 return i915_modparams.enable_execlists ?
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300159 GEN8_LR_CONTEXT_RENDER_SIZE :
160 GEN8_CXT_TOTAL_SIZE;
161 case 7:
162 if (IS_HASWELL(dev_priv))
163 return HSW_CXT_TOTAL_SIZE;
164
165 cxt_size = I915_READ(GEN7_CXT_SIZE);
166 return round_up(GEN7_CXT_TOTAL_SIZE(cxt_size) * 64,
167 PAGE_SIZE);
168 case 6:
169 cxt_size = I915_READ(CXT_SIZE);
170 return round_up(GEN6_CXT_TOTAL_SIZE(cxt_size) * 64,
171 PAGE_SIZE);
172 case 5:
173 case 4:
174 case 3:
175 case 2:
176 /* For the special day when i810 gets merged. */
177 case 1:
178 return 0;
179 }
180 break;
181 default:
182 MISSING_CASE(class);
183 case VIDEO_DECODE_CLASS:
184 case VIDEO_ENHANCEMENT_CLASS:
185 case COPY_ENGINE_CLASS:
186 if (INTEL_GEN(dev_priv) < 8)
187 return 0;
188 return GEN8_LR_CONTEXT_OTHER_SIZE;
189 }
190}
191
Akash Goel3b3f1652016-10-13 22:44:48 +0530192static int
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100193intel_engine_setup(struct drm_i915_private *dev_priv,
194 enum intel_engine_id id)
195{
196 const struct engine_info *info = &intel_engines[id];
Oscar Mateob8400f02017-04-10 07:34:32 -0700197 const struct engine_class_info *class_info;
Akash Goel3b3f1652016-10-13 22:44:48 +0530198 struct intel_engine_cs *engine;
199
Oscar Mateob8400f02017-04-10 07:34:32 -0700200 GEM_BUG_ON(info->class >= ARRAY_SIZE(intel_engine_classes));
201 class_info = &intel_engine_classes[info->class];
202
Akash Goel3b3f1652016-10-13 22:44:48 +0530203 GEM_BUG_ON(dev_priv->engine[id]);
204 engine = kzalloc(sizeof(*engine), GFP_KERNEL);
205 if (!engine)
206 return -ENOMEM;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100207
208 engine->id = id;
209 engine->i915 = dev_priv;
Oscar Mateo6e516142017-04-10 07:34:31 -0700210 WARN_ON(snprintf(engine->name, sizeof(engine->name), "%s%u",
Oscar Mateob8400f02017-04-10 07:34:32 -0700211 class_info->name, info->instance) >=
212 sizeof(engine->name));
Chris Wilson1d39f282017-04-11 13:43:06 +0100213 engine->uabi_id = info->uabi_id;
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100214 engine->hw_id = engine->guc_id = info->hw_id;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100215 engine->mmio_base = info->mmio_base;
216 engine->irq_shift = info->irq_shift;
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700217 engine->class = info->class;
218 engine->instance = info->instance;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100219
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300220 engine->context_size = __intel_engine_context_size(dev_priv,
221 engine->class);
222 if (WARN_ON(engine->context_size > BIT(20)))
223 engine->context_size = 0;
224
Chris Wilson0de91362016-11-14 20:41:01 +0000225 /* Nothing to do here, execute in order of dependencies */
226 engine->schedule = NULL;
227
Changbin Du3fc03062017-03-13 10:47:11 +0800228 ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
229
Akash Goel3b3f1652016-10-13 22:44:48 +0530230 dev_priv->engine[id] = engine;
231 return 0;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100232}
233
234/**
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300235 * intel_engines_init_mmio() - allocate and prepare the Engine Command Streamers
Tvrtko Ursulinbf9e8422016-12-01 14:16:38 +0000236 * @dev_priv: i915 device private
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100237 *
238 * Return: non-zero if the initialization failed.
239 */
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300240int intel_engines_init_mmio(struct drm_i915_private *dev_priv)
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100241{
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100242 struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
Chris Wilson5f9be052017-04-11 17:56:58 +0100243 const unsigned int ring_mask = INTEL_INFO(dev_priv)->ring_mask;
Akash Goel3b3f1652016-10-13 22:44:48 +0530244 struct intel_engine_cs *engine;
245 enum intel_engine_id id;
Chris Wilson5f9be052017-04-11 17:56:58 +0100246 unsigned int mask = 0;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100247 unsigned int i;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000248 int err;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100249
Tvrtko Ursulin70006ad2016-10-13 11:02:56 +0100250 WARN_ON(ring_mask == 0);
251 WARN_ON(ring_mask &
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100252 GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES));
253
254 for (i = 0; i < ARRAY_SIZE(intel_engines); i++) {
255 if (!HAS_ENGINE(dev_priv, i))
256 continue;
257
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000258 err = intel_engine_setup(dev_priv, i);
259 if (err)
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100260 goto cleanup;
261
262 mask |= ENGINE_MASK(i);
263 }
264
265 /*
266 * Catch failures to update intel_engines table when the new engines
267 * are added to the driver by a warning and disabling the forgotten
268 * engines.
269 */
Tvrtko Ursulin70006ad2016-10-13 11:02:56 +0100270 if (WARN_ON(mask != ring_mask))
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100271 device_info->ring_mask = mask;
272
Chris Wilson5f9be052017-04-11 17:56:58 +0100273 /* We always presume we have at least RCS available for later probing */
274 if (WARN_ON(!HAS_ENGINE(dev_priv, RCS))) {
275 err = -ENODEV;
276 goto cleanup;
277 }
278
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100279 device_info->num_rings = hweight32(mask);
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100280
281 return 0;
282
283cleanup:
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000284 for_each_engine(engine, dev_priv, id)
285 kfree(engine);
286 return err;
287}
288
289/**
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300290 * intel_engines_init() - init the Engine Command Streamers
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000291 * @dev_priv: i915 device private
292 *
293 * Return: non-zero if the initialization failed.
294 */
295int intel_engines_init(struct drm_i915_private *dev_priv)
296{
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000297 struct intel_engine_cs *engine;
298 enum intel_engine_id id, err_id;
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100299 int err;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000300
Akash Goel3b3f1652016-10-13 22:44:48 +0530301 for_each_engine(engine, dev_priv, id) {
Oscar Mateob8400f02017-04-10 07:34:32 -0700302 const struct engine_class_info *class_info =
303 &intel_engine_classes[engine->class];
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000304 int (*init)(struct intel_engine_cs *engine);
305
Michal Wajdeczko4f044a82017-09-19 19:38:44 +0000306 if (i915_modparams.enable_execlists)
Oscar Mateob8400f02017-04-10 07:34:32 -0700307 init = class_info->init_execlists;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000308 else
Oscar Mateob8400f02017-04-10 07:34:32 -0700309 init = class_info->init_legacy;
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100310
311 err = -EINVAL;
312 err_id = id;
313
314 if (GEM_WARN_ON(!init))
315 goto cleanup;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000316
317 err = init(engine);
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100318 if (err)
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000319 goto cleanup;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000320
Chris Wilsonff44ad52017-03-16 17:13:03 +0000321 GEM_BUG_ON(!engine->submit_request);
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000322 }
323
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000324 return 0;
325
326cleanup:
327 for_each_engine(engine, dev_priv, id) {
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100328 if (id >= err_id) {
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000329 kfree(engine);
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100330 dev_priv->engine[id] = NULL;
331 } else {
Tvrtko Ursulin8ee7c6e2017-02-16 12:23:22 +0000332 dev_priv->gt.cleanup_engine(engine);
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100333 }
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100334 }
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000335 return err;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100336}
337
Chris Wilson73cb9702016-10-28 13:58:46 +0100338void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
Chris Wilson57f275a2016-08-15 10:49:00 +0100339{
340 struct drm_i915_private *dev_priv = engine->i915;
341
342 /* Our semaphore implementation is strictly monotonic (i.e. we proceed
343 * so long as the semaphore value in the register/page is greater
344 * than the sync value), so whenever we reset the seqno,
345 * so long as we reset the tracking semaphore value to 0, it will
346 * always be before the next request's seqno. If we don't reset
347 * the semaphore value, then when the seqno moves backwards all
348 * future waits will complete instantly (causing rendering corruption).
349 */
350 if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv)) {
351 I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
352 I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
353 if (HAS_VEBOX(dev_priv))
354 I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
355 }
Chris Wilson51d545d2016-08-15 10:49:02 +0100356 if (dev_priv->semaphore) {
357 struct page *page = i915_vma_first_page(dev_priv->semaphore);
358 void *semaphores;
359
360 /* Semaphores are in noncoherent memory, flush to be safe */
Chris Wilson24caf652017-03-20 14:56:09 +0000361 semaphores = kmap_atomic(page);
Chris Wilson57f275a2016-08-15 10:49:00 +0100362 memset(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
363 0, I915_NUM_ENGINES * gen8_semaphore_seqno_size);
Chris Wilson51d545d2016-08-15 10:49:02 +0100364 drm_clflush_virt_range(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
365 I915_NUM_ENGINES * gen8_semaphore_seqno_size);
Chris Wilson24caf652017-03-20 14:56:09 +0000366 kunmap_atomic(semaphores);
Chris Wilson57f275a2016-08-15 10:49:00 +0100367 }
Chris Wilson57f275a2016-08-15 10:49:00 +0100368
369 intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
Chris Wilson14a6bbf2017-03-14 11:14:52 +0000370 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
Chris Wilson73cb9702016-10-28 13:58:46 +0100371
Chris Wilson57f275a2016-08-15 10:49:00 +0100372 /* After manually advancing the seqno, fake the interrupt in case
373 * there are any waiters for that seqno.
374 */
375 intel_engine_wakeup(engine);
Chris Wilson2ca9faa2017-04-05 16:30:54 +0100376
377 GEM_BUG_ON(intel_engine_get_seqno(engine) != seqno);
Chris Wilson57f275a2016-08-15 10:49:00 +0100378}
379
Chris Wilson73cb9702016-10-28 13:58:46 +0100380static void intel_engine_init_timeline(struct intel_engine_cs *engine)
Chris Wilsondcff85c2016-08-05 10:14:11 +0100381{
Chris Wilson73cb9702016-10-28 13:58:46 +0100382 engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id];
Chris Wilsondcff85c2016-08-05 10:14:11 +0100383}
384
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300385static bool csb_force_mmio(struct drm_i915_private *i915)
386{
387 /* GVT emulation depends upon intercepting CSB mmio */
388 if (intel_vgpu_active(i915))
389 return true;
390
391 /*
392 * IOMMU adds unpredictable latency causing the CSB write (from the
393 * GPU into the HWSP) to only be visible some time after the interrupt
394 * (missed breadcrumb syndrome).
395 */
396 if (intel_vtd_active())
397 return true;
398
399 return false;
400}
401
402static void intel_engine_init_execlist(struct intel_engine_cs *engine)
403{
404 struct intel_engine_execlists * const execlists = &engine->execlists;
405
406 execlists->csb_use_mmio = csb_force_mmio(engine->i915);
407
Mika Kuoppala76e70082017-09-22 15:43:07 +0300408 execlists->port_mask = 1;
409 BUILD_BUG_ON_NOT_POWER_OF_2(execlists_num_ports(execlists));
410 GEM_BUG_ON(execlists_num_ports(execlists) > EXECLIST_MAX_PORTS);
411
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300412 execlists->queue = RB_ROOT;
413 execlists->first = NULL;
414}
415
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100416/**
417 * intel_engines_setup_common - setup engine state not requiring hw access
418 * @engine: Engine to setup.
419 *
420 * Initializes @engine@ structure members shared between legacy and execlists
421 * submission modes which do not require hardware access.
422 *
423 * Typically done early in the submission mode specific engine setup stage.
424 */
425void intel_engine_setup_common(struct intel_engine_cs *engine)
426{
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300427 intel_engine_init_execlist(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100428
Chris Wilson73cb9702016-10-28 13:58:46 +0100429 intel_engine_init_timeline(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100430 intel_engine_init_hangcheck(engine);
Chris Wilson115003e92016-08-04 16:32:19 +0100431 i915_gem_batch_pool_init(engine, &engine->batch_pool);
Chris Wilson7756e452016-08-18 17:17:10 +0100432
433 intel_engine_init_cmd_parser(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100434}
435
Chris Wilsonadc320c2016-08-15 10:48:59 +0100436int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
437{
438 struct drm_i915_gem_object *obj;
439 struct i915_vma *vma;
440 int ret;
441
442 WARN_ON(engine->scratch);
443
Tvrtko Ursulin187685c2016-12-01 14:16:36 +0000444 obj = i915_gem_object_create_stolen(engine->i915, size);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100445 if (!obj)
Chris Wilson920cf412016-10-28 13:58:30 +0100446 obj = i915_gem_object_create_internal(engine->i915, size);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100447 if (IS_ERR(obj)) {
448 DRM_ERROR("Failed to allocate scratch page\n");
449 return PTR_ERR(obj);
450 }
451
Chris Wilsona01cb372017-01-16 15:21:30 +0000452 vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100453 if (IS_ERR(vma)) {
454 ret = PTR_ERR(vma);
455 goto err_unref;
456 }
457
458 ret = i915_vma_pin(vma, 0, 4096, PIN_GLOBAL | PIN_HIGH);
459 if (ret)
460 goto err_unref;
461
462 engine->scratch = vma;
Chris Wilsonbde13eb2016-08-15 10:49:07 +0100463 DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
464 engine->name, i915_ggtt_offset(vma));
Chris Wilsonadc320c2016-08-15 10:48:59 +0100465 return 0;
466
467err_unref:
468 i915_gem_object_put(obj);
469 return ret;
470}
471
472static void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
473{
Chris Wilson19880c42016-08-15 10:49:05 +0100474 i915_vma_unpin_and_release(&engine->scratch);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100475}
476
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100477static void cleanup_phys_status_page(struct intel_engine_cs *engine)
478{
479 struct drm_i915_private *dev_priv = engine->i915;
480
481 if (!dev_priv->status_page_dmah)
482 return;
483
484 drm_pci_free(&dev_priv->drm, dev_priv->status_page_dmah);
485 engine->status_page.page_addr = NULL;
486}
487
488static void cleanup_status_page(struct intel_engine_cs *engine)
489{
490 struct i915_vma *vma;
491 struct drm_i915_gem_object *obj;
492
493 vma = fetch_and_zero(&engine->status_page.vma);
494 if (!vma)
495 return;
496
497 obj = vma->obj;
498
499 i915_vma_unpin(vma);
500 i915_vma_close(vma);
501
502 i915_gem_object_unpin_map(obj);
503 __i915_gem_object_release_unless_active(obj);
504}
505
506static int init_status_page(struct intel_engine_cs *engine)
507{
508 struct drm_i915_gem_object *obj;
509 struct i915_vma *vma;
510 unsigned int flags;
511 void *vaddr;
512 int ret;
513
514 obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE);
515 if (IS_ERR(obj)) {
516 DRM_ERROR("Failed to allocate status page\n");
517 return PTR_ERR(obj);
518 }
519
520 ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
521 if (ret)
522 goto err;
523
524 vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL);
525 if (IS_ERR(vma)) {
526 ret = PTR_ERR(vma);
527 goto err;
528 }
529
530 flags = PIN_GLOBAL;
531 if (!HAS_LLC(engine->i915))
532 /* On g33, we cannot place HWS above 256MiB, so
533 * restrict its pinning to the low mappable arena.
534 * Though this restriction is not documented for
535 * gen4, gen5, or byt, they also behave similarly
536 * and hang if the HWS is placed at the top of the
537 * GTT. To generalise, it appears that all !llc
538 * platforms have issues with us placing the HWS
539 * above the mappable region (even though we never
540 * actually map it).
541 */
542 flags |= PIN_MAPPABLE;
Chris Wilson34a04e52017-09-13 09:56:03 +0100543 else
544 flags |= PIN_HIGH;
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100545 ret = i915_vma_pin(vma, 0, 4096, flags);
546 if (ret)
547 goto err;
548
549 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
550 if (IS_ERR(vaddr)) {
551 ret = PTR_ERR(vaddr);
552 goto err_unpin;
553 }
554
555 engine->status_page.vma = vma;
556 engine->status_page.ggtt_offset = i915_ggtt_offset(vma);
557 engine->status_page.page_addr = memset(vaddr, 0, PAGE_SIZE);
558
559 DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
560 engine->name, i915_ggtt_offset(vma));
561 return 0;
562
563err_unpin:
564 i915_vma_unpin(vma);
565err:
566 i915_gem_object_put(obj);
567 return ret;
568}
569
570static int init_phys_status_page(struct intel_engine_cs *engine)
571{
572 struct drm_i915_private *dev_priv = engine->i915;
573
574 GEM_BUG_ON(engine->id != RCS);
575
576 dev_priv->status_page_dmah =
577 drm_pci_alloc(&dev_priv->drm, PAGE_SIZE, PAGE_SIZE);
578 if (!dev_priv->status_page_dmah)
579 return -ENOMEM;
580
581 engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr;
582 memset(engine->status_page.page_addr, 0, PAGE_SIZE);
583
584 return 0;
585}
586
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100587/**
588 * intel_engines_init_common - initialize cengine state which might require hw access
589 * @engine: Engine to initialize.
590 *
591 * Initializes @engine@ structure members shared between legacy and execlists
592 * submission modes which do require hardware access.
593 *
594 * Typcally done at later stages of submission mode specific engine setup.
595 *
596 * Returns zero on success or an error code on failure.
597 */
598int intel_engine_init_common(struct intel_engine_cs *engine)
599{
Chris Wilson266a2402017-05-04 10:33:08 +0100600 struct intel_ring *ring;
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100601 int ret;
602
Chris Wilsonff44ad52017-03-16 17:13:03 +0000603 engine->set_default_submission(engine);
604
Chris Wilsone8a9c582016-12-18 15:37:20 +0000605 /* We may need to do things with the shrinker which
606 * require us to immediately switch back to the default
607 * context. This can cause a problem as pinning the
608 * default context also requires GTT space which may not
609 * be available. To avoid this we always pin the default
610 * context.
611 */
Chris Wilson266a2402017-05-04 10:33:08 +0100612 ring = engine->context_pin(engine, engine->i915->kernel_context);
613 if (IS_ERR(ring))
614 return PTR_ERR(ring);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100615
Chris Wilsone8a9c582016-12-18 15:37:20 +0000616 ret = intel_engine_init_breadcrumbs(engine);
617 if (ret)
618 goto err_unpin;
619
Chris Wilson4e50f082016-10-28 13:58:31 +0100620 ret = i915_gem_render_state_init(engine);
621 if (ret)
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100622 goto err_breadcrumbs;
623
624 if (HWS_NEEDS_PHYSICAL(engine->i915))
625 ret = init_phys_status_page(engine);
626 else
627 ret = init_status_page(engine);
628 if (ret)
629 goto err_rs_fini;
Chris Wilson4e50f082016-10-28 13:58:31 +0100630
Chris Wilson7756e452016-08-18 17:17:10 +0100631 return 0;
Chris Wilsone8a9c582016-12-18 15:37:20 +0000632
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100633err_rs_fini:
634 i915_gem_render_state_fini(engine);
635err_breadcrumbs:
636 intel_engine_fini_breadcrumbs(engine);
Chris Wilsone8a9c582016-12-18 15:37:20 +0000637err_unpin:
638 engine->context_unpin(engine, engine->i915->kernel_context);
639 return ret;
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100640}
Chris Wilson96a945a2016-08-03 13:19:16 +0100641
642/**
643 * intel_engines_cleanup_common - cleans up the engine state created by
644 * the common initiailizers.
645 * @engine: Engine to cleanup.
646 *
647 * This cleans up everything created by the common helpers.
648 */
649void intel_engine_cleanup_common(struct intel_engine_cs *engine)
650{
Chris Wilsonadc320c2016-08-15 10:48:59 +0100651 intel_engine_cleanup_scratch(engine);
652
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100653 if (HWS_NEEDS_PHYSICAL(engine->i915))
654 cleanup_phys_status_page(engine);
655 else
656 cleanup_status_page(engine);
657
Chris Wilson4e50f082016-10-28 13:58:31 +0100658 i915_gem_render_state_fini(engine);
Chris Wilson96a945a2016-08-03 13:19:16 +0100659 intel_engine_fini_breadcrumbs(engine);
Chris Wilson7756e452016-08-18 17:17:10 +0100660 intel_engine_cleanup_cmd_parser(engine);
Chris Wilson96a945a2016-08-03 13:19:16 +0100661 i915_gem_batch_pool_fini(&engine->batch_pool);
Chris Wilsone8a9c582016-12-18 15:37:20 +0000662
663 engine->context_unpin(engine, engine->i915->kernel_context);
Chris Wilson96a945a2016-08-03 13:19:16 +0100664}
Chris Wilson1b365952016-10-04 21:11:31 +0100665
666u64 intel_engine_get_active_head(struct intel_engine_cs *engine)
667{
668 struct drm_i915_private *dev_priv = engine->i915;
669 u64 acthd;
670
671 if (INTEL_GEN(dev_priv) >= 8)
672 acthd = I915_READ64_2x32(RING_ACTHD(engine->mmio_base),
673 RING_ACTHD_UDW(engine->mmio_base));
674 else if (INTEL_GEN(dev_priv) >= 4)
675 acthd = I915_READ(RING_ACTHD(engine->mmio_base));
676 else
677 acthd = I915_READ(ACTHD);
678
679 return acthd;
680}
681
682u64 intel_engine_get_last_batch_head(struct intel_engine_cs *engine)
683{
684 struct drm_i915_private *dev_priv = engine->i915;
685 u64 bbaddr;
686
687 if (INTEL_GEN(dev_priv) >= 8)
688 bbaddr = I915_READ64_2x32(RING_BBADDR(engine->mmio_base),
689 RING_BBADDR_UDW(engine->mmio_base));
690 else
691 bbaddr = I915_READ(RING_BBADDR(engine->mmio_base));
692
693 return bbaddr;
694}
Chris Wilson0e704472016-10-12 10:05:17 +0100695
696const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
697{
698 switch (type) {
699 case I915_CACHE_NONE: return " uncached";
700 case I915_CACHE_LLC: return HAS_LLC(i915) ? " LLC" : " snooped";
701 case I915_CACHE_L3_LLC: return " L3+LLC";
702 case I915_CACHE_WT: return " WT";
703 default: return "";
704 }
705}
706
707static inline uint32_t
708read_subslice_reg(struct drm_i915_private *dev_priv, int slice,
709 int subslice, i915_reg_t reg)
710{
711 uint32_t mcr;
712 uint32_t ret;
713 enum forcewake_domains fw_domains;
714
715 fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg,
716 FW_REG_READ);
717 fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
718 GEN8_MCR_SELECTOR,
719 FW_REG_READ | FW_REG_WRITE);
720
721 spin_lock_irq(&dev_priv->uncore.lock);
722 intel_uncore_forcewake_get__locked(dev_priv, fw_domains);
723
724 mcr = I915_READ_FW(GEN8_MCR_SELECTOR);
725 /*
726 * The HW expects the slice and sublice selectors to be reset to 0
727 * after reading out the registers.
728 */
729 WARN_ON_ONCE(mcr & (GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK));
730 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
731 mcr |= GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice);
732 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
733
734 ret = I915_READ_FW(reg);
735
736 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
737 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
738
739 intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
740 spin_unlock_irq(&dev_priv->uncore.lock);
741
742 return ret;
743}
744
745/* NB: please notice the memset */
746void intel_engine_get_instdone(struct intel_engine_cs *engine,
747 struct intel_instdone *instdone)
748{
749 struct drm_i915_private *dev_priv = engine->i915;
750 u32 mmio_base = engine->mmio_base;
751 int slice;
752 int subslice;
753
754 memset(instdone, 0, sizeof(*instdone));
755
756 switch (INTEL_GEN(dev_priv)) {
757 default:
758 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
759
760 if (engine->id != RCS)
761 break;
762
763 instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
764 for_each_instdone_slice_subslice(dev_priv, slice, subslice) {
765 instdone->sampler[slice][subslice] =
766 read_subslice_reg(dev_priv, slice, subslice,
767 GEN7_SAMPLER_INSTDONE);
768 instdone->row[slice][subslice] =
769 read_subslice_reg(dev_priv, slice, subslice,
770 GEN7_ROW_INSTDONE);
771 }
772 break;
773 case 7:
774 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
775
776 if (engine->id != RCS)
777 break;
778
779 instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
780 instdone->sampler[0][0] = I915_READ(GEN7_SAMPLER_INSTDONE);
781 instdone->row[0][0] = I915_READ(GEN7_ROW_INSTDONE);
782
783 break;
784 case 6:
785 case 5:
786 case 4:
787 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
788
789 if (engine->id == RCS)
790 /* HACK: Using the wrong struct member */
791 instdone->slice_common = I915_READ(GEN4_INSTDONE1);
792 break;
793 case 3:
794 case 2:
795 instdone->instdone = I915_READ(GEN2_INSTDONE);
796 break;
797 }
798}
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000799
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000800static int wa_add(struct drm_i915_private *dev_priv,
801 i915_reg_t addr,
802 const u32 mask, const u32 val)
803{
804 const u32 idx = dev_priv->workarounds.count;
805
806 if (WARN_ON(idx >= I915_MAX_WA_REGS))
807 return -ENOSPC;
808
809 dev_priv->workarounds.reg[idx].addr = addr;
810 dev_priv->workarounds.reg[idx].value = val;
811 dev_priv->workarounds.reg[idx].mask = mask;
812
813 dev_priv->workarounds.count++;
814
815 return 0;
816}
817
818#define WA_REG(addr, mask, val) do { \
819 const int r = wa_add(dev_priv, (addr), (mask), (val)); \
820 if (r) \
821 return r; \
822 } while (0)
823
824#define WA_SET_BIT_MASKED(addr, mask) \
825 WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
826
827#define WA_CLR_BIT_MASKED(addr, mask) \
828 WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
829
830#define WA_SET_FIELD_MASKED(addr, mask, value) \
831 WA_REG(addr, mask, _MASKED_FIELD(mask, value))
832
833#define WA_SET_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) | (mask))
834#define WA_CLR_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) & ~(mask))
835
836#define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val)
837
838static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
839 i915_reg_t reg)
840{
841 struct drm_i915_private *dev_priv = engine->i915;
842 struct i915_workarounds *wa = &dev_priv->workarounds;
843 const uint32_t index = wa->hw_whitelist_count[engine->id];
844
845 if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
846 return -EINVAL;
847
Oscar Mateo32ced392017-09-28 15:40:39 -0700848 I915_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
849 i915_mmio_reg_offset(reg));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000850 wa->hw_whitelist_count[engine->id]++;
851
852 return 0;
853}
854
855static int gen8_init_workarounds(struct intel_engine_cs *engine)
856{
857 struct drm_i915_private *dev_priv = engine->i915;
858
859 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
860
861 /* WaDisableAsyncFlipPerfMode:bdw,chv */
862 WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
863
864 /* WaDisablePartialInstShootdown:bdw,chv */
865 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
866 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
867
868 /* Use Force Non-Coherent whenever executing a 3D context. This is a
869 * workaround for for a possible hang in the unlikely event a TLB
870 * invalidation occurs during a PSD flush.
871 */
872 /* WaForceEnableNonCoherent:bdw,chv */
873 /* WaHdcDisableFetchWhenMasked:bdw,chv */
874 WA_SET_BIT_MASKED(HDC_CHICKEN0,
875 HDC_DONOT_FETCH_MEM_WHEN_MASKED |
876 HDC_FORCE_NON_COHERENT);
877
878 /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
879 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
880 * polygons in the same 8x4 pixel/sample area to be processed without
881 * stalling waiting for the earlier ones to write to Hierarchical Z
882 * buffer."
883 *
884 * This optimization is off by default for BDW and CHV; turn it on.
885 */
886 WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
887
888 /* Wa4x4STCOptimizationDisable:bdw,chv */
889 WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
890
891 /*
892 * BSpec recommends 8x4 when MSAA is used,
893 * however in practice 16x4 seems fastest.
894 *
895 * Note that PS/WM thread counts depend on the WIZ hashing
896 * disable bit, which we don't touch here, but it's good
897 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
898 */
899 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
900 GEN6_WIZ_HASHING_MASK,
901 GEN6_WIZ_HASHING_16x4);
902
903 return 0;
904}
905
906static int bdw_init_workarounds(struct intel_engine_cs *engine)
907{
908 struct drm_i915_private *dev_priv = engine->i915;
909 int ret;
910
911 ret = gen8_init_workarounds(engine);
912 if (ret)
913 return ret;
914
915 /* WaDisableThreadStallDopClockGating:bdw (pre-production) */
916 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
917
918 /* WaDisableDopClockGating:bdw
919 *
920 * Also see the related UCGTCL1 write in broadwell_init_clock_gating()
921 * to disable EUTC clock gating.
922 */
923 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
924 DOP_CLOCK_GATING_DISABLE);
925
926 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
927 GEN8_SAMPLER_POWER_BYPASS_DIS);
928
929 WA_SET_BIT_MASKED(HDC_CHICKEN0,
930 /* WaForceContextSaveRestoreNonCoherent:bdw */
931 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
932 /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
933 (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
934
935 return 0;
936}
937
938static int chv_init_workarounds(struct intel_engine_cs *engine)
939{
940 struct drm_i915_private *dev_priv = engine->i915;
941 int ret;
942
943 ret = gen8_init_workarounds(engine);
944 if (ret)
945 return ret;
946
947 /* WaDisableThreadStallDopClockGating:chv */
948 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
949
950 /* Improve HiZ throughput on CHV. */
951 WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
952
953 return 0;
954}
955
956static int gen9_init_workarounds(struct intel_engine_cs *engine)
957{
958 struct drm_i915_private *dev_priv = engine->i915;
959 int ret;
960
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700961 /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000962 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
963
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700964 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000965 I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
966 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
967
Rodrigo Vivi98eed3d2017-06-19 14:21:47 -0700968 /* WaDisableKillLogic:bxt,skl,kbl */
969 if (!IS_COFFEELAKE(dev_priv))
970 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
971 ECOCHK_DIS_TLB);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000972
Ville Syrjälä93564042017-08-24 22:10:51 +0300973 if (HAS_LLC(dev_priv)) {
974 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
975 *
976 * Must match Display Engine. See
977 * WaCompressedResourceDisplayNewHashMode.
978 */
979 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
980 GEN9_PBE_COMPRESSED_HASH_SELECTION);
981 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
982 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);
Chris Wilson53221e12017-10-04 13:41:52 +0100983
984 I915_WRITE(MMCD_MISC_CTRL,
985 I915_READ(MMCD_MISC_CTRL) |
986 MMCD_PCLA |
987 MMCD_HOTSPOT_EN);
Ville Syrjälä93564042017-08-24 22:10:51 +0300988 }
989
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700990 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
991 /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000992 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
993 FLOW_CONTROL_ENABLE |
994 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
995
996 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700997 if (!IS_COFFEELAKE(dev_priv))
998 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
999 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001000
1001 /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */
1002 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1003 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
1004 GEN9_DG_MIRROR_FIX_ENABLE);
1005
1006 /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */
1007 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1008 WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1,
1009 GEN9_RHWO_OPTIMIZATION_DISABLE);
1010 /*
1011 * WA also requires GEN9_SLICE_COMMON_ECO_CHICKEN0[14:14] to be set
1012 * but we do that in per ctx batchbuffer as there is an issue
1013 * with this register not getting restored on ctx restore
1014 */
1015 }
1016
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001017 /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */
1018 /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001019 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
Arkadiusz Hiler0b71cea2017-05-12 13:20:15 +02001020 GEN9_ENABLE_YV12_BUGFIX |
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001021 GEN9_ENABLE_GPGPU_PREEMPTION);
1022
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001023 /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */
1024 /* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001025 WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
1026 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
1027
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001028 /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001029 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
1030 GEN9_CCS_TLB_PREFETCH_ENABLE);
1031
1032 /* WaDisableMaskBasedCammingInRCC:bxt */
1033 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1034 WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0,
1035 PIXEL_MASK_CAMMING_DISABLE);
1036
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001037 /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001038 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1039 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
1040 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
1041
1042 /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
1043 * both tied to WaForceContextSaveRestoreNonCoherent
1044 * in some hsds for skl. We keep the tie for all gen9. The
1045 * documentation is a bit hazy and so we want to get common behaviour,
1046 * even though there is no clear evidence we would need both on kbl/bxt.
1047 * This area has been source of system hangs so we play it safe
1048 * and mimic the skl regardless of what bspec says.
1049 *
1050 * Use Force Non-Coherent whenever executing a 3D context. This
1051 * is a workaround for a possible hang in the unlikely event
1052 * a TLB invalidation occurs during a PSD flush.
1053 */
1054
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001055 /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001056 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1057 HDC_FORCE_NON_COHERENT);
1058
Rodrigo Vivi98eed3d2017-06-19 14:21:47 -07001059 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
1060 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
1061 BDW_DISABLE_HDC_INVALIDATION);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001062
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001063 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001064 if (IS_SKYLAKE(dev_priv) ||
1065 IS_KABYLAKE(dev_priv) ||
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001066 IS_COFFEELAKE(dev_priv) ||
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001067 IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
1068 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
1069 GEN8_SAMPLER_POWER_BYPASS_DIS);
1070
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001071 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001072 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
1073
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001074 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001075 I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
1076 GEN8_LQSC_FLUSH_COHERENT_LINES));
1077
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001078 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001079 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
1080 if (ret)
1081 return ret;
1082
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001083 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001084 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1085 if (ret)
1086 return ret;
1087
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001088 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001089 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
1090 if (ret)
1091 return ret;
1092
1093 return 0;
1094}
1095
1096static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
1097{
1098 struct drm_i915_private *dev_priv = engine->i915;
1099 u8 vals[3] = { 0, 0, 0 };
1100 unsigned int i;
1101
1102 for (i = 0; i < 3; i++) {
1103 u8 ss;
1104
1105 /*
1106 * Only consider slices where one, and only one, subslice has 7
1107 * EUs
1108 */
1109 if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
1110 continue;
1111
1112 /*
1113 * subslice_7eu[i] != 0 (because of the check above) and
1114 * ss_max == 4 (maximum number of subslices possible per slice)
1115 *
1116 * -> 0 <= ss <= 3;
1117 */
1118 ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
1119 vals[i] = 3 - ss;
1120 }
1121
1122 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
1123 return 0;
1124
1125 /* Tune IZ hashing. See intel_device_info_runtime_init() */
1126 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
1127 GEN9_IZ_HASHING_MASK(2) |
1128 GEN9_IZ_HASHING_MASK(1) |
1129 GEN9_IZ_HASHING_MASK(0),
1130 GEN9_IZ_HASHING(2, vals[2]) |
1131 GEN9_IZ_HASHING(1, vals[1]) |
1132 GEN9_IZ_HASHING(0, vals[0]));
1133
1134 return 0;
1135}
1136
1137static int skl_init_workarounds(struct intel_engine_cs *engine)
1138{
1139 struct drm_i915_private *dev_priv = engine->i915;
1140 int ret;
1141
1142 ret = gen9_init_workarounds(engine);
1143 if (ret)
1144 return ret;
1145
1146 /*
1147 * Actual WA is to disable percontext preemption granularity control
1148 * until D0 which is the default case so this is equivalent to
1149 * !WaDisablePerCtxtPreemptionGranularityControl:skl
1150 */
1151 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1152 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
1153
1154 /* WaEnableGapsTsvCreditFix:skl */
1155 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1156 GEN9_GAPS_TSV_CREDIT_DISABLE));
1157
1158 /* WaDisableGafsUnitClkGating:skl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001159 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1160 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001161
1162 /* WaInPlaceDecompressionHang:skl */
1163 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
Oscar Mateoefc886c2017-09-07 08:40:04 -07001164 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1165 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1166 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001167
1168 /* WaDisableLSQCROPERFforOCL:skl */
1169 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1170 if (ret)
1171 return ret;
1172
1173 return skl_tune_iz_hashing(engine);
1174}
1175
1176static int bxt_init_workarounds(struct intel_engine_cs *engine)
1177{
1178 struct drm_i915_private *dev_priv = engine->i915;
1179 int ret;
1180
1181 ret = gen9_init_workarounds(engine);
1182 if (ret)
1183 return ret;
1184
1185 /* WaStoreMultiplePTEenable:bxt */
1186 /* This is a requirement according to Hardware specification */
1187 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1188 I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
1189
1190 /* WaSetClckGatingDisableMedia:bxt */
1191 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1192 I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
1193 ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
1194 }
1195
1196 /* WaDisableThreadStallDopClockGating:bxt */
1197 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
1198 STALL_DOP_GATING_DISABLE);
1199
1200 /* WaDisablePooledEuLoadBalancingFix:bxt */
1201 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
Oscar Mateo212154b2017-09-07 08:40:09 -07001202 I915_WRITE(FF_SLICE_CS_CHICKEN2,
1203 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001204 }
1205
1206 /* WaDisableSbeCacheDispatchPortSharing:bxt */
1207 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) {
1208 WA_SET_BIT_MASKED(
1209 GEN7_HALF_SLICE_CHICKEN1,
1210 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1211 }
1212
1213 /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */
1214 /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */
1215 /* WaDisableObjectLevelPreemtionForInstanceId:bxt */
1216 /* WaDisableLSQCROPERFforOCL:bxt */
1217 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1218 ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1);
1219 if (ret)
1220 return ret;
1221
1222 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1223 if (ret)
1224 return ret;
1225 }
1226
1227 /* WaProgramL3SqcReg1DefaultForPerf:bxt */
1228 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
1229 I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
1230 L3_HIGH_PRIO_CREDITS(2));
1231
1232 /* WaToEnableHwFixForPushConstHWBug:bxt */
1233 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
1234 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1235 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1236
1237 /* WaInPlaceDecompressionHang:bxt */
1238 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
Oscar Mateoefc886c2017-09-07 08:40:04 -07001239 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1240 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1241 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001242
1243 return 0;
1244}
1245
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001246static int cnl_init_workarounds(struct intel_engine_cs *engine)
1247{
1248 struct drm_i915_private *dev_priv = engine->i915;
1249 int ret;
1250
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001251 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001252 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001253 I915_WRITE(GAMT_CHKN_BIT_REG,
1254 (I915_READ(GAMT_CHKN_BIT_REG) |
1255 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT));
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001256
Rodrigo Viviacfb5552017-08-23 13:35:04 -07001257 /* WaForceContextSaveRestoreNonCoherent:cnl */
1258 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0,
1259 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT);
1260
Rodrigo Viviaa9f4c42017-09-06 15:03:25 -07001261 /* WaThrottleEUPerfToAvoidTDBackPressure:cnl(pre-prod) */
1262 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
1263 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, THROTTLE_12_5);
1264
Rodrigo Vivie6d1a4f2017-08-15 16:16:49 -07001265 /* WaDisableReplayBufferBankArbitrationOptimization:cnl */
1266 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1267 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1268
Rodrigo Vivid1d24752017-08-15 16:16:50 -07001269 /* WaDisableEnhancedSBEVertexCaching:cnl (pre-prod) */
1270 if (IS_CNL_REVID(dev_priv, 0, CNL_REVID_B0))
1271 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1272 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE);
1273
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001274 /* WaInPlaceDecompressionHang:cnl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001275 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1276 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1277 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001278
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001279 /* WaPushConstantDereferenceHoldDisable:cnl */
Oscar Mateob27f5902017-09-07 08:40:06 -07001280 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE);
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001281
Rodrigo Vivi392572f2017-08-29 16:07:23 -07001282 /* FtrEnableFastAnisoL1BankingFix: cnl */
1283 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX);
1284
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001285 /* WaEnablePreemptionGranularityControlByUMD:cnl */
1286 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1287 if (ret)
1288 return ret;
1289
1290 return 0;
1291}
1292
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001293static int kbl_init_workarounds(struct intel_engine_cs *engine)
1294{
1295 struct drm_i915_private *dev_priv = engine->i915;
1296 int ret;
1297
1298 ret = gen9_init_workarounds(engine);
1299 if (ret)
1300 return ret;
1301
1302 /* WaEnableGapsTsvCreditFix:kbl */
1303 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1304 GEN9_GAPS_TSV_CREDIT_DISABLE));
1305
1306 /* WaDisableDynamicCreditSharing:kbl */
1307 if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
Oscar Mateoc6ea497c2017-09-07 08:40:08 -07001308 I915_WRITE(GAMT_CHKN_BIT_REG,
1309 (I915_READ(GAMT_CHKN_BIT_REG) |
1310 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001311
1312 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
1313 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
1314 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1315 HDC_FENCE_DEST_SLM_DISABLE);
1316
1317 /* WaToEnableHwFixForPushConstHWBug:kbl */
1318 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
1319 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1320 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1321
1322 /* WaDisableGafsUnitClkGating:kbl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001323 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1324 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001325
1326 /* WaDisableSbeCacheDispatchPortSharing:kbl */
1327 WA_SET_BIT_MASKED(
1328 GEN7_HALF_SLICE_CHICKEN1,
1329 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1330
1331 /* WaInPlaceDecompressionHang:kbl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001332 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1333 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1334 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001335
1336 /* WaDisableLSQCROPERFforOCL:kbl */
1337 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1338 if (ret)
1339 return ret;
1340
1341 return 0;
1342}
1343
1344static int glk_init_workarounds(struct intel_engine_cs *engine)
1345{
1346 struct drm_i915_private *dev_priv = engine->i915;
1347 int ret;
1348
1349 ret = gen9_init_workarounds(engine);
1350 if (ret)
1351 return ret;
1352
1353 /* WaToEnableHwFixForPushConstHWBug:glk */
1354 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1355 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1356
1357 return 0;
1358}
1359
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001360static int cfl_init_workarounds(struct intel_engine_cs *engine)
1361{
1362 struct drm_i915_private *dev_priv = engine->i915;
1363 int ret;
1364
1365 ret = gen9_init_workarounds(engine);
1366 if (ret)
1367 return ret;
1368
1369 /* WaEnableGapsTsvCreditFix:cfl */
1370 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1371 GEN9_GAPS_TSV_CREDIT_DISABLE));
1372
1373 /* WaToEnableHwFixForPushConstHWBug:cfl */
1374 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1375 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1376
1377 /* WaDisableGafsUnitClkGating:cfl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001378 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1379 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001380
1381 /* WaDisableSbeCacheDispatchPortSharing:cfl */
1382 WA_SET_BIT_MASKED(
1383 GEN7_HALF_SLICE_CHICKEN1,
1384 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1385
1386 /* WaInPlaceDecompressionHang:cfl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001387 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1388 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1389 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001390
1391 return 0;
1392}
1393
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001394int init_workarounds_ring(struct intel_engine_cs *engine)
1395{
1396 struct drm_i915_private *dev_priv = engine->i915;
Chris Wilson02e012f2017-03-01 12:11:31 +00001397 int err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001398
1399 WARN_ON(engine->id != RCS);
1400
1401 dev_priv->workarounds.count = 0;
Chris Wilson02e012f2017-03-01 12:11:31 +00001402 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001403
1404 if (IS_BROADWELL(dev_priv))
Chris Wilson02e012f2017-03-01 12:11:31 +00001405 err = bdw_init_workarounds(engine);
1406 else if (IS_CHERRYVIEW(dev_priv))
1407 err = chv_init_workarounds(engine);
1408 else if (IS_SKYLAKE(dev_priv))
1409 err = skl_init_workarounds(engine);
1410 else if (IS_BROXTON(dev_priv))
1411 err = bxt_init_workarounds(engine);
1412 else if (IS_KABYLAKE(dev_priv))
1413 err = kbl_init_workarounds(engine);
1414 else if (IS_GEMINILAKE(dev_priv))
1415 err = glk_init_workarounds(engine);
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001416 else if (IS_COFFEELAKE(dev_priv))
1417 err = cfl_init_workarounds(engine);
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001418 else if (IS_CANNONLAKE(dev_priv))
1419 err = cnl_init_workarounds(engine);
Chris Wilson02e012f2017-03-01 12:11:31 +00001420 else
1421 err = 0;
1422 if (err)
1423 return err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001424
Chris Wilson02e012f2017-03-01 12:11:31 +00001425 DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n",
1426 engine->name, dev_priv->workarounds.count);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001427 return 0;
1428}
1429
1430int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)
1431{
1432 struct i915_workarounds *w = &req->i915->workarounds;
1433 u32 *cs;
1434 int ret, i;
1435
1436 if (w->count == 0)
1437 return 0;
1438
1439 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1440 if (ret)
1441 return ret;
1442
1443 cs = intel_ring_begin(req, (w->count * 2 + 2));
1444 if (IS_ERR(cs))
1445 return PTR_ERR(cs);
1446
1447 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
1448 for (i = 0; i < w->count; i++) {
1449 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
1450 *cs++ = w->reg[i].value;
1451 }
1452 *cs++ = MI_NOOP;
1453
1454 intel_ring_advance(req, cs);
1455
1456 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1457 if (ret)
1458 return ret;
1459
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001460 return 0;
1461}
1462
Chris Wilsona091d4e2017-05-30 13:13:33 +01001463static bool ring_is_idle(struct intel_engine_cs *engine)
1464{
1465 struct drm_i915_private *dev_priv = engine->i915;
1466 bool idle = true;
1467
1468 intel_runtime_pm_get(dev_priv);
1469
Chris Wilsonaed2fc12017-05-30 13:13:34 +01001470 /* First check that no commands are left in the ring */
1471 if ((I915_READ_HEAD(engine) & HEAD_ADDR) !=
1472 (I915_READ_TAIL(engine) & TAIL_ADDR))
1473 idle = false;
1474
Chris Wilsona091d4e2017-05-30 13:13:33 +01001475 /* No bit for gen2, so assume the CS parser is idle */
1476 if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE))
1477 idle = false;
1478
1479 intel_runtime_pm_put(dev_priv);
1480
1481 return idle;
1482}
1483
Chris Wilson54003672017-03-03 12:19:46 +00001484/**
1485 * intel_engine_is_idle() - Report if the engine has finished process all work
1486 * @engine: the intel_engine_cs
1487 *
1488 * Return true if there are no requests pending, nothing left to be submitted
1489 * to hardware, and that the engine is idle.
1490 */
1491bool intel_engine_is_idle(struct intel_engine_cs *engine)
1492{
1493 struct drm_i915_private *dev_priv = engine->i915;
1494
Chris Wilsona8e9a412017-04-11 20:00:42 +01001495 /* More white lies, if wedged, hw state is inconsistent */
1496 if (i915_terminally_wedged(&dev_priv->gpu_error))
1497 return true;
1498
Chris Wilson54003672017-03-03 12:19:46 +00001499 /* Any inflight/incomplete requests? */
1500 if (!i915_seqno_passed(intel_engine_get_seqno(engine),
1501 intel_engine_last_submit(engine)))
1502 return false;
1503
Chris Wilson8968a362017-04-12 00:44:26 +01001504 if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))
1505 return true;
1506
Chris Wilson54003672017-03-03 12:19:46 +00001507 /* Interrupt/tasklet pending? */
1508 if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
1509 return false;
1510
1511 /* Both ports drained, no more ELSP submission? */
Mika Kuoppalab620e872017-09-22 15:43:03 +03001512 if (port_request(&engine->execlists.port[0]))
Chris Wilson54003672017-03-03 12:19:46 +00001513 return false;
1514
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001515 /* ELSP is empty, but there are ready requests? */
Mika Kuoppalab620e872017-09-22 15:43:03 +03001516 if (READ_ONCE(engine->execlists.first))
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001517 return false;
1518
Chris Wilson54003672017-03-03 12:19:46 +00001519 /* Ring stopped? */
Chris Wilsona091d4e2017-05-30 13:13:33 +01001520 if (!ring_is_idle(engine))
Chris Wilson54003672017-03-03 12:19:46 +00001521 return false;
1522
1523 return true;
1524}
1525
Chris Wilson05425242017-03-03 12:19:47 +00001526bool intel_engines_are_idle(struct drm_i915_private *dev_priv)
1527{
1528 struct intel_engine_cs *engine;
1529 enum intel_engine_id id;
1530
Chris Wilson8490ae202017-03-30 15:50:37 +01001531 if (READ_ONCE(dev_priv->gt.active_requests))
1532 return false;
1533
1534 /* If the driver is wedged, HW state may be very inconsistent and
1535 * report that it is still busy, even though we have stopped using it.
1536 */
1537 if (i915_terminally_wedged(&dev_priv->gpu_error))
1538 return true;
1539
Chris Wilson05425242017-03-03 12:19:47 +00001540 for_each_engine(engine, dev_priv, id) {
1541 if (!intel_engine_is_idle(engine))
1542 return false;
1543 }
1544
1545 return true;
1546}
1547
Chris Wilsonff44ad52017-03-16 17:13:03 +00001548void intel_engines_reset_default_submission(struct drm_i915_private *i915)
1549{
1550 struct intel_engine_cs *engine;
1551 enum intel_engine_id id;
1552
1553 for_each_engine(engine, i915, id)
1554 engine->set_default_submission(engine);
1555}
1556
Chris Wilson6c067572017-05-17 13:10:03 +01001557void intel_engines_mark_idle(struct drm_i915_private *i915)
1558{
1559 struct intel_engine_cs *engine;
1560 enum intel_engine_id id;
1561
1562 for_each_engine(engine, i915, id) {
1563 intel_engine_disarm_breadcrumbs(engine);
1564 i915_gem_batch_pool_fini(&engine->batch_pool);
Mika Kuoppalab620e872017-09-22 15:43:03 +03001565 tasklet_kill(&engine->execlists.irq_tasklet);
1566 engine->execlists.no_priolist = false;
Chris Wilson6c067572017-05-17 13:10:03 +01001567 }
1568}
1569
Chris Wilson90cad092017-09-06 16:28:59 +01001570bool intel_engine_can_store_dword(struct intel_engine_cs *engine)
1571{
1572 switch (INTEL_GEN(engine->i915)) {
1573 case 2:
1574 return false; /* uses physical not virtual addresses */
1575 case 3:
1576 /* maybe only uses physical not virtual addresses */
1577 return !(IS_I915G(engine->i915) || IS_I915GM(engine->i915));
1578 case 6:
1579 return engine->class != VIDEO_DECODE_CLASS; /* b0rked */
1580 default:
1581 return true;
1582 }
1583}
1584
Chris Wilsonf97fbf92017-02-13 17:15:14 +00001585#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
1586#include "selftests/mock_engine.c"
1587#endif