blob: 6245970eb3abee6778b4f15673673f7252dad703 [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
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000833static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
834 i915_reg_t reg)
835{
836 struct drm_i915_private *dev_priv = engine->i915;
837 struct i915_workarounds *wa = &dev_priv->workarounds;
838 const uint32_t index = wa->hw_whitelist_count[engine->id];
839
840 if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
841 return -EINVAL;
842
Oscar Mateo32ced392017-09-28 15:40:39 -0700843 I915_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
844 i915_mmio_reg_offset(reg));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000845 wa->hw_whitelist_count[engine->id]++;
846
847 return 0;
848}
849
850static int gen8_init_workarounds(struct intel_engine_cs *engine)
851{
852 struct drm_i915_private *dev_priv = engine->i915;
853
854 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
855
856 /* WaDisableAsyncFlipPerfMode:bdw,chv */
857 WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
858
859 /* WaDisablePartialInstShootdown:bdw,chv */
860 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
861 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
862
863 /* Use Force Non-Coherent whenever executing a 3D context. This is a
864 * workaround for for a possible hang in the unlikely event a TLB
865 * invalidation occurs during a PSD flush.
866 */
867 /* WaForceEnableNonCoherent:bdw,chv */
868 /* WaHdcDisableFetchWhenMasked:bdw,chv */
869 WA_SET_BIT_MASKED(HDC_CHICKEN0,
870 HDC_DONOT_FETCH_MEM_WHEN_MASKED |
871 HDC_FORCE_NON_COHERENT);
872
873 /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
874 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
875 * polygons in the same 8x4 pixel/sample area to be processed without
876 * stalling waiting for the earlier ones to write to Hierarchical Z
877 * buffer."
878 *
879 * This optimization is off by default for BDW and CHV; turn it on.
880 */
881 WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
882
883 /* Wa4x4STCOptimizationDisable:bdw,chv */
884 WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
885
886 /*
887 * BSpec recommends 8x4 when MSAA is used,
888 * however in practice 16x4 seems fastest.
889 *
890 * Note that PS/WM thread counts depend on the WIZ hashing
891 * disable bit, which we don't touch here, but it's good
892 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
893 */
894 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
895 GEN6_WIZ_HASHING_MASK,
896 GEN6_WIZ_HASHING_16x4);
897
898 return 0;
899}
900
901static int bdw_init_workarounds(struct intel_engine_cs *engine)
902{
903 struct drm_i915_private *dev_priv = engine->i915;
904 int ret;
905
906 ret = gen8_init_workarounds(engine);
907 if (ret)
908 return ret;
909
910 /* WaDisableThreadStallDopClockGating:bdw (pre-production) */
911 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
912
913 /* WaDisableDopClockGating:bdw
914 *
915 * Also see the related UCGTCL1 write in broadwell_init_clock_gating()
916 * to disable EUTC clock gating.
917 */
918 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
919 DOP_CLOCK_GATING_DISABLE);
920
921 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
922 GEN8_SAMPLER_POWER_BYPASS_DIS);
923
924 WA_SET_BIT_MASKED(HDC_CHICKEN0,
925 /* WaForceContextSaveRestoreNonCoherent:bdw */
926 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
927 /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
928 (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
929
930 return 0;
931}
932
933static int chv_init_workarounds(struct intel_engine_cs *engine)
934{
935 struct drm_i915_private *dev_priv = engine->i915;
936 int ret;
937
938 ret = gen8_init_workarounds(engine);
939 if (ret)
940 return ret;
941
942 /* WaDisableThreadStallDopClockGating:chv */
943 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
944
945 /* Improve HiZ throughput on CHV. */
946 WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
947
948 return 0;
949}
950
951static int gen9_init_workarounds(struct intel_engine_cs *engine)
952{
953 struct drm_i915_private *dev_priv = engine->i915;
954 int ret;
955
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700956 /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000957 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
958
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700959 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000960 I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
961 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
962
Rodrigo Vivi98eed3d2017-06-19 14:21:47 -0700963 /* WaDisableKillLogic:bxt,skl,kbl */
964 if (!IS_COFFEELAKE(dev_priv))
965 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
966 ECOCHK_DIS_TLB);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000967
Ville Syrjälä93564042017-08-24 22:10:51 +0300968 if (HAS_LLC(dev_priv)) {
969 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
970 *
971 * Must match Display Engine. See
972 * WaCompressedResourceDisplayNewHashMode.
973 */
974 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
975 GEN9_PBE_COMPRESSED_HASH_SELECTION);
976 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
977 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);
Chris Wilson53221e12017-10-04 13:41:52 +0100978
979 I915_WRITE(MMCD_MISC_CTRL,
980 I915_READ(MMCD_MISC_CTRL) |
981 MMCD_PCLA |
982 MMCD_HOTSPOT_EN);
Ville Syrjälä93564042017-08-24 22:10:51 +0300983 }
984
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700985 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
986 /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000987 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
988 FLOW_CONTROL_ENABLE |
989 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
990
991 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700992 if (!IS_COFFEELAKE(dev_priv))
993 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
994 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000995
996 /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */
997 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
998 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
999 GEN9_DG_MIRROR_FIX_ENABLE);
1000
1001 /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */
1002 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1003 WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1,
1004 GEN9_RHWO_OPTIMIZATION_DISABLE);
1005 /*
1006 * WA also requires GEN9_SLICE_COMMON_ECO_CHICKEN0[14:14] to be set
1007 * but we do that in per ctx batchbuffer as there is an issue
1008 * with this register not getting restored on ctx restore
1009 */
1010 }
1011
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001012 /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */
1013 /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001014 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
Arkadiusz Hiler0b71cea2017-05-12 13:20:15 +02001015 GEN9_ENABLE_YV12_BUGFIX |
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001016 GEN9_ENABLE_GPGPU_PREEMPTION);
1017
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001018 /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */
1019 /* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001020 WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
1021 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
1022
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001023 /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001024 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
1025 GEN9_CCS_TLB_PREFETCH_ENABLE);
1026
1027 /* WaDisableMaskBasedCammingInRCC:bxt */
1028 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1029 WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0,
1030 PIXEL_MASK_CAMMING_DISABLE);
1031
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001032 /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001033 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1034 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
1035 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
1036
1037 /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
1038 * both tied to WaForceContextSaveRestoreNonCoherent
1039 * in some hsds for skl. We keep the tie for all gen9. The
1040 * documentation is a bit hazy and so we want to get common behaviour,
1041 * even though there is no clear evidence we would need both on kbl/bxt.
1042 * This area has been source of system hangs so we play it safe
1043 * and mimic the skl regardless of what bspec says.
1044 *
1045 * Use Force Non-Coherent whenever executing a 3D context. This
1046 * is a workaround for a possible hang in the unlikely event
1047 * a TLB invalidation occurs during a PSD flush.
1048 */
1049
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001050 /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001051 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1052 HDC_FORCE_NON_COHERENT);
1053
Rodrigo Vivi98eed3d2017-06-19 14:21:47 -07001054 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
1055 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
1056 BDW_DISABLE_HDC_INVALIDATION);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001057
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001058 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001059 if (IS_SKYLAKE(dev_priv) ||
1060 IS_KABYLAKE(dev_priv) ||
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001061 IS_COFFEELAKE(dev_priv) ||
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001062 IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
1063 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
1064 GEN8_SAMPLER_POWER_BYPASS_DIS);
1065
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001066 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001067 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
1068
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001069 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001070 I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
1071 GEN8_LQSC_FLUSH_COHERENT_LINES));
1072
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001073 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001074 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
1075 if (ret)
1076 return ret;
1077
Jeff McGee1e998342017-10-03 21:34:45 +01001078 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
1079 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1080 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
1081 ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001082 if (ret)
1083 return ret;
1084
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001085 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001086 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
1087 if (ret)
1088 return ret;
1089
1090 return 0;
1091}
1092
1093static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
1094{
1095 struct drm_i915_private *dev_priv = engine->i915;
1096 u8 vals[3] = { 0, 0, 0 };
1097 unsigned int i;
1098
1099 for (i = 0; i < 3; i++) {
1100 u8 ss;
1101
1102 /*
1103 * Only consider slices where one, and only one, subslice has 7
1104 * EUs
1105 */
1106 if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
1107 continue;
1108
1109 /*
1110 * subslice_7eu[i] != 0 (because of the check above) and
1111 * ss_max == 4 (maximum number of subslices possible per slice)
1112 *
1113 * -> 0 <= ss <= 3;
1114 */
1115 ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
1116 vals[i] = 3 - ss;
1117 }
1118
1119 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
1120 return 0;
1121
1122 /* Tune IZ hashing. See intel_device_info_runtime_init() */
1123 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
1124 GEN9_IZ_HASHING_MASK(2) |
1125 GEN9_IZ_HASHING_MASK(1) |
1126 GEN9_IZ_HASHING_MASK(0),
1127 GEN9_IZ_HASHING(2, vals[2]) |
1128 GEN9_IZ_HASHING(1, vals[1]) |
1129 GEN9_IZ_HASHING(0, vals[0]));
1130
1131 return 0;
1132}
1133
1134static int skl_init_workarounds(struct intel_engine_cs *engine)
1135{
1136 struct drm_i915_private *dev_priv = engine->i915;
1137 int ret;
1138
1139 ret = gen9_init_workarounds(engine);
1140 if (ret)
1141 return ret;
1142
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001143 /* WaEnableGapsTsvCreditFix:skl */
1144 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1145 GEN9_GAPS_TSV_CREDIT_DISABLE));
1146
1147 /* WaDisableGafsUnitClkGating:skl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001148 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1149 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001150
1151 /* WaInPlaceDecompressionHang:skl */
1152 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
Oscar Mateoefc886c2017-09-07 08:40:04 -07001153 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1154 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1155 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001156
1157 /* WaDisableLSQCROPERFforOCL:skl */
1158 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1159 if (ret)
1160 return ret;
1161
1162 return skl_tune_iz_hashing(engine);
1163}
1164
1165static int bxt_init_workarounds(struct intel_engine_cs *engine)
1166{
1167 struct drm_i915_private *dev_priv = engine->i915;
1168 int ret;
1169
1170 ret = gen9_init_workarounds(engine);
1171 if (ret)
1172 return ret;
1173
1174 /* WaStoreMultiplePTEenable:bxt */
1175 /* This is a requirement according to Hardware specification */
1176 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1177 I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
1178
1179 /* WaSetClckGatingDisableMedia:bxt */
1180 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1181 I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
1182 ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
1183 }
1184
1185 /* WaDisableThreadStallDopClockGating:bxt */
1186 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
1187 STALL_DOP_GATING_DISABLE);
1188
1189 /* WaDisablePooledEuLoadBalancingFix:bxt */
1190 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
Oscar Mateo212154b2017-09-07 08:40:09 -07001191 I915_WRITE(FF_SLICE_CS_CHICKEN2,
1192 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001193 }
1194
1195 /* WaDisableSbeCacheDispatchPortSharing:bxt */
1196 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) {
1197 WA_SET_BIT_MASKED(
1198 GEN7_HALF_SLICE_CHICKEN1,
1199 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1200 }
1201
1202 /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */
1203 /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */
1204 /* WaDisableObjectLevelPreemtionForInstanceId:bxt */
1205 /* WaDisableLSQCROPERFforOCL:bxt */
1206 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1207 ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1);
1208 if (ret)
1209 return ret;
1210
1211 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1212 if (ret)
1213 return ret;
1214 }
1215
1216 /* WaProgramL3SqcReg1DefaultForPerf:bxt */
1217 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
1218 I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
1219 L3_HIGH_PRIO_CREDITS(2));
1220
1221 /* WaToEnableHwFixForPushConstHWBug:bxt */
1222 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
1223 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1224 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1225
1226 /* WaInPlaceDecompressionHang:bxt */
1227 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
Oscar Mateoefc886c2017-09-07 08:40:04 -07001228 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1229 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1230 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001231
1232 return 0;
1233}
1234
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001235static int cnl_init_workarounds(struct intel_engine_cs *engine)
1236{
1237 struct drm_i915_private *dev_priv = engine->i915;
1238 int ret;
1239
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001240 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001241 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001242 I915_WRITE(GAMT_CHKN_BIT_REG,
1243 (I915_READ(GAMT_CHKN_BIT_REG) |
1244 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT));
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001245
Rodrigo Viviacfb5552017-08-23 13:35:04 -07001246 /* WaForceContextSaveRestoreNonCoherent:cnl */
1247 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0,
1248 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT);
1249
Rodrigo Viviaa9f4c42017-09-06 15:03:25 -07001250 /* WaThrottleEUPerfToAvoidTDBackPressure:cnl(pre-prod) */
1251 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
1252 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, THROTTLE_12_5);
1253
Rodrigo Vivie6d1a4f2017-08-15 16:16:49 -07001254 /* WaDisableReplayBufferBankArbitrationOptimization:cnl */
1255 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1256 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1257
Rodrigo Vivid1d24752017-08-15 16:16:50 -07001258 /* WaDisableEnhancedSBEVertexCaching:cnl (pre-prod) */
1259 if (IS_CNL_REVID(dev_priv, 0, CNL_REVID_B0))
1260 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1261 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE);
1262
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001263 /* WaInPlaceDecompressionHang:cnl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001264 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1265 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1266 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001267
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001268 /* WaPushConstantDereferenceHoldDisable:cnl */
Oscar Mateob27f5902017-09-07 08:40:06 -07001269 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE);
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001270
Rodrigo Vivi392572f2017-08-29 16:07:23 -07001271 /* FtrEnableFastAnisoL1BankingFix: cnl */
1272 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX);
1273
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001274 /* WaEnablePreemptionGranularityControlByUMD:cnl */
Jeff McGee1e998342017-10-03 21:34:45 +01001275 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1276 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001277 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1278 if (ret)
1279 return ret;
1280
1281 return 0;
1282}
1283
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001284static int kbl_init_workarounds(struct intel_engine_cs *engine)
1285{
1286 struct drm_i915_private *dev_priv = engine->i915;
1287 int ret;
1288
1289 ret = gen9_init_workarounds(engine);
1290 if (ret)
1291 return ret;
1292
1293 /* WaEnableGapsTsvCreditFix:kbl */
1294 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1295 GEN9_GAPS_TSV_CREDIT_DISABLE));
1296
1297 /* WaDisableDynamicCreditSharing:kbl */
1298 if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
Oscar Mateoc6ea497c2017-09-07 08:40:08 -07001299 I915_WRITE(GAMT_CHKN_BIT_REG,
1300 (I915_READ(GAMT_CHKN_BIT_REG) |
1301 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001302
1303 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
1304 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
1305 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1306 HDC_FENCE_DEST_SLM_DISABLE);
1307
1308 /* WaToEnableHwFixForPushConstHWBug:kbl */
1309 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
1310 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1311 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1312
1313 /* WaDisableGafsUnitClkGating:kbl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001314 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1315 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001316
1317 /* WaDisableSbeCacheDispatchPortSharing:kbl */
1318 WA_SET_BIT_MASKED(
1319 GEN7_HALF_SLICE_CHICKEN1,
1320 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1321
1322 /* WaInPlaceDecompressionHang:kbl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001323 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1324 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1325 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001326
1327 /* WaDisableLSQCROPERFforOCL:kbl */
1328 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1329 if (ret)
1330 return ret;
1331
1332 return 0;
1333}
1334
1335static int glk_init_workarounds(struct intel_engine_cs *engine)
1336{
1337 struct drm_i915_private *dev_priv = engine->i915;
1338 int ret;
1339
1340 ret = gen9_init_workarounds(engine);
1341 if (ret)
1342 return ret;
1343
1344 /* WaToEnableHwFixForPushConstHWBug:glk */
1345 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1346 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1347
1348 return 0;
1349}
1350
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001351static int cfl_init_workarounds(struct intel_engine_cs *engine)
1352{
1353 struct drm_i915_private *dev_priv = engine->i915;
1354 int ret;
1355
1356 ret = gen9_init_workarounds(engine);
1357 if (ret)
1358 return ret;
1359
1360 /* WaEnableGapsTsvCreditFix:cfl */
1361 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1362 GEN9_GAPS_TSV_CREDIT_DISABLE));
1363
1364 /* WaToEnableHwFixForPushConstHWBug:cfl */
1365 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1366 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1367
1368 /* WaDisableGafsUnitClkGating:cfl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001369 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1370 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001371
1372 /* WaDisableSbeCacheDispatchPortSharing:cfl */
1373 WA_SET_BIT_MASKED(
1374 GEN7_HALF_SLICE_CHICKEN1,
1375 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1376
1377 /* WaInPlaceDecompressionHang:cfl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001378 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1379 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1380 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001381
1382 return 0;
1383}
1384
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001385int init_workarounds_ring(struct intel_engine_cs *engine)
1386{
1387 struct drm_i915_private *dev_priv = engine->i915;
Chris Wilson02e012f2017-03-01 12:11:31 +00001388 int err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001389
1390 WARN_ON(engine->id != RCS);
1391
1392 dev_priv->workarounds.count = 0;
Chris Wilson02e012f2017-03-01 12:11:31 +00001393 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001394
1395 if (IS_BROADWELL(dev_priv))
Chris Wilson02e012f2017-03-01 12:11:31 +00001396 err = bdw_init_workarounds(engine);
1397 else if (IS_CHERRYVIEW(dev_priv))
1398 err = chv_init_workarounds(engine);
1399 else if (IS_SKYLAKE(dev_priv))
1400 err = skl_init_workarounds(engine);
1401 else if (IS_BROXTON(dev_priv))
1402 err = bxt_init_workarounds(engine);
1403 else if (IS_KABYLAKE(dev_priv))
1404 err = kbl_init_workarounds(engine);
1405 else if (IS_GEMINILAKE(dev_priv))
1406 err = glk_init_workarounds(engine);
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001407 else if (IS_COFFEELAKE(dev_priv))
1408 err = cfl_init_workarounds(engine);
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001409 else if (IS_CANNONLAKE(dev_priv))
1410 err = cnl_init_workarounds(engine);
Chris Wilson02e012f2017-03-01 12:11:31 +00001411 else
1412 err = 0;
1413 if (err)
1414 return err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001415
Chris Wilson02e012f2017-03-01 12:11:31 +00001416 DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n",
1417 engine->name, dev_priv->workarounds.count);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001418 return 0;
1419}
1420
1421int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)
1422{
1423 struct i915_workarounds *w = &req->i915->workarounds;
1424 u32 *cs;
1425 int ret, i;
1426
1427 if (w->count == 0)
1428 return 0;
1429
1430 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1431 if (ret)
1432 return ret;
1433
1434 cs = intel_ring_begin(req, (w->count * 2 + 2));
1435 if (IS_ERR(cs))
1436 return PTR_ERR(cs);
1437
1438 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
1439 for (i = 0; i < w->count; i++) {
1440 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
1441 *cs++ = w->reg[i].value;
1442 }
1443 *cs++ = MI_NOOP;
1444
1445 intel_ring_advance(req, cs);
1446
1447 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1448 if (ret)
1449 return ret;
1450
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001451 return 0;
1452}
1453
Chris Wilsona091d4e2017-05-30 13:13:33 +01001454static bool ring_is_idle(struct intel_engine_cs *engine)
1455{
1456 struct drm_i915_private *dev_priv = engine->i915;
1457 bool idle = true;
1458
1459 intel_runtime_pm_get(dev_priv);
1460
Chris Wilsonaed2fc12017-05-30 13:13:34 +01001461 /* First check that no commands are left in the ring */
1462 if ((I915_READ_HEAD(engine) & HEAD_ADDR) !=
1463 (I915_READ_TAIL(engine) & TAIL_ADDR))
1464 idle = false;
1465
Chris Wilsona091d4e2017-05-30 13:13:33 +01001466 /* No bit for gen2, so assume the CS parser is idle */
1467 if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE))
1468 idle = false;
1469
1470 intel_runtime_pm_put(dev_priv);
1471
1472 return idle;
1473}
1474
Chris Wilson54003672017-03-03 12:19:46 +00001475/**
1476 * intel_engine_is_idle() - Report if the engine has finished process all work
1477 * @engine: the intel_engine_cs
1478 *
1479 * Return true if there are no requests pending, nothing left to be submitted
1480 * to hardware, and that the engine is idle.
1481 */
1482bool intel_engine_is_idle(struct intel_engine_cs *engine)
1483{
1484 struct drm_i915_private *dev_priv = engine->i915;
1485
Chris Wilsona8e9a412017-04-11 20:00:42 +01001486 /* More white lies, if wedged, hw state is inconsistent */
1487 if (i915_terminally_wedged(&dev_priv->gpu_error))
1488 return true;
1489
Chris Wilson54003672017-03-03 12:19:46 +00001490 /* Any inflight/incomplete requests? */
1491 if (!i915_seqno_passed(intel_engine_get_seqno(engine),
1492 intel_engine_last_submit(engine)))
1493 return false;
1494
Chris Wilson8968a362017-04-12 00:44:26 +01001495 if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))
1496 return true;
1497
Chris Wilson54003672017-03-03 12:19:46 +00001498 /* Interrupt/tasklet pending? */
1499 if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
1500 return false;
1501
1502 /* Both ports drained, no more ELSP submission? */
Mika Kuoppalab620e872017-09-22 15:43:03 +03001503 if (port_request(&engine->execlists.port[0]))
Chris Wilson54003672017-03-03 12:19:46 +00001504 return false;
1505
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001506 /* ELSP is empty, but there are ready requests? */
Mika Kuoppalab620e872017-09-22 15:43:03 +03001507 if (READ_ONCE(engine->execlists.first))
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001508 return false;
1509
Chris Wilson54003672017-03-03 12:19:46 +00001510 /* Ring stopped? */
Chris Wilsona091d4e2017-05-30 13:13:33 +01001511 if (!ring_is_idle(engine))
Chris Wilson54003672017-03-03 12:19:46 +00001512 return false;
1513
1514 return true;
1515}
1516
Chris Wilson05425242017-03-03 12:19:47 +00001517bool intel_engines_are_idle(struct drm_i915_private *dev_priv)
1518{
1519 struct intel_engine_cs *engine;
1520 enum intel_engine_id id;
1521
Chris Wilson8490ae202017-03-30 15:50:37 +01001522 if (READ_ONCE(dev_priv->gt.active_requests))
1523 return false;
1524
1525 /* If the driver is wedged, HW state may be very inconsistent and
1526 * report that it is still busy, even though we have stopped using it.
1527 */
1528 if (i915_terminally_wedged(&dev_priv->gpu_error))
1529 return true;
1530
Chris Wilson05425242017-03-03 12:19:47 +00001531 for_each_engine(engine, dev_priv, id) {
1532 if (!intel_engine_is_idle(engine))
1533 return false;
1534 }
1535
1536 return true;
1537}
1538
Chris Wilsonff44ad52017-03-16 17:13:03 +00001539void intel_engines_reset_default_submission(struct drm_i915_private *i915)
1540{
1541 struct intel_engine_cs *engine;
1542 enum intel_engine_id id;
1543
1544 for_each_engine(engine, i915, id)
1545 engine->set_default_submission(engine);
1546}
1547
Chris Wilson6c067572017-05-17 13:10:03 +01001548void intel_engines_mark_idle(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 intel_engine_disarm_breadcrumbs(engine);
1555 i915_gem_batch_pool_fini(&engine->batch_pool);
Mika Kuoppalab620e872017-09-22 15:43:03 +03001556 tasklet_kill(&engine->execlists.irq_tasklet);
1557 engine->execlists.no_priolist = false;
Chris Wilson6c067572017-05-17 13:10:03 +01001558 }
1559}
1560
Chris Wilson90cad092017-09-06 16:28:59 +01001561bool intel_engine_can_store_dword(struct intel_engine_cs *engine)
1562{
1563 switch (INTEL_GEN(engine->i915)) {
1564 case 2:
1565 return false; /* uses physical not virtual addresses */
1566 case 3:
1567 /* maybe only uses physical not virtual addresses */
1568 return !(IS_I915G(engine->i915) || IS_I915GM(engine->i915));
1569 case 6:
1570 return engine->class != VIDEO_DECODE_CLASS; /* b0rked */
1571 default:
1572 return true;
1573 }
1574}
1575
Chris Wilsonf97fbf92017-02-13 17:15:14 +00001576#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
1577#include "selftests/mock_engine.c"
1578#endif