diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_workarounds.c | 638 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_workarounds.h | 8 |
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) | |||
| 459 | int i915_gem_contexts_init(struct drm_i915_private *dev_priv) | 460 | int 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 | ||
| 1760 | static int gen9_init_render_ring(struct intel_engine_cs *engine) | 1764 | static 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 | ||
| 1771 | static void reset_common_ring(struct intel_engine_cs *engine, | 1779 | static 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 | ||
| 665 | static u32 *gen6_signal(struct i915_request *rq, u32 *cs) | 669 | static 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 | ||
| 84 | static int wa_ring_whitelist_reg(struct intel_engine_cs *engine, | 84 | static 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 | |||
| 101 | static 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 | ||
| 152 | static int bdw_init_workarounds(struct intel_engine_cs *engine) | 133 | static 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 | ||
| 184 | static int chv_init_workarounds(struct intel_engine_cs *engine) | 164 | static 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 | ||
| 202 | static int gen9_init_workarounds(struct intel_engine_cs *engine) | 181 | static 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 | ||
| 353 | static int skl_tune_iz_hashing(struct intel_engine_cs *engine) | 276 | static 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 | ||
| 394 | static int skl_init_workarounds(struct intel_engine_cs *engine) | 316 | static 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 */ | 327 | static 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 | ||
| 425 | static int bxt_init_workarounds(struct intel_engine_cs *engine) | 346 | static 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 | |||
| 371 | static 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 | ||
| 454 | static int cnl_init_workarounds(struct intel_engine_cs *engine) | 386 | static 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 | |||
| 405 | static 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 | ||
| 514 | static int kbl_init_workarounds(struct intel_engine_cs *engine) | 444 | int 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 | |||
| 478 | int 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 | |||
| 511 | static void bdw_gt_workarounds_apply(struct drm_i915_private *dev_priv) | ||
| 512 | { | ||
| 513 | } | ||
| 514 | |||
| 515 | static void chv_gt_workarounds_apply(struct drm_i915_private *dev_priv) | ||
| 516 | { | ||
| 517 | } | ||
| 518 | |||
| 519 | static 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 | |||
| 568 | static 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 | |||
| 587 | static 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 | |||
| 601 | static 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 */ | 625 | static void glk_gt_workarounds_apply(struct drm_i915_private *dev_priv) |
| 626 | { | ||
| 627 | gen9_gt_workarounds_apply(dev_priv); | ||
| 628 | } | ||
| 629 | |||
| 630 | static 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 */ | 648 | static 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 | |||
| 666 | void 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 | |||
| 690 | static 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 | |||
| 707 | static int bdw_whitelist_workarounds_apply(struct intel_engine_cs *engine) | ||
| 708 | { | ||
| 709 | return 0; | ||
| 710 | } | ||
| 711 | |||
| 712 | static int chv_whitelist_workarounds_apply(struct intel_engine_cs *engine) | ||
| 713 | { | ||
| 714 | return 0; | ||
| 715 | } | ||
| 716 | |||
| 717 | static 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 | |||
| 739 | static 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 | ||
| 564 | static int glk_init_workarounds(struct intel_engine_cs *engine) | 755 | static 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 | |||
| 766 | static 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 | ||
| 585 | static int cfl_init_workarounds(struct intel_engine_cs *engine) | 782 | static 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 */ | 798 | static 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); | 809 | static 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 | ||
| 618 | int init_workarounds_ring(struct intel_engine_cs *engine) | 821 | int 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 | |||
| 655 | int 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 | ||
| 10 | int init_workarounds_ring(struct intel_engine_cs *engine); | 10 | int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv); |
| 11 | int intel_ring_workarounds_emit(struct i915_request *rq); | 11 | int intel_ctx_workarounds_emit(struct i915_request *rq); |
| 12 | |||
| 13 | void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv); | ||
| 14 | |||
| 15 | int intel_whitelist_workarounds_apply(struct intel_engine_cs *engine); | ||
| 12 | 16 | ||
| 13 | #endif | 17 | #endif |
