]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
accel/ivpu: Don't enter d0i3 during FLR
authorJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Tue, 3 Oct 2023 06:42:13 +0000 (08:42 +0200)
committerStanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Thu, 19 Oct 2023 04:48:05 +0000 (06:48 +0200)
Avoid HW bug on some platforms where we enter D0i3 state
and CPU is in low power states (C8 or above).

Fixes: 852be13f3bd3 ("accel/ivpu: Add PM support")
Cc: stable@vger.kernel.org
Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231003064213.1527327-1-stanislaw.gruszka@linux.intel.com
drivers/accel/ivpu/ivpu_drv.c
drivers/accel/ivpu/ivpu_drv.h
drivers/accel/ivpu/ivpu_hw.h
drivers/accel/ivpu/ivpu_hw_37xx.c
drivers/accel/ivpu/ivpu_hw_40xx.c
drivers/accel/ivpu/ivpu_pm.c

index 467a60235370c58faa09901624a62b5a85ac32fe..7e9359611d69ca6fd93cc5c5731da797bc0d964c 100644 (file)
@@ -367,14 +367,19 @@ int ivpu_boot(struct ivpu_device *vdev)
        return 0;
 }
 
-int ivpu_shutdown(struct ivpu_device *vdev)
+void ivpu_prepare_for_reset(struct ivpu_device *vdev)
 {
-       int ret;
-
        ivpu_hw_irq_disable(vdev);
        disable_irq(vdev->irq);
        ivpu_ipc_disable(vdev);
        ivpu_mmu_disable(vdev);
+}
+
+int ivpu_shutdown(struct ivpu_device *vdev)
+{
+       int ret;
+
+       ivpu_prepare_for_reset(vdev);
 
        ret = ivpu_hw_power_down(vdev);
        if (ret)
index 03b3d6532fb626306e106afa2715dd02f6800ed0..2adc349126bb6622b86e6bfbd5bc9df00b8d4c17 100644 (file)
@@ -151,6 +151,7 @@ void ivpu_file_priv_put(struct ivpu_file_priv **link);
 
 int ivpu_boot(struct ivpu_device *vdev);
 int ivpu_shutdown(struct ivpu_device *vdev);
+void ivpu_prepare_for_reset(struct ivpu_device *vdev);
 
 static inline u8 ivpu_revision(struct ivpu_device *vdev)
 {
index ab341237bcf97a45608d35f965e4d3e2895f91e5..1079e06255ba6dd33b375b2485611a012eeb6d6f 100644 (file)
@@ -13,6 +13,7 @@ struct ivpu_hw_ops {
        int (*power_up)(struct ivpu_device *vdev);
        int (*boot_fw)(struct ivpu_device *vdev);
        int (*power_down)(struct ivpu_device *vdev);
+       int (*reset)(struct ivpu_device *vdev);
        bool (*is_idle)(struct ivpu_device *vdev);
        void (*wdt_disable)(struct ivpu_device *vdev);
        void (*diagnose_failure)(struct ivpu_device *vdev);
@@ -91,6 +92,13 @@ static inline int ivpu_hw_power_down(struct ivpu_device *vdev)
        return vdev->hw->ops->power_down(vdev);
 };
 
+static inline int ivpu_hw_reset(struct ivpu_device *vdev)
+{
+       ivpu_dbg(vdev, PM, "HW reset\n");
+
+       return vdev->hw->ops->reset(vdev);
+};
+
 static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
 {
        vdev->hw->ops->wdt_disable(vdev);
index 9eae1c241bc0e51f86b394b7aabb05e7936a59aa..97601942916439d33c4b6af82d0ce7f3b9ea0bc3 100644 (file)
@@ -1029,6 +1029,7 @@ const struct ivpu_hw_ops ivpu_hw_37xx_ops = {
        .power_up = ivpu_hw_37xx_power_up,
        .is_idle = ivpu_hw_37xx_is_idle,
        .power_down = ivpu_hw_37xx_power_down,
+       .reset = ivpu_hw_37xx_reset,
        .boot_fw = ivpu_hw_37xx_boot_fw,
        .wdt_disable = ivpu_hw_37xx_wdt_disable,
        .diagnose_failure = ivpu_hw_37xx_diagnose_failure,
index 8bdb59a45da6b38793d32352e159eebc42647ee3..85171a408363fae483846bf86a0975a47bb28762 100644 (file)
@@ -1179,6 +1179,7 @@ const struct ivpu_hw_ops ivpu_hw_40xx_ops = {
        .power_up = ivpu_hw_40xx_power_up,
        .is_idle = ivpu_hw_40xx_is_idle,
        .power_down = ivpu_hw_40xx_power_down,
+       .reset = ivpu_hw_40xx_reset,
        .boot_fw = ivpu_hw_40xx_boot_fw,
        .wdt_disable = ivpu_hw_40xx_wdt_disable,
        .diagnose_failure = ivpu_hw_40xx_diagnose_failure,
index e6f27daf5560b691a8483ff7963f89aa69dbea65..ffff2496e8e8e3ed90bda27217ecbae386b52d04 100644 (file)
@@ -261,7 +261,8 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev)
        ivpu_dbg(vdev, PM, "Pre-reset..\n");
        atomic_inc(&vdev->pm->reset_counter);
        atomic_set(&vdev->pm->in_reset, 1);
-       ivpu_shutdown(vdev);
+       ivpu_prepare_for_reset(vdev);
+       ivpu_hw_reset(vdev);
        ivpu_pm_prepare_cold_boot(vdev);
        ivpu_jobs_abort_all(vdev);
        ivpu_dbg(vdev, PM, "Pre-reset done.\n");