xref: /OK3568_Linux_fs/kernel/sound/soc/sof/intel/hda-ctrl.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // This file is provided under a dual BSD/GPLv2 license.  When using or
4*4882a593Smuzhiyun // redistributing this file, you may do so under either license.
5*4882a593Smuzhiyun //
6*4882a593Smuzhiyun // Copyright(c) 2018 Intel Corporation. All rights reserved.
7*4882a593Smuzhiyun //
8*4882a593Smuzhiyun // Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9*4882a593Smuzhiyun //	    Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
10*4882a593Smuzhiyun //	    Rander Wang <rander.wang@intel.com>
11*4882a593Smuzhiyun //          Keyon Jie <yang.jie@linux.intel.com>
12*4882a593Smuzhiyun //
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /*
15*4882a593Smuzhiyun  * Hardware interface for generic Intel audio DSP HDA IP
16*4882a593Smuzhiyun  */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <sound/hdaudio_ext.h>
20*4882a593Smuzhiyun #include <sound/hda_register.h>
21*4882a593Smuzhiyun #include <sound/hda_component.h>
22*4882a593Smuzhiyun #include "../ops.h"
23*4882a593Smuzhiyun #include "hda.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
26*4882a593Smuzhiyun static int hda_codec_mask = -1;
27*4882a593Smuzhiyun module_param_named(codec_mask, hda_codec_mask, int, 0444);
28*4882a593Smuzhiyun MODULE_PARM_DESC(codec_mask, "SOF HDA codec mask for probing");
29*4882a593Smuzhiyun #endif
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun /*
32*4882a593Smuzhiyun  * HDA Operations.
33*4882a593Smuzhiyun  */
34*4882a593Smuzhiyun 
hda_dsp_ctrl_link_reset(struct snd_sof_dev * sdev,bool reset)35*4882a593Smuzhiyun int hda_dsp_ctrl_link_reset(struct snd_sof_dev *sdev, bool reset)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	unsigned long timeout;
38*4882a593Smuzhiyun 	u32 gctl = 0;
39*4882a593Smuzhiyun 	u32 val;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	/* 0 to enter reset and 1 to exit reset */
42*4882a593Smuzhiyun 	val = reset ? 0 : SOF_HDA_GCTL_RESET;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	/* enter/exit HDA controller reset */
45*4882a593Smuzhiyun 	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCTL,
46*4882a593Smuzhiyun 				SOF_HDA_GCTL_RESET, val);
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	/* wait to enter/exit reset */
49*4882a593Smuzhiyun 	timeout = jiffies + msecs_to_jiffies(HDA_DSP_CTRL_RESET_TIMEOUT);
50*4882a593Smuzhiyun 	while (time_before(jiffies, timeout)) {
51*4882a593Smuzhiyun 		gctl = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCTL);
52*4882a593Smuzhiyun 		if ((gctl & SOF_HDA_GCTL_RESET) == val)
53*4882a593Smuzhiyun 			return 0;
54*4882a593Smuzhiyun 		usleep_range(500, 1000);
55*4882a593Smuzhiyun 	}
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	/* enter/exit reset failed */
58*4882a593Smuzhiyun 	dev_err(sdev->dev, "error: failed to %s HDA controller gctl 0x%x\n",
59*4882a593Smuzhiyun 		reset ? "reset" : "ready", gctl);
60*4882a593Smuzhiyun 	return -EIO;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
hda_dsp_ctrl_get_caps(struct snd_sof_dev * sdev)63*4882a593Smuzhiyun int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun 	struct hdac_bus *bus = sof_to_bus(sdev);
66*4882a593Smuzhiyun 	u32 cap, offset, feature;
67*4882a593Smuzhiyun 	int count = 0;
68*4882a593Smuzhiyun 	int ret;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	/*
71*4882a593Smuzhiyun 	 * On some devices, one reset cycle is necessary before reading
72*4882a593Smuzhiyun 	 * capabilities
73*4882a593Smuzhiyun 	 */
74*4882a593Smuzhiyun 	ret = hda_dsp_ctrl_link_reset(sdev, true);
75*4882a593Smuzhiyun 	if (ret < 0)
76*4882a593Smuzhiyun 		return ret;
77*4882a593Smuzhiyun 	ret = hda_dsp_ctrl_link_reset(sdev, false);
78*4882a593Smuzhiyun 	if (ret < 0)
79*4882a593Smuzhiyun 		return ret;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	offset = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_LLCH);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	do {
84*4882a593Smuzhiyun 		dev_dbg(sdev->dev, "checking for capabilities at offset 0x%x\n",
85*4882a593Smuzhiyun 			offset & SOF_HDA_CAP_NEXT_MASK);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 		cap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, offset);
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 		if (cap == -1) {
90*4882a593Smuzhiyun 			dev_dbg(bus->dev, "Invalid capability reg read\n");
91*4882a593Smuzhiyun 			break;
92*4882a593Smuzhiyun 		}
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 		feature = (cap & SOF_HDA_CAP_ID_MASK) >> SOF_HDA_CAP_ID_OFF;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 		switch (feature) {
97*4882a593Smuzhiyun 		case SOF_HDA_PP_CAP_ID:
98*4882a593Smuzhiyun 			dev_dbg(sdev->dev, "found DSP capability at 0x%x\n",
99*4882a593Smuzhiyun 				offset);
100*4882a593Smuzhiyun 			bus->ppcap = bus->remap_addr + offset;
101*4882a593Smuzhiyun 			sdev->bar[HDA_DSP_PP_BAR] = bus->ppcap;
102*4882a593Smuzhiyun 			break;
103*4882a593Smuzhiyun 		case SOF_HDA_SPIB_CAP_ID:
104*4882a593Smuzhiyun 			dev_dbg(sdev->dev, "found SPIB capability at 0x%x\n",
105*4882a593Smuzhiyun 				offset);
106*4882a593Smuzhiyun 			bus->spbcap = bus->remap_addr + offset;
107*4882a593Smuzhiyun 			sdev->bar[HDA_DSP_SPIB_BAR] = bus->spbcap;
108*4882a593Smuzhiyun 			break;
109*4882a593Smuzhiyun 		case SOF_HDA_DRSM_CAP_ID:
110*4882a593Smuzhiyun 			dev_dbg(sdev->dev, "found DRSM capability at 0x%x\n",
111*4882a593Smuzhiyun 				offset);
112*4882a593Smuzhiyun 			bus->drsmcap = bus->remap_addr + offset;
113*4882a593Smuzhiyun 			sdev->bar[HDA_DSP_DRSM_BAR] = bus->drsmcap;
114*4882a593Smuzhiyun 			break;
115*4882a593Smuzhiyun 		case SOF_HDA_GTS_CAP_ID:
116*4882a593Smuzhiyun 			dev_dbg(sdev->dev, "found GTS capability at 0x%x\n",
117*4882a593Smuzhiyun 				offset);
118*4882a593Smuzhiyun 			bus->gtscap = bus->remap_addr + offset;
119*4882a593Smuzhiyun 			break;
120*4882a593Smuzhiyun 		case SOF_HDA_ML_CAP_ID:
121*4882a593Smuzhiyun 			dev_dbg(sdev->dev, "found ML capability at 0x%x\n",
122*4882a593Smuzhiyun 				offset);
123*4882a593Smuzhiyun 			bus->mlcap = bus->remap_addr + offset;
124*4882a593Smuzhiyun 			break;
125*4882a593Smuzhiyun 		default:
126*4882a593Smuzhiyun 			dev_dbg(sdev->dev, "found capability %d at 0x%x\n",
127*4882a593Smuzhiyun 				feature, offset);
128*4882a593Smuzhiyun 			break;
129*4882a593Smuzhiyun 		}
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 		offset = cap & SOF_HDA_CAP_NEXT_MASK;
132*4882a593Smuzhiyun 	} while (count++ <= SOF_HDA_MAX_CAPS && offset);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	return 0;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
hda_dsp_ctrl_ppcap_enable(struct snd_sof_dev * sdev,bool enable)137*4882a593Smuzhiyun void hda_dsp_ctrl_ppcap_enable(struct snd_sof_dev *sdev, bool enable)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	u32 val = enable ? SOF_HDA_PPCTL_GPROCEN : 0;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
142*4882a593Smuzhiyun 				SOF_HDA_PPCTL_GPROCEN, val);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev * sdev,bool enable)145*4882a593Smuzhiyun void hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev *sdev, bool enable)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	u32 val	= enable ? SOF_HDA_PPCTL_PIE : 0;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
150*4882a593Smuzhiyun 				SOF_HDA_PPCTL_PIE, val);
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev * sdev,bool enable)153*4882a593Smuzhiyun void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun 	u32 val = enable ? PCI_CGCTL_MISCBDCGE_MASK : 0;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	snd_sof_pci_update_bits(sdev, PCI_CGCTL, PCI_CGCTL_MISCBDCGE_MASK, val);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /*
161*4882a593Smuzhiyun  * enable/disable audio dsp clock gating and power gating bits.
162*4882a593Smuzhiyun  * This allows the HW to opportunistically power and clock gate
163*4882a593Smuzhiyun  * the audio dsp when it is idle
164*4882a593Smuzhiyun  */
hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev * sdev,bool enable)165*4882a593Smuzhiyun int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun 	u32 val;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	/* enable/disable audio dsp clock gating */
170*4882a593Smuzhiyun 	val = enable ? PCI_CGCTL_ADSPDCGE : 0;
171*4882a593Smuzhiyun 	snd_sof_pci_update_bits(sdev, PCI_CGCTL, PCI_CGCTL_ADSPDCGE, val);
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	/* enable/disable DMI Link L1 support */
174*4882a593Smuzhiyun 	val = enable ? HDA_VS_INTEL_EM2_L1SEN : 0;
175*4882a593Smuzhiyun 	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2,
176*4882a593Smuzhiyun 				HDA_VS_INTEL_EM2_L1SEN, val);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	/* enable/disable audio dsp power gating */
179*4882a593Smuzhiyun 	val = enable ? 0 : PCI_PGCTL_ADSPPGD;
180*4882a593Smuzhiyun 	snd_sof_pci_update_bits(sdev, PCI_PGCTL, PCI_PGCTL_ADSPPGD, val);
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	return 0;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun 
hda_dsp_ctrl_init_chip(struct snd_sof_dev * sdev,bool full_reset)185*4882a593Smuzhiyun int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	struct hdac_bus *bus = sof_to_bus(sdev);
188*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
189*4882a593Smuzhiyun 	struct hdac_ext_link *hlink;
190*4882a593Smuzhiyun #endif
191*4882a593Smuzhiyun 	struct hdac_stream *stream;
192*4882a593Smuzhiyun 	int sd_offset, ret = 0;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	if (bus->chip_init)
195*4882a593Smuzhiyun 		return 0;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
198*4882a593Smuzhiyun 	snd_hdac_set_codec_wakeup(bus, true);
199*4882a593Smuzhiyun #endif
200*4882a593Smuzhiyun 	hda_dsp_ctrl_misc_clock_gating(sdev, false);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	if (full_reset) {
203*4882a593Smuzhiyun 		/* reset HDA controller */
204*4882a593Smuzhiyun 		ret = hda_dsp_ctrl_link_reset(sdev, true);
205*4882a593Smuzhiyun 		if (ret < 0) {
206*4882a593Smuzhiyun 			dev_err(sdev->dev, "error: failed to reset HDA controller\n");
207*4882a593Smuzhiyun 			goto err;
208*4882a593Smuzhiyun 		}
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 		usleep_range(500, 1000);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 		/* exit HDA controller reset */
213*4882a593Smuzhiyun 		ret = hda_dsp_ctrl_link_reset(sdev, false);
214*4882a593Smuzhiyun 		if (ret < 0) {
215*4882a593Smuzhiyun 			dev_err(sdev->dev, "error: failed to exit HDA controller reset\n");
216*4882a593Smuzhiyun 			goto err;
217*4882a593Smuzhiyun 		}
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 		usleep_range(1000, 1200);
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
223*4882a593Smuzhiyun 	/* check to see if controller is ready */
224*4882a593Smuzhiyun 	if (!snd_hdac_chip_readb(bus, GCTL)) {
225*4882a593Smuzhiyun 		dev_dbg(bus->dev, "controller not ready!\n");
226*4882a593Smuzhiyun 		ret = -EBUSY;
227*4882a593Smuzhiyun 		goto err;
228*4882a593Smuzhiyun 	}
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	/* Accept unsolicited responses */
231*4882a593Smuzhiyun 	snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	/* detect codecs */
234*4882a593Smuzhiyun 	if (!bus->codec_mask) {
235*4882a593Smuzhiyun 		bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
236*4882a593Smuzhiyun 		dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
237*4882a593Smuzhiyun 	}
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	if (hda_codec_mask != -1) {
240*4882a593Smuzhiyun 		bus->codec_mask &= hda_codec_mask;
241*4882a593Smuzhiyun 		dev_dbg(bus->dev, "filtered codec_mask = 0x%lx\n",
242*4882a593Smuzhiyun 			bus->codec_mask);
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun #endif
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	/* clear stream status */
247*4882a593Smuzhiyun 	list_for_each_entry(stream, &bus->stream_list, list) {
248*4882a593Smuzhiyun 		sd_offset = SOF_STREAM_SD_OFFSET(stream);
249*4882a593Smuzhiyun 		snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
250*4882a593Smuzhiyun 				  sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
251*4882a593Smuzhiyun 				  SOF_HDA_CL_DMA_SD_INT_MASK);
252*4882a593Smuzhiyun 	}
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	/* clear WAKESTS */
255*4882a593Smuzhiyun 	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
256*4882a593Smuzhiyun 			  SOF_HDA_WAKESTS_INT_MASK);
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
259*4882a593Smuzhiyun 	/* clear rirb status */
260*4882a593Smuzhiyun 	snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
261*4882a593Smuzhiyun #endif
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	/* clear interrupt status register */
264*4882a593Smuzhiyun 	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS,
265*4882a593Smuzhiyun 			  SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM);
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
268*4882a593Smuzhiyun 	/* initialize the codec command I/O */
269*4882a593Smuzhiyun 	snd_hdac_bus_init_cmd_io(bus);
270*4882a593Smuzhiyun #endif
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	/* enable CIE and GIE interrupts */
273*4882a593Smuzhiyun 	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
274*4882a593Smuzhiyun 				SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
275*4882a593Smuzhiyun 				SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	/* program the position buffer */
278*4882a593Smuzhiyun 	if (bus->use_posbuf && bus->posbuf.addr) {
279*4882a593Smuzhiyun 		snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
280*4882a593Smuzhiyun 				  (u32)bus->posbuf.addr);
281*4882a593Smuzhiyun 		snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
282*4882a593Smuzhiyun 				  upper_32_bits(bus->posbuf.addr));
283*4882a593Smuzhiyun 	}
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
286*4882a593Smuzhiyun 	/* Reset stream-to-link mapping */
287*4882a593Smuzhiyun 	list_for_each_entry(hlink, &bus->hlink_list, list)
288*4882a593Smuzhiyun 		writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
289*4882a593Smuzhiyun #endif
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	bus->chip_init = true;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun err:
294*4882a593Smuzhiyun 	hda_dsp_ctrl_misc_clock_gating(sdev, true);
295*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
296*4882a593Smuzhiyun 	snd_hdac_set_codec_wakeup(bus, false);
297*4882a593Smuzhiyun #endif
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	return ret;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun 
hda_dsp_ctrl_stop_chip(struct snd_sof_dev * sdev)302*4882a593Smuzhiyun void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	struct hdac_bus *bus = sof_to_bus(sdev);
305*4882a593Smuzhiyun 	struct hdac_stream *stream;
306*4882a593Smuzhiyun 	int sd_offset;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	if (!bus->chip_init)
309*4882a593Smuzhiyun 		return;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	/* disable interrupts in stream descriptor */
312*4882a593Smuzhiyun 	list_for_each_entry(stream, &bus->stream_list, list) {
313*4882a593Smuzhiyun 		sd_offset = SOF_STREAM_SD_OFFSET(stream);
314*4882a593Smuzhiyun 		snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
315*4882a593Smuzhiyun 					sd_offset +
316*4882a593Smuzhiyun 					SOF_HDA_ADSP_REG_CL_SD_CTL,
317*4882a593Smuzhiyun 					SOF_HDA_CL_DMA_SD_INT_MASK,
318*4882a593Smuzhiyun 					0);
319*4882a593Smuzhiyun 	}
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	/* disable SIE for all streams */
322*4882a593Smuzhiyun 	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
323*4882a593Smuzhiyun 				SOF_HDA_INT_ALL_STREAM,	0);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	/* disable controller CIE and GIE */
326*4882a593Smuzhiyun 	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
327*4882a593Smuzhiyun 				SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
328*4882a593Smuzhiyun 				0);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	/* clear stream status */
331*4882a593Smuzhiyun 	list_for_each_entry(stream, &bus->stream_list, list) {
332*4882a593Smuzhiyun 		sd_offset = SOF_STREAM_SD_OFFSET(stream);
333*4882a593Smuzhiyun 		snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
334*4882a593Smuzhiyun 				  sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
335*4882a593Smuzhiyun 				  SOF_HDA_CL_DMA_SD_INT_MASK);
336*4882a593Smuzhiyun 	}
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	/* clear WAKESTS */
339*4882a593Smuzhiyun 	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
340*4882a593Smuzhiyun 			  SOF_HDA_WAKESTS_INT_MASK);
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
343*4882a593Smuzhiyun 	/* clear rirb status */
344*4882a593Smuzhiyun 	snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
345*4882a593Smuzhiyun #endif
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	/* clear interrupt status register */
348*4882a593Smuzhiyun 	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS,
349*4882a593Smuzhiyun 			  SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
352*4882a593Smuzhiyun 	/* disable CORB/RIRB */
353*4882a593Smuzhiyun 	snd_hdac_bus_stop_cmd_io(bus);
354*4882a593Smuzhiyun #endif
355*4882a593Smuzhiyun 	/* disable position buffer */
356*4882a593Smuzhiyun 	if (bus->posbuf.addr) {
357*4882a593Smuzhiyun 		snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
358*4882a593Smuzhiyun 				  SOF_HDA_ADSP_DPLBASE, 0);
359*4882a593Smuzhiyun 		snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
360*4882a593Smuzhiyun 				  SOF_HDA_ADSP_DPUBASE, 0);
361*4882a593Smuzhiyun 	}
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	bus->chip_init = false;
364*4882a593Smuzhiyun }
365