ASoC: SOF: Intel: hda: add function for hda stop chip
Add common hda_dsp_ctrl_stop_chip() function to stop controller with the same function handling both HDA and non-HDA cases. This function disables IRQs and clears status masks. When CONFIG_SND_SOC_SOF_HDA is defined, also disables the CORB/RIRB, and stops i/o. Signed-off-by: Zhu Yingjiang <yingjiang.zhu@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
24b6ff686f
commit
13063a2ccf
|
@ -263,3 +263,70 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev)
|
||||||
|
{
|
||||||
|
struct hdac_bus *bus = sof_to_bus(sdev);
|
||||||
|
struct hdac_stream *stream;
|
||||||
|
int sd_offset;
|
||||||
|
|
||||||
|
if (!bus->chip_init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* disable interrupts in stream descriptor */
|
||||||
|
list_for_each_entry(stream, &bus->stream_list, list) {
|
||||||
|
sd_offset = SOF_STREAM_SD_OFFSET(stream);
|
||||||
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
|
||||||
|
sd_offset +
|
||||||
|
SOF_HDA_ADSP_REG_CL_SD_CTL,
|
||||||
|
SOF_HDA_CL_DMA_SD_INT_MASK,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disable SIE for all streams */
|
||||||
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
|
||||||
|
SOF_HDA_INT_ALL_STREAM, 0);
|
||||||
|
|
||||||
|
/* disable controller CIE and GIE */
|
||||||
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
|
||||||
|
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
|
||||||
|
0);
|
||||||
|
|
||||||
|
/* clear stream status */
|
||||||
|
list_for_each_entry(stream, &bus->stream_list, list) {
|
||||||
|
sd_offset = SOF_STREAM_SD_OFFSET(stream);
|
||||||
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
|
||||||
|
sd_offset +
|
||||||
|
SOF_HDA_ADSP_REG_CL_SD_STS,
|
||||||
|
SOF_HDA_CL_DMA_SD_INT_MASK,
|
||||||
|
SOF_HDA_CL_DMA_SD_INT_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear WAKESTS */
|
||||||
|
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
|
||||||
|
SOF_HDA_WAKESTS_INT_MASK,
|
||||||
|
SOF_HDA_WAKESTS_INT_MASK);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||||
|
/* clear rirb status */
|
||||||
|
snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clear interrupt status register */
|
||||||
|
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS,
|
||||||
|
SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
|
||||||
|
/* disable CORB/RIRB */
|
||||||
|
snd_hdac_bus_stop_cmd_io(bus);
|
||||||
|
#endif
|
||||||
|
/* disable position buffer */
|
||||||
|
if (bus->posbuf.addr) {
|
||||||
|
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
|
||||||
|
SOF_HDA_ADSP_DPLBASE, 0);
|
||||||
|
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
|
||||||
|
SOF_HDA_ADSP_DPUBASE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bus->chip_init = false;
|
||||||
|
}
|
||||||
|
|
|
@ -538,7 +538,7 @@ int hda_dsp_ctrl_link_reset(struct snd_sof_dev *sdev, bool reset);
|
||||||
void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable);
|
void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable);
|
||||||
int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable);
|
int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable);
|
||||||
int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset);
|
int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset);
|
||||||
|
void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev);
|
||||||
/*
|
/*
|
||||||
* HDA bus operations.
|
* HDA bus operations.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue