From: Rander Wang <rander.wang@xxxxxxxxx> [ Upstream commit 52a55779ed14792a150421339664193d6eb8e036 ] Add delay between set and wait command according to hardware programming sequence. Also add debug log to detect error. Signed-off-by: Rander Wang <rander.wang@xxxxxxxxx> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> Link: https://lore.kernel.org/r/20230307095453.3719-1-peter.ujfalusi@xxxxxxxxxxxxxxx Signed-off-by: Mark Brown <broonie@xxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> --- sound/soc/sof/intel/hda-dsp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index b4eacae8564c8..6b2094f74c9c0 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -399,6 +399,12 @@ static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value) snd_sof_dsp_update8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset, SOF_HDA_VS_D0I3C_I3, value); + /* + * The value written to the D0I3C::I3 bit may not be taken into account immediately. + * A delay is recommended before checking if D0I3C::CIP is cleared + */ + usleep_range(30, 40); + /* Wait for cmd in progress to be cleared before exiting the function */ ret = hda_dsp_wait_d0i3c_done(sdev); if (ret < 0) { @@ -407,6 +413,12 @@ static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value) } reg = snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, chip->d0i3_offset); + /* Confirm d0i3 state changed with paranoia check */ + if ((reg ^ value) & SOF_HDA_VS_D0I3C_I3) { + dev_err(sdev->dev, "failed to update D0I3C!\n"); + return -EIO; + } + trace_sof_intel_D0I3C_updated(sdev, reg); return 0; -- 2.39.2