Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-fixes-2018-12-14' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
"While I hoped things would calm down, the world hasn't joined with me,
but it's a few things scattered over a wide area. The i915 workarounds
regression fix is probably the largest, the rest are more usual sized.
We also get some new AMD PCI IDs.

There is also a patch in here to MAINTAINERS to added Daniel as an
official DRM toplevel co-maintainer, he's decided he wants to step up
and share the glory, and he'll likely process next weeks fixes while
I'm away on holidays.

Summary:

amdgpu:

- some new PCI IDs

- fixed firmware image updates

- power management fixes

- locking warning fix

nouveau:

- framebuffer flushing fix

- memory leak fix

- tegra device init regression fix

vmwgfx:

- OOM kernel memory fix

- excess return in function fix

i915:

- the biggest fix is a regression fix where workarounds weren't
getting reapplied after a gpu hang causing further crashing, this
fixes the workaround application to make it happen again

- GPU hang fixes for Braswell and some GEN3 GPUs

- GVT fix for broadwell tiling

rockchip:

- revert to fix a regression causing a WARN on shutdown

mediatek:

- avoid crash attaching to non-existant bridges"

* tag 'drm-fixes-2018-12-14' of git://anongit.freedesktop.org/drm/drm: (23 commits)
drm/vmwgfx: Protect from excessive execbuf kernel memory allocations v3
MAINTAINERS: Daniel for drm co-maintainer
drm/amdgpu: drop fclk/gfxclk ratio setting
drm/vmwgfx: remove redundant return ret statement
drm/i915: Flush GPU relocs harder for gen3
drm/i915: Allocate a common scratch page
drm/i915/execlists: Apply a full mb before execution for Braswell
drm/nouveau/kms: Fix memory leak in nv50_mstm_del()
drm/nouveau/kms/nv50-: also flush fb writes when rewinding push buffer
drm/amdgpu: Fix DEBUG_LOCKS_WARN_ON(depth <= 0) in amdgpu_ctx.lock
Revert "drm/rockchip: Allow driver to be shutdown on reboot/kexec"
drm/nouveau/drm/nouveau: tegra: Call nouveau_drm_device_init()
drm/amdgpu/powerplay: Apply avfs cks-off voltages on VI
drm/amdgpu: update SMC firmware image for polaris10 variants
drm/amdkfd: add new vega20 pci id
drm/amdkfd: add new vega10 pci ids
drm/amdgpu: add some additional vega20 pci ids
drm/amdgpu: add some additional vega10 pci ids
drm/amdgpu: update smu firmware images for VI variants (v2)
drm/i915: Introduce per-engine workarounds
...

+718 -335
+1
MAINTAINERS
··· 4847 4847 4848 4848 DRM DRIVERS 4849 4849 M: David Airlie <airlied@linux.ie> 4850 + M: Daniel Vetter <daniel@ffwll.ch> 4850 4851 L: dri-devel@lists.freedesktop.org 4851 4852 T: git git://anongit.freedesktop.org/drm/drm 4852 4853 B: https://bugs.freedesktop.org/
+30 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
··· 330 330 case CHIP_TOPAZ: 331 331 if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || 332 332 ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || 333 - ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87))) { 333 + ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) || 334 + ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) || 335 + ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) { 334 336 info->is_kicker = true; 335 337 strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); 336 338 } else ··· 353 351 if (type == CGS_UCODE_ID_SMU) { 354 352 if (((adev->pdev->device == 0x67ef) && 355 353 ((adev->pdev->revision == 0xe0) || 356 - (adev->pdev->revision == 0xe2) || 357 354 (adev->pdev->revision == 0xe5))) || 358 355 ((adev->pdev->device == 0x67ff) && 359 356 ((adev->pdev->revision == 0xcf) || ··· 360 359 (adev->pdev->revision == 0xff)))) { 361 360 info->is_kicker = true; 362 361 strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); 363 - } else 362 + } else if ((adev->pdev->device == 0x67ef) && 363 + (adev->pdev->revision == 0xe2)) { 364 + info->is_kicker = true; 365 + strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin"); 366 + } else { 364 367 strcpy(fw_name, "amdgpu/polaris11_smc.bin"); 368 + } 365 369 } else if (type == CGS_UCODE_ID_SMU_SK) { 366 370 strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin"); 367 371 } ··· 381 375 (adev->pdev->revision == 0xe7) || 382 376 (adev->pdev->revision == 0xef))) || 383 377 ((adev->pdev->device == 0x6fdf) && 384 - (adev->pdev->revision == 0xef))) { 378 + ((adev->pdev->revision == 0xef) || 379 + (adev->pdev->revision == 0xff)))) { 385 380 info->is_kicker = true; 386 381 strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); 387 - } else 382 + } else if ((adev->pdev->device == 0x67df) && 383 + ((adev->pdev->revision == 0xe1) || 384 + (adev->pdev->revision == 0xf7))) { 385 + info->is_kicker = true; 386 + strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin"); 387 + } else { 388 388 strcpy(fw_name, "amdgpu/polaris10_smc.bin"); 389 + } 389 390 } else if (type == CGS_UCODE_ID_SMU_SK) { 390 391 strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin"); 391 392 } 392 393 break; 393 394 case CHIP_POLARIS12: 394 - strcpy(fw_name, "amdgpu/polaris12_smc.bin"); 395 + if (((adev->pdev->device == 0x6987) && 396 + ((adev->pdev->revision == 0xc0) || 397 + (adev->pdev->revision == 0xc3))) || 398 + ((adev->pdev->device == 0x6981) && 399 + ((adev->pdev->revision == 0x00) || 400 + (adev->pdev->revision == 0x01) || 401 + (adev->pdev->revision == 0x10)))) { 402 + info->is_kicker = true; 403 + strcpy(fw_name, "amdgpu/polaris12_k_smc.bin"); 404 + } else { 405 + strcpy(fw_name, "amdgpu/polaris12_smc.bin"); 406 + } 395 407 break; 396 408 case CHIP_VEGAM: 397 409 strcpy(fw_name, "amdgpu/vegam_smc.bin");
+2 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
··· 124 124 goto free_chunk; 125 125 } 126 126 127 + mutex_lock(&p->ctx->lock); 128 + 127 129 /* skip guilty context job */ 128 130 if (atomic_read(&p->ctx->guilty) == 1) { 129 131 ret = -ECANCELED; 130 132 goto free_chunk; 131 133 } 132 - 133 - mutex_lock(&p->ctx->lock); 134 134 135 135 /* get chunks */ 136 136 chunk_array_user = u64_to_user_ptr(cs->in.chunks);
+7
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 872 872 {0x1002, 0x6864, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 873 873 {0x1002, 0x6867, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 874 874 {0x1002, 0x6868, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 875 + {0x1002, 0x6869, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 876 + {0x1002, 0x686a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 877 + {0x1002, 0x686b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 875 878 {0x1002, 0x686c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 879 + {0x1002, 0x686d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 880 + {0x1002, 0x686e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 881 + {0x1002, 0x686f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 876 882 {0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 877 883 /* Vega 12 */ 878 884 {0x1002, 0x69A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, ··· 891 885 {0x1002, 0x66A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 892 886 {0x1002, 0x66A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 893 887 {0x1002, 0x66A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 888 + {0x1002, 0x66A4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 894 889 {0x1002, 0x66A7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 895 890 {0x1002, 0x66AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 896 891 /* Raven */
+7
drivers/gpu/drm/amd/amdkfd/kfd_device.c
··· 337 337 { 0x6864, &vega10_device_info }, /* Vega10 */ 338 338 { 0x6867, &vega10_device_info }, /* Vega10 */ 339 339 { 0x6868, &vega10_device_info }, /* Vega10 */ 340 + { 0x6869, &vega10_device_info }, /* Vega10 */ 341 + { 0x686A, &vega10_device_info }, /* Vega10 */ 342 + { 0x686B, &vega10_device_info }, /* Vega10 */ 340 343 { 0x686C, &vega10_vf_device_info }, /* Vega10 vf*/ 344 + { 0x686D, &vega10_device_info }, /* Vega10 */ 345 + { 0x686E, &vega10_device_info }, /* Vega10 */ 346 + { 0x686F, &vega10_device_info }, /* Vega10 */ 341 347 { 0x687F, &vega10_device_info }, /* Vega10 */ 342 348 { 0x66a0, &vega20_device_info }, /* Vega20 */ 343 349 { 0x66a1, &vega20_device_info }, /* Vega20 */ 344 350 { 0x66a2, &vega20_device_info }, /* Vega20 */ 345 351 { 0x66a3, &vega20_device_info }, /* Vega20 */ 352 + { 0x66a4, &vega20_device_info }, /* Vega20 */ 346 353 { 0x66a7, &vega20_device_info }, /* Vega20 */ 347 354 { 0x66af, &vega20_device_info } /* Vega20 */ 348 355 };
+1 -1
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
··· 130 130 data->registry_data.disable_auto_wattman = 1; 131 131 data->registry_data.auto_wattman_debug = 0; 132 132 data->registry_data.auto_wattman_sample_period = 100; 133 - data->registry_data.fclk_gfxclk_ratio = 0x3F6CCCCD; 133 + data->registry_data.fclk_gfxclk_ratio = 0; 134 134 data->registry_data.auto_wattman_threshold = 50; 135 135 data->registry_data.gfxoff_controlled_by_driver = 1; 136 136 data->gfxoff_allowed = false;
+2
drivers/gpu/drm/amd/powerplay/inc/smu7_ppsmc.h
··· 386 386 #define PPSMC_MSG_AgmResetPsm ((uint16_t) 0x403) 387 387 #define PPSMC_MSG_ReadVftCell ((uint16_t) 0x404) 388 388 389 + #define PPSMC_MSG_ApplyAvfsCksOffVoltage ((uint16_t) 0x415) 390 + 389 391 #define PPSMC_MSG_GFX_CU_PG_ENABLE ((uint16_t) 0x280) 390 392 #define PPSMC_MSG_GFX_CU_PG_DISABLE ((uint16_t) 0x281) 391 393 #define PPSMC_MSG_GetCurrPkgPwr ((uint16_t) 0x282)
+6
drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
··· 1985 1985 1986 1986 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs); 1987 1987 1988 + /* Apply avfs cks-off voltages to avoid the overshoot 1989 + * when switching to the highest sclk frequency 1990 + */ 1991 + if (data->apply_avfs_cks_off_voltage) 1992 + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ApplyAvfsCksOffVoltage); 1993 + 1988 1994 return 0; 1989 1995 } 1990 1996
+3
drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
··· 37 37 MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); 38 38 MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); 39 39 MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin"); 40 + MODULE_FIRMWARE("amdgpu/polaris10_k2_smc.bin"); 40 41 MODULE_FIRMWARE("amdgpu/polaris11_smc.bin"); 41 42 MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin"); 42 43 MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin"); 44 + MODULE_FIRMWARE("amdgpu/polaris11_k2_smc.bin"); 43 45 MODULE_FIRMWARE("amdgpu/polaris12_smc.bin"); 46 + MODULE_FIRMWARE("amdgpu/polaris12_k_smc.bin"); 44 47 MODULE_FIRMWARE("amdgpu/vegam_smc.bin"); 45 48 MODULE_FIRMWARE("amdgpu/vega10_smc.bin"); 46 49 MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
+1 -1
drivers/gpu/drm/i915/gvt/fb_decoder.c
··· 235 235 plane->bpp = skl_pixel_formats[fmt].bpp; 236 236 plane->drm_format = skl_pixel_formats[fmt].drm_format; 237 237 } else { 238 - plane->tiled = !!(val & DISPPLANE_TILED); 238 + plane->tiled = val & DISPPLANE_TILED; 239 239 fmt = bdw_format_to_drm(val & DISPPLANE_PIXFORMAT_MASK); 240 240 plane->bpp = bdw_pixel_formats[fmt].bpp; 241 241 plane->drm_format = bdw_pixel_formats[fmt].drm_format;
+1
drivers/gpu/drm/i915/i915_drv.c
··· 1444 1444 1445 1445 intel_uncore_sanitize(dev_priv); 1446 1446 1447 + intel_gt_init_workarounds(dev_priv); 1447 1448 i915_gem_load_init_fences(dev_priv); 1448 1449 1449 1450 /* On the 945G/GM, the chipset reports the MSI capability on the
+9
drivers/gpu/drm/i915/i915_drv.h
··· 67 67 #include "intel_ringbuffer.h" 68 68 #include "intel_uncore.h" 69 69 #include "intel_wopcm.h" 70 + #include "intel_workarounds.h" 70 71 #include "intel_uc.h" 71 72 72 73 #include "i915_gem.h" ··· 1806 1805 int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; 1807 1806 1808 1807 struct i915_workarounds workarounds; 1808 + struct i915_wa_list gt_wa_list; 1809 1809 1810 1810 struct i915_frontbuffer_tracking fb_tracking; 1811 1811 ··· 2150 2148 struct delayed_work idle_work; 2151 2149 2152 2150 ktime_t last_init_time; 2151 + 2152 + struct i915_vma *scratch; 2153 2153 } gt; 2154 2154 2155 2155 /* perform PHY state sanity checks? */ ··· 3872 3868 return CNL_HWS_CSB_WRITE_INDEX; 3873 3869 else 3874 3870 return I915_HWS_CSB_WRITE_INDEX; 3871 + } 3872 + 3873 + static inline u32 i915_scratch_offset(const struct drm_i915_private *i915) 3874 + { 3875 + return i915_ggtt_offset(i915->gt.scratch); 3875 3876 } 3876 3877 3877 3878 #endif
+52 -2
drivers/gpu/drm/i915/i915_gem.c
··· 5305 5305 } 5306 5306 } 5307 5307 5308 - intel_gt_workarounds_apply(dev_priv); 5308 + intel_gt_apply_workarounds(dev_priv); 5309 5309 5310 5310 i915_gem_init_swizzling(dev_priv); 5311 5311 ··· 5500 5500 goto out_ctx; 5501 5501 } 5502 5502 5503 + static int 5504 + i915_gem_init_scratch(struct drm_i915_private *i915, unsigned int size) 5505 + { 5506 + struct drm_i915_gem_object *obj; 5507 + struct i915_vma *vma; 5508 + int ret; 5509 + 5510 + obj = i915_gem_object_create_stolen(i915, size); 5511 + if (!obj) 5512 + obj = i915_gem_object_create_internal(i915, size); 5513 + if (IS_ERR(obj)) { 5514 + DRM_ERROR("Failed to allocate scratch page\n"); 5515 + return PTR_ERR(obj); 5516 + } 5517 + 5518 + vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL); 5519 + if (IS_ERR(vma)) { 5520 + ret = PTR_ERR(vma); 5521 + goto err_unref; 5522 + } 5523 + 5524 + ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); 5525 + if (ret) 5526 + goto err_unref; 5527 + 5528 + i915->gt.scratch = vma; 5529 + return 0; 5530 + 5531 + err_unref: 5532 + i915_gem_object_put(obj); 5533 + return ret; 5534 + } 5535 + 5536 + static void i915_gem_fini_scratch(struct drm_i915_private *i915) 5537 + { 5538 + i915_vma_unpin_and_release(&i915->gt.scratch, 0); 5539 + } 5540 + 5503 5541 int i915_gem_init(struct drm_i915_private *dev_priv) 5504 5542 { 5505 5543 int ret; ··· 5584 5546 goto err_unlock; 5585 5547 } 5586 5548 5587 - ret = i915_gem_contexts_init(dev_priv); 5549 + ret = i915_gem_init_scratch(dev_priv, 5550 + IS_GEN2(dev_priv) ? SZ_256K : PAGE_SIZE); 5588 5551 if (ret) { 5589 5552 GEM_BUG_ON(ret == -EIO); 5590 5553 goto err_ggtt; 5554 + } 5555 + 5556 + ret = i915_gem_contexts_init(dev_priv); 5557 + if (ret) { 5558 + GEM_BUG_ON(ret == -EIO); 5559 + goto err_scratch; 5591 5560 } 5592 5561 5593 5562 ret = intel_engines_init(dev_priv); ··· 5669 5624 err_context: 5670 5625 if (ret != -EIO) 5671 5626 i915_gem_contexts_fini(dev_priv); 5627 + err_scratch: 5628 + i915_gem_fini_scratch(dev_priv); 5672 5629 err_ggtt: 5673 5630 err_unlock: 5674 5631 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); ··· 5722 5675 intel_uc_fini(dev_priv); 5723 5676 i915_gem_cleanup_engines(dev_priv); 5724 5677 i915_gem_contexts_fini(dev_priv); 5678 + i915_gem_fini_scratch(dev_priv); 5725 5679 mutex_unlock(&dev_priv->drm.struct_mutex); 5680 + 5681 + intel_wa_list_free(&dev_priv->gt_wa_list); 5726 5682 5727 5683 intel_cleanup_gt_powersave(dev_priv); 5728 5684
+1 -6
drivers/gpu/drm/i915/i915_gem_execbuffer.c
··· 1268 1268 else if (gen >= 4) 1269 1269 len = 4; 1270 1270 else 1271 - len = 6; 1271 + len = 3; 1272 1272 1273 1273 batch = reloc_gpu(eb, vma, len); 1274 1274 if (IS_ERR(batch)) ··· 1306 1306 *batch++ = addr; 1307 1307 *batch++ = target_offset; 1308 1308 } else { 1309 - *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL; 1310 - *batch++ = addr; 1311 - *batch++ = target_offset; 1312 - 1313 - /* And again for good measure (blb/pnv) */ 1314 1309 *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL; 1315 1310 *batch++ = addr; 1316 1311 *batch++ = target_offset;
+1 -1
drivers/gpu/drm/i915/i915_gpu_error.c
··· 1495 1495 if (HAS_BROKEN_CS_TLB(i915)) 1496 1496 ee->wa_batchbuffer = 1497 1497 i915_error_object_create(i915, 1498 - engine->scratch); 1498 + i915->gt.scratch); 1499 1499 request_record_user_bo(request, ee); 1500 1500 1501 1501 ee->ctx =
+2 -42
drivers/gpu/drm/i915/intel_engine_cs.c
··· 490 490 intel_engine_init_cmd_parser(engine); 491 491 } 492 492 493 - int intel_engine_create_scratch(struct intel_engine_cs *engine, 494 - unsigned int size) 495 - { 496 - struct drm_i915_gem_object *obj; 497 - struct i915_vma *vma; 498 - int ret; 499 - 500 - WARN_ON(engine->scratch); 501 - 502 - obj = i915_gem_object_create_stolen(engine->i915, size); 503 - if (!obj) 504 - obj = i915_gem_object_create_internal(engine->i915, size); 505 - if (IS_ERR(obj)) { 506 - DRM_ERROR("Failed to allocate scratch page\n"); 507 - return PTR_ERR(obj); 508 - } 509 - 510 - vma = i915_vma_instance(obj, &engine->i915->ggtt.vm, NULL); 511 - if (IS_ERR(vma)) { 512 - ret = PTR_ERR(vma); 513 - goto err_unref; 514 - } 515 - 516 - ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); 517 - if (ret) 518 - goto err_unref; 519 - 520 - engine->scratch = vma; 521 - return 0; 522 - 523 - err_unref: 524 - i915_gem_object_put(obj); 525 - return ret; 526 - } 527 - 528 - void intel_engine_cleanup_scratch(struct intel_engine_cs *engine) 529 - { 530 - i915_vma_unpin_and_release(&engine->scratch, 0); 531 - } 532 - 533 493 static void cleanup_status_page(struct intel_engine_cs *engine) 534 494 { 535 495 if (HWS_NEEDS_PHYSICAL(engine->i915)) { ··· 664 704 { 665 705 struct drm_i915_private *i915 = engine->i915; 666 706 667 - intel_engine_cleanup_scratch(engine); 668 - 669 707 cleanup_status_page(engine); 670 708 671 709 intel_engine_fini_breadcrumbs(engine); ··· 678 720 __intel_context_unpin(i915->kernel_context, engine); 679 721 680 722 i915_timeline_fini(&engine->timeline); 723 + 724 + intel_wa_list_free(&engine->wa_list); 681 725 } 682 726 683 727 u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
+16 -14
drivers/gpu/drm/i915/intel_lrc.c
··· 442 442 * may not be visible to the HW prior to the completion of the UC 443 443 * register write and that we may begin execution from the context 444 444 * before its image is complete leading to invalid PD chasing. 445 + * 446 + * Furthermore, Braswell, at least, wants a full mb to be sure that 447 + * the writes are coherent in memory (visible to the GPU) prior to 448 + * execution, and not just visible to other CPUs (as is the result of 449 + * wmb). 445 450 */ 446 - wmb(); 451 + mb(); 447 452 return ce->lrc_desc; 448 453 } 449 454 ··· 1448 1443 static u32 * 1449 1444 gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch) 1450 1445 { 1446 + /* NB no one else is allowed to scribble over scratch + 256! */ 1451 1447 *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 1452 1448 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 1453 - *batch++ = i915_ggtt_offset(engine->scratch) + 256; 1449 + *batch++ = i915_scratch_offset(engine->i915) + 256; 1454 1450 *batch++ = 0; 1455 1451 1456 1452 *batch++ = MI_LOAD_REGISTER_IMM(1); ··· 1465 1459 1466 1460 *batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 1467 1461 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 1468 - *batch++ = i915_ggtt_offset(engine->scratch) + 256; 1462 + *batch++ = i915_scratch_offset(engine->i915) + 256; 1469 1463 *batch++ = 0; 1470 1464 1471 1465 return batch; ··· 1502 1496 PIPE_CONTROL_GLOBAL_GTT_IVB | 1503 1497 PIPE_CONTROL_CS_STALL | 1504 1498 PIPE_CONTROL_QW_WRITE, 1505 - i915_ggtt_offset(engine->scratch) + 1499 + i915_scratch_offset(engine->i915) + 1506 1500 2 * CACHELINE_BYTES); 1507 1501 1508 1502 *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; ··· 1579 1573 PIPE_CONTROL_GLOBAL_GTT_IVB | 1580 1574 PIPE_CONTROL_CS_STALL | 1581 1575 PIPE_CONTROL_QW_WRITE, 1582 - i915_ggtt_offset(engine->scratch) 1576 + i915_scratch_offset(engine->i915) 1583 1577 + 2 * CACHELINE_BYTES); 1584 1578 } 1585 1579 ··· 1799 1793 1800 1794 static int gen8_init_common_ring(struct intel_engine_cs *engine) 1801 1795 { 1796 + intel_engine_apply_workarounds(engine); 1797 + 1802 1798 intel_mocs_init_engine(engine); 1803 1799 1804 1800 intel_engine_reset_breadcrumbs(engine); ··· 2147 2139 { 2148 2140 struct intel_engine_cs *engine = request->engine; 2149 2141 u32 scratch_addr = 2150 - i915_ggtt_offset(engine->scratch) + 2 * CACHELINE_BYTES; 2142 + i915_scratch_offset(engine->i915) + 2 * CACHELINE_BYTES; 2151 2143 bool vf_flush_wa = false, dc_flush_wa = false; 2152 2144 u32 *cs, flags = 0; 2153 2145 int len; ··· 2484 2476 if (ret) 2485 2477 return ret; 2486 2478 2487 - ret = intel_engine_create_scratch(engine, PAGE_SIZE); 2488 - if (ret) 2489 - goto err_cleanup_common; 2490 - 2491 2479 ret = intel_init_workaround_bb(engine); 2492 2480 if (ret) { 2493 2481 /* ··· 2495 2491 ret); 2496 2492 } 2497 2493 2498 - return 0; 2494 + intel_engine_init_workarounds(engine); 2499 2495 2500 - err_cleanup_common: 2501 - intel_engine_cleanup_common(engine); 2502 - return ret; 2496 + return 0; 2503 2497 } 2504 2498 2505 2499 int logical_xcs_ring_init(struct intel_engine_cs *engine)
+24 -28
drivers/gpu/drm/i915/intel_ringbuffer.c
··· 69 69 static int 70 70 gen2_render_ring_flush(struct i915_request *rq, u32 mode) 71 71 { 72 + unsigned int num_store_dw; 72 73 u32 cmd, *cs; 73 74 74 75 cmd = MI_FLUSH; 75 - 76 + num_store_dw = 0; 76 77 if (mode & EMIT_INVALIDATE) 77 78 cmd |= MI_READ_FLUSH; 79 + if (mode & EMIT_FLUSH) 80 + num_store_dw = 4; 78 81 79 - cs = intel_ring_begin(rq, 2); 82 + cs = intel_ring_begin(rq, 2 + 3 * num_store_dw); 80 83 if (IS_ERR(cs)) 81 84 return PTR_ERR(cs); 82 85 83 86 *cs++ = cmd; 84 - *cs++ = MI_NOOP; 87 + while (num_store_dw--) { 88 + *cs++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL; 89 + *cs++ = i915_scratch_offset(rq->i915); 90 + *cs++ = 0; 91 + } 92 + *cs++ = MI_FLUSH | MI_NO_WRITE_FLUSH; 93 + 85 94 intel_ring_advance(rq, cs); 86 95 87 96 return 0; ··· 159 150 */ 160 151 if (mode & EMIT_INVALIDATE) { 161 152 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 162 - *cs++ = i915_ggtt_offset(rq->engine->scratch) | 163 - PIPE_CONTROL_GLOBAL_GTT; 153 + *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT; 164 154 *cs++ = 0; 165 155 *cs++ = 0; 166 156 ··· 167 159 *cs++ = MI_FLUSH; 168 160 169 161 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 170 - *cs++ = i915_ggtt_offset(rq->engine->scratch) | 171 - PIPE_CONTROL_GLOBAL_GTT; 162 + *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT; 172 163 *cs++ = 0; 173 164 *cs++ = 0; 174 165 } ··· 219 212 static int 220 213 intel_emit_post_sync_nonzero_flush(struct i915_request *rq) 221 214 { 222 - u32 scratch_addr = 223 - i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES; 215 + u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES; 224 216 u32 *cs; 225 217 226 218 cs = intel_ring_begin(rq, 6); ··· 252 246 static int 253 247 gen6_render_ring_flush(struct i915_request *rq, u32 mode) 254 248 { 255 - u32 scratch_addr = 256 - i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES; 249 + u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES; 257 250 u32 *cs, flags = 0; 258 251 int ret; 259 252 ··· 321 316 static int 322 317 gen7_render_ring_flush(struct i915_request *rq, u32 mode) 323 318 { 324 - u32 scratch_addr = 325 - i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES; 319 + u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES; 326 320 u32 *cs, flags = 0; 327 321 328 322 /* ··· 975 971 } 976 972 977 973 /* Just userspace ABI convention to limit the wa batch bo to a resonable size */ 978 - #define I830_BATCH_LIMIT (256*1024) 974 + #define I830_BATCH_LIMIT SZ_256K 979 975 #define I830_TLB_ENTRIES (2) 980 976 #define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT) 981 977 static int ··· 983 979 u64 offset, u32 len, 984 980 unsigned int dispatch_flags) 985 981 { 986 - u32 *cs, cs_offset = i915_ggtt_offset(rq->engine->scratch); 982 + u32 *cs, cs_offset = i915_scratch_offset(rq->i915); 983 + 984 + GEM_BUG_ON(rq->i915->gt.scratch->size < I830_WA_SIZE); 987 985 988 986 cs = intel_ring_begin(rq, 6); 989 987 if (IS_ERR(cs)) ··· 1443 1437 { 1444 1438 struct i915_timeline *timeline; 1445 1439 struct intel_ring *ring; 1446 - unsigned int size; 1447 1440 int err; 1448 1441 1449 1442 intel_engine_setup_common(engine); ··· 1467 1462 GEM_BUG_ON(engine->buffer); 1468 1463 engine->buffer = ring; 1469 1464 1470 - size = PAGE_SIZE; 1471 - if (HAS_BROKEN_CS_TLB(engine->i915)) 1472 - size = I830_WA_SIZE; 1473 - err = intel_engine_create_scratch(engine, size); 1465 + err = intel_engine_init_common(engine); 1474 1466 if (err) 1475 1467 goto err_unpin; 1476 1468 1477 - err = intel_engine_init_common(engine); 1478 - if (err) 1479 - goto err_scratch; 1480 - 1481 1469 return 0; 1482 1470 1483 - err_scratch: 1484 - intel_engine_cleanup_scratch(engine); 1485 1471 err_unpin: 1486 1472 intel_ring_unpin(ring); 1487 1473 err_ring: ··· 1546 1550 /* Stall until the page table load is complete */ 1547 1551 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1548 1552 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine)); 1549 - *cs++ = i915_ggtt_offset(engine->scratch); 1553 + *cs++ = i915_scratch_offset(rq->i915); 1550 1554 *cs++ = MI_NOOP; 1551 1555 1552 1556 intel_ring_advance(rq, cs); ··· 1655 1659 /* Insert a delay before the next switch! */ 1656 1660 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1657 1661 *cs++ = i915_mmio_reg_offset(last_reg); 1658 - *cs++ = i915_ggtt_offset(engine->scratch); 1662 + *cs++ = i915_scratch_offset(rq->i915); 1659 1663 *cs++ = MI_NOOP; 1660 1664 } 1661 1665 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
+2 -5
drivers/gpu/drm/i915/intel_ringbuffer.h
··· 15 15 #include "i915_selftest.h" 16 16 #include "i915_timeline.h" 17 17 #include "intel_gpu_commands.h" 18 + #include "intel_workarounds.h" 18 19 19 20 struct drm_printer; 20 21 struct i915_sched_attr; ··· 441 440 442 441 struct intel_hw_status_page status_page; 443 442 struct i915_ctx_workarounds wa_ctx; 444 - struct i915_vma *scratch; 443 + struct i915_wa_list wa_list; 445 444 446 445 u32 irq_keep_mask; /* always keep these interrupts */ 447 446 u32 irq_enable_mask; /* bitmask to enable ring interrupt */ ··· 898 897 void intel_engine_setup_common(struct intel_engine_cs *engine); 899 898 int intel_engine_init_common(struct intel_engine_cs *engine); 900 899 void intel_engine_cleanup_common(struct intel_engine_cs *engine); 901 - 902 - int intel_engine_create_scratch(struct intel_engine_cs *engine, 903 - unsigned int size); 904 - void intel_engine_cleanup_scratch(struct intel_engine_cs *engine); 905 900 906 901 int intel_init_render_ring_buffer(struct intel_engine_cs *engine); 907 902 int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
+390 -201
drivers/gpu/drm/i915/intel_workarounds.c
··· 48 48 * - Public functions to init or apply the given workaround type. 49 49 */ 50 50 51 + static void wa_init_start(struct i915_wa_list *wal, const char *name) 52 + { 53 + wal->name = name; 54 + } 55 + 56 + static void wa_init_finish(struct i915_wa_list *wal) 57 + { 58 + if (!wal->count) 59 + return; 60 + 61 + DRM_DEBUG_DRIVER("Initialized %u %s workarounds\n", 62 + wal->count, wal->name); 63 + } 64 + 51 65 static void wa_add(struct drm_i915_private *i915, 52 66 i915_reg_t reg, const u32 mask, const u32 val) 53 67 { ··· 594 580 return 0; 595 581 } 596 582 597 - static void bdw_gt_workarounds_apply(struct drm_i915_private *dev_priv) 583 + static void 584 + wal_add(struct i915_wa_list *wal, const struct i915_wa *wa) 598 585 { 586 + const unsigned int grow = 1 << 4; 587 + 588 + GEM_BUG_ON(!is_power_of_2(grow)); 589 + 590 + if (IS_ALIGNED(wal->count, grow)) { /* Either uninitialized or full. */ 591 + struct i915_wa *list; 592 + 593 + list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*wa), 594 + GFP_KERNEL); 595 + if (!list) { 596 + DRM_ERROR("No space for workaround init!\n"); 597 + return; 598 + } 599 + 600 + if (wal->list) 601 + memcpy(list, wal->list, sizeof(*wa) * wal->count); 602 + 603 + wal->list = list; 604 + } 605 + 606 + wal->list[wal->count++] = *wa; 599 607 } 600 608 601 - static void chv_gt_workarounds_apply(struct drm_i915_private *dev_priv) 609 + static void 610 + wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val) 602 611 { 612 + struct i915_wa wa = { 613 + .reg = reg, 614 + .mask = val, 615 + .val = _MASKED_BIT_ENABLE(val) 616 + }; 617 + 618 + wal_add(wal, &wa); 603 619 } 604 620 605 - static void gen9_gt_workarounds_apply(struct drm_i915_private *dev_priv) 621 + static void 622 + wa_write_masked_or(struct i915_wa_list *wal, i915_reg_t reg, u32 mask, 623 + u32 val) 606 624 { 607 - /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ 608 - I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, 609 - _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE)); 625 + struct i915_wa wa = { 626 + .reg = reg, 627 + .mask = mask, 628 + .val = val 629 + }; 610 630 611 - /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ 612 - I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | 613 - GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); 631 + wal_add(wal, &wa); 632 + } 633 + 634 + static void 635 + wa_write(struct i915_wa_list *wal, i915_reg_t reg, u32 val) 636 + { 637 + wa_write_masked_or(wal, reg, ~0, val); 638 + } 639 + 640 + static void 641 + wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 val) 642 + { 643 + wa_write_masked_or(wal, reg, val, val); 644 + } 645 + 646 + static void gen9_gt_workarounds_init(struct drm_i915_private *i915) 647 + { 648 + struct i915_wa_list *wal = &i915->gt_wa_list; 614 649 615 650 /* WaDisableKillLogic:bxt,skl,kbl */ 616 - if (!IS_COFFEELAKE(dev_priv)) 617 - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | 618 - ECOCHK_DIS_TLB); 651 + if (!IS_COFFEELAKE(i915)) 652 + wa_write_or(wal, 653 + GAM_ECOCHK, 654 + ECOCHK_DIS_TLB); 619 655 620 - if (HAS_LLC(dev_priv)) { 656 + if (HAS_LLC(i915)) { 621 657 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl 622 658 * 623 659 * Must match Display Engine. See 624 660 * WaCompressedResourceDisplayNewHashMode. 625 661 */ 626 - I915_WRITE(MMCD_MISC_CTRL, 627 - I915_READ(MMCD_MISC_CTRL) | 628 - MMCD_PCLA | 629 - MMCD_HOTSPOT_EN); 662 + wa_write_or(wal, 663 + MMCD_MISC_CTRL, 664 + MMCD_PCLA | MMCD_HOTSPOT_EN); 630 665 } 631 666 632 667 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */ 633 - I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | 634 - BDW_DISABLE_HDC_INVALIDATION); 635 - 636 - /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */ 637 - if (IS_GEN9_LP(dev_priv)) { 638 - u32 val = I915_READ(GEN8_L3SQCREG1); 639 - 640 - val &= ~L3_PRIO_CREDITS_MASK; 641 - val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2); 642 - I915_WRITE(GEN8_L3SQCREG1, val); 643 - } 644 - 645 - /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */ 646 - I915_WRITE(GEN8_L3SQCREG4, 647 - I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES); 648 - 649 - /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */ 650 - I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, 651 - _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); 668 + wa_write_or(wal, 669 + GAM_ECOCHK, 670 + BDW_DISABLE_HDC_INVALIDATION); 652 671 } 653 672 654 - static void skl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 673 + static void skl_gt_workarounds_init(struct drm_i915_private *i915) 655 674 { 656 - gen9_gt_workarounds_apply(dev_priv); 675 + struct i915_wa_list *wal = &i915->gt_wa_list; 657 676 658 - /* WaEnableGapsTsvCreditFix:skl */ 659 - I915_WRITE(GEN8_GARBCNTL, 660 - I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 677 + gen9_gt_workarounds_init(i915); 661 678 662 679 /* WaDisableGafsUnitClkGating:skl */ 663 - I915_WRITE(GEN7_UCGCTL4, 664 - I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 680 + wa_write_or(wal, 681 + GEN7_UCGCTL4, 682 + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 665 683 666 684 /* WaInPlaceDecompressionHang:skl */ 667 - if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER)) 668 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 669 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 670 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 685 + if (IS_SKL_REVID(i915, SKL_REVID_H0, REVID_FOREVER)) 686 + wa_write_or(wal, 687 + GEN9_GAMT_ECO_REG_RW_IA, 688 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 671 689 } 672 690 673 - static void bxt_gt_workarounds_apply(struct drm_i915_private *dev_priv) 691 + static void bxt_gt_workarounds_init(struct drm_i915_private *i915) 674 692 { 675 - gen9_gt_workarounds_apply(dev_priv); 693 + struct i915_wa_list *wal = &i915->gt_wa_list; 676 694 677 - /* WaDisablePooledEuLoadBalancingFix:bxt */ 678 - I915_WRITE(FF_SLICE_CS_CHICKEN2, 679 - _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE)); 695 + gen9_gt_workarounds_init(i915); 680 696 681 697 /* WaInPlaceDecompressionHang:bxt */ 682 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 683 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 684 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 698 + wa_write_or(wal, 699 + GEN9_GAMT_ECO_REG_RW_IA, 700 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 685 701 } 686 702 687 - static void kbl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 703 + static void kbl_gt_workarounds_init(struct drm_i915_private *i915) 688 704 { 689 - gen9_gt_workarounds_apply(dev_priv); 705 + struct i915_wa_list *wal = &i915->gt_wa_list; 690 706 691 - /* WaEnableGapsTsvCreditFix:kbl */ 692 - I915_WRITE(GEN8_GARBCNTL, 693 - I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 707 + gen9_gt_workarounds_init(i915); 694 708 695 709 /* WaDisableDynamicCreditSharing:kbl */ 696 - if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) 697 - I915_WRITE(GAMT_CHKN_BIT_REG, 698 - I915_READ(GAMT_CHKN_BIT_REG) | 699 - GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING); 710 + if (IS_KBL_REVID(i915, 0, KBL_REVID_B0)) 711 + wa_write_or(wal, 712 + GAMT_CHKN_BIT_REG, 713 + GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING); 700 714 701 715 /* WaDisableGafsUnitClkGating:kbl */ 702 - I915_WRITE(GEN7_UCGCTL4, 703 - I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 716 + wa_write_or(wal, 717 + GEN7_UCGCTL4, 718 + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 704 719 705 720 /* WaInPlaceDecompressionHang:kbl */ 706 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 707 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 708 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 709 - 710 - /* WaKBLVECSSemaphoreWaitPoll:kbl */ 711 - if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_E0)) { 712 - struct intel_engine_cs *engine; 713 - unsigned int tmp; 714 - 715 - for_each_engine(engine, dev_priv, tmp) { 716 - if (engine->id == RCS) 717 - continue; 718 - 719 - I915_WRITE(RING_SEMA_WAIT_POLL(engine->mmio_base), 1); 720 - } 721 - } 721 + wa_write_or(wal, 722 + GEN9_GAMT_ECO_REG_RW_IA, 723 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 722 724 } 723 725 724 - static void glk_gt_workarounds_apply(struct drm_i915_private *dev_priv) 726 + static void glk_gt_workarounds_init(struct drm_i915_private *i915) 725 727 { 726 - gen9_gt_workarounds_apply(dev_priv); 728 + gen9_gt_workarounds_init(i915); 727 729 } 728 730 729 - static void cfl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 731 + static void cfl_gt_workarounds_init(struct drm_i915_private *i915) 730 732 { 731 - gen9_gt_workarounds_apply(dev_priv); 733 + struct i915_wa_list *wal = &i915->gt_wa_list; 732 734 733 - /* WaEnableGapsTsvCreditFix:cfl */ 734 - I915_WRITE(GEN8_GARBCNTL, 735 - I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE); 735 + gen9_gt_workarounds_init(i915); 736 736 737 737 /* WaDisableGafsUnitClkGating:cfl */ 738 - I915_WRITE(GEN7_UCGCTL4, 739 - I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 738 + wa_write_or(wal, 739 + GEN7_UCGCTL4, 740 + GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 740 741 741 742 /* WaInPlaceDecompressionHang:cfl */ 742 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 743 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 744 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 743 + wa_write_or(wal, 744 + GEN9_GAMT_ECO_REG_RW_IA, 745 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 745 746 } 746 747 747 748 static void wa_init_mcr(struct drm_i915_private *dev_priv) 748 749 { 749 750 const struct sseu_dev_info *sseu = &(INTEL_INFO(dev_priv)->sseu); 750 - u32 mcr; 751 + struct i915_wa_list *wal = &dev_priv->gt_wa_list; 751 752 u32 mcr_slice_subslice_mask; 752 753 753 754 /* ··· 799 770 WARN_ON((enabled_mask & disabled_mask) != enabled_mask); 800 771 } 801 772 802 - mcr = I915_READ(GEN8_MCR_SELECTOR); 803 - 804 773 if (INTEL_GEN(dev_priv) >= 11) 805 774 mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK | 806 775 GEN11_MCR_SUBSLICE_MASK; ··· 816 789 * occasions, such as INSTDONE, where this value is dependent 817 790 * on s/ss combo, the read should be done with read_subslice_reg. 818 791 */ 819 - mcr &= ~mcr_slice_subslice_mask; 820 - mcr |= intel_calculate_mcr_s_ss_select(dev_priv); 821 - I915_WRITE(GEN8_MCR_SELECTOR, mcr); 792 + wa_write_masked_or(wal, 793 + GEN8_MCR_SELECTOR, 794 + mcr_slice_subslice_mask, 795 + intel_calculate_mcr_s_ss_select(dev_priv)); 822 796 } 823 797 824 - static void cnl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 798 + static void cnl_gt_workarounds_init(struct drm_i915_private *i915) 825 799 { 826 - wa_init_mcr(dev_priv); 800 + struct i915_wa_list *wal = &i915->gt_wa_list; 801 + 802 + wa_init_mcr(i915); 827 803 828 804 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */ 829 - if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0)) 830 - I915_WRITE(GAMT_CHKN_BIT_REG, 831 - I915_READ(GAMT_CHKN_BIT_REG) | 832 - GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT); 805 + if (IS_CNL_REVID(i915, CNL_REVID_B0, CNL_REVID_B0)) 806 + wa_write_or(wal, 807 + GAMT_CHKN_BIT_REG, 808 + GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT); 833 809 834 810 /* WaInPlaceDecompressionHang:cnl */ 835 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 836 - I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 837 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 838 - 839 - /* WaEnablePreemptionGranularityControlByUMD:cnl */ 840 - I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1, 841 - _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL)); 811 + wa_write_or(wal, 812 + GEN9_GAMT_ECO_REG_RW_IA, 813 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 842 814 } 843 815 844 - static void icl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 816 + static void icl_gt_workarounds_init(struct drm_i915_private *i915) 845 817 { 846 - wa_init_mcr(dev_priv); 818 + struct i915_wa_list *wal = &i915->gt_wa_list; 847 819 848 - /* This is not an Wa. Enable for better image quality */ 849 - I915_WRITE(_3D_CHICKEN3, 850 - _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE)); 820 + wa_init_mcr(i915); 851 821 852 822 /* WaInPlaceDecompressionHang:icl */ 853 - I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 854 - GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 855 - 856 - /* WaPipelineFlushCoherentLines:icl */ 857 - I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | 858 - GEN8_LQSC_FLUSH_COHERENT_LINES); 859 - 860 - /* Wa_1405543622:icl 861 - * Formerly known as WaGAPZPriorityScheme 862 - */ 863 - I915_WRITE(GEN8_GARBCNTL, I915_READ(GEN8_GARBCNTL) | 864 - GEN11_ARBITRATION_PRIO_ORDER_MASK); 865 - 866 - /* Wa_1604223664:icl 867 - * Formerly known as WaL3BankAddressHashing 868 - */ 869 - I915_WRITE(GEN8_GARBCNTL, 870 - (I915_READ(GEN8_GARBCNTL) & ~GEN11_HASH_CTRL_EXCL_MASK) | 871 - GEN11_HASH_CTRL_EXCL_BIT0); 872 - I915_WRITE(GEN11_GLBLINVL, 873 - (I915_READ(GEN11_GLBLINVL) & ~GEN11_BANK_HASH_ADDR_EXCL_MASK) | 874 - GEN11_BANK_HASH_ADDR_EXCL_BIT0); 823 + wa_write_or(wal, 824 + GEN9_GAMT_ECO_REG_RW_IA, 825 + GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 875 826 876 827 /* WaModifyGamTlbPartitioning:icl */ 877 - I915_WRITE(GEN11_GACB_PERF_CTRL, 878 - (I915_READ(GEN11_GACB_PERF_CTRL) & ~GEN11_HASH_CTRL_MASK) | 879 - GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4); 880 - 881 - /* Wa_1405733216:icl 882 - * Formerly known as WaDisableCleanEvicts 883 - */ 884 - I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | 885 - GEN11_LQSC_CLEAN_EVICT_DISABLE); 828 + wa_write_masked_or(wal, 829 + GEN11_GACB_PERF_CTRL, 830 + GEN11_HASH_CTRL_MASK, 831 + GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4); 886 832 887 833 /* Wa_1405766107:icl 888 834 * Formerly known as WaCL2SFHalfMaxAlloc 889 835 */ 890 - I915_WRITE(GEN11_LSN_UNSLCVC, I915_READ(GEN11_LSN_UNSLCVC) | 891 - GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC | 892 - GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC); 836 + wa_write_or(wal, 837 + GEN11_LSN_UNSLCVC, 838 + GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC | 839 + GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC); 893 840 894 841 /* Wa_220166154:icl 895 842 * Formerly known as WaDisCtxReload 896 843 */ 897 - I915_WRITE(GAMW_ECO_DEV_RW_IA_REG, I915_READ(GAMW_ECO_DEV_RW_IA_REG) | 898 - GAMW_ECO_DEV_CTX_RELOAD_DISABLE); 844 + wa_write_or(wal, 845 + GEN8_GAMW_ECO_DEV_RW_IA, 846 + GAMW_ECO_DEV_CTX_RELOAD_DISABLE); 899 847 900 848 /* Wa_1405779004:icl (pre-prod) */ 901 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_A0)) 902 - I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, 903 - I915_READ(SLICE_UNIT_LEVEL_CLKGATE) | 904 - MSCUNIT_CLKGATE_DIS); 849 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0)) 850 + wa_write_or(wal, 851 + SLICE_UNIT_LEVEL_CLKGATE, 852 + MSCUNIT_CLKGATE_DIS); 905 853 906 854 /* Wa_1406680159:icl */ 907 - I915_WRITE(SUBSLICE_UNIT_LEVEL_CLKGATE, 908 - I915_READ(SUBSLICE_UNIT_LEVEL_CLKGATE) | 909 - GWUNIT_CLKGATE_DIS); 910 - 911 - /* Wa_1604302699:icl */ 912 - I915_WRITE(GEN10_L3_CHICKEN_MODE_REGISTER, 913 - I915_READ(GEN10_L3_CHICKEN_MODE_REGISTER) | 914 - GEN11_I2M_WRITE_DISABLE); 855 + wa_write_or(wal, 856 + SUBSLICE_UNIT_LEVEL_CLKGATE, 857 + GWUNIT_CLKGATE_DIS); 915 858 916 859 /* Wa_1406838659:icl (pre-prod) */ 917 - if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_B0)) 918 - I915_WRITE(INF_UNIT_LEVEL_CLKGATE, 919 - I915_READ(INF_UNIT_LEVEL_CLKGATE) | 920 - CGPSF_CLKGATE_DIS); 921 - 922 - /* WaForwardProgressSoftReset:icl */ 923 - I915_WRITE(GEN10_SCRATCH_LNCF2, 924 - I915_READ(GEN10_SCRATCH_LNCF2) | 925 - PMFLUSHDONE_LNICRSDROP | 926 - PMFLUSH_GAPL3UNBLOCK | 927 - PMFLUSHDONE_LNEBLK); 860 + if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0)) 861 + wa_write_or(wal, 862 + INF_UNIT_LEVEL_CLKGATE, 863 + CGPSF_CLKGATE_DIS); 928 864 929 865 /* Wa_1406463099:icl 930 866 * Formerly known as WaGamTlbPendError 931 867 */ 932 - I915_WRITE(GAMT_CHKN_BIT_REG, 933 - I915_READ(GAMT_CHKN_BIT_REG) | 934 - GAMT_CHKN_DISABLE_L3_COH_PIPE); 868 + wa_write_or(wal, 869 + GAMT_CHKN_BIT_REG, 870 + GAMT_CHKN_DISABLE_L3_COH_PIPE); 935 871 } 936 872 937 - void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv) 873 + void intel_gt_init_workarounds(struct drm_i915_private *i915) 938 874 { 939 - if (INTEL_GEN(dev_priv) < 8) 875 + struct i915_wa_list *wal = &i915->gt_wa_list; 876 + 877 + wa_init_start(wal, "GT"); 878 + 879 + if (INTEL_GEN(i915) < 8) 940 880 return; 941 - else if (IS_BROADWELL(dev_priv)) 942 - bdw_gt_workarounds_apply(dev_priv); 943 - else if (IS_CHERRYVIEW(dev_priv)) 944 - chv_gt_workarounds_apply(dev_priv); 945 - else if (IS_SKYLAKE(dev_priv)) 946 - skl_gt_workarounds_apply(dev_priv); 947 - else if (IS_BROXTON(dev_priv)) 948 - bxt_gt_workarounds_apply(dev_priv); 949 - else if (IS_KABYLAKE(dev_priv)) 950 - kbl_gt_workarounds_apply(dev_priv); 951 - else if (IS_GEMINILAKE(dev_priv)) 952 - glk_gt_workarounds_apply(dev_priv); 953 - else if (IS_COFFEELAKE(dev_priv)) 954 - cfl_gt_workarounds_apply(dev_priv); 955 - else if (IS_CANNONLAKE(dev_priv)) 956 - cnl_gt_workarounds_apply(dev_priv); 957 - else if (IS_ICELAKE(dev_priv)) 958 - icl_gt_workarounds_apply(dev_priv); 881 + else if (IS_BROADWELL(i915)) 882 + return; 883 + else if (IS_CHERRYVIEW(i915)) 884 + return; 885 + else if (IS_SKYLAKE(i915)) 886 + skl_gt_workarounds_init(i915); 887 + else if (IS_BROXTON(i915)) 888 + bxt_gt_workarounds_init(i915); 889 + else if (IS_KABYLAKE(i915)) 890 + kbl_gt_workarounds_init(i915); 891 + else if (IS_GEMINILAKE(i915)) 892 + glk_gt_workarounds_init(i915); 893 + else if (IS_COFFEELAKE(i915)) 894 + cfl_gt_workarounds_init(i915); 895 + else if (IS_CANNONLAKE(i915)) 896 + cnl_gt_workarounds_init(i915); 897 + else if (IS_ICELAKE(i915)) 898 + icl_gt_workarounds_init(i915); 959 899 else 960 - MISSING_CASE(INTEL_GEN(dev_priv)); 900 + MISSING_CASE(INTEL_GEN(i915)); 901 + 902 + wa_init_finish(wal); 903 + } 904 + 905 + static enum forcewake_domains 906 + wal_get_fw_for_rmw(struct drm_i915_private *dev_priv, 907 + const struct i915_wa_list *wal) 908 + { 909 + enum forcewake_domains fw = 0; 910 + struct i915_wa *wa; 911 + unsigned int i; 912 + 913 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) 914 + fw |= intel_uncore_forcewake_for_reg(dev_priv, 915 + wa->reg, 916 + FW_REG_READ | 917 + FW_REG_WRITE); 918 + 919 + return fw; 920 + } 921 + 922 + static void 923 + wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal) 924 + { 925 + enum forcewake_domains fw; 926 + unsigned long flags; 927 + struct i915_wa *wa; 928 + unsigned int i; 929 + 930 + if (!wal->count) 931 + return; 932 + 933 + fw = wal_get_fw_for_rmw(dev_priv, wal); 934 + 935 + spin_lock_irqsave(&dev_priv->uncore.lock, flags); 936 + intel_uncore_forcewake_get__locked(dev_priv, fw); 937 + 938 + for (i = 0, wa = wal->list; i < wal->count; i++, wa++) { 939 + u32 val = I915_READ_FW(wa->reg); 940 + 941 + val &= ~wa->mask; 942 + val |= wa->val; 943 + 944 + I915_WRITE_FW(wa->reg, val); 945 + } 946 + 947 + intel_uncore_forcewake_put__locked(dev_priv, fw); 948 + spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); 949 + 950 + DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name); 951 + } 952 + 953 + void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv) 954 + { 955 + wa_list_apply(dev_priv, &dev_priv->gt_wa_list); 961 956 } 962 957 963 958 struct whitelist { ··· 1124 1075 struct whitelist w; 1125 1076 1126 1077 whitelist_apply(engine, whitelist_build(engine, &w)); 1078 + } 1079 + 1080 + static void rcs_engine_wa_init(struct intel_engine_cs *engine) 1081 + { 1082 + struct drm_i915_private *i915 = engine->i915; 1083 + struct i915_wa_list *wal = &engine->wa_list; 1084 + 1085 + if (IS_ICELAKE(i915)) { 1086 + /* This is not an Wa. Enable for better image quality */ 1087 + wa_masked_en(wal, 1088 + _3D_CHICKEN3, 1089 + _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE); 1090 + 1091 + /* WaPipelineFlushCoherentLines:icl */ 1092 + wa_write_or(wal, 1093 + GEN8_L3SQCREG4, 1094 + GEN8_LQSC_FLUSH_COHERENT_LINES); 1095 + 1096 + /* 1097 + * Wa_1405543622:icl 1098 + * Formerly known as WaGAPZPriorityScheme 1099 + */ 1100 + wa_write_or(wal, 1101 + GEN8_GARBCNTL, 1102 + GEN11_ARBITRATION_PRIO_ORDER_MASK); 1103 + 1104 + /* 1105 + * Wa_1604223664:icl 1106 + * Formerly known as WaL3BankAddressHashing 1107 + */ 1108 + wa_write_masked_or(wal, 1109 + GEN8_GARBCNTL, 1110 + GEN11_HASH_CTRL_EXCL_MASK, 1111 + GEN11_HASH_CTRL_EXCL_BIT0); 1112 + wa_write_masked_or(wal, 1113 + GEN11_GLBLINVL, 1114 + GEN11_BANK_HASH_ADDR_EXCL_MASK, 1115 + GEN11_BANK_HASH_ADDR_EXCL_BIT0); 1116 + 1117 + /* 1118 + * Wa_1405733216:icl 1119 + * Formerly known as WaDisableCleanEvicts 1120 + */ 1121 + wa_write_or(wal, 1122 + GEN8_L3SQCREG4, 1123 + GEN11_LQSC_CLEAN_EVICT_DISABLE); 1124 + 1125 + /* Wa_1604302699:icl */ 1126 + wa_write_or(wal, 1127 + GEN10_L3_CHICKEN_MODE_REGISTER, 1128 + GEN11_I2M_WRITE_DISABLE); 1129 + 1130 + /* WaForwardProgressSoftReset:icl */ 1131 + wa_write_or(wal, 1132 + GEN10_SCRATCH_LNCF2, 1133 + PMFLUSHDONE_LNICRSDROP | 1134 + PMFLUSH_GAPL3UNBLOCK | 1135 + PMFLUSHDONE_LNEBLK); 1136 + } 1137 + 1138 + if (IS_GEN9(i915) || IS_CANNONLAKE(i915)) { 1139 + /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */ 1140 + wa_masked_en(wal, 1141 + GEN7_FF_SLICE_CS_CHICKEN1, 1142 + GEN9_FFSC_PERCTX_PREEMPT_CTRL); 1143 + } 1144 + 1145 + if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) || IS_COFFEELAKE(i915)) { 1146 + /* WaEnableGapsTsvCreditFix:skl,kbl,cfl */ 1147 + wa_write_or(wal, 1148 + GEN8_GARBCNTL, 1149 + GEN9_GAPS_TSV_CREDIT_DISABLE); 1150 + } 1151 + 1152 + if (IS_BROXTON(i915)) { 1153 + /* WaDisablePooledEuLoadBalancingFix:bxt */ 1154 + wa_masked_en(wal, 1155 + FF_SLICE_CS_CHICKEN2, 1156 + GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE); 1157 + } 1158 + 1159 + if (IS_GEN9(i915)) { 1160 + /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ 1161 + wa_masked_en(wal, 1162 + GEN9_CSFE_CHICKEN1_RCS, 1163 + GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE); 1164 + 1165 + /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ 1166 + wa_write_or(wal, 1167 + BDW_SCRATCH1, 1168 + GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); 1169 + 1170 + /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */ 1171 + if (IS_GEN9_LP(i915)) 1172 + wa_write_masked_or(wal, 1173 + GEN8_L3SQCREG1, 1174 + L3_PRIO_CREDITS_MASK, 1175 + L3_GENERAL_PRIO_CREDITS(62) | 1176 + L3_HIGH_PRIO_CREDITS(2)); 1177 + 1178 + /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */ 1179 + wa_write_or(wal, 1180 + GEN8_L3SQCREG4, 1181 + GEN8_LQSC_FLUSH_COHERENT_LINES); 1182 + } 1183 + } 1184 + 1185 + static void xcs_engine_wa_init(struct intel_engine_cs *engine) 1186 + { 1187 + struct drm_i915_private *i915 = engine->i915; 1188 + struct i915_wa_list *wal = &engine->wa_list; 1189 + 1190 + /* WaKBLVECSSemaphoreWaitPoll:kbl */ 1191 + if (IS_KBL_REVID(i915, KBL_REVID_A0, KBL_REVID_E0)) { 1192 + wa_write(wal, 1193 + RING_SEMA_WAIT_POLL(engine->mmio_base), 1194 + 1); 1195 + } 1196 + } 1197 + 1198 + void intel_engine_init_workarounds(struct intel_engine_cs *engine) 1199 + { 1200 + struct i915_wa_list *wal = &engine->wa_list; 1201 + 1202 + if (GEM_WARN_ON(INTEL_GEN(engine->i915) < 8)) 1203 + return; 1204 + 1205 + wa_init_start(wal, engine->name); 1206 + 1207 + if (engine->id == RCS) 1208 + rcs_engine_wa_init(engine); 1209 + else 1210 + xcs_engine_wa_init(engine); 1211 + 1212 + wa_init_finish(wal); 1213 + } 1214 + 1215 + void intel_engine_apply_workarounds(struct intel_engine_cs *engine) 1216 + { 1217 + wa_list_apply(engine->i915, &engine->wa_list); 1127 1218 } 1128 1219 1129 1220 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+25 -1
drivers/gpu/drm/i915/intel_workarounds.h
··· 7 7 #ifndef _I915_WORKAROUNDS_H_ 8 8 #define _I915_WORKAROUNDS_H_ 9 9 10 + #include <linux/slab.h> 11 + 12 + struct i915_wa { 13 + i915_reg_t reg; 14 + u32 mask; 15 + u32 val; 16 + }; 17 + 18 + struct i915_wa_list { 19 + const char *name; 20 + struct i915_wa *list; 21 + unsigned int count; 22 + }; 23 + 24 + static inline void intel_wa_list_free(struct i915_wa_list *wal) 25 + { 26 + kfree(wal->list); 27 + memset(wal, 0, sizeof(*wal)); 28 + } 29 + 10 30 int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv); 11 31 int intel_ctx_workarounds_emit(struct i915_request *rq); 12 32 13 - void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv); 33 + void intel_gt_init_workarounds(struct drm_i915_private *dev_priv); 34 + void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv); 14 35 15 36 void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine); 37 + 38 + void intel_engine_init_workarounds(struct intel_engine_cs *engine); 39 + void intel_engine_apply_workarounds(struct intel_engine_cs *engine); 16 40 17 41 #endif
+7 -4
drivers/gpu/drm/mediatek/mtk_dsi.c
··· 818 818 dsi->encoder.possible_crtcs = 1; 819 819 820 820 /* If there's a bridge, attach to it and let it create the connector */ 821 - ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL); 822 - if (ret) { 823 - DRM_ERROR("Failed to attach bridge to drm\n"); 824 - 821 + if (dsi->bridge) { 822 + ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL); 823 + if (ret) { 824 + DRM_ERROR("Failed to attach bridge to drm\n"); 825 + goto err_encoder_cleanup; 826 + } 827 + } else { 825 828 /* Otherwise create our own connector and attach to a panel */ 826 829 ret = mtk_dsi_create_connector(drm, dsi); 827 830 if (ret)
+19 -11
drivers/gpu/drm/nouveau/dispnv50/disp.c
··· 198 198 /****************************************************************************** 199 199 * EVO channel helpers 200 200 *****************************************************************************/ 201 + static void 202 + evo_flush(struct nv50_dmac *dmac) 203 + { 204 + /* Push buffer fetches are not coherent with BAR1, we need to ensure 205 + * writes have been flushed right through to VRAM before writing PUT. 206 + */ 207 + if (dmac->push.type & NVIF_MEM_VRAM) { 208 + struct nvif_device *device = dmac->base.device; 209 + nvif_wr32(&device->object, 0x070000, 0x00000001); 210 + nvif_msec(device, 2000, 211 + if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002)) 212 + break; 213 + ); 214 + } 215 + } 216 + 201 217 u32 * 202 218 evo_wait(struct nv50_dmac *evoc, int nr) 203 219 { ··· 224 208 mutex_lock(&dmac->lock); 225 209 if (put + nr >= (PAGE_SIZE / 4) - 8) { 226 210 dmac->ptr[put] = 0x20000000; 211 + evo_flush(dmac); 227 212 228 213 nvif_wr32(&dmac->base.user, 0x0000, 0x00000000); 229 214 if (nvif_msec(device, 2000, ··· 247 230 { 248 231 struct nv50_dmac *dmac = evoc; 249 232 250 - /* Push buffer fetches are not coherent with BAR1, we need to ensure 251 - * writes have been flushed right through to VRAM before writing PUT. 252 - */ 253 - if (dmac->push.type & NVIF_MEM_VRAM) { 254 - struct nvif_device *device = dmac->base.device; 255 - nvif_wr32(&device->object, 0x070000, 0x00000001); 256 - nvif_msec(device, 2000, 257 - if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002)) 258 - break; 259 - ); 260 - } 233 + evo_flush(dmac); 261 234 262 235 nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); 263 236 mutex_unlock(&dmac->lock); ··· 1271 1264 { 1272 1265 struct nv50_mstm *mstm = *pmstm; 1273 1266 if (mstm) { 1267 + drm_dp_mst_topology_mgr_destroy(&mstm->mgr); 1274 1268 kfree(*pmstm); 1275 1269 *pmstm = NULL; 1276 1270 }
+6
drivers/gpu/drm/nouveau/nouveau_drm.c
··· 1171 1171 goto err_free; 1172 1172 } 1173 1173 1174 + err = nouveau_drm_device_init(drm); 1175 + if (err) 1176 + goto err_put; 1177 + 1174 1178 platform_set_drvdata(pdev, drm); 1175 1179 1176 1180 return drm; 1177 1181 1182 + err_put: 1183 + drm_dev_put(drm); 1178 1184 err_free: 1179 1185 nvkm_device_del(pdevice); 1180 1186
-6
drivers/gpu/drm/rockchip/rockchip_drm_drv.c
··· 448 448 return 0; 449 449 } 450 450 451 - static void rockchip_drm_platform_shutdown(struct platform_device *pdev) 452 - { 453 - rockchip_drm_platform_remove(pdev); 454 - } 455 - 456 451 static const struct of_device_id rockchip_drm_dt_ids[] = { 457 452 { .compatible = "rockchip,display-subsystem", }, 458 453 { /* sentinel */ }, ··· 457 462 static struct platform_driver rockchip_drm_platform_driver = { 458 463 .probe = rockchip_drm_platform_probe, 459 464 .remove = rockchip_drm_platform_remove, 460 - .shutdown = rockchip_drm_platform_shutdown, 461 465 .driver = { 462 466 .name = "rockchip-drm", 463 467 .of_match_table = rockchip_drm_dt_ids,
+3 -1
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 49 49 50 50 #define VMWGFX_REPO "In Tree" 51 51 52 + #define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE) 53 + 52 54 53 55 /** 54 56 * Fully encoded drm commands. Might move to vmw_drm.h ··· 920 918 spin_unlock(&dev_priv->cap_lock); 921 919 } 922 920 923 - 921 + vmw_validation_mem_init_ttm(dev_priv, VMWGFX_VALIDATION_MEM_GRAN); 924 922 ret = vmw_kms_init(dev_priv); 925 923 if (unlikely(ret != 0)) 926 924 goto out_no_kms;
+5
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
··· 606 606 607 607 struct vmw_cmdbuf_man *cman; 608 608 DECLARE_BITMAP(irqthread_pending, VMW_IRQTHREAD_MAX); 609 + 610 + /* Validation memory reservation */ 611 + struct vmw_validation_mem vvm; 609 612 }; 610 613 611 614 static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res) ··· 849 846 extern void vmw_ttm_global_release(struct vmw_private *dev_priv); 850 847 extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma); 851 848 849 + extern void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv, 850 + size_t gran); 852 851 /** 853 852 * TTM buffer object driver - vmwgfx_ttm_buffer.c 854 853 */
+2 -2
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
··· 1738 1738 void *buf) 1739 1739 { 1740 1740 struct vmw_buffer_object *vmw_bo; 1741 - int ret; 1742 1741 1743 1742 struct { 1744 1743 uint32_t header; ··· 1747 1748 return vmw_translate_guest_ptr(dev_priv, sw_context, 1748 1749 &cmd->body.ptr, 1749 1750 &vmw_bo); 1750 - return ret; 1751 1751 } 1752 1752 1753 1753 ··· 3834 3836 int32_t out_fence_fd = -1; 3835 3837 struct sync_file *sync_file = NULL; 3836 3838 DECLARE_VAL_CONTEXT(val_ctx, &sw_context->res_ht, 1); 3839 + 3840 + vmw_validation_set_val_mem(&val_ctx, &dev_priv->vvm); 3837 3841 3838 3842 if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) { 3839 3843 out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
+36
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
··· 96 96 drm_global_item_unref(&dev_priv->bo_global_ref.ref); 97 97 drm_global_item_unref(&dev_priv->mem_global_ref); 98 98 } 99 + 100 + /* struct vmw_validation_mem callback */ 101 + static int vmw_vmt_reserve(struct vmw_validation_mem *m, size_t size) 102 + { 103 + static struct ttm_operation_ctx ctx = {.interruptible = false, 104 + .no_wait_gpu = false}; 105 + struct vmw_private *dev_priv = container_of(m, struct vmw_private, vvm); 106 + 107 + return ttm_mem_global_alloc(vmw_mem_glob(dev_priv), size, &ctx); 108 + } 109 + 110 + /* struct vmw_validation_mem callback */ 111 + static void vmw_vmt_unreserve(struct vmw_validation_mem *m, size_t size) 112 + { 113 + struct vmw_private *dev_priv = container_of(m, struct vmw_private, vvm); 114 + 115 + return ttm_mem_global_free(vmw_mem_glob(dev_priv), size); 116 + } 117 + 118 + /** 119 + * vmw_validation_mem_init_ttm - Interface the validation memory tracker 120 + * to ttm. 121 + * @dev_priv: Pointer to struct vmw_private. The reason we choose a vmw private 122 + * rather than a struct vmw_validation_mem is to make sure assumption in the 123 + * callbacks that struct vmw_private derives from struct vmw_validation_mem 124 + * holds true. 125 + * @gran: The recommended allocation granularity 126 + */ 127 + void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv, size_t gran) 128 + { 129 + struct vmw_validation_mem *vvm = &dev_priv->vvm; 130 + 131 + vvm->reserve_mem = vmw_vmt_reserve; 132 + vvm->unreserve_mem = vmw_vmt_unreserve; 133 + vvm->gran = gran; 134 + }
+20 -1
drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
··· 104 104 return NULL; 105 105 106 106 if (ctx->mem_size_left < size) { 107 - struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO); 107 + struct page *page; 108 108 109 + if (ctx->vm && ctx->vm_size_left < PAGE_SIZE) { 110 + int ret = ctx->vm->reserve_mem(ctx->vm, ctx->vm->gran); 111 + 112 + if (ret) 113 + return NULL; 114 + 115 + ctx->vm_size_left += ctx->vm->gran; 116 + ctx->total_mem += ctx->vm->gran; 117 + } 118 + 119 + page = alloc_page(GFP_KERNEL | __GFP_ZERO); 109 120 if (!page) 110 121 return NULL; 122 + 123 + if (ctx->vm) 124 + ctx->vm_size_left -= PAGE_SIZE; 111 125 112 126 list_add_tail(&page->lru, &ctx->page_list); 113 127 ctx->page_address = page_address(page); ··· 152 138 } 153 139 154 140 ctx->mem_size_left = 0; 141 + if (ctx->vm && ctx->total_mem) { 142 + ctx->vm->unreserve_mem(ctx->vm, ctx->total_mem); 143 + ctx->total_mem = 0; 144 + ctx->vm_size_left = 0; 145 + } 155 146 } 156 147 157 148 /**
+37
drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
··· 34 34 #include <drm/ttm/ttm_execbuf_util.h> 35 35 36 36 /** 37 + * struct vmw_validation_mem - Custom interface to provide memory reservations 38 + * for the validation code. 39 + * @reserve_mem: Callback to reserve memory 40 + * @unreserve_mem: Callback to unreserve memory 41 + * @gran: Reservation granularity. Contains a hint how much memory should 42 + * be reserved in each call to @reserve_mem(). A slow implementation may want 43 + * reservation to be done in large batches. 44 + */ 45 + struct vmw_validation_mem { 46 + int (*reserve_mem)(struct vmw_validation_mem *m, size_t size); 47 + void (*unreserve_mem)(struct vmw_validation_mem *m, size_t size); 48 + size_t gran; 49 + }; 50 + 51 + /** 37 52 * struct vmw_validation_context - Per command submission validation context 38 53 * @ht: Hash table used to find resource- or buffer object duplicates 39 54 * @resource_list: List head for resource validation metadata ··· 62 47 * buffer objects 63 48 * @mem_size_left: Free memory left in the last page in @page_list 64 49 * @page_address: Kernel virtual address of the last page in @page_list 50 + * @vm: A pointer to the memory reservation interface or NULL if no 51 + * memory reservation is needed. 52 + * @vm_size_left: Amount of reserved memory that so far has not been allocated. 53 + * @total_mem: Amount of reserved memory. 65 54 */ 66 55 struct vmw_validation_context { 67 56 struct drm_open_hash *ht; ··· 78 59 unsigned int merge_dups; 79 60 unsigned int mem_size_left; 80 61 u8 *page_address; 62 + struct vmw_validation_mem *vm; 63 + size_t vm_size_left; 64 + size_t total_mem; 81 65 }; 82 66 83 67 struct vmw_buffer_object; ··· 121 99 vmw_validation_has_bos(struct vmw_validation_context *ctx) 122 100 { 123 101 return !list_empty(&ctx->bo_list); 102 + } 103 + 104 + /** 105 + * vmw_validation_set_val_mem - Register a validation mem object for 106 + * validation memory reservation 107 + * @ctx: The validation context 108 + * @vm: Pointer to a struct vmw_validation_mem 109 + * 110 + * Must be set before the first attempt to allocate validation memory. 111 + */ 112 + static inline void 113 + vmw_validation_set_val_mem(struct vmw_validation_context *ctx, 114 + struct vmw_validation_mem *vm) 115 + { 116 + ctx->vm = vm; 124 117 } 125 118 126 119 /**