blob: ef8e101ebd987447e4a448adb5f779ed95b16abf [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
Chris Wilsonf636edb2017-10-09 12:02:57 +010025#include <drm/drm_print.h>
26
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010027#include "i915_drv.h"
Weinan Li1fd51d92017-10-15 11:55:25 +080028#include "i915_vgpu.h"
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010029#include "intel_ringbuffer.h"
30#include "intel_lrc.h"
31
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +030032/* Haswell does have the CXT_SIZE register however it does not appear to be
33 * valid. Now, docs explain in dwords what is in the context object. The full
34 * size is 70720 bytes, however, the power context and execlist context will
35 * never be saved (power context is stored elsewhere, and execlists don't work
36 * on HSW) - so the final size, including the extra state required for the
37 * Resource Streamer, is 66944 bytes, which rounds to 17 pages.
38 */
39#define HSW_CXT_TOTAL_SIZE (17 * PAGE_SIZE)
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +030040
41#define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE)
42#define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE)
Oscar Mateo3cf19342017-10-04 08:39:52 -070043#define GEN10_LR_CONTEXT_RENDER_SIZE (18 * PAGE_SIZE)
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +030044
45#define GEN8_LR_CONTEXT_OTHER_SIZE ( 2 * PAGE_SIZE)
46
Oscar Mateob8400f02017-04-10 07:34:32 -070047struct engine_class_info {
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010048 const char *name;
Oscar Mateob8400f02017-04-10 07:34:32 -070049 int (*init_legacy)(struct intel_engine_cs *engine);
50 int (*init_execlists)(struct intel_engine_cs *engine);
Tvrtko Ursulin1803fcbc2017-11-10 14:26:27 +000051
52 u8 uabi_class;
Oscar Mateob8400f02017-04-10 07:34:32 -070053};
54
55static const struct engine_class_info intel_engine_classes[] = {
56 [RENDER_CLASS] = {
57 .name = "rcs",
58 .init_execlists = logical_render_ring_init,
59 .init_legacy = intel_init_render_ring_buffer,
Tvrtko Ursulin1803fcbc2017-11-10 14:26:27 +000060 .uabi_class = I915_ENGINE_CLASS_RENDER,
Oscar Mateob8400f02017-04-10 07:34:32 -070061 },
62 [COPY_ENGINE_CLASS] = {
63 .name = "bcs",
64 .init_execlists = logical_xcs_ring_init,
65 .init_legacy = intel_init_blt_ring_buffer,
Tvrtko Ursulin1803fcbc2017-11-10 14:26:27 +000066 .uabi_class = I915_ENGINE_CLASS_COPY,
Oscar Mateob8400f02017-04-10 07:34:32 -070067 },
68 [VIDEO_DECODE_CLASS] = {
69 .name = "vcs",
70 .init_execlists = logical_xcs_ring_init,
71 .init_legacy = intel_init_bsd_ring_buffer,
Tvrtko Ursulin1803fcbc2017-11-10 14:26:27 +000072 .uabi_class = I915_ENGINE_CLASS_VIDEO,
Oscar Mateob8400f02017-04-10 07:34:32 -070073 },
74 [VIDEO_ENHANCEMENT_CLASS] = {
75 .name = "vecs",
76 .init_execlists = logical_xcs_ring_init,
77 .init_legacy = intel_init_vebox_ring_buffer,
Tvrtko Ursulin1803fcbc2017-11-10 14:26:27 +000078 .uabi_class = I915_ENGINE_CLASS_VIDEO_ENHANCE,
Oscar Mateob8400f02017-04-10 07:34:32 -070079 },
80};
81
82struct engine_info {
Michal Wajdeczko237ae7c2017-03-01 20:26:15 +000083 unsigned int hw_id;
Chris Wilson1d39f282017-04-11 13:43:06 +010084 unsigned int uabi_id;
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070085 u8 class;
86 u8 instance;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010087 u32 mmio_base;
88 unsigned irq_shift;
Oscar Mateob8400f02017-04-10 07:34:32 -070089};
90
91static const struct engine_info intel_engines[] = {
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010092 [RCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +010093 .hw_id = RCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +010094 .uabi_id = I915_EXEC_RENDER,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -070095 .class = RENDER_CLASS,
96 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010097 .mmio_base = RENDER_RING_BASE,
98 .irq_shift = GEN8_RCS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +010099 },
100 [BCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100101 .hw_id = BCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100102 .uabi_id = I915_EXEC_BLT,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700103 .class = COPY_ENGINE_CLASS,
104 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100105 .mmio_base = BLT_RING_BASE,
106 .irq_shift = GEN8_BCS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100107 },
108 [VCS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100109 .hw_id = VCS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100110 .uabi_id = I915_EXEC_BSD,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700111 .class = VIDEO_DECODE_CLASS,
112 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100113 .mmio_base = GEN6_BSD_RING_BASE,
114 .irq_shift = GEN8_VCS1_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100115 },
116 [VCS2] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100117 .hw_id = VCS2_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100118 .uabi_id = I915_EXEC_BSD,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700119 .class = VIDEO_DECODE_CLASS,
120 .instance = 1,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100121 .mmio_base = GEN8_BSD2_RING_BASE,
122 .irq_shift = GEN8_VCS2_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100123 },
124 [VECS] = {
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100125 .hw_id = VECS_HW,
Chris Wilson1d39f282017-04-11 13:43:06 +0100126 .uabi_id = I915_EXEC_VEBOX,
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700127 .class = VIDEO_ENHANCEMENT_CLASS,
128 .instance = 0,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100129 .mmio_base = VEBOX_RING_BASE,
130 .irq_shift = GEN8_VECS_IRQ_SHIFT,
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100131 },
132};
133
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300134/**
135 * ___intel_engine_context_size() - return the size of the context for an engine
136 * @dev_priv: i915 device private
137 * @class: engine class
138 *
139 * Each engine class may require a different amount of space for a context
140 * image.
141 *
142 * Return: size (in bytes) of an engine class specific context image
143 *
144 * Note: this size includes the HWSP, which is part of the context image
145 * in LRC mode, but does not include the "shared data page" used with
146 * GuC submission. The caller should account for this if using the GuC.
147 */
148static u32
149__intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class)
150{
151 u32 cxt_size;
152
153 BUILD_BUG_ON(I915_GTT_PAGE_SIZE != PAGE_SIZE);
154
155 switch (class) {
156 case RENDER_CLASS:
157 switch (INTEL_GEN(dev_priv)) {
158 default:
159 MISSING_CASE(INTEL_GEN(dev_priv));
Rodrigo Vivif65f8412017-07-06 14:06:24 -0700160 case 10:
Oscar Mateo7fd0b1a2017-09-21 16:19:49 -0700161 return GEN10_LR_CONTEXT_RENDER_SIZE;
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300162 case 9:
163 return GEN9_LR_CONTEXT_RENDER_SIZE;
164 case 8:
Chris Wilsonfb5c5512017-11-20 20:55:00 +0000165 return GEN8_LR_CONTEXT_RENDER_SIZE;
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300166 case 7:
167 if (IS_HASWELL(dev_priv))
168 return HSW_CXT_TOTAL_SIZE;
169
170 cxt_size = I915_READ(GEN7_CXT_SIZE);
171 return round_up(GEN7_CXT_TOTAL_SIZE(cxt_size) * 64,
172 PAGE_SIZE);
173 case 6:
174 cxt_size = I915_READ(CXT_SIZE);
175 return round_up(GEN6_CXT_TOTAL_SIZE(cxt_size) * 64,
176 PAGE_SIZE);
177 case 5:
178 case 4:
179 case 3:
180 case 2:
181 /* For the special day when i810 gets merged. */
182 case 1:
183 return 0;
184 }
185 break;
186 default:
187 MISSING_CASE(class);
188 case VIDEO_DECODE_CLASS:
189 case VIDEO_ENHANCEMENT_CLASS:
190 case COPY_ENGINE_CLASS:
191 if (INTEL_GEN(dev_priv) < 8)
192 return 0;
193 return GEN8_LR_CONTEXT_OTHER_SIZE;
194 }
195}
196
Akash Goel3b3f1652016-10-13 22:44:48 +0530197static int
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100198intel_engine_setup(struct drm_i915_private *dev_priv,
199 enum intel_engine_id id)
200{
201 const struct engine_info *info = &intel_engines[id];
Oscar Mateob8400f02017-04-10 07:34:32 -0700202 const struct engine_class_info *class_info;
Akash Goel3b3f1652016-10-13 22:44:48 +0530203 struct intel_engine_cs *engine;
204
Oscar Mateob8400f02017-04-10 07:34:32 -0700205 GEM_BUG_ON(info->class >= ARRAY_SIZE(intel_engine_classes));
206 class_info = &intel_engine_classes[info->class];
207
Akash Goel3b3f1652016-10-13 22:44:48 +0530208 GEM_BUG_ON(dev_priv->engine[id]);
209 engine = kzalloc(sizeof(*engine), GFP_KERNEL);
210 if (!engine)
211 return -ENOMEM;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100212
213 engine->id = id;
214 engine->i915 = dev_priv;
Oscar Mateo6e516142017-04-10 07:34:31 -0700215 WARN_ON(snprintf(engine->name, sizeof(engine->name), "%s%u",
Oscar Mateob8400f02017-04-10 07:34:32 -0700216 class_info->name, info->instance) >=
217 sizeof(engine->name));
Tvrtko Ursulin5ec2cf72016-08-16 17:04:20 +0100218 engine->hw_id = engine->guc_id = info->hw_id;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100219 engine->mmio_base = info->mmio_base;
220 engine->irq_shift = info->irq_shift;
Daniele Ceraolo Spurio09081802017-04-10 07:34:29 -0700221 engine->class = info->class;
222 engine->instance = info->instance;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100223
Tvrtko Ursulin1803fcbc2017-11-10 14:26:27 +0000224 engine->uabi_id = info->uabi_id;
225 engine->uabi_class = class_info->uabi_class;
226
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300227 engine->context_size = __intel_engine_context_size(dev_priv,
228 engine->class);
229 if (WARN_ON(engine->context_size > BIT(20)))
230 engine->context_size = 0;
231
Chris Wilson0de91362016-11-14 20:41:01 +0000232 /* Nothing to do here, execute in order of dependencies */
233 engine->schedule = NULL;
234
Changbin Du3fc03062017-03-13 10:47:11 +0800235 ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
236
Akash Goel3b3f1652016-10-13 22:44:48 +0530237 dev_priv->engine[id] = engine;
238 return 0;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100239}
240
241/**
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300242 * intel_engines_init_mmio() - allocate and prepare the Engine Command Streamers
Tvrtko Ursulinbf9e8422016-12-01 14:16:38 +0000243 * @dev_priv: i915 device private
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100244 *
245 * Return: non-zero if the initialization failed.
246 */
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300247int intel_engines_init_mmio(struct drm_i915_private *dev_priv)
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100248{
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100249 struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
Chris Wilson5f9be052017-04-11 17:56:58 +0100250 const unsigned int ring_mask = INTEL_INFO(dev_priv)->ring_mask;
Akash Goel3b3f1652016-10-13 22:44:48 +0530251 struct intel_engine_cs *engine;
252 enum intel_engine_id id;
Chris Wilson5f9be052017-04-11 17:56:58 +0100253 unsigned int mask = 0;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100254 unsigned int i;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000255 int err;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100256
Tvrtko Ursulin70006ad2016-10-13 11:02:56 +0100257 WARN_ON(ring_mask == 0);
258 WARN_ON(ring_mask &
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100259 GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES));
260
261 for (i = 0; i < ARRAY_SIZE(intel_engines); i++) {
262 if (!HAS_ENGINE(dev_priv, i))
263 continue;
264
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000265 err = intel_engine_setup(dev_priv, i);
266 if (err)
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100267 goto cleanup;
268
269 mask |= ENGINE_MASK(i);
270 }
271
272 /*
273 * Catch failures to update intel_engines table when the new engines
274 * are added to the driver by a warning and disabling the forgotten
275 * engines.
276 */
Tvrtko Ursulin70006ad2016-10-13 11:02:56 +0100277 if (WARN_ON(mask != ring_mask))
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100278 device_info->ring_mask = mask;
279
Chris Wilson5f9be052017-04-11 17:56:58 +0100280 /* We always presume we have at least RCS available for later probing */
281 if (WARN_ON(!HAS_ENGINE(dev_priv, RCS))) {
282 err = -ENODEV;
283 goto cleanup;
284 }
285
Tvrtko Ursulinc1bb1142016-08-10 16:22:10 +0100286 device_info->num_rings = hweight32(mask);
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100287
Michel Thierryce453b32017-11-10 16:44:47 -0800288 i915_check_and_clear_faults(dev_priv);
289
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100290 return 0;
291
292cleanup:
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000293 for_each_engine(engine, dev_priv, id)
294 kfree(engine);
295 return err;
296}
297
298/**
Joonas Lahtinen63ffbcd2017-04-28 10:53:36 +0300299 * intel_engines_init() - init the Engine Command Streamers
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000300 * @dev_priv: i915 device private
301 *
302 * Return: non-zero if the initialization failed.
303 */
304int intel_engines_init(struct drm_i915_private *dev_priv)
305{
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000306 struct intel_engine_cs *engine;
307 enum intel_engine_id id, err_id;
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100308 int err;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000309
Akash Goel3b3f1652016-10-13 22:44:48 +0530310 for_each_engine(engine, dev_priv, id) {
Oscar Mateob8400f02017-04-10 07:34:32 -0700311 const struct engine_class_info *class_info =
312 &intel_engine_classes[engine->class];
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000313 int (*init)(struct intel_engine_cs *engine);
314
Chris Wilsonfb5c5512017-11-20 20:55:00 +0000315 if (HAS_EXECLISTS(dev_priv))
Oscar Mateob8400f02017-04-10 07:34:32 -0700316 init = class_info->init_execlists;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000317 else
Oscar Mateob8400f02017-04-10 07:34:32 -0700318 init = class_info->init_legacy;
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100319
320 err = -EINVAL;
321 err_id = id;
322
323 if (GEM_WARN_ON(!init))
324 goto cleanup;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000325
326 err = init(engine);
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100327 if (err)
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000328 goto cleanup;
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000329
Chris Wilsonff44ad52017-03-16 17:13:03 +0000330 GEM_BUG_ON(!engine->submit_request);
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000331 }
332
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000333 return 0;
334
335cleanup:
336 for_each_engine(engine, dev_priv, id) {
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100337 if (id >= err_id) {
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000338 kfree(engine);
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100339 dev_priv->engine[id] = NULL;
340 } else {
Tvrtko Ursulin8ee7c6e2017-02-16 12:23:22 +0000341 dev_priv->gt.cleanup_engine(engine);
Tvrtko Ursulin33def1f2017-06-16 14:03:38 +0100342 }
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100343 }
Chris Wilsonbb8f0f52017-01-24 11:01:34 +0000344 return err;
Tvrtko Ursulin88d2ba22016-07-13 16:03:40 +0100345}
346
Chris Wilson73cb9702016-10-28 13:58:46 +0100347void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
Chris Wilson57f275a2016-08-15 10:49:00 +0100348{
349 struct drm_i915_private *dev_priv = engine->i915;
350
351 /* Our semaphore implementation is strictly monotonic (i.e. we proceed
352 * so long as the semaphore value in the register/page is greater
353 * than the sync value), so whenever we reset the seqno,
354 * so long as we reset the tracking semaphore value to 0, it will
355 * always be before the next request's seqno. If we don't reset
356 * the semaphore value, then when the seqno moves backwards all
357 * future waits will complete instantly (causing rendering corruption).
358 */
359 if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv)) {
360 I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
361 I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
362 if (HAS_VEBOX(dev_priv))
363 I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
364 }
Chris Wilson57f275a2016-08-15 10:49:00 +0100365
366 intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
Chris Wilson14a6bbf2017-03-14 11:14:52 +0000367 clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
Chris Wilson73cb9702016-10-28 13:58:46 +0100368
Chris Wilson57f275a2016-08-15 10:49:00 +0100369 /* After manually advancing the seqno, fake the interrupt in case
370 * there are any waiters for that seqno.
371 */
372 intel_engine_wakeup(engine);
Chris Wilson2ca9faa2017-04-05 16:30:54 +0100373
374 GEM_BUG_ON(intel_engine_get_seqno(engine) != seqno);
Chris Wilson57f275a2016-08-15 10:49:00 +0100375}
376
Chris Wilson73cb9702016-10-28 13:58:46 +0100377static void intel_engine_init_timeline(struct intel_engine_cs *engine)
Chris Wilsondcff85c2016-08-05 10:14:11 +0100378{
Chris Wilson73cb9702016-10-28 13:58:46 +0100379 engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id];
Chris Wilsondcff85c2016-08-05 10:14:11 +0100380}
381
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300382static bool csb_force_mmio(struct drm_i915_private *i915)
383{
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300384 /*
385 * IOMMU adds unpredictable latency causing the CSB write (from the
386 * GPU into the HWSP) to only be visible some time after the interrupt
387 * (missed breadcrumb syndrome).
388 */
389 if (intel_vtd_active())
390 return true;
391
Weinan Li1fd51d92017-10-15 11:55:25 +0800392 /* Older GVT emulation depends upon intercepting CSB mmio */
393 if (intel_vgpu_active(i915) && !intel_vgpu_has_hwsp_emulation(i915))
394 return true;
395
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300396 return false;
397}
398
399static void intel_engine_init_execlist(struct intel_engine_cs *engine)
400{
401 struct intel_engine_execlists * const execlists = &engine->execlists;
402
403 execlists->csb_use_mmio = csb_force_mmio(engine->i915);
404
Mika Kuoppala76e70082017-09-22 15:43:07 +0300405 execlists->port_mask = 1;
406 BUILD_BUG_ON_NOT_POWER_OF_2(execlists_num_ports(execlists));
407 GEM_BUG_ON(execlists_num_ports(execlists) > EXECLIST_MAX_PORTS);
408
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300409 execlists->queue = RB_ROOT;
410 execlists->first = NULL;
411}
412
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100413/**
414 * intel_engines_setup_common - setup engine state not requiring hw access
415 * @engine: Engine to setup.
416 *
417 * Initializes @engine@ structure members shared between legacy and execlists
418 * submission modes which do not require hardware access.
419 *
420 * Typically done early in the submission mode specific engine setup stage.
421 */
422void intel_engine_setup_common(struct intel_engine_cs *engine)
423{
Mika Kuoppala19df9a52017-09-22 15:43:04 +0300424 intel_engine_init_execlist(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100425
Chris Wilson73cb9702016-10-28 13:58:46 +0100426 intel_engine_init_timeline(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100427 intel_engine_init_hangcheck(engine);
Chris Wilson115003e92016-08-04 16:32:19 +0100428 i915_gem_batch_pool_init(engine, &engine->batch_pool);
Chris Wilson7756e452016-08-18 17:17:10 +0100429
430 intel_engine_init_cmd_parser(engine);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100431}
432
Chris Wilsonadc320c2016-08-15 10:48:59 +0100433int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
434{
435 struct drm_i915_gem_object *obj;
436 struct i915_vma *vma;
437 int ret;
438
439 WARN_ON(engine->scratch);
440
Tvrtko Ursulin187685c2016-12-01 14:16:36 +0000441 obj = i915_gem_object_create_stolen(engine->i915, size);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100442 if (!obj)
Chris Wilson920cf412016-10-28 13:58:30 +0100443 obj = i915_gem_object_create_internal(engine->i915, size);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100444 if (IS_ERR(obj)) {
445 DRM_ERROR("Failed to allocate scratch page\n");
446 return PTR_ERR(obj);
447 }
448
Chris Wilsona01cb372017-01-16 15:21:30 +0000449 vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100450 if (IS_ERR(vma)) {
451 ret = PTR_ERR(vma);
452 goto err_unref;
453 }
454
455 ret = i915_vma_pin(vma, 0, 4096, PIN_GLOBAL | PIN_HIGH);
456 if (ret)
457 goto err_unref;
458
459 engine->scratch = vma;
Chris Wilsonbde13eb2016-08-15 10:49:07 +0100460 DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
461 engine->name, i915_ggtt_offset(vma));
Chris Wilsonadc320c2016-08-15 10:48:59 +0100462 return 0;
463
464err_unref:
465 i915_gem_object_put(obj);
466 return ret;
467}
468
469static void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
470{
Chris Wilson19880c42016-08-15 10:49:05 +0100471 i915_vma_unpin_and_release(&engine->scratch);
Chris Wilsonadc320c2016-08-15 10:48:59 +0100472}
473
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100474static void cleanup_phys_status_page(struct intel_engine_cs *engine)
475{
476 struct drm_i915_private *dev_priv = engine->i915;
477
478 if (!dev_priv->status_page_dmah)
479 return;
480
481 drm_pci_free(&dev_priv->drm, dev_priv->status_page_dmah);
482 engine->status_page.page_addr = NULL;
483}
484
485static void cleanup_status_page(struct intel_engine_cs *engine)
486{
487 struct i915_vma *vma;
488 struct drm_i915_gem_object *obj;
489
490 vma = fetch_and_zero(&engine->status_page.vma);
491 if (!vma)
492 return;
493
494 obj = vma->obj;
495
496 i915_vma_unpin(vma);
497 i915_vma_close(vma);
498
499 i915_gem_object_unpin_map(obj);
500 __i915_gem_object_release_unless_active(obj);
501}
502
503static int init_status_page(struct intel_engine_cs *engine)
504{
505 struct drm_i915_gem_object *obj;
506 struct i915_vma *vma;
507 unsigned int flags;
508 void *vaddr;
509 int ret;
510
511 obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE);
512 if (IS_ERR(obj)) {
513 DRM_ERROR("Failed to allocate status page\n");
514 return PTR_ERR(obj);
515 }
516
517 ret = i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
518 if (ret)
519 goto err;
520
521 vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL);
522 if (IS_ERR(vma)) {
523 ret = PTR_ERR(vma);
524 goto err;
525 }
526
527 flags = PIN_GLOBAL;
528 if (!HAS_LLC(engine->i915))
529 /* On g33, we cannot place HWS above 256MiB, so
530 * restrict its pinning to the low mappable arena.
531 * Though this restriction is not documented for
532 * gen4, gen5, or byt, they also behave similarly
533 * and hang if the HWS is placed at the top of the
534 * GTT. To generalise, it appears that all !llc
535 * platforms have issues with us placing the HWS
536 * above the mappable region (even though we never
537 * actually map it).
538 */
539 flags |= PIN_MAPPABLE;
Chris Wilson34a04e52017-09-13 09:56:03 +0100540 else
541 flags |= PIN_HIGH;
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100542 ret = i915_vma_pin(vma, 0, 4096, flags);
543 if (ret)
544 goto err;
545
546 vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
547 if (IS_ERR(vaddr)) {
548 ret = PTR_ERR(vaddr);
549 goto err_unpin;
550 }
551
552 engine->status_page.vma = vma;
553 engine->status_page.ggtt_offset = i915_ggtt_offset(vma);
554 engine->status_page.page_addr = memset(vaddr, 0, PAGE_SIZE);
555
556 DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n",
557 engine->name, i915_ggtt_offset(vma));
558 return 0;
559
560err_unpin:
561 i915_vma_unpin(vma);
562err:
563 i915_gem_object_put(obj);
564 return ret;
565}
566
567static int init_phys_status_page(struct intel_engine_cs *engine)
568{
569 struct drm_i915_private *dev_priv = engine->i915;
570
571 GEM_BUG_ON(engine->id != RCS);
572
573 dev_priv->status_page_dmah =
574 drm_pci_alloc(&dev_priv->drm, PAGE_SIZE, PAGE_SIZE);
575 if (!dev_priv->status_page_dmah)
576 return -ENOMEM;
577
578 engine->status_page.page_addr = dev_priv->status_page_dmah->vaddr;
579 memset(engine->status_page.page_addr, 0, PAGE_SIZE);
580
581 return 0;
582}
583
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100584/**
585 * intel_engines_init_common - initialize cengine state which might require hw access
586 * @engine: Engine to initialize.
587 *
588 * Initializes @engine@ structure members shared between legacy and execlists
589 * submission modes which do require hardware access.
590 *
591 * Typcally done at later stages of submission mode specific engine setup.
592 *
593 * Returns zero on success or an error code on failure.
594 */
595int intel_engine_init_common(struct intel_engine_cs *engine)
596{
Chris Wilson266a2402017-05-04 10:33:08 +0100597 struct intel_ring *ring;
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100598 int ret;
599
Chris Wilsonff44ad52017-03-16 17:13:03 +0000600 engine->set_default_submission(engine);
601
Chris Wilsone8a9c582016-12-18 15:37:20 +0000602 /* We may need to do things with the shrinker which
603 * require us to immediately switch back to the default
604 * context. This can cause a problem as pinning the
605 * default context also requires GTT space which may not
606 * be available. To avoid this we always pin the default
607 * context.
608 */
Chris Wilson266a2402017-05-04 10:33:08 +0100609 ring = engine->context_pin(engine, engine->i915->kernel_context);
610 if (IS_ERR(ring))
611 return PTR_ERR(ring);
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100612
Chris Wilsone7af3112017-10-03 21:34:48 +0100613 /*
614 * Similarly the preempt context must always be available so that
615 * we can interrupt the engine at any time.
616 */
Michał Winiarskia4598d12017-10-25 22:00:18 +0200617 if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) {
Chris Wilsone7af3112017-10-03 21:34:48 +0100618 ring = engine->context_pin(engine,
619 engine->i915->preempt_context);
620 if (IS_ERR(ring)) {
621 ret = PTR_ERR(ring);
622 goto err_unpin_kernel;
623 }
624 }
625
Chris Wilsone8a9c582016-12-18 15:37:20 +0000626 ret = intel_engine_init_breadcrumbs(engine);
627 if (ret)
Chris Wilsone7af3112017-10-03 21:34:48 +0100628 goto err_unpin_preempt;
Chris Wilsone8a9c582016-12-18 15:37:20 +0000629
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100630 if (HWS_NEEDS_PHYSICAL(engine->i915))
631 ret = init_phys_status_page(engine);
632 else
633 ret = init_status_page(engine);
634 if (ret)
Chris Wilson7c2fa7f2017-11-10 14:26:34 +0000635 goto err_breadcrumbs;
Chris Wilson4e50f082016-10-28 13:58:31 +0100636
Chris Wilson7756e452016-08-18 17:17:10 +0100637 return 0;
Chris Wilsone8a9c582016-12-18 15:37:20 +0000638
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100639err_breadcrumbs:
640 intel_engine_fini_breadcrumbs(engine);
Chris Wilsone7af3112017-10-03 21:34:48 +0100641err_unpin_preempt:
Michał Winiarskia4598d12017-10-25 22:00:18 +0200642 if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
Chris Wilsone7af3112017-10-03 21:34:48 +0100643 engine->context_unpin(engine, engine->i915->preempt_context);
644err_unpin_kernel:
Chris Wilsone8a9c582016-12-18 15:37:20 +0000645 engine->context_unpin(engine, engine->i915->kernel_context);
646 return ret;
Tvrtko Ursulin019bf272016-07-13 16:03:41 +0100647}
Chris Wilson96a945a2016-08-03 13:19:16 +0100648
649/**
650 * intel_engines_cleanup_common - cleans up the engine state created by
651 * the common initiailizers.
652 * @engine: Engine to cleanup.
653 *
654 * This cleans up everything created by the common helpers.
655 */
656void intel_engine_cleanup_common(struct intel_engine_cs *engine)
657{
Chris Wilsonadc320c2016-08-15 10:48:59 +0100658 intel_engine_cleanup_scratch(engine);
659
Daniele Ceraolo Spurio486e93f2017-09-13 09:56:02 +0100660 if (HWS_NEEDS_PHYSICAL(engine->i915))
661 cleanup_phys_status_page(engine);
662 else
663 cleanup_status_page(engine);
664
Chris Wilson96a945a2016-08-03 13:19:16 +0100665 intel_engine_fini_breadcrumbs(engine);
Chris Wilson7756e452016-08-18 17:17:10 +0100666 intel_engine_cleanup_cmd_parser(engine);
Chris Wilson96a945a2016-08-03 13:19:16 +0100667 i915_gem_batch_pool_fini(&engine->batch_pool);
Chris Wilsone8a9c582016-12-18 15:37:20 +0000668
Chris Wilsond2b4b972017-11-10 14:26:33 +0000669 if (engine->default_state)
670 i915_gem_object_put(engine->default_state);
671
Michał Winiarskia4598d12017-10-25 22:00:18 +0200672 if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
Chris Wilsone7af3112017-10-03 21:34:48 +0100673 engine->context_unpin(engine, engine->i915->preempt_context);
Chris Wilsone8a9c582016-12-18 15:37:20 +0000674 engine->context_unpin(engine, engine->i915->kernel_context);
Chris Wilson96a945a2016-08-03 13:19:16 +0100675}
Chris Wilson1b365952016-10-04 21:11:31 +0100676
677u64 intel_engine_get_active_head(struct intel_engine_cs *engine)
678{
679 struct drm_i915_private *dev_priv = engine->i915;
680 u64 acthd;
681
682 if (INTEL_GEN(dev_priv) >= 8)
683 acthd = I915_READ64_2x32(RING_ACTHD(engine->mmio_base),
684 RING_ACTHD_UDW(engine->mmio_base));
685 else if (INTEL_GEN(dev_priv) >= 4)
686 acthd = I915_READ(RING_ACTHD(engine->mmio_base));
687 else
688 acthd = I915_READ(ACTHD);
689
690 return acthd;
691}
692
693u64 intel_engine_get_last_batch_head(struct intel_engine_cs *engine)
694{
695 struct drm_i915_private *dev_priv = engine->i915;
696 u64 bbaddr;
697
698 if (INTEL_GEN(dev_priv) >= 8)
699 bbaddr = I915_READ64_2x32(RING_BBADDR(engine->mmio_base),
700 RING_BBADDR_UDW(engine->mmio_base));
701 else
702 bbaddr = I915_READ(RING_BBADDR(engine->mmio_base));
703
704 return bbaddr;
705}
Chris Wilson0e704472016-10-12 10:05:17 +0100706
707const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
708{
709 switch (type) {
710 case I915_CACHE_NONE: return " uncached";
711 case I915_CACHE_LLC: return HAS_LLC(i915) ? " LLC" : " snooped";
712 case I915_CACHE_L3_LLC: return " L3+LLC";
713 case I915_CACHE_WT: return " WT";
714 default: return "";
715 }
716}
717
718static inline uint32_t
719read_subslice_reg(struct drm_i915_private *dev_priv, int slice,
720 int subslice, i915_reg_t reg)
721{
722 uint32_t mcr;
723 uint32_t ret;
724 enum forcewake_domains fw_domains;
725
726 fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg,
727 FW_REG_READ);
728 fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
729 GEN8_MCR_SELECTOR,
730 FW_REG_READ | FW_REG_WRITE);
731
732 spin_lock_irq(&dev_priv->uncore.lock);
733 intel_uncore_forcewake_get__locked(dev_priv, fw_domains);
734
735 mcr = I915_READ_FW(GEN8_MCR_SELECTOR);
736 /*
737 * The HW expects the slice and sublice selectors to be reset to 0
738 * after reading out the registers.
739 */
740 WARN_ON_ONCE(mcr & (GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK));
741 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
742 mcr |= GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice);
743 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
744
745 ret = I915_READ_FW(reg);
746
747 mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
748 I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
749
750 intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
751 spin_unlock_irq(&dev_priv->uncore.lock);
752
753 return ret;
754}
755
756/* NB: please notice the memset */
757void intel_engine_get_instdone(struct intel_engine_cs *engine,
758 struct intel_instdone *instdone)
759{
760 struct drm_i915_private *dev_priv = engine->i915;
761 u32 mmio_base = engine->mmio_base;
762 int slice;
763 int subslice;
764
765 memset(instdone, 0, sizeof(*instdone));
766
767 switch (INTEL_GEN(dev_priv)) {
768 default:
769 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
770
771 if (engine->id != RCS)
772 break;
773
774 instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
775 for_each_instdone_slice_subslice(dev_priv, slice, subslice) {
776 instdone->sampler[slice][subslice] =
777 read_subslice_reg(dev_priv, slice, subslice,
778 GEN7_SAMPLER_INSTDONE);
779 instdone->row[slice][subslice] =
780 read_subslice_reg(dev_priv, slice, subslice,
781 GEN7_ROW_INSTDONE);
782 }
783 break;
784 case 7:
785 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
786
787 if (engine->id != RCS)
788 break;
789
790 instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
791 instdone->sampler[0][0] = I915_READ(GEN7_SAMPLER_INSTDONE);
792 instdone->row[0][0] = I915_READ(GEN7_ROW_INSTDONE);
793
794 break;
795 case 6:
796 case 5:
797 case 4:
798 instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
799
800 if (engine->id == RCS)
801 /* HACK: Using the wrong struct member */
802 instdone->slice_common = I915_READ(GEN4_INSTDONE1);
803 break;
804 case 3:
805 case 2:
806 instdone->instdone = I915_READ(GEN2_INSTDONE);
807 break;
808 }
809}
Chris Wilsonf97fbf92017-02-13 17:15:14 +0000810
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000811static int wa_add(struct drm_i915_private *dev_priv,
812 i915_reg_t addr,
813 const u32 mask, const u32 val)
814{
815 const u32 idx = dev_priv->workarounds.count;
816
817 if (WARN_ON(idx >= I915_MAX_WA_REGS))
818 return -ENOSPC;
819
820 dev_priv->workarounds.reg[idx].addr = addr;
821 dev_priv->workarounds.reg[idx].value = val;
822 dev_priv->workarounds.reg[idx].mask = mask;
823
824 dev_priv->workarounds.count++;
825
826 return 0;
827}
828
829#define WA_REG(addr, mask, val) do { \
830 const int r = wa_add(dev_priv, (addr), (mask), (val)); \
831 if (r) \
832 return r; \
833 } while (0)
834
835#define WA_SET_BIT_MASKED(addr, mask) \
836 WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
837
838#define WA_CLR_BIT_MASKED(addr, mask) \
839 WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
840
841#define WA_SET_FIELD_MASKED(addr, mask, value) \
842 WA_REG(addr, mask, _MASKED_FIELD(mask, value))
843
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000844static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
845 i915_reg_t reg)
846{
847 struct drm_i915_private *dev_priv = engine->i915;
848 struct i915_workarounds *wa = &dev_priv->workarounds;
849 const uint32_t index = wa->hw_whitelist_count[engine->id];
850
851 if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
852 return -EINVAL;
853
Oscar Mateo32ced392017-09-28 15:40:39 -0700854 I915_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
855 i915_mmio_reg_offset(reg));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000856 wa->hw_whitelist_count[engine->id]++;
857
858 return 0;
859}
860
861static int gen8_init_workarounds(struct intel_engine_cs *engine)
862{
863 struct drm_i915_private *dev_priv = engine->i915;
864
865 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
866
867 /* WaDisableAsyncFlipPerfMode:bdw,chv */
868 WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
869
870 /* WaDisablePartialInstShootdown:bdw,chv */
871 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
872 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
873
874 /* Use Force Non-Coherent whenever executing a 3D context. This is a
875 * workaround for for a possible hang in the unlikely event a TLB
876 * invalidation occurs during a PSD flush.
877 */
878 /* WaForceEnableNonCoherent:bdw,chv */
879 /* WaHdcDisableFetchWhenMasked:bdw,chv */
880 WA_SET_BIT_MASKED(HDC_CHICKEN0,
881 HDC_DONOT_FETCH_MEM_WHEN_MASKED |
882 HDC_FORCE_NON_COHERENT);
883
884 /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
885 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
886 * polygons in the same 8x4 pixel/sample area to be processed without
887 * stalling waiting for the earlier ones to write to Hierarchical Z
888 * buffer."
889 *
890 * This optimization is off by default for BDW and CHV; turn it on.
891 */
892 WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
893
894 /* Wa4x4STCOptimizationDisable:bdw,chv */
895 WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
896
897 /*
898 * BSpec recommends 8x4 when MSAA is used,
899 * however in practice 16x4 seems fastest.
900 *
901 * Note that PS/WM thread counts depend on the WIZ hashing
902 * disable bit, which we don't touch here, but it's good
903 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
904 */
905 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
906 GEN6_WIZ_HASHING_MASK,
907 GEN6_WIZ_HASHING_16x4);
908
909 return 0;
910}
911
912static int bdw_init_workarounds(struct intel_engine_cs *engine)
913{
914 struct drm_i915_private *dev_priv = engine->i915;
915 int ret;
916
917 ret = gen8_init_workarounds(engine);
918 if (ret)
919 return ret;
920
921 /* WaDisableThreadStallDopClockGating:bdw (pre-production) */
922 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
923
924 /* WaDisableDopClockGating:bdw
925 *
926 * Also see the related UCGTCL1 write in broadwell_init_clock_gating()
927 * to disable EUTC clock gating.
928 */
929 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
930 DOP_CLOCK_GATING_DISABLE);
931
932 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
933 GEN8_SAMPLER_POWER_BYPASS_DIS);
934
935 WA_SET_BIT_MASKED(HDC_CHICKEN0,
936 /* WaForceContextSaveRestoreNonCoherent:bdw */
937 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
938 /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
939 (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
940
941 return 0;
942}
943
944static int chv_init_workarounds(struct intel_engine_cs *engine)
945{
946 struct drm_i915_private *dev_priv = engine->i915;
947 int ret;
948
949 ret = gen8_init_workarounds(engine);
950 if (ret)
951 return ret;
952
953 /* WaDisableThreadStallDopClockGating:chv */
954 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
955
956 /* Improve HiZ throughput on CHV. */
957 WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
958
959 return 0;
960}
961
962static int gen9_init_workarounds(struct intel_engine_cs *engine)
963{
964 struct drm_i915_private *dev_priv = engine->i915;
965 int ret;
966
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700967 /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000968 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
969
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700970 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000971 I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
972 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
973
Rodrigo Vivi98eed3d2017-06-19 14:21:47 -0700974 /* WaDisableKillLogic:bxt,skl,kbl */
975 if (!IS_COFFEELAKE(dev_priv))
976 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
977 ECOCHK_DIS_TLB);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000978
Ville Syrjälä93564042017-08-24 22:10:51 +0300979 if (HAS_LLC(dev_priv)) {
980 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
981 *
982 * Must match Display Engine. See
983 * WaCompressedResourceDisplayNewHashMode.
984 */
985 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
986 GEN9_PBE_COMPRESSED_HASH_SELECTION);
987 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
988 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);
Chris Wilson53221e12017-10-04 13:41:52 +0100989
990 I915_WRITE(MMCD_MISC_CTRL,
991 I915_READ(MMCD_MISC_CTRL) |
992 MMCD_PCLA |
993 MMCD_HOTSPOT_EN);
Ville Syrjälä93564042017-08-24 22:10:51 +0300994 }
995
Rodrigo Vivi46c26662017-06-16 15:49:58 -0700996 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
997 /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +0000998 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
999 FLOW_CONTROL_ENABLE |
1000 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
1001
1002 /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001003 if (!IS_COFFEELAKE(dev_priv))
1004 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
1005 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001006
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001007 /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */
1008 /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001009 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
Arkadiusz Hiler0b71cea2017-05-12 13:20:15 +02001010 GEN9_ENABLE_YV12_BUGFIX |
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001011 GEN9_ENABLE_GPGPU_PREEMPTION);
1012
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001013 /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */
1014 /* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001015 WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
1016 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
1017
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001018 /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001019 WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
1020 GEN9_CCS_TLB_PREFETCH_ENABLE);
1021
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001022 /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001023 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1024 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
1025 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
1026
1027 /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
1028 * both tied to WaForceContextSaveRestoreNonCoherent
1029 * in some hsds for skl. We keep the tie for all gen9. The
1030 * documentation is a bit hazy and so we want to get common behaviour,
1031 * even though there is no clear evidence we would need both on kbl/bxt.
1032 * This area has been source of system hangs so we play it safe
1033 * and mimic the skl regardless of what bspec says.
1034 *
1035 * Use Force Non-Coherent whenever executing a 3D context. This
1036 * is a workaround for a possible hang in the unlikely event
1037 * a TLB invalidation occurs during a PSD flush.
1038 */
1039
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001040 /* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001041 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1042 HDC_FORCE_NON_COHERENT);
1043
Rodrigo Vivi98eed3d2017-06-19 14:21:47 -07001044 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
1045 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
1046 BDW_DISABLE_HDC_INVALIDATION);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001047
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001048 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001049 if (IS_SKYLAKE(dev_priv) ||
1050 IS_KABYLAKE(dev_priv) ||
Chris Wilsonf3e2b2c2017-11-14 13:43:39 +00001051 IS_COFFEELAKE(dev_priv))
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001052 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
1053 GEN8_SAMPLER_POWER_BYPASS_DIS);
1054
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001055 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001056 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
1057
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001058 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001059 I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
1060 GEN8_LQSC_FLUSH_COHERENT_LINES));
1061
Michał Winiarski5152def2017-10-03 21:34:46 +01001062 /*
1063 * Supporting preemption with fine-granularity requires changes in the
1064 * batch buffer programming. Since we can't break old userspace, we
1065 * need to set our default preemption level to safe value. Userspace is
1066 * still able to use more fine-grained preemption levels, since in
1067 * WaEnablePreemptionGranularityControlByUMD we're whitelisting the
1068 * per-ctx register. As such, WaDisable{3D,GPGPU}MidCmdPreemption are
1069 * not real HW workarounds, but merely a way to start using preemption
1070 * while maintaining old contract with userspace.
1071 */
1072
1073 /* WaDisable3DMidCmdPreemption:skl,bxt,glk,cfl,[cnl] */
1074 WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL);
1075
1076 /* WaDisableGPGPUMidCmdPreemption:skl,bxt,blk,cfl,[cnl] */
1077 WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK,
1078 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
1079
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001080 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001081 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
1082 if (ret)
1083 return ret;
1084
Jeff McGee1e998342017-10-03 21:34:45 +01001085 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
1086 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1087 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
1088 ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001089 if (ret)
1090 return ret;
1091
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001092 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001093 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
1094 if (ret)
1095 return ret;
1096
1097 return 0;
1098}
1099
1100static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
1101{
1102 struct drm_i915_private *dev_priv = engine->i915;
1103 u8 vals[3] = { 0, 0, 0 };
1104 unsigned int i;
1105
1106 for (i = 0; i < 3; i++) {
1107 u8 ss;
1108
1109 /*
1110 * Only consider slices where one, and only one, subslice has 7
1111 * EUs
1112 */
1113 if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
1114 continue;
1115
1116 /*
1117 * subslice_7eu[i] != 0 (because of the check above) and
1118 * ss_max == 4 (maximum number of subslices possible per slice)
1119 *
1120 * -> 0 <= ss <= 3;
1121 */
1122 ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
1123 vals[i] = 3 - ss;
1124 }
1125
1126 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
1127 return 0;
1128
1129 /* Tune IZ hashing. See intel_device_info_runtime_init() */
1130 WA_SET_FIELD_MASKED(GEN7_GT_MODE,
1131 GEN9_IZ_HASHING_MASK(2) |
1132 GEN9_IZ_HASHING_MASK(1) |
1133 GEN9_IZ_HASHING_MASK(0),
1134 GEN9_IZ_HASHING(2, vals[2]) |
1135 GEN9_IZ_HASHING(1, vals[1]) |
1136 GEN9_IZ_HASHING(0, vals[0]));
1137
1138 return 0;
1139}
1140
1141static int skl_init_workarounds(struct intel_engine_cs *engine)
1142{
1143 struct drm_i915_private *dev_priv = engine->i915;
1144 int ret;
1145
1146 ret = gen9_init_workarounds(engine);
1147 if (ret)
1148 return ret;
1149
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001150 /* 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;
Chris Wilson70a84f32017-11-14 13:43:40 +00001175 u32 val;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001176 int ret;
1177
1178 ret = gen9_init_workarounds(engine);
1179 if (ret)
1180 return ret;
1181
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001182 /* WaDisableThreadStallDopClockGating:bxt */
1183 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
1184 STALL_DOP_GATING_DISABLE);
1185
1186 /* WaDisablePooledEuLoadBalancingFix:bxt */
Chris Wilson70a84f32017-11-14 13:43:40 +00001187 I915_WRITE(FF_SLICE_CS_CHICKEN2,
1188 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001189
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001190 /* WaProgramL3SqcReg1DefaultForPerf:bxt */
Chris Wilson70a84f32017-11-14 13:43:40 +00001191 val = I915_READ(GEN8_L3SQCREG1);
1192 val &= ~L3_PRIO_CREDITS_MASK;
1193 val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
1194 I915_WRITE(GEN8_L3SQCREG1, val);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001195
1196 /* WaToEnableHwFixForPushConstHWBug:bxt */
Chris Wilson70a84f32017-11-14 13:43:40 +00001197 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1198 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001199
1200 /* WaInPlaceDecompressionHang:bxt */
Chris Wilson70a84f32017-11-14 13:43:40 +00001201 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1202 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1203 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001204
1205 return 0;
1206}
1207
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001208static int cnl_init_workarounds(struct intel_engine_cs *engine)
1209{
1210 struct drm_i915_private *dev_priv = engine->i915;
1211 int ret;
1212
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001213 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001214 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
Oscar Mateo6cf20a02017-09-07 08:40:05 -07001215 I915_WRITE(GAMT_CHKN_BIT_REG,
1216 (I915_READ(GAMT_CHKN_BIT_REG) |
1217 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT));
Rodrigo Vivi86ebb012017-08-29 16:07:51 -07001218
Rodrigo Viviacfb5552017-08-23 13:35:04 -07001219 /* WaForceContextSaveRestoreNonCoherent:cnl */
1220 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0,
1221 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT);
1222
Rodrigo Viviaa9f4c42017-09-06 15:03:25 -07001223 /* WaThrottleEUPerfToAvoidTDBackPressure:cnl(pre-prod) */
1224 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
1225 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, THROTTLE_12_5);
1226
Rodrigo Vivie6d1a4f2017-08-15 16:16:49 -07001227 /* WaDisableReplayBufferBankArbitrationOptimization:cnl */
1228 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1229 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1230
Rodrigo Vivid1d24752017-08-15 16:16:50 -07001231 /* WaDisableEnhancedSBEVertexCaching:cnl (pre-prod) */
1232 if (IS_CNL_REVID(dev_priv, 0, CNL_REVID_B0))
1233 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1234 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE);
1235
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001236 /* WaInPlaceDecompressionHang:cnl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001237 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1238 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1239 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001240
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001241 /* WaPushConstantDereferenceHoldDisable:cnl */
Oscar Mateob27f5902017-09-07 08:40:06 -07001242 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE);
Oscar Mateo2cbecff2017-08-23 12:56:31 -07001243
Rodrigo Vivi392572f2017-08-29 16:07:23 -07001244 /* FtrEnableFastAnisoL1BankingFix: cnl */
1245 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX);
1246
Michał Winiarski5152def2017-10-03 21:34:46 +01001247 /* WaDisable3DMidCmdPreemption:cnl */
1248 WA_CLR_BIT_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL);
1249
1250 /* WaDisableGPGPUMidCmdPreemption:cnl */
1251 WA_SET_FIELD_MASKED(GEN8_CS_CHICKEN1, GEN9_PREEMPT_GPGPU_LEVEL_MASK,
1252 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
1253
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001254 /* WaEnablePreemptionGranularityControlByUMD:cnl */
Jeff McGee1e998342017-10-03 21:34:45 +01001255 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
1256 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001257 ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
1258 if (ret)
1259 return ret;
1260
1261 return 0;
1262}
1263
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001264static int kbl_init_workarounds(struct intel_engine_cs *engine)
1265{
1266 struct drm_i915_private *dev_priv = engine->i915;
1267 int ret;
1268
1269 ret = gen9_init_workarounds(engine);
1270 if (ret)
1271 return ret;
1272
1273 /* WaEnableGapsTsvCreditFix:kbl */
1274 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1275 GEN9_GAPS_TSV_CREDIT_DISABLE));
1276
1277 /* WaDisableDynamicCreditSharing:kbl */
1278 if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
Oscar Mateoc6ea497c2017-09-07 08:40:08 -07001279 I915_WRITE(GAMT_CHKN_BIT_REG,
1280 (I915_READ(GAMT_CHKN_BIT_REG) |
1281 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001282
1283 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
1284 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
1285 WA_SET_BIT_MASKED(HDC_CHICKEN0,
1286 HDC_FENCE_DEST_SLM_DISABLE);
1287
1288 /* WaToEnableHwFixForPushConstHWBug:kbl */
1289 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
1290 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1291 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1292
1293 /* WaDisableGafsUnitClkGating:kbl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001294 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1295 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001296
1297 /* WaDisableSbeCacheDispatchPortSharing:kbl */
1298 WA_SET_BIT_MASKED(
1299 GEN7_HALF_SLICE_CHICKEN1,
1300 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1301
1302 /* WaInPlaceDecompressionHang:kbl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001303 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1304 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1305 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001306
1307 /* WaDisableLSQCROPERFforOCL:kbl */
1308 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
1309 if (ret)
1310 return ret;
1311
1312 return 0;
1313}
1314
1315static int glk_init_workarounds(struct intel_engine_cs *engine)
1316{
1317 struct drm_i915_private *dev_priv = engine->i915;
1318 int ret;
1319
1320 ret = gen9_init_workarounds(engine);
1321 if (ret)
1322 return ret;
1323
1324 /* WaToEnableHwFixForPushConstHWBug:glk */
1325 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1326 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1327
1328 return 0;
1329}
1330
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001331static int cfl_init_workarounds(struct intel_engine_cs *engine)
1332{
1333 struct drm_i915_private *dev_priv = engine->i915;
1334 int ret;
1335
1336 ret = gen9_init_workarounds(engine);
1337 if (ret)
1338 return ret;
1339
1340 /* WaEnableGapsTsvCreditFix:cfl */
1341 I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
1342 GEN9_GAPS_TSV_CREDIT_DISABLE));
1343
1344 /* WaToEnableHwFixForPushConstHWBug:cfl */
1345 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
1346 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
1347
1348 /* WaDisableGafsUnitClkGating:cfl */
Oscar Mateo4827c542017-09-07 08:40:07 -07001349 I915_WRITE(GEN7_UCGCTL4, (I915_READ(GEN7_UCGCTL4) |
1350 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001351
1352 /* WaDisableSbeCacheDispatchPortSharing:cfl */
1353 WA_SET_BIT_MASKED(
1354 GEN7_HALF_SLICE_CHICKEN1,
1355 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
1356
1357 /* WaInPlaceDecompressionHang:cfl */
Oscar Mateoefc886c2017-09-07 08:40:04 -07001358 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
1359 (I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
1360 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS));
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001361
1362 return 0;
1363}
1364
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001365int init_workarounds_ring(struct intel_engine_cs *engine)
1366{
1367 struct drm_i915_private *dev_priv = engine->i915;
Chris Wilson02e012f2017-03-01 12:11:31 +00001368 int err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001369
1370 WARN_ON(engine->id != RCS);
1371
1372 dev_priv->workarounds.count = 0;
Chris Wilson02e012f2017-03-01 12:11:31 +00001373 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001374
1375 if (IS_BROADWELL(dev_priv))
Chris Wilson02e012f2017-03-01 12:11:31 +00001376 err = bdw_init_workarounds(engine);
1377 else if (IS_CHERRYVIEW(dev_priv))
1378 err = chv_init_workarounds(engine);
1379 else if (IS_SKYLAKE(dev_priv))
1380 err = skl_init_workarounds(engine);
1381 else if (IS_BROXTON(dev_priv))
1382 err = bxt_init_workarounds(engine);
1383 else if (IS_KABYLAKE(dev_priv))
1384 err = kbl_init_workarounds(engine);
1385 else if (IS_GEMINILAKE(dev_priv))
1386 err = glk_init_workarounds(engine);
Rodrigo Vivi46c26662017-06-16 15:49:58 -07001387 else if (IS_COFFEELAKE(dev_priv))
1388 err = cfl_init_workarounds(engine);
Rodrigo Vivi90007bc2017-08-15 16:16:48 -07001389 else if (IS_CANNONLAKE(dev_priv))
1390 err = cnl_init_workarounds(engine);
Chris Wilson02e012f2017-03-01 12:11:31 +00001391 else
1392 err = 0;
1393 if (err)
1394 return err;
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001395
Chris Wilson02e012f2017-03-01 12:11:31 +00001396 DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n",
1397 engine->name, dev_priv->workarounds.count);
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001398 return 0;
1399}
1400
1401int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)
1402{
1403 struct i915_workarounds *w = &req->i915->workarounds;
1404 u32 *cs;
1405 int ret, i;
1406
1407 if (w->count == 0)
1408 return 0;
1409
1410 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1411 if (ret)
1412 return ret;
1413
1414 cs = intel_ring_begin(req, (w->count * 2 + 2));
1415 if (IS_ERR(cs))
1416 return PTR_ERR(cs);
1417
1418 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
1419 for (i = 0; i < w->count; i++) {
1420 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
1421 *cs++ = w->reg[i].value;
1422 }
1423 *cs++ = MI_NOOP;
1424
1425 intel_ring_advance(req, cs);
1426
1427 ret = req->engine->emit_flush(req, EMIT_BARRIER);
1428 if (ret)
1429 return ret;
1430
Tvrtko Ursulin133b4bd2017-02-16 12:23:23 +00001431 return 0;
1432}
1433
Chris Wilsona091d4e2017-05-30 13:13:33 +01001434static bool ring_is_idle(struct intel_engine_cs *engine)
1435{
1436 struct drm_i915_private *dev_priv = engine->i915;
1437 bool idle = true;
1438
1439 intel_runtime_pm_get(dev_priv);
1440
Chris Wilsonaed2fc12017-05-30 13:13:34 +01001441 /* First check that no commands are left in the ring */
1442 if ((I915_READ_HEAD(engine) & HEAD_ADDR) !=
1443 (I915_READ_TAIL(engine) & TAIL_ADDR))
1444 idle = false;
1445
Chris Wilsona091d4e2017-05-30 13:13:33 +01001446 /* No bit for gen2, so assume the CS parser is idle */
1447 if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE))
1448 idle = false;
1449
1450 intel_runtime_pm_put(dev_priv);
1451
1452 return idle;
1453}
1454
Chris Wilson54003672017-03-03 12:19:46 +00001455/**
1456 * intel_engine_is_idle() - Report if the engine has finished process all work
1457 * @engine: the intel_engine_cs
1458 *
1459 * Return true if there are no requests pending, nothing left to be submitted
1460 * to hardware, and that the engine is idle.
1461 */
1462bool intel_engine_is_idle(struct intel_engine_cs *engine)
1463{
1464 struct drm_i915_private *dev_priv = engine->i915;
1465
Chris Wilsona8e9a412017-04-11 20:00:42 +01001466 /* More white lies, if wedged, hw state is inconsistent */
1467 if (i915_terminally_wedged(&dev_priv->gpu_error))
1468 return true;
1469
Chris Wilson54003672017-03-03 12:19:46 +00001470 /* Any inflight/incomplete requests? */
1471 if (!i915_seqno_passed(intel_engine_get_seqno(engine),
1472 intel_engine_last_submit(engine)))
1473 return false;
1474
Chris Wilson8968a362017-04-12 00:44:26 +01001475 if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))
1476 return true;
1477
Chris Wilson54003672017-03-03 12:19:46 +00001478 /* Interrupt/tasklet pending? */
1479 if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
1480 return false;
1481
Chris Wilson4a118ec2017-10-23 22:32:36 +01001482 /* Waiting to drain ELSP? */
1483 if (READ_ONCE(engine->execlists.active))
Chris Wilson54003672017-03-03 12:19:46 +00001484 return false;
1485
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001486 /* ELSP is empty, but there are ready requests? */
Mika Kuoppalab620e872017-09-22 15:43:03 +03001487 if (READ_ONCE(engine->execlists.first))
Chris Wilsond6edb6e2017-07-21 13:32:24 +01001488 return false;
1489
Chris Wilson54003672017-03-03 12:19:46 +00001490 /* Ring stopped? */
Chris Wilsona091d4e2017-05-30 13:13:33 +01001491 if (!ring_is_idle(engine))
Chris Wilson54003672017-03-03 12:19:46 +00001492 return false;
1493
1494 return true;
1495}
1496
Chris Wilson05425242017-03-03 12:19:47 +00001497bool intel_engines_are_idle(struct drm_i915_private *dev_priv)
1498{
1499 struct intel_engine_cs *engine;
1500 enum intel_engine_id id;
1501
Chris Wilson8490ae202017-03-30 15:50:37 +01001502 if (READ_ONCE(dev_priv->gt.active_requests))
1503 return false;
1504
1505 /* If the driver is wedged, HW state may be very inconsistent and
1506 * report that it is still busy, even though we have stopped using it.
1507 */
1508 if (i915_terminally_wedged(&dev_priv->gpu_error))
1509 return true;
1510
Chris Wilson05425242017-03-03 12:19:47 +00001511 for_each_engine(engine, dev_priv, id) {
1512 if (!intel_engine_is_idle(engine))
1513 return false;
1514 }
1515
1516 return true;
1517}
1518
Chris Wilsonae6c4572017-11-10 14:26:28 +00001519/**
1520 * intel_engine_has_kernel_context:
1521 * @engine: the engine
1522 *
1523 * Returns true if the last context to be executed on this engine, or has been
1524 * executed if the engine is already idle, is the kernel context
1525 * (#i915.kernel_context).
1526 */
Chris Wilson20ccd4d2017-10-24 23:08:55 +01001527bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine)
1528{
Chris Wilsonae6c4572017-11-10 14:26:28 +00001529 const struct i915_gem_context * const kernel_context =
1530 engine->i915->kernel_context;
1531 struct drm_i915_gem_request *rq;
1532
1533 lockdep_assert_held(&engine->i915->drm.struct_mutex);
1534
1535 /*
1536 * Check the last context seen by the engine. If active, it will be
1537 * the last request that remains in the timeline. When idle, it is
1538 * the last executed context as tracked by retirement.
1539 */
1540 rq = __i915_gem_active_peek(&engine->timeline->last_request);
1541 if (rq)
1542 return rq->ctx == kernel_context;
1543 else
1544 return engine->last_retired_context == kernel_context;
Chris Wilson20ccd4d2017-10-24 23:08:55 +01001545}
1546
Chris Wilsonff44ad52017-03-16 17:13:03 +00001547void intel_engines_reset_default_submission(struct drm_i915_private *i915)
1548{
1549 struct intel_engine_cs *engine;
1550 enum intel_engine_id id;
1551
1552 for_each_engine(engine, i915, id)
1553 engine->set_default_submission(engine);
1554}
1555
Chris Wilsonaba5e272017-10-25 15:39:41 +01001556/**
1557 * intel_engines_park: called when the GT is transitioning from busy->idle
1558 * @i915: the i915 device
1559 *
1560 * The GT is now idle and about to go to sleep (maybe never to wake again?).
1561 * Time for us to tidy and put away our toys (release resources back to the
1562 * system).
1563 */
1564void intel_engines_park(struct drm_i915_private *i915)
Chris Wilson6c067572017-05-17 13:10:03 +01001565{
1566 struct intel_engine_cs *engine;
1567 enum intel_engine_id id;
1568
1569 for_each_engine(engine, i915, id) {
Chris Wilson820c5bb2017-11-01 20:21:49 +00001570 /* Flush the residual irq tasklets first. */
1571 intel_engine_disarm_breadcrumbs(engine);
Sagar Arun Kamblec6dce8f2017-11-16 19:02:37 +05301572 tasklet_kill(&engine->execlists.tasklet);
Chris Wilson820c5bb2017-11-01 20:21:49 +00001573
Chris Wilson32651242017-10-27 12:06:17 +01001574 /*
1575 * We are committed now to parking the engines, make sure there
1576 * will be no more interrupts arriving later and the engines
1577 * are truly idle.
1578 */
Chris Wilson30b29402017-11-10 11:25:50 +00001579 if (wait_for(intel_engine_is_idle(engine), 10)) {
Chris Wilson32651242017-10-27 12:06:17 +01001580 struct drm_printer p = drm_debug_printer(__func__);
1581
Chris Wilson30b29402017-11-10 11:25:50 +00001582 dev_err(i915->drm.dev,
1583 "%s is not idle before parking\n",
1584 engine->name);
Chris Wilson32651242017-10-27 12:06:17 +01001585 intel_engine_dump(engine, &p);
1586 }
1587
Chris Wilsonaba5e272017-10-25 15:39:41 +01001588 if (engine->park)
1589 engine->park(engine);
1590
Chris Wilsonaba5e272017-10-25 15:39:41 +01001591 i915_gem_batch_pool_fini(&engine->batch_pool);
Mika Kuoppalab620e872017-09-22 15:43:03 +03001592 engine->execlists.no_priolist = false;
Chris Wilson6c067572017-05-17 13:10:03 +01001593 }
1594}
1595
Chris Wilsonaba5e272017-10-25 15:39:41 +01001596/**
1597 * intel_engines_unpark: called when the GT is transitioning from idle->busy
1598 * @i915: the i915 device
1599 *
1600 * The GT was idle and now about to fire up with some new user requests.
1601 */
1602void intel_engines_unpark(struct drm_i915_private *i915)
1603{
1604 struct intel_engine_cs *engine;
1605 enum intel_engine_id id;
1606
1607 for_each_engine(engine, i915, id) {
1608 if (engine->unpark)
1609 engine->unpark(engine);
1610 }
1611}
1612
Chris Wilson90cad092017-09-06 16:28:59 +01001613bool intel_engine_can_store_dword(struct intel_engine_cs *engine)
1614{
1615 switch (INTEL_GEN(engine->i915)) {
1616 case 2:
1617 return false; /* uses physical not virtual addresses */
1618 case 3:
1619 /* maybe only uses physical not virtual addresses */
1620 return !(IS_I915G(engine->i915) || IS_I915GM(engine->i915));
1621 case 6:
1622 return engine->class != VIDEO_DECODE_CLASS; /* b0rked */
1623 default:
1624 return true;
1625 }
1626}
1627
Chris Wilsond2b4b972017-11-10 14:26:33 +00001628unsigned int intel_engines_has_context_isolation(struct drm_i915_private *i915)
1629{
1630 struct intel_engine_cs *engine;
1631 enum intel_engine_id id;
1632 unsigned int which;
1633
1634 which = 0;
1635 for_each_engine(engine, i915, id)
1636 if (engine->default_state)
1637 which |= BIT(engine->uabi_class);
1638
1639 return which;
1640}
1641
Chris Wilsonf636edb2017-10-09 12:02:57 +01001642static void print_request(struct drm_printer *m,
1643 struct drm_i915_gem_request *rq,
1644 const char *prefix)
1645{
Chris Wilsona27d5a42017-10-15 21:43:10 +01001646 drm_printf(m, "%s%x%s [%x:%x] prio=%d @ %dms: %s\n", prefix,
1647 rq->global_seqno,
1648 i915_gem_request_completed(rq) ? "!" : "",
1649 rq->ctx->hw_id, rq->fence.seqno,
Chris Wilsonf636edb2017-10-09 12:02:57 +01001650 rq->priotree.priority,
1651 jiffies_to_msecs(jiffies - rq->emitted_jiffies),
1652 rq->timeline->common->name);
1653}
1654
1655void intel_engine_dump(struct intel_engine_cs *engine, struct drm_printer *m)
1656{
Chris Wilsona27d5a42017-10-15 21:43:10 +01001657 struct intel_breadcrumbs * const b = &engine->breadcrumbs;
1658 const struct intel_engine_execlists * const execlists = &engine->execlists;
1659 struct i915_gpu_error * const error = &engine->i915->gpu_error;
Chris Wilsonf636edb2017-10-09 12:02:57 +01001660 struct drm_i915_private *dev_priv = engine->i915;
1661 struct drm_i915_gem_request *rq;
1662 struct rb_node *rb;
1663 u64 addr;
1664
1665 drm_printf(m, "%s\n", engine->name);
1666 drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n",
1667 intel_engine_get_seqno(engine),
1668 intel_engine_last_submit(engine),
1669 engine->hangcheck.seqno,
1670 jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
1671 engine->timeline->inflight_seqnos);
1672 drm_printf(m, "\tReset count: %d\n",
1673 i915_reset_engine_count(error, engine));
1674
1675 rcu_read_lock();
1676
1677 drm_printf(m, "\tRequests:\n");
1678
1679 rq = list_first_entry(&engine->timeline->requests,
1680 struct drm_i915_gem_request, link);
1681 if (&rq->link != &engine->timeline->requests)
1682 print_request(m, rq, "\t\tfirst ");
1683
1684 rq = list_last_entry(&engine->timeline->requests,
1685 struct drm_i915_gem_request, link);
1686 if (&rq->link != &engine->timeline->requests)
1687 print_request(m, rq, "\t\tlast ");
1688
1689 rq = i915_gem_find_active_request(engine);
1690 if (rq) {
1691 print_request(m, rq, "\t\tactive ");
1692 drm_printf(m,
1693 "\t\t[head %04x, postfix %04x, tail %04x, batch 0x%08x_%08x]\n",
1694 rq->head, rq->postfix, rq->tail,
1695 rq->batch ? upper_32_bits(rq->batch->node.start) : ~0u,
1696 rq->batch ? lower_32_bits(rq->batch->node.start) : ~0u);
1697 }
1698
1699 drm_printf(m, "\tRING_START: 0x%08x [0x%08x]\n",
1700 I915_READ(RING_START(engine->mmio_base)),
1701 rq ? i915_ggtt_offset(rq->ring->vma) : 0);
1702 drm_printf(m, "\tRING_HEAD: 0x%08x [0x%08x]\n",
1703 I915_READ(RING_HEAD(engine->mmio_base)) & HEAD_ADDR,
1704 rq ? rq->ring->head : 0);
1705 drm_printf(m, "\tRING_TAIL: 0x%08x [0x%08x]\n",
1706 I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR,
1707 rq ? rq->ring->tail : 0);
Chris Wilson3c75de52017-10-26 12:50:48 +01001708 drm_printf(m, "\tRING_CTL: 0x%08x%s\n",
Chris Wilsonf636edb2017-10-09 12:02:57 +01001709 I915_READ(RING_CTL(engine->mmio_base)),
Chris Wilson3c75de52017-10-26 12:50:48 +01001710 I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? " [waiting]" : "");
1711 if (INTEL_GEN(engine->i915) > 2) {
1712 drm_printf(m, "\tRING_MODE: 0x%08x%s\n",
1713 I915_READ(RING_MI_MODE(engine->mmio_base)),
1714 I915_READ(RING_MI_MODE(engine->mmio_base)) & (MODE_IDLE) ? " [idle]" : "");
1715 }
Chris Wilsonaf9ff6c2017-11-20 20:55:03 +00001716 if (i915_modparams.semaphores) {
1717 drm_printf(m, "\tSYNC_0: 0x%08x\n",
1718 I915_READ(RING_SYNC_0(engine->mmio_base)));
1719 drm_printf(m, "\tSYNC_1: 0x%08x\n",
1720 I915_READ(RING_SYNC_1(engine->mmio_base)));
1721 if (HAS_VEBOX(dev_priv))
1722 drm_printf(m, "\tSYNC_2: 0x%08x\n",
1723 I915_READ(RING_SYNC_2(engine->mmio_base)));
1724 }
Chris Wilsonf636edb2017-10-09 12:02:57 +01001725
1726 rcu_read_unlock();
1727
1728 addr = intel_engine_get_active_head(engine);
1729 drm_printf(m, "\tACTHD: 0x%08x_%08x\n",
1730 upper_32_bits(addr), lower_32_bits(addr));
1731 addr = intel_engine_get_last_batch_head(engine);
1732 drm_printf(m, "\tBBADDR: 0x%08x_%08x\n",
1733 upper_32_bits(addr), lower_32_bits(addr));
1734
Chris Wilsonfb5c5512017-11-20 20:55:00 +00001735 if (HAS_EXECLISTS(dev_priv)) {
Chris Wilsonf636edb2017-10-09 12:02:57 +01001736 const u32 *hws = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX];
Chris Wilsonf636edb2017-10-09 12:02:57 +01001737 u32 ptr, read, write;
1738 unsigned int idx;
1739
1740 drm_printf(m, "\tExeclist status: 0x%08x %08x\n",
1741 I915_READ(RING_EXECLIST_STATUS_LO(engine)),
1742 I915_READ(RING_EXECLIST_STATUS_HI(engine)));
1743
1744 ptr = I915_READ(RING_CONTEXT_STATUS_PTR(engine));
1745 read = GEN8_CSB_READ_PTR(ptr);
1746 write = GEN8_CSB_WRITE_PTR(ptr);
1747 drm_printf(m, "\tExeclist CSB read %d [%d cached], write %d [%d from hws], interrupt posted? %s\n",
1748 read, execlists->csb_head,
1749 write,
1750 intel_read_status_page(engine, intel_hws_csb_write_index(engine->i915)),
1751 yesno(test_bit(ENGINE_IRQ_EXECLIST,
1752 &engine->irq_posted)));
1753 if (read >= GEN8_CSB_ENTRIES)
1754 read = 0;
1755 if (write >= GEN8_CSB_ENTRIES)
1756 write = 0;
1757 if (read > write)
1758 write += GEN8_CSB_ENTRIES;
1759 while (read < write) {
1760 idx = ++read % GEN8_CSB_ENTRIES;
1761 drm_printf(m, "\tExeclist CSB[%d]: 0x%08x [0x%08x in hwsp], context: %d [%d in hwsp]\n",
1762 idx,
1763 I915_READ(RING_CONTEXT_STATUS_BUF_LO(engine, idx)),
1764 hws[idx * 2],
1765 I915_READ(RING_CONTEXT_STATUS_BUF_HI(engine, idx)),
1766 hws[idx * 2 + 1]);
1767 }
1768
1769 rcu_read_lock();
1770 for (idx = 0; idx < execlists_num_ports(execlists); idx++) {
1771 unsigned int count;
1772
1773 rq = port_unpack(&execlists->port[idx], &count);
1774 if (rq) {
1775 drm_printf(m, "\t\tELSP[%d] count=%d, ",
1776 idx, count);
1777 print_request(m, rq, "rq: ");
1778 } else {
1779 drm_printf(m, "\t\tELSP[%d] idle\n",
1780 idx);
1781 }
1782 }
Chris Wilson4a118ec2017-10-23 22:32:36 +01001783 drm_printf(m, "\t\tHW active? 0x%x\n", execlists->active);
Chris Wilsonf636edb2017-10-09 12:02:57 +01001784 rcu_read_unlock();
Chris Wilsonf636edb2017-10-09 12:02:57 +01001785 } else if (INTEL_GEN(dev_priv) > 6) {
1786 drm_printf(m, "\tPP_DIR_BASE: 0x%08x\n",
1787 I915_READ(RING_PP_DIR_BASE(engine)));
1788 drm_printf(m, "\tPP_DIR_BASE_READ: 0x%08x\n",
1789 I915_READ(RING_PP_DIR_BASE_READ(engine)));
1790 drm_printf(m, "\tPP_DIR_DCLV: 0x%08x\n",
1791 I915_READ(RING_PP_DIR_DCLV(engine)));
1792 }
1793
Chris Wilsona27d5a42017-10-15 21:43:10 +01001794 spin_lock_irq(&engine->timeline->lock);
1795 list_for_each_entry(rq, &engine->timeline->requests, link)
1796 print_request(m, rq, "\t\tE ");
1797 for (rb = execlists->first; rb; rb = rb_next(rb)) {
1798 struct i915_priolist *p =
1799 rb_entry(rb, typeof(*p), node);
1800
1801 list_for_each_entry(rq, &p->requests, priotree.link)
1802 print_request(m, rq, "\t\tQ ");
1803 }
1804 spin_unlock_irq(&engine->timeline->lock);
1805
Chris Wilsonf636edb2017-10-09 12:02:57 +01001806 spin_lock_irq(&b->rb_lock);
1807 for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
1808 struct intel_wait *w = rb_entry(rb, typeof(*w), node);
1809
1810 drm_printf(m, "\t%s [%d] waiting for %x\n",
1811 w->tsk->comm, w->tsk->pid, w->seqno);
1812 }
1813 spin_unlock_irq(&b->rb_lock);
1814
Chris Wilsonc400cc22017-11-07 15:22:11 +00001815 drm_printf(m, "Idle? %s\n", yesno(intel_engine_is_idle(engine)));
Chris Wilsonf636edb2017-10-09 12:02:57 +01001816 drm_printf(m, "\n");
1817}
1818
Chris Wilsonf97fbf92017-02-13 17:15:14 +00001819#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
1820#include "selftests/mock_engine.c"
1821#endif