@@ -443,6 +443,19 @@ static int mt8195_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
{
struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev);
int ret;
+ u32 reset_sw, dbg_pc;
+
+ /* wait dsp enter idle, timeout is 1 second */
+ ret = snd_sof_dsp_read_poll_timeout(sdev, DSP_REG_BAR,
+ DSP_RESET_SW, reset_sw,
+ ((reset_sw & ADSP_PWAIT) == ADSP_PWAIT),
+ SUSPEND_DSP_IDLE_POLL_INTERVAL_US,
+ SUSPEND_DSP_IDLE_TIMEOUT_US);
+ if (ret < 0) {
+ dbg_pc = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGPC);
+ dev_warn(sdev->dev, "dsp not idle, powering off anyway : swrest %#x, pc %#x, ret %d\n",
+ reset_sw, dbg_pc, ret);
+ }
/* stall and reset dsp */
sof_hifixdsp_shutdown(sdev);
@@ -34,6 +34,7 @@ struct snd_sof_dev;
#define ADSP_DRESET_SW BIT(1)
#define ADSP_RUNSTALL BIT(3)
#define STATVECTOR_SEL BIT(4)
+#define ADSP_PWAIT BIT(16)
#define DSP_PFAULTBUS 0x0028
#define DSP_PFAULTINFO 0x002c
#define DSP_GPR00 0x0030
@@ -153,6 +154,10 @@ struct snd_sof_dev;
#define DRAM_REMAP_SHIFT 12
#define DRAM_REMAP_MASK (BIT(DRAM_REMAP_SHIFT) - 1)
+/* suspend dsp idle check interval and timeout */
+#define SUSPEND_DSP_IDLE_TIMEOUT_US 1000000 /* timeout to wait dsp idle, 1 sec */
+#define SUSPEND_DSP_IDLE_POLL_INTERVAL_US 500 /* 0.5 msec */
+
void sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr);
void sof_hifixdsp_shutdown(struct snd_sof_dev *sdev);
#endif