accel/ivpu: Disable buttress on device removal
authorStanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Thu, 23 Mar 2023 12:55:01 +0000 (13:55 +0100)
committerJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Fri, 24 Mar 2023 09:52:20 +0000 (10:52 +0100)
Use pci_set_power_state() to disable buttress when device is removed.
This is workaround of hardware bug that hangs the system.

Additionally not disabling buttress prevents CPU enter deeper Pkg-C
states when the driver is unloaded or fail to probe.

Fixes: 35b137630f08 ("accel/ivpu: Introduce a new DRM driver for Intel VPU")
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230323125504.2586442-6-stanislaw.gruszka@linux.intel.com
drivers/accel/ivpu/ivpu_drv.c
drivers/accel/ivpu/ivpu_drv.h
drivers/accel/ivpu/ivpu_hw_mtl.c

index 70245cf..6a320a7 100644 (file)
@@ -569,6 +569,8 @@ err_mmu_gctx_fini:
        ivpu_mmu_global_context_fini(vdev);
 err_power_down:
        ivpu_hw_power_down(vdev);
+       if (IVPU_WA(d3hot_after_power_off))
+               pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
 err_xa_destroy:
        xa_destroy(&vdev->submitted_jobs_xa);
        xa_destroy(&vdev->context_xa);
@@ -579,6 +581,8 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)
 {
        ivpu_pm_disable(vdev);
        ivpu_shutdown(vdev);
+       if (IVPU_WA(d3hot_after_power_off))
+               pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
        ivpu_job_done_thread_fini(vdev);
        ivpu_pm_cancel_recovery(vdev);
 
index ef12a38..d3013fb 100644 (file)
@@ -74,6 +74,7 @@
 struct ivpu_wa_table {
        bool punit_disabled;
        bool clear_runtime_mem;
+       bool d3hot_after_power_off;
 };
 
 struct ivpu_hw_info;
index 70ca6de..133ba33 100644 (file)
@@ -101,6 +101,7 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
 {
        vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
        vdev->wa.clear_runtime_mem = false;
+       vdev->wa.d3hot_after_power_off = true;
 }
 
 static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)