Skip to content

Commit 0d3ff80

Browse files
committed
Merge tag 'drm-fixes-2023-03-30' of git://anongit.freedesktop.org/drm/drm
Pull drm fixes from Daniel Vetter: "Two regression fixes in here, otherwise just the usual stuff: - i915 fixes for color mgmt, psr, lmem flush, hibernate oops, and more - amdgpu: dp mst and hibernate regression fix - etnaviv: revert fdinfo support (incl drm/sched revert), leak fix - misc ivpu fixes, nouveau backlight, drm buddy allocator 32bit fixes" * tag 'drm-fixes-2023-03-30' of git://anongit.freedesktop.org/drm/drm: (27 commits) Revert "drm/scheduler: track GPU active time per entity" Revert "drm/etnaviv: export client GPU usage statistics via fdinfo" drm/etnaviv: fix reference leak when mmaping imported buffer drm/amdgpu: allow more APUs to do mode2 reset when go to S4 drm/amd/display: Take FEC Overhead into Timeslot Calculation drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub drm: test: Fix 32-bit issue in drm_buddy_test drm: buddy_allocator: Fix buddy allocator init on 32-bit systems drm/nouveau/kms: Fix backlight registration drm/i915/perf: Drop wakeref on GuC RC error drm/i915/dpt: Treat the DPT BO as a framebuffer drm/i915/gem: Flush lmem contents after construction drm/i915/tc: Fix the ICL PHY ownership check in TC-cold state drm/i915: Disable DC states for all commits drm/i915: Workaround ICL CSC_MODE sticky arming drm/i915: Add a .color_post_update() hook drm/i915: Move CSC load back into .color_commit_arm() when PSR is enabled on skl/glk drm/i915: Split icl_color_commit_noarm() from skl_color_commit_noarm() drm/i915/pmu: Use functions common with sysfs to read actual freq accel/ivpu: Fix IPC buffer header status field value ...
2 parents 8bb95a1 + 7af63e0 commit 0d3ff80

30 files changed

+341
-200
lines changed

drivers/accel/ivpu/ivpu_drv.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <linux/pci.h>
99

1010
#include <drm/drm_accel.h>
11-
#include <drm/drm_drv.h>
1211
#include <drm/drm_file.h>
1312
#include <drm/drm_gem.h>
1413
#include <drm/drm_ioctl.h>
@@ -118,6 +117,10 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
118117
struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
119118
struct drm_ivpu_param *args = data;
120119
int ret = 0;
120+
int idx;
121+
122+
if (!drm_dev_enter(dev, &idx))
123+
return -ENODEV;
121124

122125
switch (args->param) {
123126
case DRM_IVPU_PARAM_DEVICE_ID:
@@ -171,6 +174,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
171174
break;
172175
}
173176

177+
drm_dev_exit(idx);
174178
return ret;
175179
}
176180

@@ -470,8 +474,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
470474

471475
vdev->hw->ops = &ivpu_hw_mtl_ops;
472476
vdev->platform = IVPU_PLATFORM_INVALID;
473-
vdev->context_xa_limit.min = IVPU_GLOBAL_CONTEXT_MMU_SSID + 1;
474-
vdev->context_xa_limit.max = IVPU_CONTEXT_LIMIT;
477+
vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
478+
vdev->context_xa_limit.max = IVPU_USER_CONTEXT_MAX_SSID;
475479
atomic64_set(&vdev->unique_id_counter, 0);
476480
xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC);
477481
xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
@@ -565,6 +569,8 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
565569
ivpu_mmu_global_context_fini(vdev);
566570
err_power_down:
567571
ivpu_hw_power_down(vdev);
572+
if (IVPU_WA(d3hot_after_power_off))
573+
pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
568574
err_xa_destroy:
569575
xa_destroy(&vdev->submitted_jobs_xa);
570576
xa_destroy(&vdev->context_xa);
@@ -575,7 +581,11 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)
575581
{
576582
ivpu_pm_disable(vdev);
577583
ivpu_shutdown(vdev);
584+
if (IVPU_WA(d3hot_after_power_off))
585+
pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
578586
ivpu_job_done_thread_fini(vdev);
587+
ivpu_pm_cancel_recovery(vdev);
588+
579589
ivpu_ipc_fini(vdev);
580590
ivpu_fw_fini(vdev);
581591
ivpu_mmu_global_context_fini(vdev);
@@ -622,7 +632,7 @@ static void ivpu_remove(struct pci_dev *pdev)
622632
{
623633
struct ivpu_device *vdev = pci_get_drvdata(pdev);
624634

625-
drm_dev_unregister(&vdev->drm);
635+
drm_dev_unplug(&vdev->drm);
626636
ivpu_dev_fini(vdev);
627637
}
628638

drivers/accel/ivpu/ivpu_drv.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define __IVPU_DRV_H__
88

99
#include <drm/drm_device.h>
10+
#include <drm/drm_drv.h>
1011
#include <drm/drm_managed.h>
1112
#include <drm/drm_mm.h>
1213
#include <drm/drm_print.h>
@@ -24,7 +25,10 @@
2425
#define PCI_DEVICE_ID_MTL 0x7d1d
2526

2627
#define IVPU_GLOBAL_CONTEXT_MMU_SSID 0
27-
#define IVPU_CONTEXT_LIMIT 64
28+
/* SSID 1 is used by the VPU to represent invalid context */
29+
#define IVPU_USER_CONTEXT_MIN_SSID 2
30+
#define IVPU_USER_CONTEXT_MAX_SSID (IVPU_USER_CONTEXT_MIN_SSID + 63)
31+
2832
#define IVPU_NUM_ENGINES 2
2933

3034
#define IVPU_PLATFORM_SILICON 0
@@ -70,6 +74,7 @@
7074
struct ivpu_wa_table {
7175
bool punit_disabled;
7276
bool clear_runtime_mem;
77+
bool d3hot_after_power_off;
7378
};
7479

7580
struct ivpu_hw_info;

drivers/accel/ivpu/ivpu_hw_mtl.c

Lines changed: 35 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,23 @@
1212
#include "ivpu_mmu.h"
1313
#include "ivpu_pm.h"
1414

15-
#define TILE_FUSE_ENABLE_BOTH 0x0
16-
#define TILE_FUSE_ENABLE_UPPER 0x1
17-
#define TILE_FUSE_ENABLE_LOWER 0x2
18-
19-
#define TILE_SKU_BOTH_MTL 0x3630
20-
#define TILE_SKU_LOWER_MTL 0x3631
21-
#define TILE_SKU_UPPER_MTL 0x3632
15+
#define TILE_FUSE_ENABLE_BOTH 0x0
16+
#define TILE_SKU_BOTH_MTL 0x3630
2217

2318
/* Work point configuration values */
24-
#define WP_CONFIG_1_TILE_5_3_RATIO 0x0101
25-
#define WP_CONFIG_1_TILE_4_3_RATIO 0x0102
26-
#define WP_CONFIG_2_TILE_5_3_RATIO 0x0201
27-
#define WP_CONFIG_2_TILE_4_3_RATIO 0x0202
28-
#define WP_CONFIG_0_TILE_PLL_OFF 0x0000
19+
#define CONFIG_1_TILE 0x01
20+
#define CONFIG_2_TILE 0x02
21+
#define PLL_RATIO_5_3 0x01
22+
#define PLL_RATIO_4_3 0x02
23+
#define WP_CONFIG(tile, ratio) (((tile) << 8) | (ratio))
24+
#define WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_5_3)
25+
#define WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(CONFIG_1_TILE, PLL_RATIO_4_3)
26+
#define WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_5_3)
27+
#define WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(CONFIG_2_TILE, PLL_RATIO_4_3)
28+
#define WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0)
2929

3030
#define PLL_REF_CLK_FREQ (50 * 1000000)
3131
#define PLL_SIMULATION_FREQ (10 * 1000000)
32-
#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
3332
#define PLL_DEFAULT_EPP_VALUE 0x80
3433

3534
#define TIM_SAFE_ENABLE 0xf1d0dead
@@ -101,6 +100,7 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
101100
{
102101
vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
103102
vdev->wa.clear_runtime_mem = false;
103+
vdev->wa.d3hot_after_power_off = true;
104104
}
105105

106106
static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
@@ -218,7 +218,8 @@ static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
218218
config = 0;
219219
}
220220

221-
ivpu_dbg(vdev, PM, "PLL workpoint request: %d Hz\n", PLL_RATIO_TO_FREQ(target_ratio));
221+
ivpu_dbg(vdev, PM, "PLL workpoint request: config 0x%04x pll ratio 0x%x\n",
222+
config, target_ratio);
222223

223224
ret = ivpu_pll_cmd_send(vdev, hw->pll.min_ratio, hw->pll.max_ratio, target_ratio, config);
224225
if (ret) {
@@ -403,11 +404,6 @@ static int ivpu_boot_host_ss_axi_enable(struct ivpu_device *vdev)
403404
return ivpu_boot_host_ss_axi_drive(vdev, true);
404405
}
405406

406-
static int ivpu_boot_host_ss_axi_disable(struct ivpu_device *vdev)
407-
{
408-
return ivpu_boot_host_ss_axi_drive(vdev, false);
409-
}
410-
411407
static int ivpu_boot_host_ss_top_noc_drive(struct ivpu_device *vdev, bool enable)
412408
{
413409
int ret;
@@ -441,11 +437,6 @@ static int ivpu_boot_host_ss_top_noc_enable(struct ivpu_device *vdev)
441437
return ivpu_boot_host_ss_top_noc_drive(vdev, true);
442438
}
443439

444-
static int ivpu_boot_host_ss_top_noc_disable(struct ivpu_device *vdev)
445-
{
446-
return ivpu_boot_host_ss_top_noc_drive(vdev, false);
447-
}
448-
449440
static void ivpu_boot_pwr_island_trickle_drive(struct ivpu_device *vdev, bool enable)
450441
{
451442
u32 val = REGV_RD32(MTL_VPU_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
@@ -504,16 +495,6 @@ static void ivpu_boot_dpu_active_drive(struct ivpu_device *vdev, bool enable)
504495
REGV_WR32(MTL_VPU_HOST_SS_AON_DPU_ACTIVE, val);
505496
}
506497

507-
static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
508-
{
509-
ivpu_boot_dpu_active_drive(vdev, false);
510-
ivpu_boot_pwr_island_isolation_drive(vdev, true);
511-
ivpu_boot_pwr_island_trickle_drive(vdev, false);
512-
ivpu_boot_pwr_island_drive(vdev, false);
513-
514-
return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
515-
}
516-
517498
static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
518499
{
519500
int ret;
@@ -629,34 +610,10 @@ static int ivpu_boot_d0i3_drive(struct ivpu_device *vdev, bool enable)
629610
static int ivpu_hw_mtl_info_init(struct ivpu_device *vdev)
630611
{
631612
struct ivpu_hw_info *hw = vdev->hw;
632-
u32 tile_fuse;
633-
634-
tile_fuse = REGB_RD32(MTL_BUTTRESS_TILE_FUSE);
635-
if (!REG_TEST_FLD(MTL_BUTTRESS_TILE_FUSE, VALID, tile_fuse))
636-
ivpu_warn(vdev, "Tile Fuse: Invalid (0x%x)\n", tile_fuse);
637-
638-
hw->tile_fuse = REG_GET_FLD(MTL_BUTTRESS_TILE_FUSE, SKU, tile_fuse);
639-
switch (hw->tile_fuse) {
640-
case TILE_FUSE_ENABLE_LOWER:
641-
hw->sku = TILE_SKU_LOWER_MTL;
642-
hw->config = WP_CONFIG_1_TILE_5_3_RATIO;
643-
ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Lower\n");
644-
break;
645-
case TILE_FUSE_ENABLE_UPPER:
646-
hw->sku = TILE_SKU_UPPER_MTL;
647-
hw->config = WP_CONFIG_1_TILE_4_3_RATIO;
648-
ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Upper\n");
649-
break;
650-
case TILE_FUSE_ENABLE_BOTH:
651-
hw->sku = TILE_SKU_BOTH_MTL;
652-
hw->config = WP_CONFIG_2_TILE_5_3_RATIO;
653-
ivpu_dbg(vdev, MISC, "Tile Fuse: Enable Both\n");
654-
break;
655-
default:
656-
hw->config = WP_CONFIG_0_TILE_PLL_OFF;
657-
ivpu_dbg(vdev, MISC, "Tile Fuse: Disable\n");
658-
break;
659-
}
613+
614+
hw->tile_fuse = TILE_FUSE_ENABLE_BOTH;
615+
hw->sku = TILE_SKU_BOTH_MTL;
616+
hw->config = WP_CONFIG_2_TILE_4_3_RATIO;
660617

661618
ivpu_pll_init_frequency_ratios(vdev);
662619

@@ -797,21 +754,8 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
797754
{
798755
int ret = 0;
799756

800-
/* FPGA requires manual clearing of IP_Reset bit by enabling quiescent state */
801-
if (ivpu_is_fpga(vdev)) {
802-
if (ivpu_boot_host_ss_top_noc_disable(vdev)) {
803-
ivpu_err(vdev, "Failed to disable TOP NOC\n");
804-
ret = -EIO;
805-
}
806-
807-
if (ivpu_boot_host_ss_axi_disable(vdev)) {
808-
ivpu_err(vdev, "Failed to disable AXI\n");
809-
ret = -EIO;
810-
}
811-
}
812-
813-
if (ivpu_boot_pwr_domain_disable(vdev)) {
814-
ivpu_err(vdev, "Failed to disable power domain\n");
757+
if (ivpu_hw_mtl_reset(vdev)) {
758+
ivpu_err(vdev, "Failed to reset the VPU\n");
815759
ret = -EIO;
816760
}
817761

@@ -844,6 +788,19 @@ static void ivpu_hw_mtl_wdt_disable(struct ivpu_device *vdev)
844788
REGV_WR32(MTL_VPU_CPU_SS_TIM_GEN_CONFIG, val);
845789
}
846790

791+
static u32 ivpu_hw_mtl_pll_to_freq(u32 ratio, u32 config)
792+
{
793+
u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
794+
u32 cpu_clock;
795+
796+
if ((config & 0xff) == PLL_RATIO_4_3)
797+
cpu_clock = pll_clock * 2 / 4;
798+
else
799+
cpu_clock = pll_clock * 2 / 5;
800+
801+
return cpu_clock;
802+
}
803+
847804
/* Register indirect accesses */
848805
static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
849806
{
@@ -855,7 +812,7 @@ static u32 ivpu_hw_mtl_reg_pll_freq_get(struct ivpu_device *vdev)
855812
if (!ivpu_is_silicon(vdev))
856813
return PLL_SIMULATION_FREQ;
857814

858-
return PLL_RATIO_TO_FREQ(pll_curr_ratio);
815+
return ivpu_hw_mtl_pll_to_freq(pll_curr_ratio, vdev->hw->config);
859816
}
860817

861818
static u32 ivpu_hw_mtl_reg_telemetry_offset_get(struct ivpu_device *vdev)

drivers/accel/ivpu/ivpu_ipc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct ivpu_bo;
2121
#define IVPU_IPC_ALIGNMENT 64
2222

2323
#define IVPU_IPC_HDR_FREE 0
24-
#define IVPU_IPC_HDR_ALLOCATED 0
24+
#define IVPU_IPC_HDR_ALLOCATED 1
2525

2626
/**
2727
* struct ivpu_ipc_hdr - The IPC message header structure, exchanged

drivers/accel/ivpu/ivpu_job.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,12 +489,12 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32
489489

490490
int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
491491
{
492-
int ret = 0;
493492
struct ivpu_file_priv *file_priv = file->driver_priv;
494493
struct ivpu_device *vdev = file_priv->vdev;
495494
struct drm_ivpu_submit *params = data;
496495
struct ivpu_job *job;
497496
u32 *buf_handles;
497+
int idx, ret;
498498

499499
if (params->engine > DRM_IVPU_ENGINE_COPY)
500500
return -EINVAL;
@@ -523,14 +523,19 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
523523
goto free_handles;
524524
}
525525

526+
if (!drm_dev_enter(&vdev->drm, &idx)) {
527+
ret = -ENODEV;
528+
goto free_handles;
529+
}
530+
526531
ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n",
527532
file_priv->ctx.id, params->buffer_count);
528533

529534
job = ivpu_create_job(file_priv, params->engine, params->buffer_count);
530535
if (!job) {
531536
ivpu_err(vdev, "Failed to create job\n");
532537
ret = -ENOMEM;
533-
goto free_handles;
538+
goto dev_exit;
534539
}
535540

536541
ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count,
@@ -548,6 +553,8 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
548553

549554
job_put:
550555
job_put(job);
556+
dev_exit:
557+
drm_dev_exit(idx);
551558
free_handles:
552559
kfree(buf_handles);
553560

drivers/accel/ivpu/ivpu_pm.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,18 @@ static int ivpu_resume(struct ivpu_device *vdev)
9898
static void ivpu_pm_recovery_work(struct work_struct *work)
9999
{
100100
struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work);
101-
struct ivpu_device *vdev = pm->vdev;
101+
struct ivpu_device *vdev = pm->vdev;
102102
char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL};
103103
int ret;
104104

105-
ret = pci_reset_function(to_pci_dev(vdev->drm.dev));
106-
if (ret)
105+
retry:
106+
ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev));
107+
if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) {
108+
cond_resched();
109+
goto retry;
110+
}
111+
112+
if (ret && ret != -EAGAIN)
107113
ivpu_err(vdev, "Failed to reset VPU: %d\n", ret);
108114

109115
kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt);
@@ -306,6 +312,11 @@ int ivpu_pm_init(struct ivpu_device *vdev)
306312
return 0;
307313
}
308314

315+
void ivpu_pm_cancel_recovery(struct ivpu_device *vdev)
316+
{
317+
cancel_work_sync(&vdev->pm->recovery_work);
318+
}
319+
309320
void ivpu_pm_enable(struct ivpu_device *vdev)
310321
{
311322
struct device *dev = vdev->drm.dev;

drivers/accel/ivpu/ivpu_pm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct ivpu_pm_info {
2121
int ivpu_pm_init(struct ivpu_device *vdev);
2222
void ivpu_pm_enable(struct ivpu_device *vdev);
2323
void ivpu_pm_disable(struct ivpu_device *vdev);
24+
void ivpu_pm_cancel_recovery(struct ivpu_device *vdev);
2425

2526
int ivpu_pm_suspend_cb(struct device *dev);
2627
int ivpu_pm_resume_cb(struct device *dev);

drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,12 @@ static bool amdgpu_atcs_pci_probe_handle(struct pci_dev *pdev)
981981
*/
982982
bool amdgpu_acpi_should_gpu_reset(struct amdgpu_device *adev)
983983
{
984-
if (adev->flags & AMD_IS_APU)
984+
if ((adev->flags & AMD_IS_APU) &&
985+
adev->gfx.imu.funcs) /* Not need to do mode2 reset for IMU enabled APUs */
986+
return false;
987+
988+
if ((adev->flags & AMD_IS_APU) &&
989+
amdgpu_acpi_is_s3_active(adev))
985990
return false;
986991

987992
if (amdgpu_sriov_vf(adev))

0 commit comments

Comments
 (0)