mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev);
|
||||
/*
|
||||
* HDA bus operations.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user