blob: a75f5e889927848c562dc198ce89c5dc4ed3ee71 [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);
983 WA_SET_BIT(MMCD_MISC_CTRL, MMCD_PCLA | MMCD_HOTSPOT_EN);
984 }
985
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700986 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
987 /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000988 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
989 FLOW_CONTROL_ENABLE |
990 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
991
992 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700993 if (!IS_COFFEELAKE(dev_priv))
994 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
995 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000996
997 /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */
998 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
999 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
1000 GEN9_DG_MIRROR_FIX_ENABLE);
1001
1002 /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */
1003 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1004 WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1,
1005 GEN9_RHWO_OPTIMIZATION_DISABLE);
1006 /*
1007 * WA also requires GEN9_SLICE_COMMON_ECO_CHICKEN0[14:14] to be set
1008 * but we do that in per ctx batchbuffer as there is an issue
1009 * with this register not getting restored on ctx restore
1010 */
1011 }
1012
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001013 /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */
1014 /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001015 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
Arkadiusz Hiler0b71cea2017-05-12 13:20:15 +02001016 GEN9_ENABLE_YV12_BUGFIX |
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001017 GEN9_ENABLE_GPGPU_PREEMPTION);
1018
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001019 /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */
1020 /* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001021 WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
1022 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
1023
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001024 /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001025 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
1026 GEN9_CCS_TLB_PREFETCH_ENABLE);
1027
1028 /* WaDisableMaskBasedCammingInRCC:bxt */
1029 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1030 WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0,
1031 PIXEL_MASK_CAMMING_DISABLE);
1032
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001033 /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001034 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1035 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
1036 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
1037
1038 /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
1039 * both tied to WaForceContextSaveRestoreNonCoherent
1040 * in some hsds for skl. We keep the tie for all gen9. The
1041 * documentation is a bit hazy and so we want to get common behaviour,
1042 * even though there is no clear evidence we would need both on kbl/bxt.
1043 * This area has been source of system hangs so we play it safe
1044 * and mimic the skl regardless of what bspec says.
1045 *
1046 * Use Force Non-Coherent whenever executing a 3D context. This
1047 * is a workaround for a possible hang in the unlikely event
1048 * a TLB invalidation occurs during a PSD flush.
1049 */
1050
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001051 /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001052 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1053 HDC_FORCE_NON_COHERENT);
1054
Rodrigo Vivi98eed3d2017-06-19 14:21:47 -07001055 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
1056 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
1057 BDW_DISABLE_HDC_INVALIDATION);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001058
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001059 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001060 if (IS_SKYLAKE(dev_priv) ||
1061 IS_KABYLAKE(dev_priv) ||
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001062 IS_COFFEELAKE(dev_priv) ||
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001063 IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
1064 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
1065 GEN8_SAMPLER_POWER_BYPASS_DIS);
1066
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001067 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001068 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
1069
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001070 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001071 I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
1072 GEN8_LQSC_FLUSH_COHERENT_LINES));
1073
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001074 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001075 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
1076 if (ret)
1077 return ret;
1078
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001079 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001080 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1081 if (ret)
1082 return ret;
1083
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001084 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001085 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
1086 if (ret)
1087 return ret;
1088
1089 return 0;
1090}
1091
1092static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
1093{
1094 struct drm_i915_private *dev_priv = engine->i915;
1095 u8 vals[3] = { 0, 0, 0 };
1096 unsigned int i;
1097
1098 for (i = 0; i < 3; i++) {
1099 u8 ss;
1100
1101 /*
1102 * Only consider slices where one, and only one, subslice has 7
1103 * EUs
1104 */
1105 if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
1106 continue;
1107
1108 /*
1109 * subslice_7eu[i] != 0 (because of the check above) and
1110 * ss_max == 4 (maximum number of subslices possible per slice)
1111 *
1112 * -> 0 <= ss <= 3;
1113 */
1114 ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
1115 vals[i] = 3 - ss;
1116 }
1117
1118 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
1119 return 0;
1120
1121 /* Tune IZ hashing. See intel_device_info_runtime_init() */
1122 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
1123 GEN9_IZ_HASHING_MASK(2) |
1124 GEN9_IZ_HASHING_MASK(1) |
1125 GEN9_IZ_HASHING_MASK(0),
1126 GEN9_IZ_HASHING(2, vals[2]) |
1127 GEN9_IZ_HASHING(1, vals[1]) |
1128 GEN9_IZ_HASHING(0, vals[0]));
1129
1130 return 0;
1131}
1132
1133static int skl_init_workarounds(struct intel_engine_cs *engine)
1134{
1135 struct drm_i915_private *dev_priv = engine->i915;
1136 int ret;
1137
1138 ret = gen9_init_workarounds(engine);
1139 if (ret)
1140 return ret;
1141
1142 /*
1143 * Actual WA is to disable percontext preemption granularity control
1144 * until D0 which is the default case so this is equivalent to
1145 * !WaDisablePerCtxtPreemptionGranularityControl:skl
1146 */
1147 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1148 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
1149
1150 /* WaEnableGapsTsvCreditFix:skl */
1151 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1152 GEN9_GAPS_TSV_CREDIT_DISABLE));
1153
1154 /* WaDisableGafsUnitClkGating:skl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001155 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1156 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001157
1158 /* WaInPlaceDecompressionHang:skl */
1159 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
Oscar Mateoefc886c2017-09-07 08:40:04 -07001160 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1161 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1162 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001163
1164 /* WaDisableLSQCROPERFforOCL:skl */
1165 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1166 if (ret)
1167 return ret;
1168
1169 return skl_tune_iz_hashing(engine);
1170}
1171
1172static int bxt_init_workarounds(struct intel_engine_cs *engine)
1173{
1174 struct drm_i915_private *dev_priv = engine->i915;
1175 int ret;
1176
1177 ret = gen9_init_workarounds(engine);
1178 if (ret)
1179 return ret;
1180
1181 /* WaStoreMultiplePTEenable:bxt */
1182 /* This is a requirement according to Hardware specification */
1183 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
1184 I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
1185
1186 /* WaSetClckGatingDisableMedia:bxt */
1187 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1188 I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
1189 ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
1190 }
1191
1192 /* WaDisableThreadStallDopClockGating:bxt */
1193 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
1194 STALL_DOP_GATING_DISABLE);
1195
1196 /* WaDisablePooledEuLoadBalancingFix:bxt */
1197 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
Oscar Mateo212154b2017-09-07 08:40:09 -07001198 I915_WRITE(FF_SLICE_CS_CHICKEN2,
1199 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001200 }
1201
1202 /* WaDisableSbeCacheDispatchPortSharing:bxt */
1203 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) {
1204 WA_SET_BIT_MASKED(
1205 GEN7_HALF_SLICE_CHICKEN1,
1206 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1207 }
1208
1209 /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */
1210 /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */
1211 /* WaDisableObjectLevelPreemtionForInstanceId:bxt */
1212 /* WaDisableLSQCROPERFforOCL:bxt */
1213 if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
1214 ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1);
1215 if (ret)
1216 return ret;
1217
1218 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1219 if (ret)
1220 return ret;
1221 }
1222
1223 /* WaProgramL3SqcReg1DefaultForPerf:bxt */
1224 if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
1225 I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
1226 L3_HIGH_PRIO_CREDITS(2));
1227
1228 /* WaToEnableHwFixForPushConstHWBug:bxt */
1229 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
1230 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1231 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1232
1233 /* WaInPlaceDecompressionHang:bxt */
1234 if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
Oscar Mateoefc886c2017-09-07 08:40:04 -07001235 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1236 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1237 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001238
1239 return 0;
1240}
1241
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001242static int cnl_init_workarounds(struct intel_engine_cs *engine)
1243{
1244 struct drm_i915_private *dev_priv = engine->i915;
1245 int ret;
1246
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001247 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001248 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001249 I915_WRITE(GAMT_CHKN_BIT_REG,
1250 (I915_READ(GAMT_CHKN_BIT_REG) |
1251 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT));
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001252
Rodrigo Viviacfb5552017-08-23 13:35:04 -07001253 /* WaForceContextSaveRestoreNonCoherent:cnl */
1254 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0,
1255 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT);
1256
Rodrigo Viviaa9f4c42017-09-06 15:03:25 -07001257 /* WaThrottleEUPerfToAvoidTDBackPressure:cnl(pre-prod) */
1258 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
1259 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, THROTTLE_12_5);
1260
Rodrigo Vivie6d1a4f2017-08-15 16:16:49 -07001261 /* WaDisableReplayBufferBankArbitrationOptimization:cnl */
1262 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1263 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1264
Rodrigo Vivid1d24752017-08-15 16:16:50 -07001265 /* WaDisableEnhancedSBEVertexCaching:cnl (pre-prod) */
1266 if (IS_CNL_REVID(dev_priv, 0, CNL_REVID_B0))
1267 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1268 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE);
1269
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001270 /* WaInPlaceDecompressionHang:cnl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001271 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1272 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1273 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001274
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001275 /* WaPushConstantDereferenceHoldDisable:cnl */
Oscar Mateob27f5902017-09-07 08:40:06 -07001276 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE);
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001277
Rodrigo Vivi392572f2017-08-29 16:07:23 -07001278 /* FtrEnableFastAnisoL1BankingFix: cnl */
1279 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX);
1280
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001281 /* WaEnablePreemptionGranularityControlByUMD:cnl */
1282 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1283 if (ret)
1284 return ret;
1285
1286 return 0;
1287}
1288
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001289static int kbl_init_workarounds(struct intel_engine_cs *engine)
1290{
1291 struct drm_i915_private *dev_priv = engine->i915;
1292 int ret;
1293
1294 ret = gen9_init_workarounds(engine);
1295 if (ret)
1296 return ret;
1297
1298 /* WaEnableGapsTsvCreditFix:kbl */
1299 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1300 GEN9_GAPS_TSV_CREDIT_DISABLE));
1301
1302 /* WaDisableDynamicCreditSharing:kbl */
1303 if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
Oscar Mateoc6ea497c2017-09-07 08:40:08 -07001304 I915_WRITE(GAMT_CHKN_BIT_REG,
1305 (I915_READ(GAMT_CHKN_BIT_REG) |
1306 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001307
1308 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
1309 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
1310 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1311 HDC_FENCE_DEST_SLM_DISABLE);
1312
1313 /* WaToEnableHwFixForPushConstHWBug:kbl */
1314 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
1315 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1316 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1317
1318 /* WaDisableGafsUnitClkGating:kbl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001319 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1320 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001321
1322 /* WaDisableSbeCacheDispatchPortSharing:kbl */
1323 WA_SET_BIT_MASKED(
1324 GEN7_HALF_SLICE_CHICKEN1,
1325 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1326
1327 /* WaInPlaceDecompressionHang:kbl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001328 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1329 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1330 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001331
1332 /* WaDisableLSQCROPERFforOCL:kbl */
1333 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1334 if (ret)
1335 return ret;
1336
1337 return 0;
1338}
1339
1340static int glk_init_workarounds(struct intel_engine_cs *engine)
1341{
1342 struct drm_i915_private *dev_priv = engine->i915;
1343 int ret;
1344
1345 ret = gen9_init_workarounds(engine);
1346 if (ret)
1347 return ret;
1348
1349 /* WaToEnableHwFixForPushConstHWBug:glk */
1350 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1351 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1352
1353 return 0;
1354}
1355
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001356static int cfl_init_workarounds(struct intel_engine_cs *engine)
1357{
1358 struct drm_i915_private *dev_priv = engine->i915;
1359 int ret;
1360
1361 ret = gen9_init_workarounds(engine);
1362 if (ret)
1363 return ret;
1364
1365 /* WaEnableGapsTsvCreditFix:cfl */
1366 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1367 GEN9_GAPS_TSV_CREDIT_DISABLE));
1368
1369 /* WaToEnableHwFixForPushConstHWBug:cfl */
1370 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1371 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1372
1373 /* WaDisableGafsUnitClkGating:cfl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001374 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1375 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001376
1377 /* WaDisableSbeCacheDispatchPortSharing:cfl */
1378 WA_SET_BIT_MASKED(
1379 GEN7_HALF_SLICE_CHICKEN1,
1380 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1381
1382 /* WaInPlaceDecompressionHang:cfl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001383 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1384 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1385 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001386
1387 return 0;
1388}
1389
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001390int init_workarounds_ring(struct intel_engine_cs *engine)
1391{
1392 struct drm_i915_private *dev_priv = engine->i915;
Chris Wilson02e012f2017-03-01 12:11:31 +00001393 int err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001394
1395 WARN_ON(engine->id != RCS);
1396
1397 dev_priv->workarounds.count = 0;
Chris Wilson02e012f2017-03-01 12:11:31 +00001398 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001399
1400 if (IS_BROADWELL(dev_priv))
Chris Wilson02e012f2017-03-01 12:11:31 +00001401 err = bdw_init_workarounds(engine);
1402 else if (IS_CHERRYVIEW(dev_priv))
1403 err = chv_init_workarounds(engine);
1404 else if (IS_SKYLAKE(dev_priv))
1405 err = skl_init_workarounds(engine);
1406 else if (IS_BROXTON(dev_priv))
1407 err = bxt_init_workarounds(engine);
1408 else if (IS_KABYLAKE(dev_priv))
1409 err = kbl_init_workarounds(engine);
1410 else if (IS_GEMINILAKE(dev_priv))
1411 err = glk_init_workarounds(engine);
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001412 else if (IS_COFFEELAKE(dev_priv))
1413 err = cfl_init_workarounds(engine);
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001414 else if (IS_CANNONLAKE(dev_priv))
1415 err = cnl_init_workarounds(engine);
Chris Wilson02e012f2017-03-01 12:11:31 +00001416 else
1417 err = 0;
1418 if (err)
1419 return err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001420
Chris Wilson02e012f2017-03-01 12:11:31 +00001421 DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n",
1422 engine->name, dev_priv->workarounds.count);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001423 return 0;
1424}
1425
1426int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)
1427{
1428 struct i915_workarounds *w = &req->i915->workarounds;
1429 u32 *cs;
1430 int ret, i;
1431
1432 if (w->count == 0)
1433 return 0;
1434
1435 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1436 if (ret)
1437 return ret;
1438
1439 cs = intel_ring_begin(req, (w->count * 2 + 2));
1440 if (IS_ERR(cs))
1441 return PTR_ERR(cs);
1442
1443 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
1444 for (i = 0; i < w->count; i++) {
1445 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
1446 *cs++ = w->reg[i].value;
1447 }
1448 *cs++ = MI_NOOP;
1449
1450 intel_ring_advance(req, cs);
1451
1452 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1453 if (ret)
1454 return ret;
1455
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001456 return 0;
1457}
1458
Chris Wilsona091d4e2017-05-30 13:13:33 +01001459static bool ring_is_idle(struct intel_engine_cs *engine)
1460{
1461 struct drm_i915_private *dev_priv = engine->i915;
1462 bool idle = true;
1463
1464 intel_runtime_pm_get(dev_priv);
1465
Chris Wilsonaed2fc12017-05-30 13:13:34 +01001466 /* First check that no commands are left in the ring */
1467 if ((I915_READ_HEAD(engine) & HEAD_ADDR) !=
1468 (I915_READ_TAIL(engine) & TAIL_ADDR))
1469 idle = false;
1470
Chris Wilsona091d4e2017-05-30 13:13:33 +01001471 /* No bit for gen2, so assume the CS parser is idle */
1472 if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE))
1473 idle = false;
1474
1475 intel_runtime_pm_put(dev_priv);
1476
1477 return idle;
1478}
1479
Chris Wilson54003672017-03-03 12:19:46 +00001480/**
1481 * intel_engine_is_idle() - Report if the engine has finished process all work
1482 * @engine: the intel_engine_cs
1483 *
1484 * Return true if there are no requests pending, nothing left to be submitted
1485 * to hardware, and that the engine is idle.
1486 */
1487bool intel_engine_is_idle(struct intel_engine_cs *engine)
1488{
1489 struct drm_i915_private *dev_priv = engine->i915;
1490
Chris Wilsona8e9a412017-04-11 20:00:42 +01001491 /* More white lies, if wedged, hw state is inconsistent */
1492 if (i915_terminally_wedged(&dev_priv->gpu_error))
1493 return true;
1494
Chris Wilson54003672017-03-03 12:19:46 +00001495 /* Any inflight/incomplete requests? */
1496 if (!i915_seqno_passed(intel_engine_get_seqno(engine),
1497 intel_engine_last_submit(engine)))
1498 return false;
1499
Chris Wilson8968a362017-04-12 00:44:26 +01001500 if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))
1501 return true;
1502
Chris Wilson54003672017-03-03 12:19:46 +00001503 /* Interrupt/tasklet pending? */
1504 if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
1505 return false;
1506
1507 /* Both ports drained, no more ELSP submission? */
Mika Kuoppalab620e872017-09-22 15:43:03 +03001508 if (port_request(&engine->execlists.port[0]))
Chris Wilson54003672017-03-03 12:19:46 +00001509 return false;
1510
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001511 /* ELSP is empty, but there are ready requests? */
Mika Kuoppalab620e872017-09-22 15:43:03 +03001512 if (READ_ONCE(engine->execlists.first))
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001513 return false;
1514
Chris Wilson54003672017-03-03 12:19:46 +00001515 /* Ring stopped? */
Chris Wilsona091d4e2017-05-30 13:13:33 +01001516 if (!ring_is_idle(engine))
Chris Wilson54003672017-03-03 12:19:46 +00001517 return false;
1518
1519 return true;
1520}
1521
Chris Wilson05425242017-03-03 12:19:47 +00001522bool intel_engines_are_idle(struct drm_i915_private *dev_priv)
1523{
1524 struct intel_engine_cs *engine;
1525 enum intel_engine_id id;
1526
Chris Wilson8490ae202017-03-30 15:50:37 +01001527 if (READ_ONCE(dev_priv->gt.active_requests))
1528 return false;
1529
1530 /* If the driver is wedged, HW state may be very inconsistent and
1531 * report that it is still busy, even though we have stopped using it.
1532 */
1533 if (i915_terminally_wedged(&dev_priv->gpu_error))
1534 return true;
1535
Chris Wilson05425242017-03-03 12:19:47 +00001536 for_each_engine(engine, dev_priv, id) {
1537 if (!intel_engine_is_idle(engine))
1538 return false;
1539 }
1540
1541 return true;
1542}
1543
Chris Wilsonff44ad52017-03-16 17:13:03 +00001544void intel_engines_reset_default_submission(struct drm_i915_private *i915)
1545{
1546 struct intel_engine_cs *engine;
1547 enum intel_engine_id id;
1548
1549 for_each_engine(engine, i915, id)
1550 engine->set_default_submission(engine);
1551}
1552
Chris Wilson6c067572017-05-17 13:10:03 +01001553void intel_engines_mark_idle(struct drm_i915_private *i915)
1554{
1555 struct intel_engine_cs *engine;
1556 enum intel_engine_id id;
1557
1558 for_each_engine(engine, i915, id) {
1559 intel_engine_disarm_breadcrumbs(engine);
1560 i915_gem_batch_pool_fini(&engine->batch_pool);
Mika Kuoppalab620e872017-09-22 15:43:03 +03001561 tasklet_kill(&engine->execlists.irq_tasklet);
1562 engine->execlists.no_priolist = false;
Chris Wilson6c067572017-05-17 13:10:03 +01001563 }
1564}
1565
Chris Wilson90cad092017-09-06 16:28:59 +01001566bool intel_engine_can_store_dword(struct intel_engine_cs *engine)
1567{
1568 switch (INTEL_GEN(engine->i915)) {
1569 case 2:
1570 return false; /* uses physical not virtual addresses */
1571 case 3:
1572 /* maybe only uses physical not virtual addresses */
1573 return !(IS_I915G(engine->i915) || IS_I915GM(engine->i915));
1574 case 6:
1575 return engine->class != VIDEO_DECODE_CLASS; /* b0rked */
1576 default:
1577 return true;
1578 }
1579}
1580
Chris Wilsonf97fbf92017-02-13 17:15:14 +00001581#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
1582#include "selftests/mock_engine.c"
1583#endif