aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c6
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c14
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c8
-rw-r--r--drivers/gpu/drm/i915/intel_workarounds.c638
-rw-r--r--drivers/gpu/drm/i915/intel_workarounds.h8
6 files changed, 436 insertions, 241 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 60cf7cfc24ee..4c9d2a6f7d28 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -35,6 +35,7 @@
35#include "intel_drv.h" 35#include "intel_drv.h"
36#include "intel_frontbuffer.h" 36#include "intel_frontbuffer.h"
37#include "intel_mocs.h" 37#include "intel_mocs.h"
38#include "intel_workarounds.h"
38#include "i915_gemfs.h" 39#include "i915_gemfs.h"
39#include <linux/dma-fence-array.h> 40#include <linux/dma-fence-array.h>
40#include <linux/kthread.h> 41#include <linux/kthread.h>
@@ -5191,6 +5192,8 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
5191 } 5192 }
5192 } 5193 }
5193 5194
5195 intel_gt_workarounds_apply(dev_priv);
5196
5194 i915_gem_init_swizzling(dev_priv); 5197 i915_gem_init_swizzling(dev_priv);
5195 5198
5196 /* 5199 /*
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 5cfac0255758..9b3834a846e8 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -90,6 +90,7 @@
90#include <drm/i915_drm.h> 90#include <drm/i915_drm.h>
91#include "i915_drv.h" 91#include "i915_drv.h"
92#include "i915_trace.h" 92#include "i915_trace.h"
93#include "intel_workarounds.h"
93 94
94#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1 95#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
95 96
@@ -459,11 +460,16 @@ static bool needs_preempt_context(struct drm_i915_private *i915)
459int i915_gem_contexts_init(struct drm_i915_private *dev_priv) 460int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
460{ 461{
461 struct i915_gem_context *ctx; 462 struct i915_gem_context *ctx;
463 int ret;
462 464
463 /* Reassure ourselves we are only called once */ 465 /* Reassure ourselves we are only called once */
464 GEM_BUG_ON(dev_priv->kernel_context); 466 GEM_BUG_ON(dev_priv->kernel_context);
465 GEM_BUG_ON(dev_priv->preempt_context); 467 GEM_BUG_ON(dev_priv->preempt_context);
466 468
469 ret = intel_ctx_workarounds_init(dev_priv);
470 if (ret)
471 return ret;
472
467 INIT_LIST_HEAD(&dev_priv->contexts.list); 473 INIT_LIST_HEAD(&dev_priv->contexts.list);
468 INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker); 474 INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker);
469 init_llist_head(&dev_priv->contexts.free_list); 475 init_llist_head(&dev_priv->contexts.free_list);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 03b9d5ae883a..c7c85134a84a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1744,6 +1744,10 @@ static int gen8_init_render_ring(struct intel_engine_cs *engine)
1744 if (ret) 1744 if (ret)
1745 return ret; 1745 return ret;
1746 1746
1747 ret = intel_whitelist_workarounds_apply(engine);
1748 if (ret)
1749 return ret;
1750
1747 /* We need to disable the AsyncFlip performance optimisations in order 1751 /* We need to disable the AsyncFlip performance optimisations in order
1748 * to use MI_WAIT_FOR_EVENT within the CS. It should already be 1752 * to use MI_WAIT_FOR_EVENT within the CS. It should already be
1749 * programmed to '1' on all products. 1753 * programmed to '1' on all products.
@@ -1754,7 +1758,7 @@ static int gen8_init_render_ring(struct intel_engine_cs *engine)
1754 1758
1755 I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); 1759 I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
1756 1760
1757 return init_workarounds_ring(engine); 1761 return 0;
1758} 1762}
1759 1763
1760static int gen9_init_render_ring(struct intel_engine_cs *engine) 1764static int gen9_init_render_ring(struct intel_engine_cs *engine)
@@ -1765,7 +1769,11 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine)
1765 if (ret) 1769 if (ret)
1766 return ret; 1770 return ret;
1767 1771
1768 return init_workarounds_ring(engine); 1772 ret = intel_whitelist_workarounds_apply(engine);
1773 if (ret)
1774 return ret;
1775
1776 return 0;
1769} 1777}
1770 1778
1771static void reset_common_ring(struct intel_engine_cs *engine, 1779static void reset_common_ring(struct intel_engine_cs *engine,
@@ -2090,7 +2098,7 @@ static int gen8_init_rcs_context(struct i915_request *rq)
2090{ 2098{
2091 int ret; 2099 int ret;
2092 2100
2093 ret = intel_ring_workarounds_emit(rq); 2101 ret = intel_ctx_workarounds_emit(rq);
2094 if (ret) 2102 if (ret)
2095 return ret; 2103 return ret;
2096 2104
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 36acc32374e4..757bb0990c07 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -600,7 +600,7 @@ static int intel_rcs_ctx_init(struct i915_request *rq)
600{ 600{
601 int ret; 601 int ret;
602 602
603 ret = intel_ring_workarounds_emit(rq); 603 ret = intel_ctx_workarounds_emit(rq);
604 if (ret != 0) 604 if (ret != 0)
605 return ret; 605 return ret;
606 606
@@ -618,6 +618,10 @@ static int init_render_ring(struct intel_engine_cs *engine)
618 if (ret) 618 if (ret)
619 return ret; 619 return ret;
620 620
621 ret = intel_whitelist_workarounds_apply(engine);
622 if (ret)
623 return ret;
624
621 /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */ 625 /* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */
622 if (IS_GEN(dev_priv, 4, 6)) 626 if (IS_GEN(dev_priv, 4, 6))
623 I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH)); 627 I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH));
@@ -659,7 +663,7 @@ static int init_render_ring(struct intel_engine_cs *engine)
659 if (INTEL_GEN(dev_priv) >= 6) 663 if (INTEL_GEN(dev_priv) >= 6)
660 I915_WRITE_IMR(engine, ~engine->irq_keep_mask); 664 I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
661 665
662 return init_workarounds_ring(engine); 666 return 0;
663} 667}
664 668
665static u32 *gen6_signal(struct i915_request *rq, u32 *cs) 669static u32 *gen6_signal(struct i915_request *rq, u32 *cs)
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index d60a37700f84..bbbf4ed4aa97 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -81,27 +81,8 @@ static int wa_add(struct drm_i915_private *dev_priv,
81#define WA_SET_FIELD_MASKED(addr, mask, value) \ 81#define WA_SET_FIELD_MASKED(addr, mask, value) \
82 WA_REG(addr, (mask), _MASKED_FIELD(mask, value)) 82 WA_REG(addr, (mask), _MASKED_FIELD(mask, value))
83 83
84static int wa_ring_whitelist_reg(struct intel_engine_cs *engine, 84static int gen8_ctx_workarounds_init(struct drm_i915_private *dev_priv)
85 i915_reg_t reg)
86{ 85{
87 struct drm_i915_private *dev_priv = engine->i915;
88 struct i915_workarounds *wa = &dev_priv->workarounds;
89 const unsigned int index = wa->hw_whitelist_count[engine->id];
90
91 if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
92 return -EINVAL;
93
94 I915_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
95 i915_mmio_reg_offset(reg));
96 wa->hw_whitelist_count[engine->id]++;
97
98 return 0;
99}
100
101static int gen8_init_workarounds(struct intel_engine_cs *engine)
102{
103 struct drm_i915_private *dev_priv = engine->i915;
104
105 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING); 86 WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
106 87
107 /* WaDisableAsyncFlipPerfMode:bdw,chv */ 88 /* WaDisableAsyncFlipPerfMode:bdw,chv */
@@ -149,12 +130,11 @@ static int gen8_init_workarounds(struct intel_engine_cs *engine)
149 return 0; 130 return 0;
150} 131}
151 132
152static int bdw_init_workarounds(struct intel_engine_cs *engine) 133static int bdw_ctx_workarounds_init(struct drm_i915_private *dev_priv)
153{ 134{
154 struct drm_i915_private *dev_priv = engine->i915;
155 int ret; 135 int ret;
156 136
157 ret = gen8_init_workarounds(engine); 137 ret = gen8_ctx_workarounds_init(dev_priv);
158 if (ret) 138 if (ret)
159 return ret; 139 return ret;
160 140
@@ -181,12 +161,11 @@ static int bdw_init_workarounds(struct intel_engine_cs *engine)
181 return 0; 161 return 0;
182} 162}
183 163
184static int chv_init_workarounds(struct intel_engine_cs *engine) 164static int chv_ctx_workarounds_init(struct drm_i915_private *dev_priv)
185{ 165{
186 struct drm_i915_private *dev_priv = engine->i915;
187 int ret; 166 int ret;
188 167
189 ret = gen8_init_workarounds(engine); 168 ret = gen8_ctx_workarounds_init(dev_priv);
190 if (ret) 169 if (ret)
191 return ret; 170 return ret;
192 171
@@ -199,25 +178,8 @@ static int chv_init_workarounds(struct intel_engine_cs *engine)
199 return 0; 178 return 0;
200} 179}
201 180
202static int gen9_init_workarounds(struct intel_engine_cs *engine) 181static int gen9_ctx_workarounds_init(struct drm_i915_private *dev_priv)
203{ 182{
204 struct drm_i915_private *dev_priv = engine->i915;
205 int ret;
206
207 /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
208 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS,
209 _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
210
211 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
212 I915_WRITE(BDW_SCRATCH1,
213 I915_READ(BDW_SCRATCH1) |
214 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
215
216 /* WaDisableKillLogic:bxt,skl,kbl */
217 if (!IS_COFFEELAKE(dev_priv))
218 I915_WRITE(GAM_ECOCHK,
219 I915_READ(GAM_ECOCHK) | ECOCHK_DIS_TLB);
220
221 if (HAS_LLC(dev_priv)) { 183 if (HAS_LLC(dev_priv)) {
222 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl 184 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
223 * 185 *
@@ -228,11 +190,6 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
228 GEN9_PBE_COMPRESSED_HASH_SELECTION); 190 GEN9_PBE_COMPRESSED_HASH_SELECTION);
229 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7, 191 WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
230 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR); 192 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);
231
232 I915_WRITE(MMCD_MISC_CTRL,
233 I915_READ(MMCD_MISC_CTRL) |
234 MMCD_PCLA |
235 MMCD_HOTSPOT_EN);
236 } 193 }
237 194
238 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */ 195 /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
@@ -284,10 +241,6 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
284 WA_SET_BIT_MASKED(HDC_CHICKEN0, 241 WA_SET_BIT_MASKED(HDC_CHICKEN0,
285 HDC_FORCE_NON_COHERENT); 242 HDC_FORCE_NON_COHERENT);
286 243
287 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
288 I915_WRITE(GAM_ECOCHK,
289 I915_READ(GAM_ECOCHK) | BDW_DISABLE_HDC_INVALIDATION);
290
291 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */ 244 /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
292 if (IS_SKYLAKE(dev_priv) || 245 if (IS_SKYLAKE(dev_priv) ||
293 IS_KABYLAKE(dev_priv) || 246 IS_KABYLAKE(dev_priv) ||
@@ -298,19 +251,6 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
298 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */ 251 /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */
299 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE); 252 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
300 253
301 /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */
302 if (IS_GEN9_LP(dev_priv)) {
303 u32 val = I915_READ(GEN8_L3SQCREG1);
304
305 val &= ~L3_PRIO_CREDITS_MASK;
306 val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
307 I915_WRITE(GEN8_L3SQCREG1, val);
308 }
309
310 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
311 I915_WRITE(GEN8_L3SQCREG4,
312 I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES);
313
314 /* 254 /*
315 * Supporting preemption with fine-granularity requires changes in the 255 * Supporting preemption with fine-granularity requires changes in the
316 * batch buffer programming. Since we can't break old userspace, we 256 * batch buffer programming. Since we can't break old userspace, we
@@ -330,29 +270,11 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
330 GEN9_PREEMPT_GPGPU_LEVEL_MASK, 270 GEN9_PREEMPT_GPGPU_LEVEL_MASK,
331 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); 271 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
332 272
333 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
334 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
335 if (ret)
336 return ret;
337
338 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
339 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
340 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
341 ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
342 if (ret)
343 return ret;
344
345 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
346 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
347 if (ret)
348 return ret;
349
350 return 0; 273 return 0;
351} 274}
352 275
353static int skl_tune_iz_hashing(struct intel_engine_cs *engine) 276static int skl_tune_iz_hashing(struct drm_i915_private *dev_priv)
354{ 277{
355 struct drm_i915_private *dev_priv = engine->i915;
356 u8 vals[3] = { 0, 0, 0 }; 278 u8 vals[3] = { 0, 0, 0 };
357 unsigned int i; 279 unsigned int i;
358 280
@@ -391,77 +313,97 @@ static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
391 return 0; 313 return 0;
392} 314}
393 315
394static int skl_init_workarounds(struct intel_engine_cs *engine) 316static int skl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
395{ 317{
396 struct drm_i915_private *dev_priv = engine->i915;
397 int ret; 318 int ret;
398 319
399 ret = gen9_init_workarounds(engine); 320 ret = gen9_ctx_workarounds_init(dev_priv);
400 if (ret) 321 if (ret)
401 return ret; 322 return ret;
402 323
403 /* WaEnableGapsTsvCreditFix:skl */ 324 return skl_tune_iz_hashing(dev_priv);
404 I915_WRITE(GEN8_GARBCNTL, 325}
405 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
406
407 /* WaDisableGafsUnitClkGating:skl */
408 I915_WRITE(GEN7_UCGCTL4,
409 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
410 326
411 /* WaInPlaceDecompressionHang:skl */ 327static int bxt_ctx_workarounds_init(struct drm_i915_private *dev_priv)
412 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER)) 328{
413 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 329 int ret;
414 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
415 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
416 330
417 /* WaDisableLSQCROPERFforOCL:skl */ 331 ret = gen9_ctx_workarounds_init(dev_priv);
418 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
419 if (ret) 332 if (ret)
420 return ret; 333 return ret;
421 334
422 return skl_tune_iz_hashing(engine); 335 /* WaDisableThreadStallDopClockGating:bxt */
336 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
337 STALL_DOP_GATING_DISABLE);
338
339 /* WaToEnableHwFixForPushConstHWBug:bxt */
340 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
341 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
342
343 return 0;
423} 344}
424 345
425static int bxt_init_workarounds(struct intel_engine_cs *engine) 346static int kbl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
426{ 347{
427 struct drm_i915_private *dev_priv = engine->i915;
428 int ret; 348 int ret;
429 349
430 ret = gen9_init_workarounds(engine); 350 ret = gen9_ctx_workarounds_init(dev_priv);
431 if (ret) 351 if (ret)
432 return ret; 352 return ret;
433 353
434 /* WaDisableThreadStallDopClockGating:bxt */ 354 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
435 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, 355 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
436 STALL_DOP_GATING_DISABLE); 356 WA_SET_BIT_MASKED(HDC_CHICKEN0,
357 HDC_FENCE_DEST_SLM_DISABLE);
437 358
438 /* WaDisablePooledEuLoadBalancingFix:bxt */ 359 /* WaToEnableHwFixForPushConstHWBug:kbl */
439 I915_WRITE(FF_SLICE_CS_CHICKEN2, 360 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
440 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE)); 361 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
362 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
441 363
442 /* WaToEnableHwFixForPushConstHWBug:bxt */ 364 /* WaDisableSbeCacheDispatchPortSharing:kbl */
365 WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1,
366 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
367
368 return 0;
369}
370
371static int glk_ctx_workarounds_init(struct drm_i915_private *dev_priv)
372{
373 int ret;
374
375 ret = gen9_ctx_workarounds_init(dev_priv);
376 if (ret)
377 return ret;
378
379 /* WaToEnableHwFixForPushConstHWBug:glk */
443 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 380 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
444 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); 381 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
445 382
446 /* WaInPlaceDecompressionHang:bxt */
447 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
448 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
449 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
450
451 return 0; 383 return 0;
452} 384}
453 385
454static int cnl_init_workarounds(struct intel_engine_cs *engine) 386static int cfl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
455{ 387{
456 struct drm_i915_private *dev_priv = engine->i915;
457 int ret; 388 int ret;
458 389
459 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */ 390 ret = gen9_ctx_workarounds_init(dev_priv);
460 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0)) 391 if (ret)
461 I915_WRITE(GAMT_CHKN_BIT_REG, 392 return ret;
462 I915_READ(GAMT_CHKN_BIT_REG) | 393
463 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT); 394 /* WaToEnableHwFixForPushConstHWBug:cfl */
395 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
396 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
464 397
398 /* WaDisableSbeCacheDispatchPortSharing:cfl */
399 WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1,
400 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
401
402 return 0;
403}
404
405static int cnl_ctx_workarounds_init(struct drm_i915_private *dev_priv)
406{
465 /* WaForceContextSaveRestoreNonCoherent:cnl */ 407 /* WaForceContextSaveRestoreNonCoherent:cnl */
466 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0, 408 WA_SET_BIT_MASKED(CNL_HDC_CHICKEN0,
467 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT); 409 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT);
@@ -479,15 +421,10 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine)
479 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 421 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
480 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE); 422 GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE);
481 423
482 /* WaInPlaceDecompressionHang:cnl */
483 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
484 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
485 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
486
487 /* WaPushConstantDereferenceHoldDisable:cnl */ 424 /* WaPushConstantDereferenceHoldDisable:cnl */
488 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE); 425 WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, PUSH_CONSTANT_DEREF_DISABLE);
489 426
490 /* FtrEnableFastAnisoL1BankingFix: cnl */ 427 /* FtrEnableFastAnisoL1BankingFix:cnl */
491 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX); 428 WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3, CNL_FAST_ANISO_L1_BANKING_FIX);
492 429
493 /* WaDisable3DMidCmdPreemption:cnl */ 430 /* WaDisable3DMidCmdPreemption:cnl */
@@ -498,28 +435,173 @@ static int cnl_init_workarounds(struct intel_engine_cs *engine)
498 GEN9_PREEMPT_GPGPU_LEVEL_MASK, 435 GEN9_PREEMPT_GPGPU_LEVEL_MASK,
499 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL); 436 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
500 437
501 /* WaEnablePreemptionGranularityControlByUMD:cnl */
502 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
503 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
504 ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
505 if (ret)
506 return ret;
507
508 /* WaDisableEarlyEOT:cnl */ 438 /* WaDisableEarlyEOT:cnl */
509 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, DISABLE_EARLY_EOT); 439 WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, DISABLE_EARLY_EOT);
510 440
511 return 0; 441 return 0;
512} 442}
513 443
514static int kbl_init_workarounds(struct intel_engine_cs *engine) 444int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv)
515{ 445{
516 struct drm_i915_private *dev_priv = engine->i915; 446 int err = 0;
517 int ret;
518 447
519 ret = gen9_init_workarounds(engine); 448 dev_priv->workarounds.count = 0;
449
450 if (INTEL_GEN(dev_priv) < 8)
451 err = 0;
452 else if (IS_BROADWELL(dev_priv))
453 err = bdw_ctx_workarounds_init(dev_priv);
454 else if (IS_CHERRYVIEW(dev_priv))
455 err = chv_ctx_workarounds_init(dev_priv);
456 else if (IS_SKYLAKE(dev_priv))
457 err = skl_ctx_workarounds_init(dev_priv);
458 else if (IS_BROXTON(dev_priv))
459 err = bxt_ctx_workarounds_init(dev_priv);
460 else if (IS_KABYLAKE(dev_priv))
461 err = kbl_ctx_workarounds_init(dev_priv);
462 else if (IS_GEMINILAKE(dev_priv))
463 err = glk_ctx_workarounds_init(dev_priv);
464 else if (IS_COFFEELAKE(dev_priv))
465 err = cfl_ctx_workarounds_init(dev_priv);
466 else if (IS_CANNONLAKE(dev_priv))
467 err = cnl_ctx_workarounds_init(dev_priv);
468 else
469 MISSING_CASE(INTEL_GEN(dev_priv));
470 if (err)
471 return err;
472
473 DRM_DEBUG_DRIVER("Number of context specific w/a: %d\n",
474 dev_priv->workarounds.count);
475 return 0;
476}
477
478int intel_ctx_workarounds_emit(struct i915_request *rq)
479{
480 struct i915_workarounds *w = &rq->i915->workarounds;
481 u32 *cs;
482 int ret, i;
483
484 if (w->count == 0)
485 return 0;
486
487 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
520 if (ret) 488 if (ret)
521 return ret; 489 return ret;
522 490
491 cs = intel_ring_begin(rq, (w->count * 2 + 2));
492 if (IS_ERR(cs))
493 return PTR_ERR(cs);
494
495 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
496 for (i = 0; i < w->count; i++) {
497 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
498 *cs++ = w->reg[i].value;
499 }
500 *cs++ = MI_NOOP;
501
502 intel_ring_advance(rq, cs);
503
504 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
505 if (ret)
506 return ret;
507
508 return 0;
509}
510
511static void bdw_gt_workarounds_apply(struct drm_i915_private *dev_priv)
512{
513}
514
515static void chv_gt_workarounds_apply(struct drm_i915_private *dev_priv)
516{
517}
518
519static void gen9_gt_workarounds_apply(struct drm_i915_private *dev_priv)
520{
521 /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
522 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS,
523 _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
524
525 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
526 I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
527 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
528
529 /* WaDisableKillLogic:bxt,skl,kbl */
530 if (!IS_COFFEELAKE(dev_priv))
531 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
532 ECOCHK_DIS_TLB);
533
534 if (HAS_LLC(dev_priv)) {
535 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
536 *
537 * Must match Display Engine. See
538 * WaCompressedResourceDisplayNewHashMode.
539 */
540 I915_WRITE(MMCD_MISC_CTRL,
541 I915_READ(MMCD_MISC_CTRL) |
542 MMCD_PCLA |
543 MMCD_HOTSPOT_EN);
544 }
545
546 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
547 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
548 BDW_DISABLE_HDC_INVALIDATION);
549
550 /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */
551 if (IS_GEN9_LP(dev_priv)) {
552 u32 val = I915_READ(GEN8_L3SQCREG1);
553
554 val &= ~L3_PRIO_CREDITS_MASK;
555 val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
556 I915_WRITE(GEN8_L3SQCREG1, val);
557 }
558
559 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
560 I915_WRITE(GEN8_L3SQCREG4,
561 I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES);
562
563 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
564 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
565 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
566}
567
568static void skl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
569{
570 gen9_gt_workarounds_apply(dev_priv);
571
572 /* WaEnableGapsTsvCreditFix:skl */
573 I915_WRITE(GEN8_GARBCNTL,
574 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
575
576 /* WaDisableGafsUnitClkGating:skl */
577 I915_WRITE(GEN7_UCGCTL4,
578 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
579
580 /* WaInPlaceDecompressionHang:skl */
581 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
582 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
583 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
584 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
585}
586
587static void bxt_gt_workarounds_apply(struct drm_i915_private *dev_priv)
588{
589 gen9_gt_workarounds_apply(dev_priv);
590
591 /* WaDisablePooledEuLoadBalancingFix:bxt */
592 I915_WRITE(FF_SLICE_CS_CHICKEN2,
593 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
594
595 /* WaInPlaceDecompressionHang:bxt */
596 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
597 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
598 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
599}
600
601static void kbl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
602{
603 gen9_gt_workarounds_apply(dev_priv);
604
523 /* WaEnableGapsTsvCreditFix:kbl */ 605 /* WaEnableGapsTsvCreditFix:kbl */
524 I915_WRITE(GEN8_GARBCNTL, 606 I915_WRITE(GEN8_GARBCNTL,
525 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 607 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
@@ -530,30 +612,139 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine)
530 I915_READ(GAMT_CHKN_BIT_REG) | 612 I915_READ(GAMT_CHKN_BIT_REG) |
531 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING); 613 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
532 614
533 /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */ 615 /* WaDisableGafsUnitClkGating:kbl */
534 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0)) 616 I915_WRITE(GEN7_UCGCTL4,
535 WA_SET_BIT_MASKED(HDC_CHICKEN0, 617 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
536 HDC_FENCE_DEST_SLM_DISABLE);
537 618
538 /* WaToEnableHwFixForPushConstHWBug:kbl */ 619 /* WaInPlaceDecompressionHang:kbl */
539 if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER)) 620 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
540 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 621 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
541 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); 622 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
623}
542 624
543 /* WaDisableGafsUnitClkGating:kbl */ 625static void glk_gt_workarounds_apply(struct drm_i915_private *dev_priv)
626{
627 gen9_gt_workarounds_apply(dev_priv);
628}
629
630static void cfl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
631{
632 gen9_gt_workarounds_apply(dev_priv);
633
634 /* WaEnableGapsTsvCreditFix:cfl */
635 I915_WRITE(GEN8_GARBCNTL,
636 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
637
638 /* WaDisableGafsUnitClkGating:cfl */
544 I915_WRITE(GEN7_UCGCTL4, 639 I915_WRITE(GEN7_UCGCTL4,
545 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 640 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
546 641
547 /* WaDisableSbeCacheDispatchPortSharing:kbl */ 642 /* WaInPlaceDecompressionHang:cfl */
548 WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1, 643 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
549 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); 644 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
645 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
646}
550 647
551 /* WaInPlaceDecompressionHang:kbl */ 648static void cnl_gt_workarounds_apply(struct drm_i915_private *dev_priv)
649{
650 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
651 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0))
652 I915_WRITE(GAMT_CHKN_BIT_REG,
653 I915_READ(GAMT_CHKN_BIT_REG) |
654 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT);
655
656 /* WaInPlaceDecompressionHang:cnl */
552 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 657 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA,
553 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 658 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) |
554 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 659 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
555 660
556 /* WaDisableLSQCROPERFforOCL:kbl */ 661 /* WaEnablePreemptionGranularityControlByUMD:cnl */
662 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
663 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
664}
665
666void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv)
667{
668 if (INTEL_GEN(dev_priv) < 8)
669 return;
670 else if (IS_BROADWELL(dev_priv))
671 bdw_gt_workarounds_apply(dev_priv);
672 else if (IS_CHERRYVIEW(dev_priv))
673 chv_gt_workarounds_apply(dev_priv);
674 else if (IS_SKYLAKE(dev_priv))
675 skl_gt_workarounds_apply(dev_priv);
676 else if (IS_BROXTON(dev_priv))
677 bxt_gt_workarounds_apply(dev_priv);
678 else if (IS_KABYLAKE(dev_priv))
679 kbl_gt_workarounds_apply(dev_priv);
680 else if (IS_GEMINILAKE(dev_priv))
681 glk_gt_workarounds_apply(dev_priv);
682 else if (IS_COFFEELAKE(dev_priv))
683 cfl_gt_workarounds_apply(dev_priv);
684 else if (IS_CANNONLAKE(dev_priv))
685 cnl_gt_workarounds_apply(dev_priv);
686 else
687 MISSING_CASE(INTEL_GEN(dev_priv));
688}
689
690static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
691 i915_reg_t reg)
692{
693 struct drm_i915_private *dev_priv = engine->i915;
694 struct i915_workarounds *wa = &dev_priv->workarounds;
695 const unsigned int index = wa->hw_whitelist_count[engine->id];
696
697 if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
698 return -EINVAL;
699
700 I915_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
701 i915_mmio_reg_offset(reg));
702 wa->hw_whitelist_count[engine->id]++;
703
704 return 0;
705}
706
707static int bdw_whitelist_workarounds_apply(struct intel_engine_cs *engine)
708{
709 return 0;
710}
711
712static int chv_whitelist_workarounds_apply(struct intel_engine_cs *engine)
713{
714 return 0;
715}
716
717static int gen9_whitelist_workarounds_apply(struct intel_engine_cs *engine)
718{
719 int ret;
720
721 /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */
722 ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
723 if (ret)
724 return ret;
725
726 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
727 ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
728 if (ret)
729 return ret;
730
731 /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */
732 ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
733 if (ret)
734 return ret;
735
736 return 0;
737}
738
739static int skl_whitelist_workarounds_apply(struct intel_engine_cs *engine)
740{
741 int ret;
742
743 ret = gen9_whitelist_workarounds_apply(engine);
744 if (ret)
745 return ret;
746
747 /* WaDisableLSQCROPERFforOCL:skl */
557 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4); 748 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
558 if (ret) 749 if (ret)
559 return ret; 750 return ret;
@@ -561,126 +752,105 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine)
561 return 0; 752 return 0;
562} 753}
563 754
564static int glk_init_workarounds(struct intel_engine_cs *engine) 755static int bxt_whitelist_workarounds_apply(struct intel_engine_cs *engine)
565{ 756{
566 struct drm_i915_private *dev_priv = engine->i915;
567 int ret; 757 int ret;
568 758
569 ret = gen9_init_workarounds(engine); 759 ret = gen9_whitelist_workarounds_apply(engine);
570 if (ret) 760 if (ret)
571 return ret; 761 return ret;
572 762
573 /* WA #0862: Userspace has to set "Barrier Mode" to avoid hangs. */ 763 return 0;
574 ret = wa_ring_whitelist_reg(engine, GEN9_SLICE_COMMON_ECO_CHICKEN1); 764}
765
766static int kbl_whitelist_workarounds_apply(struct intel_engine_cs *engine)
767{
768 int ret;
769
770 ret = gen9_whitelist_workarounds_apply(engine);
575 if (ret) 771 if (ret)
576 return ret; 772 return ret;
577 773
578 /* WaToEnableHwFixForPushConstHWBug:glk */ 774 /* WaDisableLSQCROPERFforOCL:kbl */
579 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 775 ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
580 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION); 776 if (ret)
777 return ret;
581 778
582 return 0; 779 return 0;
583} 780}
584 781
585static int cfl_init_workarounds(struct intel_engine_cs *engine) 782static int glk_whitelist_workarounds_apply(struct intel_engine_cs *engine)
586{ 783{
587 struct drm_i915_private *dev_priv = engine->i915;
588 int ret; 784 int ret;
589 785
590 ret = gen9_init_workarounds(engine); 786 ret = gen9_whitelist_workarounds_apply(engine);
591 if (ret) 787 if (ret)
592 return ret; 788 return ret;
593 789
594 /* WaEnableGapsTsvCreditFix:cfl */ 790 /* WA #0862: Userspace has to set "Barrier Mode" to avoid hangs. */
595 I915_WRITE(GEN8_GARBCNTL, 791 ret = wa_ring_whitelist_reg(engine, GEN9_SLICE_COMMON_ECO_CHICKEN1);
596 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 792 if (ret)
793 return ret;
597 794
598 /* WaToEnableHwFixForPushConstHWBug:cfl */ 795 return 0;
599 WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2, 796}
600 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
601 797
602 /* WaDisableGafsUnitClkGating:cfl */ 798static int cfl_whitelist_workarounds_apply(struct intel_engine_cs *engine)
603 I915_WRITE(GEN7_UCGCTL4, 799{
604 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 800 int ret;
605 801
606 /* WaDisableSbeCacheDispatchPortSharing:cfl */ 802 ret = gen9_whitelist_workarounds_apply(engine);
607 WA_SET_BIT_MASKED(GEN7_HALF_SLICE_CHICKEN1, 803 if (ret)
608 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE); 804 return ret;
609 805
610 /* WaInPlaceDecompressionHang:cfl */ 806 return 0;
611 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 807}
612 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 808
613 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 809static int cnl_whitelist_workarounds_apply(struct intel_engine_cs *engine)
810{
811 int ret;
812
813 /* WaEnablePreemptionGranularityControlByUMD:cnl */
814 ret = wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
815 if (ret)
816 return ret;
614 817
615 return 0; 818 return 0;
616} 819}
617 820
618int init_workarounds_ring(struct intel_engine_cs *engine) 821int intel_whitelist_workarounds_apply(struct intel_engine_cs *engine)
619{ 822{
620 struct drm_i915_private *dev_priv = engine->i915; 823 struct drm_i915_private *dev_priv = engine->i915;
621 int err; 824 int err = 0;
622 825
623 if (GEM_WARN_ON(engine->id != RCS)) 826 WARN_ON(engine->id != RCS);
624 return -EINVAL;
625 827
626 dev_priv->workarounds.count = 0;
627 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0; 828 dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
628 829
629 if (IS_BROADWELL(dev_priv)) 830 if (INTEL_GEN(dev_priv) < 8)
630 err = bdw_init_workarounds(engine); 831 err = 0;
832 else if (IS_BROADWELL(dev_priv))
833 err = bdw_whitelist_workarounds_apply(engine);
631 else if (IS_CHERRYVIEW(dev_priv)) 834 else if (IS_CHERRYVIEW(dev_priv))
632 err = chv_init_workarounds(engine); 835 err = chv_whitelist_workarounds_apply(engine);
633 else if (IS_SKYLAKE(dev_priv)) 836 else if (IS_SKYLAKE(dev_priv))
634 err = skl_init_workarounds(engine); 837 err = skl_whitelist_workarounds_apply(engine);
635 else if (IS_BROXTON(dev_priv)) 838 else if (IS_BROXTON(dev_priv))
636 err = bxt_init_workarounds(engine); 839 err = bxt_whitelist_workarounds_apply(engine);
637 else if (IS_KABYLAKE(dev_priv)) 840 else if (IS_KABYLAKE(dev_priv))
638 err = kbl_init_workarounds(engine); 841 err = kbl_whitelist_workarounds_apply(engine);
639 else if (IS_GEMINILAKE(dev_priv)) 842 else if (IS_GEMINILAKE(dev_priv))
640 err = glk_init_workarounds(engine); 843 err = glk_whitelist_workarounds_apply(engine);
641 else if (IS_COFFEELAKE(dev_priv)) 844 else if (IS_COFFEELAKE(dev_priv))
642 err = cfl_init_workarounds(engine); 845 err = cfl_whitelist_workarounds_apply(engine);
643 else if (IS_CANNONLAKE(dev_priv)) 846 else if (IS_CANNONLAKE(dev_priv))
644 err = cnl_init_workarounds(engine); 847 err = cnl_whitelist_workarounds_apply(engine);
645 else 848 else
646 err = 0; 849 MISSING_CASE(INTEL_GEN(dev_priv));
647 if (err) 850 if (err)
648 return err; 851 return err;
649 852
650 DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n", 853 DRM_DEBUG_DRIVER("%s: Number of whitelist w/a: %d\n", engine->name,
651 engine->name, dev_priv->workarounds.count); 854 dev_priv->workarounds.hw_whitelist_count[engine->id]);
652 return 0;
653}
654
655int intel_ring_workarounds_emit(struct i915_request *rq)
656{
657 struct i915_workarounds *w = &rq->i915->workarounds;
658 u32 *cs;
659 int ret, i;
660
661 if (w->count == 0)
662 return 0;
663
664 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
665 if (ret)
666 return ret;
667
668 cs = intel_ring_begin(rq, w->count * 2 + 2);
669 if (IS_ERR(cs))
670 return PTR_ERR(cs);
671
672 *cs++ = MI_LOAD_REGISTER_IMM(w->count);
673 for (i = 0; i < w->count; i++) {
674 *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
675 *cs++ = w->reg[i].value;
676 }
677 *cs++ = MI_NOOP;
678
679 intel_ring_advance(rq, cs);
680
681 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
682 if (ret)
683 return ret;
684
685 return 0; 855 return 0;
686} 856}
diff --git a/drivers/gpu/drm/i915/intel_workarounds.h b/drivers/gpu/drm/i915/intel_workarounds.h
index 2afea73aeeae..d9b0cc5afb4a 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.h
+++ b/drivers/gpu/drm/i915/intel_workarounds.h
@@ -7,7 +7,11 @@
7#ifndef _I915_WORKAROUNDS_H_ 7#ifndef _I915_WORKAROUNDS_H_
8#define _I915_WORKAROUNDS_H_ 8#define _I915_WORKAROUNDS_H_
9 9
10int init_workarounds_ring(struct intel_engine_cs *engine); 10int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv);
11int intel_ring_workarounds_emit(struct i915_request *rq); 11int intel_ctx_workarounds_emit(struct i915_request *rq);
12
13void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv);
14
15int intel_whitelist_workarounds_apply(struct intel_engine_cs *engine);
12 16
13#endif 17#endif