aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c36
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c7
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device.c7
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/smu7_ppsmc.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c6
-rw-r--r--drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c3
-rw-r--r--drivers/gpu/drm/i915/gvt/fb_decoder.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c1
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h9
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c54
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c7
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c2
-rw-r--r--drivers/gpu/drm/i915/intel_engine_cs.c44
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c30
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c52
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h7
-rw-r--r--drivers/gpu/drm/i915/intel_workarounds.c591
-rw-r--r--drivers/gpu/drm/i915/intel_workarounds.h26
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c11
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/disp.c30
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c6
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c6
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h5
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c36
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_validation.c21
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_validation.h37
31 files changed, 718 insertions, 335 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 0767f1d1b579..3318f30903b2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4847,6 +4847,7 @@ F: include/uapi/drm/vmwgfx_drm.h
4847 4847
4848DRM DRIVERS 4848DRM DRIVERS
4849M: David Airlie <airlied@linux.ie> 4849M: David Airlie <airlied@linux.ie>
4850M: Daniel Vetter <daniel@ffwll.ch>
4850L: dri-devel@lists.freedesktop.org 4851L: dri-devel@lists.freedesktop.org
4851T: git git://anongit.freedesktop.org/drm/drm 4852T: git git://anongit.freedesktop.org/drm/drm
4852B: https://bugs.freedesktop.org/ 4853B: https://bugs.freedesktop.org/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index 8816c697b205..387f1cf1dc20 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -330,7 +330,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
330 case CHIP_TOPAZ: 330 case CHIP_TOPAZ:
331 if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || 331 if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
332 ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || 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 info->is_kicker = true; 336 info->is_kicker = true;
335 strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); 337 strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
336 } else 338 } else
@@ -351,7 +353,6 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
351 if (type == CGS_UCODE_ID_SMU) { 353 if (type == CGS_UCODE_ID_SMU) {
352 if (((adev->pdev->device == 0x67ef) && 354 if (((adev->pdev->device == 0x67ef) &&
353 ((adev->pdev->revision == 0xe0) || 355 ((adev->pdev->revision == 0xe0) ||
354 (adev->pdev->revision == 0xe2) ||
355 (adev->pdev->revision == 0xe5))) || 356 (adev->pdev->revision == 0xe5))) ||
356 ((adev->pdev->device == 0x67ff) && 357 ((adev->pdev->device == 0x67ff) &&
357 ((adev->pdev->revision == 0xcf) || 358 ((adev->pdev->revision == 0xcf) ||
@@ -359,8 +360,13 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
359 (adev->pdev->revision == 0xff)))) { 360 (adev->pdev->revision == 0xff)))) {
360 info->is_kicker = true; 361 info->is_kicker = true;
361 strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); 362 strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
362 } else 363 } else if ((adev->pdev->device == 0x67ef) &&
364 (adev->pdev->revision == 0xe2)) {
365 info->is_kicker = true;
366 strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
367 } else {
363 strcpy(fw_name, "amdgpu/polaris11_smc.bin"); 368 strcpy(fw_name, "amdgpu/polaris11_smc.bin");
369 }
364 } else if (type == CGS_UCODE_ID_SMU_SK) { 370 } else if (type == CGS_UCODE_ID_SMU_SK) {
365 strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin"); 371 strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
366 } 372 }
@@ -375,17 +381,35 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
375 (adev->pdev->revision == 0xe7) || 381 (adev->pdev->revision == 0xe7) ||
376 (adev->pdev->revision == 0xef))) || 382 (adev->pdev->revision == 0xef))) ||
377 ((adev->pdev->device == 0x6fdf) && 383 ((adev->pdev->device == 0x6fdf) &&
378 (adev->pdev->revision == 0xef))) { 384 ((adev->pdev->revision == 0xef) ||
385 (adev->pdev->revision == 0xff)))) {
379 info->is_kicker = true; 386 info->is_kicker = true;
380 strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); 387 strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
381 } else 388 } else if ((adev->pdev->device == 0x67df) &&
389 ((adev->pdev->revision == 0xe1) ||
390 (adev->pdev->revision == 0xf7))) {
391 info->is_kicker = true;
392 strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
393 } else {
382 strcpy(fw_name, "amdgpu/polaris10_smc.bin"); 394 strcpy(fw_name, "amdgpu/polaris10_smc.bin");
395 }
383 } else if (type == CGS_UCODE_ID_SMU_SK) { 396 } else if (type == CGS_UCODE_ID_SMU_SK) {
384 strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin"); 397 strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
385 } 398 }
386 break; 399 break;
387 case CHIP_POLARIS12: 400 case CHIP_POLARIS12:
388 strcpy(fw_name, "amdgpu/polaris12_smc.bin"); 401 if (((adev->pdev->device == 0x6987) &&
402 ((adev->pdev->revision == 0xc0) ||
403 (adev->pdev->revision == 0xc3))) ||
404 ((adev->pdev->device == 0x6981) &&
405 ((adev->pdev->revision == 0x00) ||
406 (adev->pdev->revision == 0x01) ||
407 (adev->pdev->revision == 0x10)))) {
408 info->is_kicker = true;
409 strcpy(fw_name, "amdgpu/polaris12_k_smc.bin");
410 } else {
411 strcpy(fw_name, "amdgpu/polaris12_smc.bin");
412 }
389 break; 413 break;
390 case CHIP_VEGAM: 414 case CHIP_VEGAM:
391 strcpy(fw_name, "amdgpu/vegam_smc.bin"); 415 strcpy(fw_name, "amdgpu/vegam_smc.bin");
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 663043c8f0f5..0acc8dee2cb8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -124,14 +124,14 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
124 goto free_chunk; 124 goto free_chunk;
125 } 125 }
126 126
127 mutex_lock(&p->ctx->lock);
128
127 /* skip guilty context job */ 129 /* skip guilty context job */
128 if (atomic_read(&p->ctx->guilty) == 1) { 130 if (atomic_read(&p->ctx->guilty) == 1) {
129 ret = -ECANCELED; 131 ret = -ECANCELED;
130 goto free_chunk; 132 goto free_chunk;
131 } 133 }
132 134
133 mutex_lock(&p->ctx->lock);
134
135 /* get chunks */ 135 /* get chunks */
136 chunk_array_user = u64_to_user_ptr(cs->in.chunks); 136 chunk_array_user = u64_to_user_ptr(cs->in.chunks);
137 if (copy_from_user(chunk_array, chunk_array_user, 137 if (copy_from_user(chunk_array, chunk_array_user,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 8de55f7f1a3a..74b611e8a1b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -872,7 +872,13 @@ static const struct pci_device_id pciidlist[] = {
872 {0x1002, 0x6864, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 872 {0x1002, 0x6864, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
873 {0x1002, 0x6867, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 873 {0x1002, 0x6867, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
874 {0x1002, 0x6868, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 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 {0x1002, 0x686c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 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 {0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, 882 {0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10},
877 /* Vega 12 */ 883 /* Vega 12 */
878 {0x1002, 0x69A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12}, 884 {0x1002, 0x69A0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA12},
@@ -885,6 +891,7 @@ static const struct pci_device_id pciidlist[] = {
885 {0x1002, 0x66A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 891 {0x1002, 0x66A1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
886 {0x1002, 0x66A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 892 {0x1002, 0x66A2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
887 {0x1002, 0x66A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 893 {0x1002, 0x66A3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
894 {0x1002, 0x66A4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
888 {0x1002, 0x66A7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 895 {0x1002, 0x66A7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
889 {0x1002, 0x66AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20}, 896 {0x1002, 0x66AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA20},
890 /* Raven */ 897 /* Raven */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index a9f18ea7e354..e4ded890b1cb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -337,12 +337,19 @@ static const struct kfd_deviceid supported_devices[] = {
337 { 0x6864, &vega10_device_info }, /* Vega10 */ 337 { 0x6864, &vega10_device_info }, /* Vega10 */
338 { 0x6867, &vega10_device_info }, /* Vega10 */ 338 { 0x6867, &vega10_device_info }, /* Vega10 */
339 { 0x6868, &vega10_device_info }, /* Vega10 */ 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 { 0x686C, &vega10_vf_device_info }, /* Vega10 vf*/ 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 { 0x687F, &vega10_device_info }, /* Vega10 */ 347 { 0x687F, &vega10_device_info }, /* Vega10 */
342 { 0x66a0, &vega20_device_info }, /* Vega20 */ 348 { 0x66a0, &vega20_device_info }, /* Vega20 */
343 { 0x66a1, &vega20_device_info }, /* Vega20 */ 349 { 0x66a1, &vega20_device_info }, /* Vega20 */
344 { 0x66a2, &vega20_device_info }, /* Vega20 */ 350 { 0x66a2, &vega20_device_info }, /* Vega20 */
345 { 0x66a3, &vega20_device_info }, /* Vega20 */ 351 { 0x66a3, &vega20_device_info }, /* Vega20 */
352 { 0x66a4, &vega20_device_info }, /* Vega20 */
346 { 0x66a7, &vega20_device_info }, /* Vega20 */ 353 { 0x66a7, &vega20_device_info }, /* Vega20 */
347 { 0x66af, &vega20_device_info } /* Vega20 */ 354 { 0x66af, &vega20_device_info } /* Vega20 */
348}; 355};
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
index 3367dd30cdd0..3b7fce5d7258 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
@@ -130,7 +130,7 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr)
130 data->registry_data.disable_auto_wattman = 1; 130 data->registry_data.disable_auto_wattman = 1;
131 data->registry_data.auto_wattman_debug = 0; 131 data->registry_data.auto_wattman_debug = 0;
132 data->registry_data.auto_wattman_sample_period = 100; 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 data->registry_data.auto_wattman_threshold = 50; 134 data->registry_data.auto_wattman_threshold = 50;
135 data->registry_data.gfxoff_controlled_by_driver = 1; 135 data->registry_data.gfxoff_controlled_by_driver = 1;
136 data->gfxoff_allowed = false; 136 data->gfxoff_allowed = false;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu7_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/smu7_ppsmc.h
index 62f36ba2435b..c1a99dfe4913 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/smu7_ppsmc.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/smu7_ppsmc.h
@@ -386,6 +386,8 @@ typedef uint16_t PPSMC_Result;
386#define PPSMC_MSG_AgmResetPsm ((uint16_t) 0x403) 386#define PPSMC_MSG_AgmResetPsm ((uint16_t) 0x403)
387#define PPSMC_MSG_ReadVftCell ((uint16_t) 0x404) 387#define PPSMC_MSG_ReadVftCell ((uint16_t) 0x404)
388 388
389#define PPSMC_MSG_ApplyAvfsCksOffVoltage ((uint16_t) 0x415)
390
389#define PPSMC_MSG_GFX_CU_PG_ENABLE ((uint16_t) 0x280) 391#define PPSMC_MSG_GFX_CU_PG_ENABLE ((uint16_t) 0x280)
390#define PPSMC_MSG_GFX_CU_PG_DISABLE ((uint16_t) 0x281) 392#define PPSMC_MSG_GFX_CU_PG_DISABLE ((uint16_t) 0x281)
391#define PPSMC_MSG_GetCurrPkgPwr ((uint16_t) 0x282) 393#define PPSMC_MSG_GetCurrPkgPwr ((uint16_t) 0x282)
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
index 872d3824337b..a1e0ac9ae248 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c
@@ -1985,6 +1985,12 @@ int polaris10_thermal_avfs_enable(struct pp_hwmgr *hwmgr)
1985 1985
1986 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAvfs); 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 return 0; 1994 return 0;
1989} 1995}
1990 1996
diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
index 99d5e4f98f49..a6edd5df33b0 100644
--- a/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
+++ b/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c
@@ -37,10 +37,13 @@ MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
37MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); 37MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
38MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); 38MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
39MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin"); 39MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin");
40MODULE_FIRMWARE("amdgpu/polaris10_k2_smc.bin");
40MODULE_FIRMWARE("amdgpu/polaris11_smc.bin"); 41MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
41MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin"); 42MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
42MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin"); 43MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
44MODULE_FIRMWARE("amdgpu/polaris11_k2_smc.bin");
43MODULE_FIRMWARE("amdgpu/polaris12_smc.bin"); 45MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
46MODULE_FIRMWARE("amdgpu/polaris12_k_smc.bin");
44MODULE_FIRMWARE("amdgpu/vegam_smc.bin"); 47MODULE_FIRMWARE("amdgpu/vegam_smc.bin");
45MODULE_FIRMWARE("amdgpu/vega10_smc.bin"); 48MODULE_FIRMWARE("amdgpu/vega10_smc.bin");
46MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin"); 49MODULE_FIRMWARE("amdgpu/vega10_acg_smc.bin");
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c
index 481896fb712a..85e6736f0a32 100644
--- a/drivers/gpu/drm/i915/gvt/fb_decoder.c
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -235,7 +235,7 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
235 plane->bpp = skl_pixel_formats[fmt].bpp; 235 plane->bpp = skl_pixel_formats[fmt].bpp;
236 plane->drm_format = skl_pixel_formats[fmt].drm_format; 236 plane->drm_format = skl_pixel_formats[fmt].drm_format;
237 } else { 237 } else {
238 plane->tiled = !!(val & DISPPLANE_TILED); 238 plane->tiled = val & DISPPLANE_TILED;
239 fmt = bdw_format_to_drm(val & DISPPLANE_PIXFORMAT_MASK); 239 fmt = bdw_format_to_drm(val & DISPPLANE_PIXFORMAT_MASK);
240 plane->bpp = bdw_pixel_formats[fmt].bpp; 240 plane->bpp = bdw_pixel_formats[fmt].bpp;
241 plane->drm_format = bdw_pixel_formats[fmt].drm_format; 241 plane->drm_format = bdw_pixel_formats[fmt].drm_format;
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ffdbbac4400e..47062ee979cf 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1444,6 +1444,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
1444 1444
1445 intel_uncore_sanitize(dev_priv); 1445 intel_uncore_sanitize(dev_priv);
1446 1446
1447 intel_gt_init_workarounds(dev_priv);
1447 i915_gem_load_init_fences(dev_priv); 1448 i915_gem_load_init_fences(dev_priv);
1448 1449
1449 /* On the 945G/GM, the chipset reports the MSI capability on the 1450 /* On the 945G/GM, the chipset reports the MSI capability on the
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9102571e9692..872a2e159a5f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -67,6 +67,7 @@
67#include "intel_ringbuffer.h" 67#include "intel_ringbuffer.h"
68#include "intel_uncore.h" 68#include "intel_uncore.h"
69#include "intel_wopcm.h" 69#include "intel_wopcm.h"
70#include "intel_workarounds.h"
70#include "intel_uc.h" 71#include "intel_uc.h"
71 72
72#include "i915_gem.h" 73#include "i915_gem.h"
@@ -1805,6 +1806,7 @@ struct drm_i915_private {
1805 int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; 1806 int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
1806 1807
1807 struct i915_workarounds workarounds; 1808 struct i915_workarounds workarounds;
1809 struct i915_wa_list gt_wa_list;
1808 1810
1809 struct i915_frontbuffer_tracking fb_tracking; 1811 struct i915_frontbuffer_tracking fb_tracking;
1810 1812
@@ -2148,6 +2150,8 @@ struct drm_i915_private {
2148 struct delayed_work idle_work; 2150 struct delayed_work idle_work;
2149 2151
2150 ktime_t last_init_time; 2152 ktime_t last_init_time;
2153
2154 struct i915_vma *scratch;
2151 } gt; 2155 } gt;
2152 2156
2153 /* perform PHY state sanity checks? */ 2157 /* perform PHY state sanity checks? */
@@ -3870,4 +3874,9 @@ static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
3870 return I915_HWS_CSB_WRITE_INDEX; 3874 return I915_HWS_CSB_WRITE_INDEX;
3871} 3875}
3872 3876
3877static inline u32 i915_scratch_offset(const struct drm_i915_private *i915)
3878{
3879 return i915_ggtt_offset(i915->gt.scratch);
3880}
3881
3873#endif 3882#endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0c8aa57ce83b..6ae9a6080cc8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5305,7 +5305,7 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
5305 } 5305 }
5306 } 5306 }
5307 5307
5308 intel_gt_workarounds_apply(dev_priv); 5308 intel_gt_apply_workarounds(dev_priv);
5309 5309
5310 i915_gem_init_swizzling(dev_priv); 5310 i915_gem_init_swizzling(dev_priv);
5311 5311
@@ -5500,6 +5500,44 @@ err_active:
5500 goto out_ctx; 5500 goto out_ctx;
5501} 5501}
5502 5502
5503static int
5504i915_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
5531err_unref:
5532 i915_gem_object_put(obj);
5533 return ret;
5534}
5535
5536static void i915_gem_fini_scratch(struct drm_i915_private *i915)
5537{
5538 i915_vma_unpin_and_release(&i915->gt.scratch, 0);
5539}
5540
5503int i915_gem_init(struct drm_i915_private *dev_priv) 5541int i915_gem_init(struct drm_i915_private *dev_priv)
5504{ 5542{
5505 int ret; 5543 int ret;
@@ -5546,12 +5584,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
5546 goto err_unlock; 5584 goto err_unlock;
5547 } 5585 }
5548 5586
5549 ret = i915_gem_contexts_init(dev_priv); 5587 ret = i915_gem_init_scratch(dev_priv,
5588 IS_GEN2(dev_priv) ? SZ_256K : PAGE_SIZE);
5550 if (ret) { 5589 if (ret) {
5551 GEM_BUG_ON(ret == -EIO); 5590 GEM_BUG_ON(ret == -EIO);
5552 goto err_ggtt; 5591 goto err_ggtt;
5553 } 5592 }
5554 5593
5594 ret = i915_gem_contexts_init(dev_priv);
5595 if (ret) {
5596 GEM_BUG_ON(ret == -EIO);
5597 goto err_scratch;
5598 }
5599
5555 ret = intel_engines_init(dev_priv); 5600 ret = intel_engines_init(dev_priv);
5556 if (ret) { 5601 if (ret) {
5557 GEM_BUG_ON(ret == -EIO); 5602 GEM_BUG_ON(ret == -EIO);
@@ -5624,6 +5669,8 @@ err_pm:
5624err_context: 5669err_context:
5625 if (ret != -EIO) 5670 if (ret != -EIO)
5626 i915_gem_contexts_fini(dev_priv); 5671 i915_gem_contexts_fini(dev_priv);
5672err_scratch:
5673 i915_gem_fini_scratch(dev_priv);
5627err_ggtt: 5674err_ggtt:
5628err_unlock: 5675err_unlock:
5629 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); 5676 intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
@@ -5675,8 +5722,11 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)
5675 intel_uc_fini(dev_priv); 5722 intel_uc_fini(dev_priv);
5676 i915_gem_cleanup_engines(dev_priv); 5723 i915_gem_cleanup_engines(dev_priv);
5677 i915_gem_contexts_fini(dev_priv); 5724 i915_gem_contexts_fini(dev_priv);
5725 i915_gem_fini_scratch(dev_priv);
5678 mutex_unlock(&dev_priv->drm.struct_mutex); 5726 mutex_unlock(&dev_priv->drm.struct_mutex);
5679 5727
5728 intel_wa_list_free(&dev_priv->gt_wa_list);
5729
5680 intel_cleanup_gt_powersave(dev_priv); 5730 intel_cleanup_gt_powersave(dev_priv);
5681 5731
5682 intel_uc_fini_misc(dev_priv); 5732 intel_uc_fini_misc(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index d4fac09095f8..1aaccbe7e1de 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1268,7 +1268,7 @@ relocate_entry(struct i915_vma *vma,
1268 else if (gen >= 4) 1268 else if (gen >= 4)
1269 len = 4; 1269 len = 4;
1270 else 1270 else
1271 len = 6; 1271 len = 3;
1272 1272
1273 batch = reloc_gpu(eb, vma, len); 1273 batch = reloc_gpu(eb, vma, len);
1274 if (IS_ERR(batch)) 1274 if (IS_ERR(batch))
@@ -1309,11 +1309,6 @@ relocate_entry(struct i915_vma *vma,
1309 *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL; 1309 *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
1310 *batch++ = addr; 1310 *batch++ = addr;
1311 *batch++ = target_offset; 1311 *batch++ = target_offset;
1312
1313 /* And again for good measure (blb/pnv) */
1314 *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
1315 *batch++ = addr;
1316 *batch++ = target_offset;
1317 } 1312 }
1318 1313
1319 goto out; 1314 goto out;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 3eb33e000d6f..db4128d6c09b 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1495,7 +1495,7 @@ static void gem_record_rings(struct i915_gpu_state *error)
1495 if (HAS_BROKEN_CS_TLB(i915)) 1495 if (HAS_BROKEN_CS_TLB(i915))
1496 ee->wa_batchbuffer = 1496 ee->wa_batchbuffer =
1497 i915_error_object_create(i915, 1497 i915_error_object_create(i915,
1498 engine->scratch); 1498 i915->gt.scratch);
1499 request_record_user_bo(request, ee); 1499 request_record_user_bo(request, ee);
1500 1500
1501 ee->ctx = 1501 ee->ctx =
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 217ed3ee1cab..76b5f94ea6cb 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -490,46 +490,6 @@ void intel_engine_setup_common(struct intel_engine_cs *engine)
490 intel_engine_init_cmd_parser(engine); 490 intel_engine_init_cmd_parser(engine);
491} 491}
492 492
493int 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
523err_unref:
524 i915_gem_object_put(obj);
525 return ret;
526}
527
528void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
529{
530 i915_vma_unpin_and_release(&engine->scratch, 0);
531}
532
533static void cleanup_status_page(struct intel_engine_cs *engine) 493static void cleanup_status_page(struct intel_engine_cs *engine)
534{ 494{
535 if (HWS_NEEDS_PHYSICAL(engine->i915)) { 495 if (HWS_NEEDS_PHYSICAL(engine->i915)) {
@@ -704,8 +664,6 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
704{ 664{
705 struct drm_i915_private *i915 = engine->i915; 665 struct drm_i915_private *i915 = engine->i915;
706 666
707 intel_engine_cleanup_scratch(engine);
708
709 cleanup_status_page(engine); 667 cleanup_status_page(engine);
710 668
711 intel_engine_fini_breadcrumbs(engine); 669 intel_engine_fini_breadcrumbs(engine);
@@ -720,6 +678,8 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
720 __intel_context_unpin(i915->kernel_context, engine); 678 __intel_context_unpin(i915->kernel_context, engine);
721 679
722 i915_timeline_fini(&engine->timeline); 680 i915_timeline_fini(&engine->timeline);
681
682 intel_wa_list_free(&engine->wa_list);
723} 683}
724 684
725u64 intel_engine_get_active_head(const struct intel_engine_cs *engine) 685u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 37c94a54efcb..58d1d3d47dd3 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -442,8 +442,13 @@ static u64 execlists_update_context(struct i915_request *rq)
442 * may not be visible to the HW prior to the completion of the UC 442 * may not be visible to the HW prior to the completion of the UC
443 * register write and that we may begin execution from the context 443 * register write and that we may begin execution from the context
444 * before its image is complete leading to invalid PD chasing. 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 return ce->lrc_desc; 452 return ce->lrc_desc;
448} 453}
449 454
@@ -1443,9 +1448,10 @@ static int execlists_request_alloc(struct i915_request *request)
1443static u32 * 1448static u32 *
1444gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch) 1449gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch)
1445{ 1450{
1451 /* NB no one else is allowed to scribble over scratch + 256! */
1446 *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 1452 *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT;
1447 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 1453 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4);
1448 *batch++ = i915_ggtt_offset(engine->scratch) + 256; 1454 *batch++ = i915_scratch_offset(engine->i915) + 256;
1449 *batch++ = 0; 1455 *batch++ = 0;
1450 1456
1451 *batch++ = MI_LOAD_REGISTER_IMM(1); 1457 *batch++ = MI_LOAD_REGISTER_IMM(1);
@@ -1459,7 +1465,7 @@ gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch)
1459 1465
1460 *batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 1466 *batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT;
1461 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 1467 *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4);
1462 *batch++ = i915_ggtt_offset(engine->scratch) + 256; 1468 *batch++ = i915_scratch_offset(engine->i915) + 256;
1463 *batch++ = 0; 1469 *batch++ = 0;
1464 1470
1465 return batch; 1471 return batch;
@@ -1496,7 +1502,7 @@ static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
1496 PIPE_CONTROL_GLOBAL_GTT_IVB | 1502 PIPE_CONTROL_GLOBAL_GTT_IVB |
1497 PIPE_CONTROL_CS_STALL | 1503 PIPE_CONTROL_CS_STALL |
1498 PIPE_CONTROL_QW_WRITE, 1504 PIPE_CONTROL_QW_WRITE,
1499 i915_ggtt_offset(engine->scratch) + 1505 i915_scratch_offset(engine->i915) +
1500 2 * CACHELINE_BYTES); 1506 2 * CACHELINE_BYTES);
1501 1507
1502 *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; 1508 *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
@@ -1573,7 +1579,7 @@ static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
1573 PIPE_CONTROL_GLOBAL_GTT_IVB | 1579 PIPE_CONTROL_GLOBAL_GTT_IVB |
1574 PIPE_CONTROL_CS_STALL | 1580 PIPE_CONTROL_CS_STALL |
1575 PIPE_CONTROL_QW_WRITE, 1581 PIPE_CONTROL_QW_WRITE,
1576 i915_ggtt_offset(engine->scratch) 1582 i915_scratch_offset(engine->i915)
1577 + 2 * CACHELINE_BYTES); 1583 + 2 * CACHELINE_BYTES);
1578 } 1584 }
1579 1585
@@ -1793,6 +1799,8 @@ static bool unexpected_starting_state(struct intel_engine_cs *engine)
1793 1799
1794static int gen8_init_common_ring(struct intel_engine_cs *engine) 1800static int gen8_init_common_ring(struct intel_engine_cs *engine)
1795{ 1801{
1802 intel_engine_apply_workarounds(engine);
1803
1796 intel_mocs_init_engine(engine); 1804 intel_mocs_init_engine(engine);
1797 1805
1798 intel_engine_reset_breadcrumbs(engine); 1806 intel_engine_reset_breadcrumbs(engine);
@@ -2139,7 +2147,7 @@ static int gen8_emit_flush_render(struct i915_request *request,
2139{ 2147{
2140 struct intel_engine_cs *engine = request->engine; 2148 struct intel_engine_cs *engine = request->engine;
2141 u32 scratch_addr = 2149 u32 scratch_addr =
2142 i915_ggtt_offset(engine->scratch) + 2 * CACHELINE_BYTES; 2150 i915_scratch_offset(engine->i915) + 2 * CACHELINE_BYTES;
2143 bool vf_flush_wa = false, dc_flush_wa = false; 2151 bool vf_flush_wa = false, dc_flush_wa = false;
2144 u32 *cs, flags = 0; 2152 u32 *cs, flags = 0;
2145 int len; 2153 int len;
@@ -2476,10 +2484,6 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
2476 if (ret) 2484 if (ret)
2477 return ret; 2485 return ret;
2478 2486
2479 ret = intel_engine_create_scratch(engine, PAGE_SIZE);
2480 if (ret)
2481 goto err_cleanup_common;
2482
2483 ret = intel_init_workaround_bb(engine); 2487 ret = intel_init_workaround_bb(engine);
2484 if (ret) { 2488 if (ret) {
2485 /* 2489 /*
@@ -2491,11 +2495,9 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
2491 ret); 2495 ret);
2492 } 2496 }
2493 2497
2494 return 0; 2498 intel_engine_init_workarounds(engine);
2495 2499
2496err_cleanup_common: 2500 return 0;
2497 intel_engine_cleanup_common(engine);
2498 return ret;
2499} 2501}
2500 2502
2501int logical_xcs_ring_init(struct intel_engine_cs *engine) 2503int logical_xcs_ring_init(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 187bb0ceb4ac..1f8d2a66c791 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -69,19 +69,28 @@ unsigned int intel_ring_update_space(struct intel_ring *ring)
69static int 69static int
70gen2_render_ring_flush(struct i915_request *rq, u32 mode) 70gen2_render_ring_flush(struct i915_request *rq, u32 mode)
71{ 71{
72 unsigned int num_store_dw;
72 u32 cmd, *cs; 73 u32 cmd, *cs;
73 74
74 cmd = MI_FLUSH; 75 cmd = MI_FLUSH;
75 76 num_store_dw = 0;
76 if (mode & EMIT_INVALIDATE) 77 if (mode & EMIT_INVALIDATE)
77 cmd |= MI_READ_FLUSH; 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 if (IS_ERR(cs)) 83 if (IS_ERR(cs))
81 return PTR_ERR(cs); 84 return PTR_ERR(cs);
82 85
83 *cs++ = cmd; 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 intel_ring_advance(rq, cs); 94 intel_ring_advance(rq, cs);
86 95
87 return 0; 96 return 0;
@@ -150,8 +159,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
150 */ 159 */
151 if (mode & EMIT_INVALIDATE) { 160 if (mode & EMIT_INVALIDATE) {
152 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 161 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
153 *cs++ = i915_ggtt_offset(rq->engine->scratch) | 162 *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT;
154 PIPE_CONTROL_GLOBAL_GTT;
155 *cs++ = 0; 163 *cs++ = 0;
156 *cs++ = 0; 164 *cs++ = 0;
157 165
@@ -159,8 +167,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
159 *cs++ = MI_FLUSH; 167 *cs++ = MI_FLUSH;
160 168
161 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE; 169 *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
162 *cs++ = i915_ggtt_offset(rq->engine->scratch) | 170 *cs++ = i915_scratch_offset(rq->i915) | PIPE_CONTROL_GLOBAL_GTT;
163 PIPE_CONTROL_GLOBAL_GTT;
164 *cs++ = 0; 171 *cs++ = 0;
165 *cs++ = 0; 172 *cs++ = 0;
166 } 173 }
@@ -212,8 +219,7 @@ gen4_render_ring_flush(struct i915_request *rq, u32 mode)
212static int 219static int
213intel_emit_post_sync_nonzero_flush(struct i915_request *rq) 220intel_emit_post_sync_nonzero_flush(struct i915_request *rq)
214{ 221{
215 u32 scratch_addr = 222 u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
216 i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
217 u32 *cs; 223 u32 *cs;
218 224
219 cs = intel_ring_begin(rq, 6); 225 cs = intel_ring_begin(rq, 6);
@@ -246,8 +252,7 @@ intel_emit_post_sync_nonzero_flush(struct i915_request *rq)
246static int 252static int
247gen6_render_ring_flush(struct i915_request *rq, u32 mode) 253gen6_render_ring_flush(struct i915_request *rq, u32 mode)
248{ 254{
249 u32 scratch_addr = 255 u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
250 i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
251 u32 *cs, flags = 0; 256 u32 *cs, flags = 0;
252 int ret; 257 int ret;
253 258
@@ -316,8 +321,7 @@ gen7_render_ring_cs_stall_wa(struct i915_request *rq)
316static int 321static int
317gen7_render_ring_flush(struct i915_request *rq, u32 mode) 322gen7_render_ring_flush(struct i915_request *rq, u32 mode)
318{ 323{
319 u32 scratch_addr = 324 u32 scratch_addr = i915_scratch_offset(rq->i915) + 2 * CACHELINE_BYTES;
320 i915_ggtt_offset(rq->engine->scratch) + 2 * CACHELINE_BYTES;
321 u32 *cs, flags = 0; 325 u32 *cs, flags = 0;
322 326
323 /* 327 /*
@@ -971,7 +975,7 @@ i965_emit_bb_start(struct i915_request *rq,
971} 975}
972 976
973/* Just userspace ABI convention to limit the wa batch bo to a resonable size */ 977/* Just userspace ABI convention to limit the wa batch bo to a resonable size */
974#define I830_BATCH_LIMIT (256*1024) 978#define I830_BATCH_LIMIT SZ_256K
975#define I830_TLB_ENTRIES (2) 979#define I830_TLB_ENTRIES (2)
976#define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT) 980#define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT)
977static int 981static int
@@ -979,7 +983,9 @@ i830_emit_bb_start(struct i915_request *rq,
979 u64 offset, u32 len, 983 u64 offset, u32 len,
980 unsigned int dispatch_flags) 984 unsigned int dispatch_flags)
981{ 985{
982 u32 *cs, cs_offset = i915_ggtt_offset(rq->engine->scratch); 986 u32 *cs, cs_offset = i915_scratch_offset(rq->i915);
987
988 GEM_BUG_ON(rq->i915->gt.scratch->size < I830_WA_SIZE);
983 989
984 cs = intel_ring_begin(rq, 6); 990 cs = intel_ring_begin(rq, 6);
985 if (IS_ERR(cs)) 991 if (IS_ERR(cs))
@@ -1437,7 +1443,6 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
1437{ 1443{
1438 struct i915_timeline *timeline; 1444 struct i915_timeline *timeline;
1439 struct intel_ring *ring; 1445 struct intel_ring *ring;
1440 unsigned int size;
1441 int err; 1446 int err;
1442 1447
1443 intel_engine_setup_common(engine); 1448 intel_engine_setup_common(engine);
@@ -1462,21 +1467,12 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
1462 GEM_BUG_ON(engine->buffer); 1467 GEM_BUG_ON(engine->buffer);
1463 engine->buffer = ring; 1468 engine->buffer = ring;
1464 1469
1465 size = PAGE_SIZE;
1466 if (HAS_BROKEN_CS_TLB(engine->i915))
1467 size = I830_WA_SIZE;
1468 err = intel_engine_create_scratch(engine, size);
1469 if (err)
1470 goto err_unpin;
1471
1472 err = intel_engine_init_common(engine); 1470 err = intel_engine_init_common(engine);
1473 if (err) 1471 if (err)
1474 goto err_scratch; 1472 goto err_unpin;
1475 1473
1476 return 0; 1474 return 0;
1477 1475
1478err_scratch:
1479 intel_engine_cleanup_scratch(engine);
1480err_unpin: 1476err_unpin:
1481 intel_ring_unpin(ring); 1477 intel_ring_unpin(ring);
1482err_ring: 1478err_ring:
@@ -1550,7 +1546,7 @@ static int flush_pd_dir(struct i915_request *rq)
1550 /* Stall until the page table load is complete */ 1546 /* Stall until the page table load is complete */
1551 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1547 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
1552 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine)); 1548 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
1553 *cs++ = i915_ggtt_offset(engine->scratch); 1549 *cs++ = i915_scratch_offset(rq->i915);
1554 *cs++ = MI_NOOP; 1550 *cs++ = MI_NOOP;
1555 1551
1556 intel_ring_advance(rq, cs); 1552 intel_ring_advance(rq, cs);
@@ -1659,7 +1655,7 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags)
1659 /* Insert a delay before the next switch! */ 1655 /* Insert a delay before the next switch! */
1660 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT; 1656 *cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
1661 *cs++ = i915_mmio_reg_offset(last_reg); 1657 *cs++ = i915_mmio_reg_offset(last_reg);
1662 *cs++ = i915_ggtt_offset(engine->scratch); 1658 *cs++ = i915_scratch_offset(rq->i915);
1663 *cs++ = MI_NOOP; 1659 *cs++ = MI_NOOP;
1664 } 1660 }
1665 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; 1661 *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 2dfa585712c2..767a7192c969 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -15,6 +15,7 @@
15#include "i915_selftest.h" 15#include "i915_selftest.h"
16#include "i915_timeline.h" 16#include "i915_timeline.h"
17#include "intel_gpu_commands.h" 17#include "intel_gpu_commands.h"
18#include "intel_workarounds.h"
18 19
19struct drm_printer; 20struct drm_printer;
20struct i915_sched_attr; 21struct i915_sched_attr;
@@ -440,7 +441,7 @@ struct intel_engine_cs {
440 441
441 struct intel_hw_status_page status_page; 442 struct intel_hw_status_page status_page;
442 struct i915_ctx_workarounds wa_ctx; 443 struct i915_ctx_workarounds wa_ctx;
443 struct i915_vma *scratch; 444 struct i915_wa_list wa_list;
444 445
445 u32 irq_keep_mask; /* always keep these interrupts */ 446 u32 irq_keep_mask; /* always keep these interrupts */
446 u32 irq_enable_mask; /* bitmask to enable ring interrupt */ 447 u32 irq_enable_mask; /* bitmask to enable ring interrupt */
@@ -898,10 +899,6 @@ void intel_engine_setup_common(struct intel_engine_cs *engine);
898int intel_engine_init_common(struct intel_engine_cs *engine); 899int intel_engine_init_common(struct intel_engine_cs *engine);
899void intel_engine_cleanup_common(struct intel_engine_cs *engine); 900void intel_engine_cleanup_common(struct intel_engine_cs *engine);
900 901
901int intel_engine_create_scratch(struct intel_engine_cs *engine,
902 unsigned int size);
903void intel_engine_cleanup_scratch(struct intel_engine_cs *engine);
904
905int intel_init_render_ring_buffer(struct intel_engine_cs *engine); 902int intel_init_render_ring_buffer(struct intel_engine_cs *engine);
906int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine); 903int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
907int intel_init_blt_ring_buffer(struct intel_engine_cs *engine); 904int intel_init_blt_ring_buffer(struct intel_engine_cs *engine);
diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c
index 4bcdeaf8d98f..6e580891db96 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.c
+++ b/drivers/gpu/drm/i915/intel_workarounds.c
@@ -48,6 +48,20 @@
48 * - Public functions to init or apply the given workaround type. 48 * - Public functions to init or apply the given workaround type.
49 */ 49 */
50 50
51static void wa_init_start(struct i915_wa_list *wal, const char *name)
52{
53 wal->name = name;
54}
55
56static 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
51static void wa_add(struct drm_i915_private *i915, 65static void wa_add(struct drm_i915_private *i915,
52 i915_reg_t reg, const u32 mask, const u32 val) 66 i915_reg_t reg, const u32 mask, const u32 val)
53{ 67{
@@ -580,160 +594,175 @@ int intel_ctx_workarounds_emit(struct i915_request *rq)
580 return 0; 594 return 0;
581} 595}
582 596
583static void bdw_gt_workarounds_apply(struct drm_i915_private *dev_priv) 597static void
598wal_add(struct i915_wa_list *wal, const struct i915_wa *wa)
599{
600 const unsigned int grow = 1 << 4;
601
602 GEM_BUG_ON(!is_power_of_2(grow));
603
604 if (IS_ALIGNED(wal->count, grow)) { /* Either uninitialized or full. */
605 struct i915_wa *list;
606
607 list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*wa),
608 GFP_KERNEL);
609 if (!list) {
610 DRM_ERROR("No space for workaround init!\n");
611 return;
612 }
613
614 if (wal->list)
615 memcpy(list, wal->list, sizeof(*wa) * wal->count);
616
617 wal->list = list;
618 }
619
620 wal->list[wal->count++] = *wa;
621}
622
623static void
624wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
625{
626 struct i915_wa wa = {
627 .reg = reg,
628 .mask = val,
629 .val = _MASKED_BIT_ENABLE(val)
630 };
631
632 wal_add(wal, &wa);
633}
634
635static void
636wa_write_masked_or(struct i915_wa_list *wal, i915_reg_t reg, u32 mask,
637 u32 val)
584{ 638{
639 struct i915_wa wa = {
640 .reg = reg,
641 .mask = mask,
642 .val = val
643 };
644
645 wal_add(wal, &wa);
585} 646}
586 647
587static void chv_gt_workarounds_apply(struct drm_i915_private *dev_priv) 648static void
649wa_write(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
588{ 650{
651 wa_write_masked_or(wal, reg, ~0, val);
589} 652}
590 653
591static void gen9_gt_workarounds_apply(struct drm_i915_private *dev_priv) 654static void
655wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
592{ 656{
593 /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ 657 wa_write_masked_or(wal, reg, val, val);
594 I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, 658}
595 _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
596 659
597 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ 660static void gen9_gt_workarounds_init(struct drm_i915_private *i915)
598 I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | 661{
599 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); 662 struct i915_wa_list *wal = &i915->gt_wa_list;
600 663
601 /* WaDisableKillLogic:bxt,skl,kbl */ 664 /* WaDisableKillLogic:bxt,skl,kbl */
602 if (!IS_COFFEELAKE(dev_priv)) 665 if (!IS_COFFEELAKE(i915))
603 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | 666 wa_write_or(wal,
604 ECOCHK_DIS_TLB); 667 GAM_ECOCHK,
668 ECOCHK_DIS_TLB);
605 669
606 if (HAS_LLC(dev_priv)) { 670 if (HAS_LLC(i915)) {
607 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl 671 /* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl
608 * 672 *
609 * Must match Display Engine. See 673 * Must match Display Engine. See
610 * WaCompressedResourceDisplayNewHashMode. 674 * WaCompressedResourceDisplayNewHashMode.
611 */ 675 */
612 I915_WRITE(MMCD_MISC_CTRL, 676 wa_write_or(wal,
613 I915_READ(MMCD_MISC_CTRL) | 677 MMCD_MISC_CTRL,
614 MMCD_PCLA | 678 MMCD_PCLA | MMCD_HOTSPOT_EN);
615 MMCD_HOTSPOT_EN);
616 } 679 }
617 680
618 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */ 681 /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
619 I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | 682 wa_write_or(wal,
620 BDW_DISABLE_HDC_INVALIDATION); 683 GAM_ECOCHK,
621 684 BDW_DISABLE_HDC_INVALIDATION);
622 /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */
623 if (IS_GEN9_LP(dev_priv)) {
624 u32 val = I915_READ(GEN8_L3SQCREG1);
625
626 val &= ~L3_PRIO_CREDITS_MASK;
627 val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
628 I915_WRITE(GEN8_L3SQCREG1, val);
629 }
630
631 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
632 I915_WRITE(GEN8_L3SQCREG4,
633 I915_READ(GEN8_L3SQCREG4) | GEN8_LQSC_FLUSH_COHERENT_LINES);
634
635 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */
636 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
637 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
638} 685}
639 686
640static void skl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 687static void skl_gt_workarounds_init(struct drm_i915_private *i915)
641{ 688{
642 gen9_gt_workarounds_apply(dev_priv); 689 struct i915_wa_list *wal = &i915->gt_wa_list;
643 690
644 /* WaEnableGapsTsvCreditFix:skl */ 691 gen9_gt_workarounds_init(i915);
645 I915_WRITE(GEN8_GARBCNTL,
646 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
647 692
648 /* WaDisableGafsUnitClkGating:skl */ 693 /* WaDisableGafsUnitClkGating:skl */
649 I915_WRITE(GEN7_UCGCTL4, 694 wa_write_or(wal,
650 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 695 GEN7_UCGCTL4,
696 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
651 697
652 /* WaInPlaceDecompressionHang:skl */ 698 /* WaInPlaceDecompressionHang:skl */
653 if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER)) 699 if (IS_SKL_REVID(i915, SKL_REVID_H0, REVID_FOREVER))
654 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 700 wa_write_or(wal,
655 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 701 GEN9_GAMT_ECO_REG_RW_IA,
656 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 702 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
657} 703}
658 704
659static void bxt_gt_workarounds_apply(struct drm_i915_private *dev_priv) 705static void bxt_gt_workarounds_init(struct drm_i915_private *i915)
660{ 706{
661 gen9_gt_workarounds_apply(dev_priv); 707 struct i915_wa_list *wal = &i915->gt_wa_list;
662 708
663 /* WaDisablePooledEuLoadBalancingFix:bxt */ 709 gen9_gt_workarounds_init(i915);
664 I915_WRITE(FF_SLICE_CS_CHICKEN2,
665 _MASKED_BIT_ENABLE(GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE));
666 710
667 /* WaInPlaceDecompressionHang:bxt */ 711 /* WaInPlaceDecompressionHang:bxt */
668 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 712 wa_write_or(wal,
669 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 713 GEN9_GAMT_ECO_REG_RW_IA,
670 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 714 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
671} 715}
672 716
673static void kbl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 717static void kbl_gt_workarounds_init(struct drm_i915_private *i915)
674{ 718{
675 gen9_gt_workarounds_apply(dev_priv); 719 struct i915_wa_list *wal = &i915->gt_wa_list;
676 720
677 /* WaEnableGapsTsvCreditFix:kbl */ 721 gen9_gt_workarounds_init(i915);
678 I915_WRITE(GEN8_GARBCNTL,
679 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
680 722
681 /* WaDisableDynamicCreditSharing:kbl */ 723 /* WaDisableDynamicCreditSharing:kbl */
682 if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0)) 724 if (IS_KBL_REVID(i915, 0, KBL_REVID_B0))
683 I915_WRITE(GAMT_CHKN_BIT_REG, 725 wa_write_or(wal,
684 I915_READ(GAMT_CHKN_BIT_REG) | 726 GAMT_CHKN_BIT_REG,
685 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING); 727 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
686 728
687 /* WaDisableGafsUnitClkGating:kbl */ 729 /* WaDisableGafsUnitClkGating:kbl */
688 I915_WRITE(GEN7_UCGCTL4, 730 wa_write_or(wal,
689 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 731 GEN7_UCGCTL4,
732 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
690 733
691 /* WaInPlaceDecompressionHang:kbl */ 734 /* WaInPlaceDecompressionHang:kbl */
692 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 735 wa_write_or(wal,
693 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 736 GEN9_GAMT_ECO_REG_RW_IA,
694 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 737 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
695
696 /* WaKBLVECSSemaphoreWaitPoll:kbl */
697 if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_E0)) {
698 struct intel_engine_cs *engine;
699 unsigned int tmp;
700
701 for_each_engine(engine, dev_priv, tmp) {
702 if (engine->id == RCS)
703 continue;
704
705 I915_WRITE(RING_SEMA_WAIT_POLL(engine->mmio_base), 1);
706 }
707 }
708} 738}
709 739
710static void glk_gt_workarounds_apply(struct drm_i915_private *dev_priv) 740static void glk_gt_workarounds_init(struct drm_i915_private *i915)
711{ 741{
712 gen9_gt_workarounds_apply(dev_priv); 742 gen9_gt_workarounds_init(i915);
713} 743}
714 744
715static void cfl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 745static void cfl_gt_workarounds_init(struct drm_i915_private *i915)
716{ 746{
717 gen9_gt_workarounds_apply(dev_priv); 747 struct i915_wa_list *wal = &i915->gt_wa_list;
718 748
719 /* WaEnableGapsTsvCreditFix:cfl */ 749 gen9_gt_workarounds_init(i915);
720 I915_WRITE(GEN8_GARBCNTL,
721 I915_READ(GEN8_GARBCNTL) | GEN9_GAPS_TSV_CREDIT_DISABLE);
722 750
723 /* WaDisableGafsUnitClkGating:cfl */ 751 /* WaDisableGafsUnitClkGating:cfl */
724 I915_WRITE(GEN7_UCGCTL4, 752 wa_write_or(wal,
725 I915_READ(GEN7_UCGCTL4) | GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE); 753 GEN7_UCGCTL4,
754 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
726 755
727 /* WaInPlaceDecompressionHang:cfl */ 756 /* WaInPlaceDecompressionHang:cfl */
728 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 757 wa_write_or(wal,
729 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 758 GEN9_GAMT_ECO_REG_RW_IA,
730 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 759 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
731} 760}
732 761
733static void wa_init_mcr(struct drm_i915_private *dev_priv) 762static void wa_init_mcr(struct drm_i915_private *dev_priv)
734{ 763{
735 const struct sseu_dev_info *sseu = &(INTEL_INFO(dev_priv)->sseu); 764 const struct sseu_dev_info *sseu = &(INTEL_INFO(dev_priv)->sseu);
736 u32 mcr; 765 struct i915_wa_list *wal = &dev_priv->gt_wa_list;
737 u32 mcr_slice_subslice_mask; 766 u32 mcr_slice_subslice_mask;
738 767
739 /* 768 /*
@@ -770,8 +799,6 @@ static void wa_init_mcr(struct drm_i915_private *dev_priv)
770 WARN_ON((enabled_mask & disabled_mask) != enabled_mask); 799 WARN_ON((enabled_mask & disabled_mask) != enabled_mask);
771 } 800 }
772 801
773 mcr = I915_READ(GEN8_MCR_SELECTOR);
774
775 if (INTEL_GEN(dev_priv) >= 11) 802 if (INTEL_GEN(dev_priv) >= 11)
776 mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK | 803 mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK |
777 GEN11_MCR_SUBSLICE_MASK; 804 GEN11_MCR_SUBSLICE_MASK;
@@ -789,148 +816,170 @@ static void wa_init_mcr(struct drm_i915_private *dev_priv)
789 * occasions, such as INSTDONE, where this value is dependent 816 * occasions, such as INSTDONE, where this value is dependent
790 * on s/ss combo, the read should be done with read_subslice_reg. 817 * on s/ss combo, the read should be done with read_subslice_reg.
791 */ 818 */
792 mcr &= ~mcr_slice_subslice_mask; 819 wa_write_masked_or(wal,
793 mcr |= intel_calculate_mcr_s_ss_select(dev_priv); 820 GEN8_MCR_SELECTOR,
794 I915_WRITE(GEN8_MCR_SELECTOR, mcr); 821 mcr_slice_subslice_mask,
822 intel_calculate_mcr_s_ss_select(dev_priv));
795} 823}
796 824
797static void cnl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 825static void cnl_gt_workarounds_init(struct drm_i915_private *i915)
798{ 826{
799 wa_init_mcr(dev_priv); 827 struct i915_wa_list *wal = &i915->gt_wa_list;
828
829 wa_init_mcr(i915);
800 830
801 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */ 831 /* WaDisableI2mCycleOnWRPort:cnl (pre-prod) */
802 if (IS_CNL_REVID(dev_priv, CNL_REVID_B0, CNL_REVID_B0)) 832 if (IS_CNL_REVID(i915, CNL_REVID_B0, CNL_REVID_B0))
803 I915_WRITE(GAMT_CHKN_BIT_REG, 833 wa_write_or(wal,
804 I915_READ(GAMT_CHKN_BIT_REG) | 834 GAMT_CHKN_BIT_REG,
805 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT); 835 GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT);
806 836
807 /* WaInPlaceDecompressionHang:cnl */ 837 /* WaInPlaceDecompressionHang:cnl */
808 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, 838 wa_write_or(wal,
809 I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 839 GEN9_GAMT_ECO_REG_RW_IA,
810 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 840 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
811
812 /* WaEnablePreemptionGranularityControlByUMD:cnl */
813 I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
814 _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
815} 841}
816 842
817static void icl_gt_workarounds_apply(struct drm_i915_private *dev_priv) 843static void icl_gt_workarounds_init(struct drm_i915_private *i915)
818{ 844{
819 wa_init_mcr(dev_priv); 845 struct i915_wa_list *wal = &i915->gt_wa_list;
820 846
821 /* This is not an Wa. Enable for better image quality */ 847 wa_init_mcr(i915);
822 I915_WRITE(_3D_CHICKEN3,
823 _MASKED_BIT_ENABLE(_3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE));
824 848
825 /* WaInPlaceDecompressionHang:icl */ 849 /* WaInPlaceDecompressionHang:icl */
826 I915_WRITE(GEN9_GAMT_ECO_REG_RW_IA, I915_READ(GEN9_GAMT_ECO_REG_RW_IA) | 850 wa_write_or(wal,
827 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 851 GEN9_GAMT_ECO_REG_RW_IA,
828 852 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
829 /* WaPipelineFlushCoherentLines:icl */
830 I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
831 GEN8_LQSC_FLUSH_COHERENT_LINES);
832
833 /* Wa_1405543622:icl
834 * Formerly known as WaGAPZPriorityScheme
835 */
836 I915_WRITE(GEN8_GARBCNTL, I915_READ(GEN8_GARBCNTL) |
837 GEN11_ARBITRATION_PRIO_ORDER_MASK);
838
839 /* Wa_1604223664:icl
840 * Formerly known as WaL3BankAddressHashing
841 */
842 I915_WRITE(GEN8_GARBCNTL,
843 (I915_READ(GEN8_GARBCNTL) & ~GEN11_HASH_CTRL_EXCL_MASK) |
844 GEN11_HASH_CTRL_EXCL_BIT0);
845 I915_WRITE(GEN11_GLBLINVL,
846 (I915_READ(GEN11_GLBLINVL) & ~GEN11_BANK_HASH_ADDR_EXCL_MASK) |
847 GEN11_BANK_HASH_ADDR_EXCL_BIT0);
848 853
849 /* WaModifyGamTlbPartitioning:icl */ 854 /* WaModifyGamTlbPartitioning:icl */
850 I915_WRITE(GEN11_GACB_PERF_CTRL, 855 wa_write_masked_or(wal,
851 (I915_READ(GEN11_GACB_PERF_CTRL) & ~GEN11_HASH_CTRL_MASK) | 856 GEN11_GACB_PERF_CTRL,
852 GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4); 857 GEN11_HASH_CTRL_MASK,
853 858 GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4);
854 /* Wa_1405733216:icl
855 * Formerly known as WaDisableCleanEvicts
856 */
857 I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
858 GEN11_LQSC_CLEAN_EVICT_DISABLE);
859 859
860 /* Wa_1405766107:icl 860 /* Wa_1405766107:icl
861 * Formerly known as WaCL2SFHalfMaxAlloc 861 * Formerly known as WaCL2SFHalfMaxAlloc
862 */ 862 */
863 I915_WRITE(GEN11_LSN_UNSLCVC, I915_READ(GEN11_LSN_UNSLCVC) | 863 wa_write_or(wal,
864 GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC | 864 GEN11_LSN_UNSLCVC,
865 GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC); 865 GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC |
866 GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC);
866 867
867 /* Wa_220166154:icl 868 /* Wa_220166154:icl
868 * Formerly known as WaDisCtxReload 869 * Formerly known as WaDisCtxReload
869 */ 870 */
870 I915_WRITE(GAMW_ECO_DEV_RW_IA_REG, I915_READ(GAMW_ECO_DEV_RW_IA_REG) | 871 wa_write_or(wal,
871 GAMW_ECO_DEV_CTX_RELOAD_DISABLE); 872 GEN8_GAMW_ECO_DEV_RW_IA,
873 GAMW_ECO_DEV_CTX_RELOAD_DISABLE);
872 874
873 /* Wa_1405779004:icl (pre-prod) */ 875 /* Wa_1405779004:icl (pre-prod) */
874 if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_A0)) 876 if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0))
875 I915_WRITE(SLICE_UNIT_LEVEL_CLKGATE, 877 wa_write_or(wal,
876 I915_READ(SLICE_UNIT_LEVEL_CLKGATE) | 878 SLICE_UNIT_LEVEL_CLKGATE,
877 MSCUNIT_CLKGATE_DIS); 879 MSCUNIT_CLKGATE_DIS);
878 880
879 /* Wa_1406680159:icl */ 881 /* Wa_1406680159:icl */
880 I915_WRITE(SUBSLICE_UNIT_LEVEL_CLKGATE, 882 wa_write_or(wal,
881 I915_READ(SUBSLICE_UNIT_LEVEL_CLKGATE) | 883 SUBSLICE_UNIT_LEVEL_CLKGATE,
882 GWUNIT_CLKGATE_DIS); 884 GWUNIT_CLKGATE_DIS);
883
884 /* Wa_1604302699:icl */
885 I915_WRITE(GEN10_L3_CHICKEN_MODE_REGISTER,
886 I915_READ(GEN10_L3_CHICKEN_MODE_REGISTER) |
887 GEN11_I2M_WRITE_DISABLE);
888 885
889 /* Wa_1406838659:icl (pre-prod) */ 886 /* Wa_1406838659:icl (pre-prod) */
890 if (IS_ICL_REVID(dev_priv, ICL_REVID_A0, ICL_REVID_B0)) 887 if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0))
891 I915_WRITE(INF_UNIT_LEVEL_CLKGATE, 888 wa_write_or(wal,
892 I915_READ(INF_UNIT_LEVEL_CLKGATE) | 889 INF_UNIT_LEVEL_CLKGATE,
893 CGPSF_CLKGATE_DIS); 890 CGPSF_CLKGATE_DIS);
894
895 /* WaForwardProgressSoftReset:icl */
896 I915_WRITE(GEN10_SCRATCH_LNCF2,
897 I915_READ(GEN10_SCRATCH_LNCF2) |
898 PMFLUSHDONE_LNICRSDROP |
899 PMFLUSH_GAPL3UNBLOCK |
900 PMFLUSHDONE_LNEBLK);
901 891
902 /* Wa_1406463099:icl 892 /* Wa_1406463099:icl
903 * Formerly known as WaGamTlbPendError 893 * Formerly known as WaGamTlbPendError
904 */ 894 */
905 I915_WRITE(GAMT_CHKN_BIT_REG, 895 wa_write_or(wal,
906 I915_READ(GAMT_CHKN_BIT_REG) | 896 GAMT_CHKN_BIT_REG,
907 GAMT_CHKN_DISABLE_L3_COH_PIPE); 897 GAMT_CHKN_DISABLE_L3_COH_PIPE);
908} 898}
909 899
910void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv) 900void intel_gt_init_workarounds(struct drm_i915_private *i915)
911{ 901{
912 if (INTEL_GEN(dev_priv) < 8) 902 struct i915_wa_list *wal = &i915->gt_wa_list;
903
904 wa_init_start(wal, "GT");
905
906 if (INTEL_GEN(i915) < 8)
913 return; 907 return;
914 else if (IS_BROADWELL(dev_priv)) 908 else if (IS_BROADWELL(i915))
915 bdw_gt_workarounds_apply(dev_priv); 909 return;
916 else if (IS_CHERRYVIEW(dev_priv)) 910 else if (IS_CHERRYVIEW(i915))
917 chv_gt_workarounds_apply(dev_priv); 911 return;
918 else if (IS_SKYLAKE(dev_priv)) 912 else if (IS_SKYLAKE(i915))
919 skl_gt_workarounds_apply(dev_priv); 913 skl_gt_workarounds_init(i915);
920 else if (IS_BROXTON(dev_priv)) 914 else if (IS_BROXTON(i915))
921 bxt_gt_workarounds_apply(dev_priv); 915 bxt_gt_workarounds_init(i915);
922 else if (IS_KABYLAKE(dev_priv)) 916 else if (IS_KABYLAKE(i915))
923 kbl_gt_workarounds_apply(dev_priv); 917 kbl_gt_workarounds_init(i915);
924 else if (IS_GEMINILAKE(dev_priv)) 918 else if (IS_GEMINILAKE(i915))
925 glk_gt_workarounds_apply(dev_priv); 919 glk_gt_workarounds_init(i915);
926 else if (IS_COFFEELAKE(dev_priv)) 920 else if (IS_COFFEELAKE(i915))
927 cfl_gt_workarounds_apply(dev_priv); 921 cfl_gt_workarounds_init(i915);
928 else if (IS_CANNONLAKE(dev_priv)) 922 else if (IS_CANNONLAKE(i915))
929 cnl_gt_workarounds_apply(dev_priv); 923 cnl_gt_workarounds_init(i915);
930 else if (IS_ICELAKE(dev_priv)) 924 else if (IS_ICELAKE(i915))
931 icl_gt_workarounds_apply(dev_priv); 925 icl_gt_workarounds_init(i915);
932 else 926 else
933 MISSING_CASE(INTEL_GEN(dev_priv)); 927 MISSING_CASE(INTEL_GEN(i915));
928
929 wa_init_finish(wal);
930}
931
932static enum forcewake_domains
933wal_get_fw_for_rmw(struct drm_i915_private *dev_priv,
934 const struct i915_wa_list *wal)
935{
936 enum forcewake_domains fw = 0;
937 struct i915_wa *wa;
938 unsigned int i;
939
940 for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
941 fw |= intel_uncore_forcewake_for_reg(dev_priv,
942 wa->reg,
943 FW_REG_READ |
944 FW_REG_WRITE);
945
946 return fw;
947}
948
949static void
950wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal)
951{
952 enum forcewake_domains fw;
953 unsigned long flags;
954 struct i915_wa *wa;
955 unsigned int i;
956
957 if (!wal->count)
958 return;
959
960 fw = wal_get_fw_for_rmw(dev_priv, wal);
961
962 spin_lock_irqsave(&dev_priv->uncore.lock, flags);
963 intel_uncore_forcewake_get__locked(dev_priv, fw);
964
965 for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
966 u32 val = I915_READ_FW(wa->reg);
967
968 val &= ~wa->mask;
969 val |= wa->val;
970
971 I915_WRITE_FW(wa->reg, val);
972 }
973
974 intel_uncore_forcewake_put__locked(dev_priv, fw);
975 spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
976
977 DRM_DEBUG_DRIVER("Applied %u %s workarounds\n", wal->count, wal->name);
978}
979
980void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv)
981{
982 wa_list_apply(dev_priv, &dev_priv->gt_wa_list);
934} 983}
935 984
936struct whitelist { 985struct whitelist {
@@ -1077,6 +1126,146 @@ void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine)
1077 whitelist_apply(engine, whitelist_build(engine, &w)); 1126 whitelist_apply(engine, whitelist_build(engine, &w));
1078} 1127}
1079 1128
1129static void rcs_engine_wa_init(struct intel_engine_cs *engine)
1130{
1131 struct drm_i915_private *i915 = engine->i915;
1132 struct i915_wa_list *wal = &engine->wa_list;
1133
1134 if (IS_ICELAKE(i915)) {
1135 /* This is not an Wa. Enable for better image quality */
1136 wa_masked_en(wal,
1137 _3D_CHICKEN3,
1138 _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE);
1139
1140 /* WaPipelineFlushCoherentLines:icl */
1141 wa_write_or(wal,
1142 GEN8_L3SQCREG4,
1143 GEN8_LQSC_FLUSH_COHERENT_LINES);
1144
1145 /*
1146 * Wa_1405543622:icl
1147 * Formerly known as WaGAPZPriorityScheme
1148 */
1149 wa_write_or(wal,
1150 GEN8_GARBCNTL,
1151 GEN11_ARBITRATION_PRIO_ORDER_MASK);
1152
1153 /*
1154 * Wa_1604223664:icl
1155 * Formerly known as WaL3BankAddressHashing
1156 */
1157 wa_write_masked_or(wal,
1158 GEN8_GARBCNTL,
1159 GEN11_HASH_CTRL_EXCL_MASK,
1160 GEN11_HASH_CTRL_EXCL_BIT0);
1161 wa_write_masked_or(wal,
1162 GEN11_GLBLINVL,
1163 GEN11_BANK_HASH_ADDR_EXCL_MASK,
1164 GEN11_BANK_HASH_ADDR_EXCL_BIT0);
1165
1166 /*
1167 * Wa_1405733216:icl
1168 * Formerly known as WaDisableCleanEvicts
1169 */
1170 wa_write_or(wal,
1171 GEN8_L3SQCREG4,
1172 GEN11_LQSC_CLEAN_EVICT_DISABLE);
1173
1174 /* Wa_1604302699:icl */
1175 wa_write_or(wal,
1176 GEN10_L3_CHICKEN_MODE_REGISTER,
1177 GEN11_I2M_WRITE_DISABLE);
1178
1179 /* WaForwardProgressSoftReset:icl */
1180 wa_write_or(wal,
1181 GEN10_SCRATCH_LNCF2,
1182 PMFLUSHDONE_LNICRSDROP |
1183 PMFLUSH_GAPL3UNBLOCK |
1184 PMFLUSHDONE_LNEBLK);
1185 }
1186
1187 if (IS_GEN9(i915) || IS_CANNONLAKE(i915)) {
1188 /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */
1189 wa_masked_en(wal,
1190 GEN7_FF_SLICE_CS_CHICKEN1,
1191 GEN9_FFSC_PERCTX_PREEMPT_CTRL);
1192 }
1193
1194 if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) || IS_COFFEELAKE(i915)) {
1195 /* WaEnableGapsTsvCreditFix:skl,kbl,cfl */
1196 wa_write_or(wal,
1197 GEN8_GARBCNTL,
1198 GEN9_GAPS_TSV_CREDIT_DISABLE);
1199 }
1200
1201 if (IS_BROXTON(i915)) {
1202 /* WaDisablePooledEuLoadBalancingFix:bxt */
1203 wa_masked_en(wal,
1204 FF_SLICE_CS_CHICKEN2,
1205 GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE);
1206 }
1207
1208 if (IS_GEN9(i915)) {
1209 /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */
1210 wa_masked_en(wal,
1211 GEN9_CSFE_CHICKEN1_RCS,
1212 GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE);
1213
1214 /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */
1215 wa_write_or(wal,
1216 BDW_SCRATCH1,
1217 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
1218
1219 /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */
1220 if (IS_GEN9_LP(i915))
1221 wa_write_masked_or(wal,
1222 GEN8_L3SQCREG1,
1223 L3_PRIO_CREDITS_MASK,
1224 L3_GENERAL_PRIO_CREDITS(62) |
1225 L3_HIGH_PRIO_CREDITS(2));
1226
1227 /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */
1228 wa_write_or(wal,
1229 GEN8_L3SQCREG4,
1230 GEN8_LQSC_FLUSH_COHERENT_LINES);
1231 }
1232}
1233
1234static void xcs_engine_wa_init(struct intel_engine_cs *engine)
1235{
1236 struct drm_i915_private *i915 = engine->i915;
1237 struct i915_wa_list *wal = &engine->wa_list;
1238
1239 /* WaKBLVECSSemaphoreWaitPoll:kbl */
1240 if (IS_KBL_REVID(i915, KBL_REVID_A0, KBL_REVID_E0)) {
1241 wa_write(wal,
1242 RING_SEMA_WAIT_POLL(engine->mmio_base),
1243 1);
1244 }
1245}
1246
1247void intel_engine_init_workarounds(struct intel_engine_cs *engine)
1248{
1249 struct i915_wa_list *wal = &engine->wa_list;
1250
1251 if (GEM_WARN_ON(INTEL_GEN(engine->i915) < 8))
1252 return;
1253
1254 wa_init_start(wal, engine->name);
1255
1256 if (engine->id == RCS)
1257 rcs_engine_wa_init(engine);
1258 else
1259 xcs_engine_wa_init(engine);
1260
1261 wa_init_finish(wal);
1262}
1263
1264void intel_engine_apply_workarounds(struct intel_engine_cs *engine)
1265{
1266 wa_list_apply(engine->i915, &engine->wa_list);
1267}
1268
1080#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 1269#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
1081#include "selftests/intel_workarounds.c" 1270#include "selftests/intel_workarounds.c"
1082#endif 1271#endif
diff --git a/drivers/gpu/drm/i915/intel_workarounds.h b/drivers/gpu/drm/i915/intel_workarounds.h
index b11d0623e626..979695a53964 100644
--- a/drivers/gpu/drm/i915/intel_workarounds.h
+++ b/drivers/gpu/drm/i915/intel_workarounds.h
@@ -7,11 +7,35 @@
7#ifndef _I915_WORKAROUNDS_H_ 7#ifndef _I915_WORKAROUNDS_H_
8#define _I915_WORKAROUNDS_H_ 8#define _I915_WORKAROUNDS_H_
9 9
10#include <linux/slab.h>
11
12struct i915_wa {
13 i915_reg_t reg;
14 u32 mask;
15 u32 val;
16};
17
18struct i915_wa_list {
19 const char *name;
20 struct i915_wa *list;
21 unsigned int count;
22};
23
24static inline void intel_wa_list_free(struct i915_wa_list *wal)
25{
26 kfree(wal->list);
27 memset(wal, 0, sizeof(*wal));
28}
29
10int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv); 30int intel_ctx_workarounds_init(struct drm_i915_private *dev_priv);
11int intel_ctx_workarounds_emit(struct i915_request *rq); 31int intel_ctx_workarounds_emit(struct i915_request *rq);
12 32
13void intel_gt_workarounds_apply(struct drm_i915_private *dev_priv); 33void intel_gt_init_workarounds(struct drm_i915_private *dev_priv);
34void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv);
14 35
15void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine); 36void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine);
16 37
38void intel_engine_init_workarounds(struct intel_engine_cs *engine);
39void intel_engine_apply_workarounds(struct intel_engine_cs *engine);
40
17#endif 41#endif
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 66df1b177959..27b507eb4a99 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -818,10 +818,13 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi)
818 dsi->encoder.possible_crtcs = 1; 818 dsi->encoder.possible_crtcs = 1;
819 819
820 /* If there's a bridge, attach to it and let it create the connector */ 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); 821 if (dsi->bridge) {
822 if (ret) { 822 ret = drm_bridge_attach(&dsi->encoder, dsi->bridge, NULL);
823 DRM_ERROR("Failed to attach bridge to drm\n"); 823 if (ret) {
824 824 DRM_ERROR("Failed to attach bridge to drm\n");
825 goto err_encoder_cleanup;
826 }
827 } else {
825 /* Otherwise create our own connector and attach to a panel */ 828 /* Otherwise create our own connector and attach to a panel */
826 ret = mtk_dsi_create_connector(drm, dsi); 829 ret = mtk_dsi_create_connector(drm, dsi);
827 if (ret) 830 if (ret)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 6cbbae3f438b..db1bf7f88c1f 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -198,6 +198,22 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
198/****************************************************************************** 198/******************************************************************************
199 * EVO channel helpers 199 * EVO channel helpers
200 *****************************************************************************/ 200 *****************************************************************************/
201static void
202evo_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
201u32 * 217u32 *
202evo_wait(struct nv50_dmac *evoc, int nr) 218evo_wait(struct nv50_dmac *evoc, int nr)
203{ 219{
@@ -208,6 +224,7 @@ evo_wait(struct nv50_dmac *evoc, int nr)
208 mutex_lock(&dmac->lock); 224 mutex_lock(&dmac->lock);
209 if (put + nr >= (PAGE_SIZE / 4) - 8) { 225 if (put + nr >= (PAGE_SIZE / 4) - 8) {
210 dmac->ptr[put] = 0x20000000; 226 dmac->ptr[put] = 0x20000000;
227 evo_flush(dmac);
211 228
212 nvif_wr32(&dmac->base.user, 0x0000, 0x00000000); 229 nvif_wr32(&dmac->base.user, 0x0000, 0x00000000);
213 if (nvif_msec(device, 2000, 230 if (nvif_msec(device, 2000,
@@ -230,17 +247,7 @@ evo_kick(u32 *push, struct nv50_dmac *evoc)
230{ 247{
231 struct nv50_dmac *dmac = evoc; 248 struct nv50_dmac *dmac = evoc;
232 249
233 /* Push buffer fetches are not coherent with BAR1, we need to ensure 250 evo_flush(dmac);
234 * writes have been flushed right through to VRAM before writing PUT.
235 */
236 if (dmac->push.type & NVIF_MEM_VRAM) {
237 struct nvif_device *device = dmac->base.device;
238 nvif_wr32(&device->object, 0x070000, 0x00000001);
239 nvif_msec(device, 2000,
240 if (!(nvif_rd32(&device->object, 0x070000) & 0x00000002))
241 break;
242 );
243 }
244 251
245 nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2); 252 nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2);
246 mutex_unlock(&dmac->lock); 253 mutex_unlock(&dmac->lock);
@@ -1264,6 +1271,7 @@ nv50_mstm_del(struct nv50_mstm **pmstm)
1264{ 1271{
1265 struct nv50_mstm *mstm = *pmstm; 1272 struct nv50_mstm *mstm = *pmstm;
1266 if (mstm) { 1273 if (mstm) {
1274 drm_dp_mst_topology_mgr_destroy(&mstm->mgr);
1267 kfree(*pmstm); 1275 kfree(*pmstm);
1268 *pmstm = NULL; 1276 *pmstm = NULL;
1269 } 1277 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 2b2baf6e0e0d..d2928d43f29a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1171,10 +1171,16 @@ nouveau_platform_device_create(const struct nvkm_device_tegra_func *func,
1171 goto err_free; 1171 goto err_free;
1172 } 1172 }
1173 1173
1174 err = nouveau_drm_device_init(drm);
1175 if (err)
1176 goto err_put;
1177
1174 platform_set_drvdata(pdev, drm); 1178 platform_set_drvdata(pdev, drm);
1175 1179
1176 return drm; 1180 return drm;
1177 1181
1182err_put:
1183 drm_dev_put(drm);
1178err_free: 1184err_free:
1179 nvkm_device_del(pdevice); 1185 nvkm_device_del(pdevice);
1180 1186
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 941f35233b1f..5864cb452c5c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -448,11 +448,6 @@ static int rockchip_drm_platform_remove(struct platform_device *pdev)
448 return 0; 448 return 0;
449} 449}
450 450
451static void rockchip_drm_platform_shutdown(struct platform_device *pdev)
452{
453 rockchip_drm_platform_remove(pdev);
454}
455
456static const struct of_device_id rockchip_drm_dt_ids[] = { 451static const struct of_device_id rockchip_drm_dt_ids[] = {
457 { .compatible = "rockchip,display-subsystem", }, 452 { .compatible = "rockchip,display-subsystem", },
458 { /* sentinel */ }, 453 { /* sentinel */ },
@@ -462,7 +457,6 @@ MODULE_DEVICE_TABLE(of, rockchip_drm_dt_ids);
462static struct platform_driver rockchip_drm_platform_driver = { 457static struct platform_driver rockchip_drm_platform_driver = {
463 .probe = rockchip_drm_platform_probe, 458 .probe = rockchip_drm_platform_probe,
464 .remove = rockchip_drm_platform_remove, 459 .remove = rockchip_drm_platform_remove,
465 .shutdown = rockchip_drm_platform_shutdown,
466 .driver = { 460 .driver = {
467 .name = "rockchip-drm", 461 .name = "rockchip-drm",
468 .of_match_table = rockchip_drm_dt_ids, 462 .of_match_table = rockchip_drm_dt_ids,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 61a84b958d67..d7a2dfb8ee9b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -49,6 +49,8 @@
49 49
50#define VMWGFX_REPO "In Tree" 50#define VMWGFX_REPO "In Tree"
51 51
52#define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE)
53
52 54
53/** 55/**
54 * Fully encoded drm commands. Might move to vmw_drm.h 56 * Fully encoded drm commands. Might move to vmw_drm.h
@@ -918,7 +920,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
918 spin_unlock(&dev_priv->cap_lock); 920 spin_unlock(&dev_priv->cap_lock);
919 } 921 }
920 922
921 923 vmw_validation_mem_init_ttm(dev_priv, VMWGFX_VALIDATION_MEM_GRAN);
922 ret = vmw_kms_init(dev_priv); 924 ret = vmw_kms_init(dev_priv);
923 if (unlikely(ret != 0)) 925 if (unlikely(ret != 0))
924 goto out_no_kms; 926 goto out_no_kms;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 59f614225bcd..aca974b14b55 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -606,6 +606,9 @@ struct vmw_private {
606 606
607 struct vmw_cmdbuf_man *cman; 607 struct vmw_cmdbuf_man *cman;
608 DECLARE_BITMAP(irqthread_pending, VMW_IRQTHREAD_MAX); 608 DECLARE_BITMAP(irqthread_pending, VMW_IRQTHREAD_MAX);
609
610 /* Validation memory reservation */
611 struct vmw_validation_mem vvm;
609}; 612};
610 613
611static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res) 614static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res)
@@ -846,6 +849,8 @@ extern int vmw_ttm_global_init(struct vmw_private *dev_priv);
846extern void vmw_ttm_global_release(struct vmw_private *dev_priv); 849extern void vmw_ttm_global_release(struct vmw_private *dev_priv);
847extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma); 850extern int vmw_mmap(struct file *filp, struct vm_area_struct *vma);
848 851
852extern void vmw_validation_mem_init_ttm(struct vmw_private *dev_priv,
853 size_t gran);
849/** 854/**
850 * TTM buffer object driver - vmwgfx_ttm_buffer.c 855 * TTM buffer object driver - vmwgfx_ttm_buffer.c
851 */ 856 */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 5a6b70ba137a..f2d13a72c05d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -1738,7 +1738,6 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
1738 void *buf) 1738 void *buf)
1739{ 1739{
1740 struct vmw_buffer_object *vmw_bo; 1740 struct vmw_buffer_object *vmw_bo;
1741 int ret;
1742 1741
1743 struct { 1742 struct {
1744 uint32_t header; 1743 uint32_t header;
@@ -1748,7 +1747,6 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
1748 return vmw_translate_guest_ptr(dev_priv, sw_context, 1747 return vmw_translate_guest_ptr(dev_priv, sw_context,
1749 &cmd->body.ptr, 1748 &cmd->body.ptr,
1750 &vmw_bo); 1749 &vmw_bo);
1751 return ret;
1752} 1750}
1753 1751
1754 1752
@@ -3837,6 +3835,8 @@ int vmw_execbuf_process(struct drm_file *file_priv,
3837 struct sync_file *sync_file = NULL; 3835 struct sync_file *sync_file = NULL;
3838 DECLARE_VAL_CONTEXT(val_ctx, &sw_context->res_ht, 1); 3836 DECLARE_VAL_CONTEXT(val_ctx, &sw_context->res_ht, 1);
3839 3837
3838 vmw_validation_set_val_mem(&val_ctx, &dev_priv->vvm);
3839
3840 if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) { 3840 if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) {
3841 out_fence_fd = get_unused_fd_flags(O_CLOEXEC); 3841 out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
3842 if (out_fence_fd < 0) { 3842 if (out_fence_fd < 0) {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
index 7b1e5a5cbd2c..f88247046721 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c
@@ -96,3 +96,39 @@ void vmw_ttm_global_release(struct vmw_private *dev_priv)
96 drm_global_item_unref(&dev_priv->bo_global_ref.ref); 96 drm_global_item_unref(&dev_priv->bo_global_ref.ref);
97 drm_global_item_unref(&dev_priv->mem_global_ref); 97 drm_global_item_unref(&dev_priv->mem_global_ref);
98} 98}
99
100/* struct vmw_validation_mem callback */
101static 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 */
111static 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 */
127void 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}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
index 184025fa938e..f116f092e00b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
@@ -104,11 +104,25 @@ void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx,
104 return NULL; 104 return NULL;
105 105
106 if (ctx->mem_size_left < size) { 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 if (!page) 120 if (!page)
110 return NULL; 121 return NULL;
111 122
123 if (ctx->vm)
124 ctx->vm_size_left -= PAGE_SIZE;
125
112 list_add_tail(&page->lru, &ctx->page_list); 126 list_add_tail(&page->lru, &ctx->page_list);
113 ctx->page_address = page_address(page); 127 ctx->page_address = page_address(page);
114 ctx->mem_size_left = PAGE_SIZE; 128 ctx->mem_size_left = PAGE_SIZE;
@@ -138,6 +152,11 @@ static void vmw_validation_mem_free(struct vmw_validation_context *ctx)
138 } 152 }
139 153
140 ctx->mem_size_left = 0; 154 ctx->mem_size_left = 0;
155 if (ctx->vm && ctx->total_mem) {
156 ctx->vm->unreserve_mem(ctx->vm, ctx->total_mem);
157 ctx->total_mem = 0;
158 ctx->vm_size_left = 0;
159 }
141} 160}
142 161
143/** 162/**
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
index b57e3292c386..3b396fea40d7 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
@@ -34,6 +34,21 @@
34#include <drm/ttm/ttm_execbuf_util.h> 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 */
45struct 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 * struct vmw_validation_context - Per command submission validation context 52 * struct vmw_validation_context - Per command submission validation context
38 * @ht: Hash table used to find resource- or buffer object duplicates 53 * @ht: Hash table used to find resource- or buffer object duplicates
39 * @resource_list: List head for resource validation metadata 54 * @resource_list: List head for resource validation metadata
@@ -47,6 +62,10 @@
47 * buffer objects 62 * buffer objects
48 * @mem_size_left: Free memory left in the last page in @page_list 63 * @mem_size_left: Free memory left in the last page in @page_list
49 * @page_address: Kernel virtual address of the last page in @page_list 64 * @page_address: Kernel virtual address of the last page in @page_list
65 * @vm: A pointer to the memory reservation interface or NULL if no
66 * memory reservation is needed.
67 * @vm_size_left: Amount of reserved memory that so far has not been allocated.
68 * @total_mem: Amount of reserved memory.
50 */ 69 */
51struct vmw_validation_context { 70struct vmw_validation_context {
52 struct drm_open_hash *ht; 71 struct drm_open_hash *ht;
@@ -59,6 +78,9 @@ struct vmw_validation_context {
59 unsigned int merge_dups; 78 unsigned int merge_dups;
60 unsigned int mem_size_left; 79 unsigned int mem_size_left;
61 u8 *page_address; 80 u8 *page_address;
81 struct vmw_validation_mem *vm;
82 size_t vm_size_left;
83 size_t total_mem;
62}; 84};
63 85
64struct vmw_buffer_object; 86struct vmw_buffer_object;
@@ -102,6 +124,21 @@ vmw_validation_has_bos(struct vmw_validation_context *ctx)
102} 124}
103 125
104/** 126/**
127 * vmw_validation_set_val_mem - Register a validation mem object for
128 * validation memory reservation
129 * @ctx: The validation context
130 * @vm: Pointer to a struct vmw_validation_mem
131 *
132 * Must be set before the first attempt to allocate validation memory.
133 */
134static inline void
135vmw_validation_set_val_mem(struct vmw_validation_context *ctx,
136 struct vmw_validation_mem *vm)
137{
138 ctx->vm = vm;
139}
140
141/**
105 * vmw_validation_set_ht - Register a hash table for duplicate finding 142 * vmw_validation_set_ht - Register a hash table for duplicate finding
106 * @ctx: The validation context 143 * @ctx: The validation context
107 * @ht: Pointer to a hash table to use for duplicate finding 144 * @ht: Pointer to a hash table to use for duplicate finding