From 3b9eda55852002aaafab2a22e92197317211864a Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 8 Mar 2019 13:17:23 +0800 Subject: [PATCH] ASoC:sof:hda: fix hda preload issue This issue could be reproduced by multiplex_pipeline-test.sh with two pipelines. The hda preload would be in unexpected status sometimes and this results ipc timeout. The recommended hardware programming sequence for HDAudio DMA format is: 1. Put DMA into coupled mode by clearing PPCTL.PROCEN bit for corresponding stream index before the time of writing format to SDxFMT register. 2. Write SDxFMT 3. Set PPCTL.PROCEN bit for corresponding stream index to enable decoupled mode I reproduced this issue on Apollolake UP2 a few times and validated the fix a few times. I can't reproduce it on Icelake because this platform is not stable with multiple threads test for other reasons, but this patch didn't make any negative effect with single thread test of playback or capture. Signed-off-by: Keyon Jie Signed-off-by: Rander Wang --- sound/soc/sof/intel/hda-stream.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index c70046f20eece1..5b8e589b1bd9b0 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -363,12 +363,31 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL, hstream->bufsize); + /* + * Recommended hardware programming sequence for HDAudio DMA format + * + * 1. Put DMA into coupled mode by clearing PPCTL.PROCEN bit + * for corresponding stream index before the time of writing + * format to SDxFMT register. + * 2. Write SDxFMT + * 3. Set PPCTL.PROCEN bit for corresponding stream index to + * enable decoupled mode + */ + + /* couple host and link DMA, disable DSP features */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, + mask, 0); + /* program stream format */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset + SOF_HDA_ADSP_REG_CL_SD_FORMAT, 0xffff, hstream->format_val); + /* decouple host and link DMA, enable DSP features */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, + mask, mask); + /* program last valid index */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,