xref: /openbmc/linux/sound/soc/sof/intel/hda-dsp.c (revision 1a59d1b8)
1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 //
3 // This file is provided under a dual BSD/GPLv2 license.  When using or
4 // redistributing this file, you may do so under either license.
5 //
6 // Copyright(c) 2018 Intel Corporation. All rights reserved.
7 //
8 // Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9 //	    Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
10 //	    Rander Wang <rander.wang@intel.com>
11 //          Keyon Jie <yang.jie@linux.intel.com>
12 //
13 
14 /*
15  * Hardware interface for generic Intel audio DSP HDA IP
16  */
17 
18 #include <sound/hdaudio_ext.h>
19 #include <sound/hda_register.h>
20 #include "../ops.h"
21 #include "hda.h"
22 
23 /*
24  * DSP Core control.
25  */
26 
27 int hda_dsp_core_reset_enter(struct snd_sof_dev *sdev, unsigned int core_mask)
28 {
29 	u32 adspcs;
30 	u32 reset;
31 	int ret;
32 
33 	/* set reset bits for cores */
34 	reset = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
35 	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
36 					 HDA_DSP_REG_ADSPCS,
37 					 reset, reset),
38 
39 	/* poll with timeout to check if operation successful */
40 	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
41 					HDA_DSP_REG_ADSPCS, adspcs,
42 					((adspcs & reset) == reset),
43 					HDA_DSP_REG_POLL_INTERVAL_US,
44 					HDA_DSP_RESET_TIMEOUT_US);
45 
46 	/* has core entered reset ? */
47 	adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
48 				  HDA_DSP_REG_ADSPCS);
49 	if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) !=
50 		HDA_DSP_ADSPCS_CRST_MASK(core_mask)) {
51 		dev_err(sdev->dev,
52 			"error: reset enter failed: core_mask %x adspcs 0x%x\n",
53 			core_mask, adspcs);
54 		ret = -EIO;
55 	}
56 
57 	return ret;
58 }
59 
60 int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask)
61 {
62 	unsigned int crst;
63 	u32 adspcs;
64 	int ret;
65 
66 	/* clear reset bits for cores */
67 	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
68 					 HDA_DSP_REG_ADSPCS,
69 					 HDA_DSP_ADSPCS_CRST_MASK(core_mask),
70 					 0);
71 
72 	/* poll with timeout to check if operation successful */
73 	crst = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
74 	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
75 					    HDA_DSP_REG_ADSPCS, adspcs,
76 					    !(adspcs & crst),
77 					    HDA_DSP_REG_POLL_INTERVAL_US,
78 					    HDA_DSP_RESET_TIMEOUT_US);
79 
80 	/* has core left reset ? */
81 	adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
82 				  HDA_DSP_REG_ADSPCS);
83 	if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) != 0) {
84 		dev_err(sdev->dev,
85 			"error: reset leave failed: core_mask %x adspcs 0x%x\n",
86 			core_mask, adspcs);
87 		ret = -EIO;
88 	}
89 
90 	return ret;
91 }
92 
93 int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask)
94 {
95 	/* stall core */
96 	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
97 					 HDA_DSP_REG_ADSPCS,
98 					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
99 					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
100 
101 	/* set reset state */
102 	return hda_dsp_core_reset_enter(sdev, core_mask);
103 }
104 
105 int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask)
106 {
107 	int ret;
108 
109 	/* leave reset state */
110 	ret = hda_dsp_core_reset_leave(sdev, core_mask);
111 	if (ret < 0)
112 		return ret;
113 
114 	/* run core */
115 	dev_dbg(sdev->dev, "unstall/run core: core_mask = %x\n", core_mask);
116 	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
117 					 HDA_DSP_REG_ADSPCS,
118 					 HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
119 					 0);
120 
121 	/* is core now running ? */
122 	if (!hda_dsp_core_is_enabled(sdev, core_mask)) {
123 		hda_dsp_core_stall_reset(sdev, core_mask);
124 		dev_err(sdev->dev, "error: DSP start core failed: core_mask %x\n",
125 			core_mask);
126 		ret = -EIO;
127 	}
128 
129 	return ret;
130 }
131 
132 /*
133  * Power Management.
134  */
135 
136 int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask)
137 {
138 	unsigned int cpa;
139 	u32 adspcs;
140 	int ret;
141 
142 	/* update bits */
143 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS,
144 				HDA_DSP_ADSPCS_SPA_MASK(core_mask),
145 				HDA_DSP_ADSPCS_SPA_MASK(core_mask));
146 
147 	/* poll with timeout to check if operation successful */
148 	cpa = HDA_DSP_ADSPCS_CPA_MASK(core_mask);
149 	ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
150 					    HDA_DSP_REG_ADSPCS, adspcs,
151 					    (adspcs & cpa) == cpa,
152 					    HDA_DSP_REG_POLL_INTERVAL_US,
153 					    HDA_DSP_RESET_TIMEOUT_US);
154 	if (ret < 0)
155 		dev_err(sdev->dev, "error: timeout on core powerup\n");
156 
157 	/* did core power up ? */
158 	adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
159 				  HDA_DSP_REG_ADSPCS);
160 	if ((adspcs & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) !=
161 		HDA_DSP_ADSPCS_CPA_MASK(core_mask)) {
162 		dev_err(sdev->dev,
163 			"error: power up core failed core_mask %xadspcs 0x%x\n",
164 			core_mask, adspcs);
165 		ret = -EIO;
166 	}
167 
168 	return ret;
169 }
170 
171 int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask)
172 {
173 	u32 adspcs;
174 
175 	/* update bits */
176 	snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
177 					 HDA_DSP_REG_ADSPCS,
178 					 HDA_DSP_ADSPCS_SPA_MASK(core_mask), 0);
179 
180 	return snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
181 				HDA_DSP_REG_ADSPCS, adspcs,
182 				!(adspcs & HDA_DSP_ADSPCS_SPA_MASK(core_mask)),
183 				HDA_DSP_REG_POLL_INTERVAL_US,
184 				HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC);
185 }
186 
187 bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev,
188 			     unsigned int core_mask)
189 {
190 	int val;
191 	bool is_enable;
192 
193 	val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS);
194 
195 	is_enable = ((val & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) &&
196 			(val & HDA_DSP_ADSPCS_SPA_MASK(core_mask)) &&
197 			!(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) &&
198 			!(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)));
199 
200 	dev_dbg(sdev->dev, "DSP core(s) enabled? %d : core_mask %x\n",
201 		is_enable, core_mask);
202 
203 	return is_enable;
204 }
205 
206 int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask)
207 {
208 	int ret;
209 
210 	/* return if core is already enabled */
211 	if (hda_dsp_core_is_enabled(sdev, core_mask))
212 		return 0;
213 
214 	/* power up */
215 	ret = hda_dsp_core_power_up(sdev, core_mask);
216 	if (ret < 0) {
217 		dev_err(sdev->dev, "error: dsp core power up failed: core_mask %x\n",
218 			core_mask);
219 		return ret;
220 	}
221 
222 	return hda_dsp_core_run(sdev, core_mask);
223 }
224 
225 int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
226 				  unsigned int core_mask)
227 {
228 	int ret;
229 
230 	/* place core in reset prior to power down */
231 	ret = hda_dsp_core_stall_reset(sdev, core_mask);
232 	if (ret < 0) {
233 		dev_err(sdev->dev, "error: dsp core reset failed: core_mask %x\n",
234 			core_mask);
235 		return ret;
236 	}
237 
238 	/* power down core */
239 	ret = hda_dsp_core_power_down(sdev, core_mask);
240 	if (ret < 0) {
241 		dev_err(sdev->dev, "error: dsp core power down fail mask %x: %d\n",
242 			core_mask, ret);
243 		return ret;
244 	}
245 
246 	/* make sure we are in OFF state */
247 	if (hda_dsp_core_is_enabled(sdev, core_mask)) {
248 		dev_err(sdev->dev, "error: dsp core disable fail mask %x: %d\n",
249 			core_mask, ret);
250 		ret = -EIO;
251 	}
252 
253 	return ret;
254 }
255 
256 void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev)
257 {
258 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
259 	const struct sof_intel_dsp_desc *chip = hda->desc;
260 
261 	/* enable IPC DONE and BUSY interrupts */
262 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
263 			HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY,
264 			HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY);
265 
266 	/* enable IPC interrupt */
267 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
268 				HDA_DSP_ADSPIC_IPC, HDA_DSP_ADSPIC_IPC);
269 }
270 
271 void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
272 {
273 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
274 	const struct sof_intel_dsp_desc *chip = hda->desc;
275 
276 	/* disable IPC interrupt */
277 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
278 				HDA_DSP_ADSPIC_IPC, 0);
279 
280 	/* disable IPC BUSY and DONE interrupt */
281 	snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
282 			HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0);
283 }
284 
285 static int hda_suspend(struct snd_sof_dev *sdev, int state)
286 {
287 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
288 	const struct sof_intel_dsp_desc *chip = hda->desc;
289 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
290 	struct hdac_bus *bus = sof_to_bus(sdev);
291 #endif
292 	int ret;
293 
294 	/* disable IPC interrupts */
295 	hda_dsp_ipc_int_disable(sdev);
296 
297 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
298 	/* power down all hda link */
299 	snd_hdac_ext_bus_link_power_down_all(bus);
300 #endif
301 
302 	/* power down DSP */
303 	ret = hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
304 	if (ret < 0) {
305 		dev_err(sdev->dev,
306 			"error: failed to power down core during suspend\n");
307 		return ret;
308 	}
309 
310 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
311 	/* disable ppcap interrupt */
312 	snd_hdac_ext_bus_ppcap_int_enable(bus, false);
313 	snd_hdac_ext_bus_ppcap_enable(bus, false);
314 
315 	/* disable hda bus irq and i/o */
316 	snd_hdac_bus_stop_chip(bus);
317 #else
318 	/* disable ppcap interrupt */
319 	hda_dsp_ctrl_ppcap_enable(sdev, false);
320 	hda_dsp_ctrl_ppcap_int_enable(sdev, false);
321 
322 	/* disable hda bus irq */
323 	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
324 				SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
325 				0);
326 #endif
327 
328 	/* disable LP retention mode */
329 	snd_sof_pci_update_bits(sdev, PCI_PGCTL,
330 				PCI_PGCTL_LSRMD_MASK, PCI_PGCTL_LSRMD_MASK);
331 
332 	/* reset controller */
333 	ret = hda_dsp_ctrl_link_reset(sdev, true);
334 	if (ret < 0) {
335 		dev_err(sdev->dev,
336 			"error: failed to reset controller during suspend\n");
337 		return ret;
338 	}
339 
340 	return 0;
341 }
342 
343 static int hda_resume(struct snd_sof_dev *sdev)
344 {
345 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
346 	struct hdac_bus *bus = sof_to_bus(sdev);
347 	struct hdac_ext_link *hlink = NULL;
348 #endif
349 	int ret;
350 
351 	/*
352 	 * clear TCSEL to clear playback on some HD Audio
353 	 * codecs. PCI TCSEL is defined in the Intel manuals.
354 	 */
355 	snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
356 
357 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
358 	/* reset and start hda controller */
359 	ret = hda_dsp_ctrl_init_chip(sdev, true);
360 	if (ret < 0) {
361 		dev_err(sdev->dev,
362 			"error: failed to start controller after resume\n");
363 		return ret;
364 	}
365 
366 	hda_dsp_ctrl_misc_clock_gating(sdev, false);
367 
368 	/* Reset stream-to-link mapping */
369 	list_for_each_entry(hlink, &bus->hlink_list, list)
370 		bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
371 
372 	hda_dsp_ctrl_misc_clock_gating(sdev, true);
373 
374 	/* enable ppcap interrupt */
375 	snd_hdac_ext_bus_ppcap_enable(bus, true);
376 	snd_hdac_ext_bus_ppcap_int_enable(bus, true);
377 #else
378 
379 	hda_dsp_ctrl_misc_clock_gating(sdev, false);
380 
381 	/* reset controller */
382 	ret = hda_dsp_ctrl_link_reset(sdev, true);
383 	if (ret < 0) {
384 		dev_err(sdev->dev,
385 			"error: failed to reset controller during resume\n");
386 		return ret;
387 	}
388 
389 	/* take controller out of reset */
390 	ret = hda_dsp_ctrl_link_reset(sdev, false);
391 	if (ret < 0) {
392 		dev_err(sdev->dev,
393 			"error: failed to ready controller during resume\n");
394 		return ret;
395 	}
396 
397 	/* enable hda bus irq */
398 	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
399 				SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
400 				SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
401 
402 	hda_dsp_ctrl_misc_clock_gating(sdev, true);
403 
404 	/* enable ppcap interrupt */
405 	hda_dsp_ctrl_ppcap_enable(sdev, true);
406 	hda_dsp_ctrl_ppcap_int_enable(sdev, true);
407 #endif
408 
409 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
410 	/* turn off the links that were off before suspend */
411 	list_for_each_entry(hlink, &bus->hlink_list, list) {
412 		if (!hlink->ref_count)
413 			snd_hdac_ext_bus_link_power_down(hlink);
414 	}
415 
416 	/* check dma status and clean up CORB/RIRB buffers */
417 	if (!bus->cmd_dma_state)
418 		snd_hdac_bus_stop_cmd_io(bus);
419 #endif
420 
421 	return 0;
422 }
423 
424 int hda_dsp_resume(struct snd_sof_dev *sdev)
425 {
426 	/* init hda controller. DSP cores will be powered up during fw boot */
427 	return hda_resume(sdev);
428 }
429 
430 int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
431 {
432 	/* init hda controller. DSP cores will be powered up during fw boot */
433 	return hda_resume(sdev);
434 }
435 
436 int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state)
437 {
438 	/* stop hda controller and power dsp off */
439 	return hda_suspend(sdev, state);
440 }
441 
442 int hda_dsp_suspend(struct snd_sof_dev *sdev, int state)
443 {
444 	struct hdac_bus *bus = sof_to_bus(sdev);
445 	int ret;
446 
447 	/* stop hda controller and power dsp off */
448 	ret = hda_suspend(sdev, state);
449 	if (ret < 0) {
450 		dev_err(bus->dev, "error: suspending dsp\n");
451 		return ret;
452 	}
453 
454 	return 0;
455 }
456 
457 void hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
458 {
459 	struct hdac_bus *bus = sof_to_bus(sdev);
460 	struct sof_intel_hda_stream *hda_stream;
461 	struct hdac_ext_stream *stream;
462 	struct hdac_stream *s;
463 
464 	/* set internal flag for BE */
465 	list_for_each_entry(s, &bus->stream_list, list) {
466 		stream = stream_to_hdac_ext_stream(s);
467 		hda_stream = container_of(stream, struct sof_intel_hda_stream,
468 					  hda_stream);
469 		hda_stream->hw_params_upon_resume = 1;
470 	}
471 }
472