mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-20 16:13:15 +00:00
accel/ivpu: Don't enter d0i3 during FLR
Avoid HW bug on some platforms where we enter D0i3 state
and CPU is in low power states (C8 or above).
Fixes: 852be13f3b
("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
This commit is contained in:
parent
fa8391ad68
commit
828d63042a
6 changed files with 21 additions and 4 deletions
|
@ -367,14 +367,19 @@ int ivpu_boot(struct ivpu_device *vdev)
|
||||||
return 0;
|
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);
|
ivpu_hw_irq_disable(vdev);
|
||||||
disable_irq(vdev->irq);
|
disable_irq(vdev->irq);
|
||||||
ivpu_ipc_disable(vdev);
|
ivpu_ipc_disable(vdev);
|
||||||
ivpu_mmu_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);
|
ret = ivpu_hw_power_down(vdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -151,6 +151,7 @@ void ivpu_file_priv_put(struct ivpu_file_priv **link);
|
||||||
|
|
||||||
int ivpu_boot(struct ivpu_device *vdev);
|
int ivpu_boot(struct ivpu_device *vdev);
|
||||||
int ivpu_shutdown(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)
|
static inline u8 ivpu_revision(struct ivpu_device *vdev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@ struct ivpu_hw_ops {
|
||||||
int (*power_up)(struct ivpu_device *vdev);
|
int (*power_up)(struct ivpu_device *vdev);
|
||||||
int (*boot_fw)(struct ivpu_device *vdev);
|
int (*boot_fw)(struct ivpu_device *vdev);
|
||||||
int (*power_down)(struct ivpu_device *vdev);
|
int (*power_down)(struct ivpu_device *vdev);
|
||||||
|
int (*reset)(struct ivpu_device *vdev);
|
||||||
bool (*is_idle)(struct ivpu_device *vdev);
|
bool (*is_idle)(struct ivpu_device *vdev);
|
||||||
void (*wdt_disable)(struct ivpu_device *vdev);
|
void (*wdt_disable)(struct ivpu_device *vdev);
|
||||||
void (*diagnose_failure)(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);
|
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)
|
static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
|
||||||
{
|
{
|
||||||
vdev->hw->ops->wdt_disable(vdev);
|
vdev->hw->ops->wdt_disable(vdev);
|
||||||
|
|
|
@ -1029,6 +1029,7 @@ const struct ivpu_hw_ops ivpu_hw_37xx_ops = {
|
||||||
.power_up = ivpu_hw_37xx_power_up,
|
.power_up = ivpu_hw_37xx_power_up,
|
||||||
.is_idle = ivpu_hw_37xx_is_idle,
|
.is_idle = ivpu_hw_37xx_is_idle,
|
||||||
.power_down = ivpu_hw_37xx_power_down,
|
.power_down = ivpu_hw_37xx_power_down,
|
||||||
|
.reset = ivpu_hw_37xx_reset,
|
||||||
.boot_fw = ivpu_hw_37xx_boot_fw,
|
.boot_fw = ivpu_hw_37xx_boot_fw,
|
||||||
.wdt_disable = ivpu_hw_37xx_wdt_disable,
|
.wdt_disable = ivpu_hw_37xx_wdt_disable,
|
||||||
.diagnose_failure = ivpu_hw_37xx_diagnose_failure,
|
.diagnose_failure = ivpu_hw_37xx_diagnose_failure,
|
||||||
|
|
|
@ -1179,6 +1179,7 @@ const struct ivpu_hw_ops ivpu_hw_40xx_ops = {
|
||||||
.power_up = ivpu_hw_40xx_power_up,
|
.power_up = ivpu_hw_40xx_power_up,
|
||||||
.is_idle = ivpu_hw_40xx_is_idle,
|
.is_idle = ivpu_hw_40xx_is_idle,
|
||||||
.power_down = ivpu_hw_40xx_power_down,
|
.power_down = ivpu_hw_40xx_power_down,
|
||||||
|
.reset = ivpu_hw_40xx_reset,
|
||||||
.boot_fw = ivpu_hw_40xx_boot_fw,
|
.boot_fw = ivpu_hw_40xx_boot_fw,
|
||||||
.wdt_disable = ivpu_hw_40xx_wdt_disable,
|
.wdt_disable = ivpu_hw_40xx_wdt_disable,
|
||||||
.diagnose_failure = ivpu_hw_40xx_diagnose_failure,
|
.diagnose_failure = ivpu_hw_40xx_diagnose_failure,
|
||||||
|
|
|
@ -261,7 +261,8 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev)
|
||||||
ivpu_dbg(vdev, PM, "Pre-reset..\n");
|
ivpu_dbg(vdev, PM, "Pre-reset..\n");
|
||||||
atomic_inc(&vdev->pm->reset_counter);
|
atomic_inc(&vdev->pm->reset_counter);
|
||||||
atomic_set(&vdev->pm->in_reset, 1);
|
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_pm_prepare_cold_boot(vdev);
|
||||||
ivpu_jobs_abort_all(vdev);
|
ivpu_jobs_abort_all(vdev);
|
||||||
ivpu_dbg(vdev, PM, "Pre-reset done.\n");
|
ivpu_dbg(vdev, PM, "Pre-reset done.\n");
|
||||||
|
|
Loading…
Add table
Reference in a new issue