xref: /openbmc/linux/sound/soc/sof/intel/hda-dsp.c (revision fb8d6c8d)
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, bool runtime_suspend)
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 	if (runtime_suspend)
299 		hda_codec_jack_wake_enable(sdev);
300 
301 	/* power down all hda link */
302 	snd_hdac_ext_bus_link_power_down_all(bus);
303 #endif
304 
305 	/* power down DSP */
306 	ret = hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
307 	if (ret < 0) {
308 		dev_err(sdev->dev,
309 			"error: failed to power down core during suspend\n");
310 		return ret;
311 	}
312 
313 	/* disable ppcap interrupt */
314 	hda_dsp_ctrl_ppcap_enable(sdev, false);
315 	hda_dsp_ctrl_ppcap_int_enable(sdev, false);
316 
317 	/* disable hda bus irq and streams */
318 	hda_dsp_ctrl_stop_chip(sdev);
319 
320 	/* disable LP retention mode */
321 	snd_sof_pci_update_bits(sdev, PCI_PGCTL,
322 				PCI_PGCTL_LSRMD_MASK, PCI_PGCTL_LSRMD_MASK);
323 
324 	/* reset controller */
325 	ret = hda_dsp_ctrl_link_reset(sdev, true);
326 	if (ret < 0) {
327 		dev_err(sdev->dev,
328 			"error: failed to reset controller during suspend\n");
329 		return ret;
330 	}
331 
332 	return 0;
333 }
334 
335 static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
336 {
337 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
338 	struct hdac_bus *bus = sof_to_bus(sdev);
339 	struct hdac_ext_link *hlink = NULL;
340 #endif
341 	int ret;
342 
343 	/*
344 	 * clear TCSEL to clear playback on some HD Audio
345 	 * codecs. PCI TCSEL is defined in the Intel manuals.
346 	 */
347 	snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
348 
349 	/* reset and start hda controller */
350 	ret = hda_dsp_ctrl_init_chip(sdev, true);
351 	if (ret < 0) {
352 		dev_err(sdev->dev,
353 			"error: failed to start controller after resume\n");
354 		return ret;
355 	}
356 
357 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
358 	/* check jack status */
359 	if (runtime_resume)
360 		hda_codec_jack_check(sdev);
361 
362 	/* turn off the links that were off before suspend */
363 	list_for_each_entry(hlink, &bus->hlink_list, list) {
364 		if (!hlink->ref_count)
365 			snd_hdac_ext_bus_link_power_down(hlink);
366 	}
367 
368 	/* check dma status and clean up CORB/RIRB buffers */
369 	if (!bus->cmd_dma_state)
370 		snd_hdac_bus_stop_cmd_io(bus);
371 #endif
372 
373 	/* enable ppcap interrupt */
374 	hda_dsp_ctrl_ppcap_enable(sdev, true);
375 	hda_dsp_ctrl_ppcap_int_enable(sdev, true);
376 
377 	return 0;
378 }
379 
380 int hda_dsp_resume(struct snd_sof_dev *sdev)
381 {
382 	/* init hda controller. DSP cores will be powered up during fw boot */
383 	return hda_resume(sdev, false);
384 }
385 
386 int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
387 {
388 	/* init hda controller. DSP cores will be powered up during fw boot */
389 	return hda_resume(sdev, true);
390 }
391 
392 int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
393 {
394 	struct hdac_bus *hbus = sof_to_bus(sdev);
395 
396 	if (hbus->codec_powered) {
397 		dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n",
398 			(unsigned int)hbus->codec_powered);
399 		return -EBUSY;
400 	}
401 
402 	return 0;
403 }
404 
405 int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
406 {
407 	/* stop hda controller and power dsp off */
408 	return hda_suspend(sdev, true);
409 }
410 
411 int hda_dsp_suspend(struct snd_sof_dev *sdev)
412 {
413 	struct hdac_bus *bus = sof_to_bus(sdev);
414 	int ret;
415 
416 	/* stop hda controller and power dsp off */
417 	ret = hda_suspend(sdev, false);
418 	if (ret < 0) {
419 		dev_err(bus->dev, "error: suspending dsp\n");
420 		return ret;
421 	}
422 
423 	return 0;
424 }
425 
426 int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
427 {
428 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
429 	struct hdac_bus *bus = sof_to_bus(sdev);
430 	struct snd_soc_pcm_runtime *rtd;
431 	struct hdac_ext_stream *stream;
432 	struct hdac_ext_link *link;
433 	struct hdac_stream *s;
434 	const char *name;
435 	int stream_tag;
436 
437 	/* set internal flag for BE */
438 	list_for_each_entry(s, &bus->stream_list, list) {
439 		stream = stream_to_hdac_ext_stream(s);
440 
441 		/*
442 		 * clear stream. This should already be taken care for running
443 		 * streams when the SUSPEND trigger is called. But paused
444 		 * streams do not get suspended, so this needs to be done
445 		 * explicitly during suspend.
446 		 */
447 		if (stream->link_substream) {
448 			rtd = snd_pcm_substream_chip(stream->link_substream);
449 			name = rtd->codec_dai->component->name;
450 			link = snd_hdac_ext_bus_get_link(bus, name);
451 			if (!link)
452 				return -EINVAL;
453 
454 			stream->link_prepared = 0;
455 
456 			if (hdac_stream(stream)->direction ==
457 				SNDRV_PCM_STREAM_CAPTURE)
458 				continue;
459 
460 			stream_tag = hdac_stream(stream)->stream_tag;
461 			snd_hdac_ext_link_clear_stream_id(link, stream_tag);
462 		}
463 	}
464 #endif
465 	return 0;
466 }
467