Unverified Commit 13063a2c authored by Zhu Yingjiang's avatar Zhu Yingjiang Committed by Mark Brown
Browse files

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: default avatarZhu Yingjiang <yingjiang.zhu@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 24b6ff68
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
@@ -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;
}
+1 −1
Original line number Diff line number Diff line
@@ -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.
 */