Skip to content

Commit 3f7c063

Browse files
committed
accel/ivpu/37xx: Fix hangs related to MMIO reset
There is no need to call MMIO reset using VPU_37XX_BUTTRESS_VPU_IP_RESET register. IP will be reset by FLR or by entering d0i3. Also IP reset during power_up is not needed as the VPU is already in reset. Removing MMIO reset improves stability as it a partial device reset that is not safe in some corner cases. This change also brings back ivpu_boot_pwr_domain_disable() that helps to properly power down VPU when it is hung by a buggy workload. Signed-off-by: Jacek Lawrynowicz <[email protected]> Fixes: 828d630 ("accel/ivpu: Don't enter d0i3 during FLR") Reviewed-by: Jeffrey Hugo <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent bb0a05a commit 3f7c063

File tree

1 file changed

+22
-24
lines changed

1 file changed

+22
-24
lines changed

drivers/accel/ivpu/ivpu_hw_37xx.c

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,16 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
502502
return ret;
503503
}
504504

505+
static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev)
506+
{
507+
ivpu_boot_dpu_active_drive(vdev, false);
508+
ivpu_boot_pwr_island_isolation_drive(vdev, true);
509+
ivpu_boot_pwr_island_trickle_drive(vdev, false);
510+
ivpu_boot_pwr_island_drive(vdev, false);
511+
512+
return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0);
513+
}
514+
505515
static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev)
506516
{
507517
u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
@@ -600,25 +610,17 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev)
600610

601611
static int ivpu_hw_37xx_reset(struct ivpu_device *vdev)
602612
{
603-
int ret;
604-
u32 val;
605-
606-
if (IVPU_WA(punit_disabled))
607-
return 0;
613+
int ret = 0;
608614

609-
ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
610-
if (ret) {
611-
ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n");
612-
return ret;
615+
if (ivpu_boot_pwr_domain_disable(vdev)) {
616+
ivpu_err(vdev, "Failed to disable power domain\n");
617+
ret = -EIO;
613618
}
614619

615-
val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_IP_RESET);
616-
val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, val);
617-
REGB_WR32(VPU_37XX_BUTTRESS_VPU_IP_RESET, val);
618-
619-
ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US);
620-
if (ret)
621-
ivpu_err(vdev, "Timed out waiting for RESET completion\n");
620+
if (ivpu_pll_disable(vdev)) {
621+
ivpu_err(vdev, "Failed to disable PLL\n");
622+
ret = -EIO;
623+
}
622624

623625
return ret;
624626
}
@@ -651,10 +653,6 @@ static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev)
651653
{
652654
int ret;
653655

654-
ret = ivpu_hw_37xx_reset(vdev);
655-
if (ret)
656-
ivpu_warn(vdev, "Failed to reset HW: %d\n", ret);
657-
658656
ret = ivpu_hw_37xx_d0i3_disable(vdev);
659657
if (ret)
660658
ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
@@ -722,11 +720,11 @@ static int ivpu_hw_37xx_power_down(struct ivpu_device *vdev)
722720
{
723721
int ret = 0;
724722

725-
if (!ivpu_hw_37xx_is_idle(vdev) && ivpu_hw_37xx_reset(vdev))
726-
ivpu_err(vdev, "Failed to reset the VPU\n");
723+
if (!ivpu_hw_37xx_is_idle(vdev))
724+
ivpu_warn(vdev, "VPU not idle during power down\n");
727725

728-
if (ivpu_pll_disable(vdev)) {
729-
ivpu_err(vdev, "Failed to disable PLL\n");
726+
if (ivpu_hw_37xx_reset(vdev)) {
727+
ivpu_err(vdev, "Failed to reset VPU\n");
730728
ret = -EIO;
731729
}
732730

0 commit comments

Comments
 (0)