ASoC: SOF: Intel: hda: couple host and link DMA during FE hw_free
[linux-block.git] / sound / soc / sof / intel / hda-stream.c
CommitLineData
a1d1e266
LG
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 <linux/pm_runtime.h>
19#include <sound/hdaudio_ext.h>
20#include <sound/hda_register.h>
21#include <sound/sof.h>
22#include "../ops.h"
23#include "hda.h"
24
25/*
26 * set up one of BDL entries for a stream
27 */
28static int hda_setup_bdle(struct snd_sof_dev *sdev,
29 struct snd_dma_buffer *dmab,
30 struct hdac_stream *stream,
31 struct sof_intel_dsp_bdl **bdlp,
32 int offset, int size, int ioc)
33{
34 struct hdac_bus *bus = sof_to_bus(sdev);
35 struct sof_intel_dsp_bdl *bdl = *bdlp;
36
37 while (size > 0) {
38 dma_addr_t addr;
39 int chunk;
40
41 if (stream->frags >= HDA_DSP_MAX_BDL_ENTRIES) {
42 dev_err(sdev->dev, "error: stream frags exceeded\n");
43 return -EINVAL;
44 }
45
46 addr = snd_sgbuf_get_addr(dmab, offset);
47 /* program BDL addr */
48 bdl->addr_l = cpu_to_le32(lower_32_bits(addr));
49 bdl->addr_h = cpu_to_le32(upper_32_bits(addr));
50 /* program BDL size */
51 chunk = snd_sgbuf_get_chunk_size(dmab, offset, size);
52 /* one BDLE should not cross 4K boundary */
53 if (bus->align_bdle_4k) {
54 u32 remain = 0x1000 - (offset & 0xfff);
55
56 if (chunk > remain)
57 chunk = remain;
58 }
59 bdl->size = cpu_to_le32(chunk);
60 /* only program IOC when the whole segment is processed */
61 size -= chunk;
62 bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01);
63 bdl++;
64 stream->frags++;
65 offset += chunk;
66
67 dev_vdbg(sdev->dev, "bdl, frags:%d, chunk size:0x%x;\n",
68 stream->frags, chunk);
69 }
70
71 *bdlp = bdl;
72 return offset;
73}
74
75/*
76 * set up Buffer Descriptor List (BDL) for host memory transfer
77 * BDL describes the location of the individual buffers and is little endian.
78 */
79int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
80 struct snd_dma_buffer *dmab,
81 struct hdac_stream *stream)
82{
83 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
84 struct sof_intel_dsp_bdl *bdl;
85 int i, offset, period_bytes, periods;
86 int remain, ioc;
87
88 period_bytes = stream->period_bytes;
89 dev_dbg(sdev->dev, "period_bytes:0x%x\n", period_bytes);
90 if (!period_bytes)
91 period_bytes = stream->bufsize;
92
93 periods = stream->bufsize / period_bytes;
94
95 dev_dbg(sdev->dev, "periods:%d\n", periods);
96
97 remain = stream->bufsize % period_bytes;
98 if (remain)
99 periods++;
100
101 /* program the initial BDL entries */
102 bdl = (struct sof_intel_dsp_bdl *)stream->bdl.area;
103 offset = 0;
104 stream->frags = 0;
105
106 /*
107 * set IOC if don't use position IPC
108 * and period_wakeup needed.
109 */
110 ioc = hda->no_ipc_position ?
111 !stream->no_period_wakeup : 0;
112
113 for (i = 0; i < periods; i++) {
114 if (i == (periods - 1) && remain)
115 /* set the last small entry */
116 offset = hda_setup_bdle(sdev, dmab,
117 stream, &bdl, offset,
118 remain, 0);
119 else
120 offset = hda_setup_bdle(sdev, dmab,
121 stream, &bdl, offset,
122 period_bytes, ioc);
123 }
124
125 return offset;
126}
127
128int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
129 struct hdac_ext_stream *stream,
130 int enable, u32 size)
131{
132 struct hdac_stream *hstream = &stream->hstream;
133 u32 mask;
134
135 if (!sdev->bar[HDA_DSP_SPIB_BAR]) {
136 dev_err(sdev->dev, "error: address of spib capability is NULL\n");
137 return -EINVAL;
138 }
139
140 mask = (1 << hstream->index);
141
142 /* enable/disable SPIB for the stream */
143 snd_sof_dsp_update_bits(sdev, HDA_DSP_SPIB_BAR,
144 SOF_HDA_ADSP_REG_CL_SPBFIFO_SPBFCCTL, mask,
145 enable << hstream->index);
146
147 /* set the SPIB value */
148 sof_io_write(sdev, stream->spib_addr, size);
149
150 return 0;
151}
152
153/* get next unused stream */
154struct hdac_ext_stream *
155hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
156{
157 struct hdac_bus *bus = sof_to_bus(sdev);
6b2239e3 158 struct sof_intel_hda_stream *hda_stream;
a1d1e266
LG
159 struct hdac_ext_stream *stream = NULL;
160 struct hdac_stream *s;
161
162 spin_lock_irq(&bus->reg_lock);
163
164 /* get an unused stream */
165 list_for_each_entry(s, &bus->stream_list, list) {
166 if (s->direction == direction && !s->opened) {
a1d1e266 167 stream = stream_to_hdac_ext_stream(s);
6b2239e3
RS
168 hda_stream = container_of(stream,
169 struct sof_intel_hda_stream,
170 hda_stream);
171 /* check if the host DMA channel is reserved */
172 if (hda_stream->host_reserved)
173 continue;
174
175 s->opened = true;
a1d1e266
LG
176 break;
177 }
178 }
179
180 spin_unlock_irq(&bus->reg_lock);
181
182 /* stream found ? */
183 if (!stream)
184 dev_err(sdev->dev, "error: no free %s streams\n",
185 direction == SNDRV_PCM_STREAM_PLAYBACK ?
186 "playback" : "capture");
187
188 return stream;
189}
190
191/* free a stream */
192int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
193{
194 struct hdac_bus *bus = sof_to_bus(sdev);
195 struct hdac_stream *s;
196
197 spin_lock_irq(&bus->reg_lock);
198
199 /* find used stream */
200 list_for_each_entry(s, &bus->stream_list, list) {
201 if (s->direction == direction &&
202 s->opened && s->stream_tag == stream_tag) {
203 s->opened = false;
204 spin_unlock_irq(&bus->reg_lock);
205 return 0;
206 }
207 }
208
209 spin_unlock_irq(&bus->reg_lock);
210
211 dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag);
212 return -ENODEV;
213}
214
215int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
216 struct hdac_ext_stream *stream, int cmd)
217{
218 struct hdac_stream *hstream = &stream->hstream;
219 int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
220
221 /* cmd must be for audio stream */
222 switch (cmd) {
223 case SNDRV_PCM_TRIGGER_RESUME:
224 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
225 case SNDRV_PCM_TRIGGER_START:
226 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
227 1 << hstream->index,
228 1 << hstream->index);
229
230 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
231 sd_offset,
232 SOF_HDA_SD_CTL_DMA_START |
233 SOF_HDA_CL_DMA_SD_INT_MASK,
234 SOF_HDA_SD_CTL_DMA_START |
235 SOF_HDA_CL_DMA_SD_INT_MASK);
236
237 hstream->running = true;
238 break;
239 case SNDRV_PCM_TRIGGER_SUSPEND:
240 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
241 case SNDRV_PCM_TRIGGER_STOP:
242 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
243 sd_offset,
244 SOF_HDA_SD_CTL_DMA_START |
245 SOF_HDA_CL_DMA_SD_INT_MASK, 0x0);
246
247 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, sd_offset +
248 SOF_HDA_ADSP_REG_CL_SD_STS,
249 SOF_HDA_CL_DMA_SD_INT_MASK);
250
251 hstream->running = false;
252 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
253 1 << hstream->index, 0x0);
254 break;
255 default:
256 dev_err(sdev->dev, "error: unknown command: %d\n", cmd);
257 return -EINVAL;
258 }
259
260 return 0;
261}
262
263/*
264 * prepare for common hdac registers settings, for both code loader
265 * and normal stream.
266 */
267int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
268 struct hdac_ext_stream *stream,
269 struct snd_dma_buffer *dmab,
270 struct snd_pcm_hw_params *params)
271{
272 struct hdac_bus *bus = sof_to_bus(sdev);
273 struct hdac_stream *hstream = &stream->hstream;
274 int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
275 int ret, timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
276 u32 val, mask;
277
278 if (!stream) {
279 dev_err(sdev->dev, "error: no stream available\n");
280 return -ENODEV;
281 }
282
283 /* decouple host and link DMA */
284 mask = 0x1 << hstream->index;
285 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
286 mask, mask);
287
288 if (!dmab) {
289 dev_err(sdev->dev, "error: no dma buffer allocated!\n");
290 return -ENODEV;
291 }
292
293 /* clear stream status */
294 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
295 SOF_HDA_CL_DMA_SD_INT_MASK |
296 SOF_HDA_SD_CTL_DMA_START, 0);
297 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
298 sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
299 SOF_HDA_CL_DMA_SD_INT_MASK,
300 SOF_HDA_CL_DMA_SD_INT_MASK);
301
302 /* stream reset */
303 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
304 0x1);
305 udelay(3);
306 do {
307 val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
308 sd_offset);
309 if (val & 0x1)
310 break;
311 } while (--timeout);
312 if (timeout == 0) {
313 dev_err(sdev->dev, "error: stream reset failed\n");
314 return -ETIMEDOUT;
315 }
316
317 timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
318 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
319 0x0);
320
321 /* wait for hardware to report that stream is out of reset */
322 udelay(3);
323 do {
324 val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
325 sd_offset);
326 if ((val & 0x1) == 0)
327 break;
328 } while (--timeout);
329 if (timeout == 0) {
330 dev_err(sdev->dev, "error: timeout waiting for stream reset\n");
331 return -ETIMEDOUT;
332 }
333
334 if (hstream->posbuf)
335 *hstream->posbuf = 0;
336
337 /* reset BDL address */
338 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
339 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
340 0x0);
341 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
342 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
343 0x0);
344
345 /* clear stream status */
346 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
347 SOF_HDA_CL_DMA_SD_INT_MASK |
348 SOF_HDA_SD_CTL_DMA_START, 0);
349 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
350 sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
351 SOF_HDA_CL_DMA_SD_INT_MASK,
352 SOF_HDA_CL_DMA_SD_INT_MASK);
353
354 hstream->frags = 0;
355
356 ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
357 if (ret < 0) {
358 dev_err(sdev->dev, "error: set up of BDL failed\n");
359 return ret;
360 }
361
362 /* program stream tag to set up stream descriptor for DMA */
363 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
364 SOF_HDA_CL_SD_CTL_STREAM_TAG_MASK,
365 hstream->stream_tag <<
366 SOF_HDA_CL_SD_CTL_STREAM_TAG_SHIFT);
367
368 /* program cyclic buffer length */
369 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
370 sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
371 hstream->bufsize);
372
373 /*
374 * Recommended hardware programming sequence for HDAudio DMA format
375 *
376 * 1. Put DMA into coupled mode by clearing PPCTL.PROCEN bit
377 * for corresponding stream index before the time of writing
378 * format to SDxFMT register.
379 * 2. Write SDxFMT
380 * 3. Set PPCTL.PROCEN bit for corresponding stream index to
381 * enable decoupled mode
382 */
383
384 /* couple host and link DMA, disable DSP features */
385 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
386 mask, 0);
387
388 /* program stream format */
389 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
390 sd_offset +
391 SOF_HDA_ADSP_REG_CL_SD_FORMAT,
392 0xffff, hstream->format_val);
393
394 /* decouple host and link DMA, enable DSP features */
395 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
396 mask, mask);
397
398 /* program last valid index */
399 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
400 sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
401 0xffff, (hstream->frags - 1));
402
403 /* program BDL address */
404 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
405 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
406 (u32)hstream->bdl.addr);
407 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
408 sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
409 upper_32_bits(hstream->bdl.addr));
410
411 /* enable position buffer */
412 if (!(snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE)
413 & SOF_HDA_ADSP_DPLBASE_ENABLE)) {
414 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
415 upper_32_bits(bus->posbuf.addr));
416 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
417 (u32)bus->posbuf.addr |
418 SOF_HDA_ADSP_DPLBASE_ENABLE);
419 }
420
421 /* set interrupt enable bits */
422 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
423 SOF_HDA_CL_DMA_SD_INT_MASK,
424 SOF_HDA_CL_DMA_SD_INT_MASK);
425
426 /* read FIFO size */
427 if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) {
428 hstream->fifo_size =
429 snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
430 sd_offset +
431 SOF_HDA_ADSP_REG_CL_SD_FIFOSIZE);
432 hstream->fifo_size &= 0xffff;
433 hstream->fifo_size += 1;
434 } else {
435 hstream->fifo_size = 0;
436 }
437
438 return ret;
439}
440
93146bc2
RS
441int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
442 struct snd_pcm_substream *substream)
443{
444 struct hdac_stream *stream = substream->runtime->private_data;
445 struct hdac_ext_stream *link_dev = container_of(stream,
446 struct hdac_ext_stream,
447 hstream);
448 struct hdac_bus *bus = sof_to_bus(sdev);
449 u32 mask = 0x1 << stream->index;
450
451 spin_lock(&bus->reg_lock);
452 /* couple host and link DMA if link DMA channel is idle */
453 if (!link_dev->link_locked)
454 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR,
455 SOF_HDA_REG_PP_PPCTL, mask, 0);
456 spin_unlock(&bus->reg_lock);
457
458 return 0;
459}
460
a1d1e266
LG
461irqreturn_t hda_dsp_stream_interrupt(int irq, void *context)
462{
463 struct hdac_bus *bus = context;
20d0aff7
KJ
464 struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
465 u32 stream_mask;
a1d1e266
LG
466 u32 status;
467
468 if (!pm_runtime_active(bus->dev))
469 return IRQ_NONE;
470
471 spin_lock(&bus->reg_lock);
472
473 status = snd_hdac_chip_readl(bus, INTSTS);
20d0aff7
KJ
474 stream_mask = GENMASK(sof_hda->stream_max - 1, 0) | AZX_INT_CTRL_EN;
475
476 /* Not stream interrupt or register inaccessible, ignore it.*/
477 if (!(status & stream_mask) || status == 0xffffffff) {
a1d1e266
LG
478 spin_unlock(&bus->reg_lock);
479 return IRQ_NONE;
480 }
481
482#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
483 /* clear rirb int */
484 status = snd_hdac_chip_readb(bus, RIRBSTS);
485 if (status & RIRB_INT_MASK) {
486 if (status & RIRB_INT_RESPONSE)
487 snd_hdac_bus_update_rirb(bus);
488 snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
489 }
490#endif
491
492 spin_unlock(&bus->reg_lock);
493
494 return snd_hdac_chip_readl(bus, INTSTS) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
495}
496
497irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
498{
499 struct hdac_bus *bus = context;
500 struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
a1d1e266 501 u32 status = snd_hdac_chip_readl(bus, INTSTS);
8242d539 502 struct hdac_stream *s;
a1d1e266
LG
503 u32 sd_status;
504
505 /* check streams */
506 list_for_each_entry(s, &bus->stream_list, list) {
507 if (status & (1 << s->index) && s->opened) {
508 sd_status = snd_hdac_stream_readb(s, SD_STS);
509
510 dev_vdbg(bus->dev, "stream %d status 0x%x\n",
511 s->index, sd_status);
512
513 snd_hdac_stream_writeb(s, SD_STS, SD_INT_MASK);
514
515 if (!s->substream ||
516 !s->running ||
517 (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0)
518 continue;
519
520 /* Inform ALSA only in case not do that with IPC */
521 if (sof_hda->no_ipc_position)
8242d539 522 snd_sof_pcm_period_elapsed(s->substream);
a1d1e266
LG
523
524 }
525 }
526
527 return IRQ_HANDLED;
528}
529
530int hda_dsp_stream_init(struct snd_sof_dev *sdev)
531{
532 struct hdac_bus *bus = sof_to_bus(sdev);
533 struct hdac_ext_stream *stream;
534 struct hdac_stream *hstream;
535 struct pci_dev *pci = to_pci_dev(sdev->dev);
e8e55dbe 536 struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
a1d1e266
LG
537 int sd_offset;
538 int i, num_playback, num_capture, num_total, ret;
539 u32 gcap;
540
541 gcap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCAP);
542 dev_dbg(sdev->dev, "hda global caps = 0x%x\n", gcap);
543
544 /* get stream count from GCAP */
545 num_capture = (gcap >> 8) & 0x0f;
546 num_playback = (gcap >> 12) & 0x0f;
547 num_total = num_playback + num_capture;
548
549 dev_dbg(sdev->dev, "detected %d playback and %d capture streams\n",
550 num_playback, num_capture);
551
552 if (num_playback >= SOF_HDA_PLAYBACK_STREAMS) {
553 dev_err(sdev->dev, "error: too many playback streams %d\n",
554 num_playback);
555 return -EINVAL;
556 }
557
558 if (num_capture >= SOF_HDA_CAPTURE_STREAMS) {
559 dev_err(sdev->dev, "error: too many capture streams %d\n",
560 num_playback);
561 return -EINVAL;
562 }
563
564 /*
565 * mem alloc for the position buffer
566 * TODO: check position buffer update
567 */
568 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
569 SOF_HDA_DPIB_ENTRY_SIZE * num_total,
570 &bus->posbuf);
571 if (ret < 0) {
572 dev_err(sdev->dev, "error: posbuffer dma alloc failed\n");
573 return -ENOMEM;
574 }
575
576#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
577 /* mem alloc for the CORB/RIRB ringbuffers */
578 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
579 PAGE_SIZE, &bus->rb);
580 if (ret < 0) {
581 dev_err(sdev->dev, "error: RB alloc failed\n");
582 return -ENOMEM;
583 }
584#endif
585
586 /* create capture streams */
587 for (i = 0; i < num_capture; i++) {
588 struct sof_intel_hda_stream *hda_stream;
589
590 hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
591 GFP_KERNEL);
592 if (!hda_stream)
593 return -ENOMEM;
594
7623ae79
RS
595 hda_stream->sdev = sdev;
596
a1d1e266
LG
597 stream = &hda_stream->hda_stream;
598
599 stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
600 SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
601
602 stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
603 SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
604 SOF_HDA_PPLC_INTERVAL * i;
605
606 /* do we support SPIB */
607 if (sdev->bar[HDA_DSP_SPIB_BAR]) {
608 stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
609 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
610 SOF_HDA_SPIB_SPIB;
611
612 stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
613 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
614 SOF_HDA_SPIB_MAXFIFO;
615 }
616
617 hstream = &stream->hstream;
618 hstream->bus = bus;
619 hstream->sd_int_sta_mask = 1 << i;
620 hstream->index = i;
621 sd_offset = SOF_STREAM_SD_OFFSET(hstream);
622 hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
623 hstream->stream_tag = i + 1;
624 hstream->opened = false;
625 hstream->running = false;
626 hstream->direction = SNDRV_PCM_STREAM_CAPTURE;
627
628 /* memory alloc for stream BDL */
629 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
630 HDA_DSP_BDL_SIZE, &hstream->bdl);
631 if (ret < 0) {
632 dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
633 return -ENOMEM;
634 }
635 hstream->posbuf = (__le32 *)(bus->posbuf.area +
636 (hstream->index) * 8);
637
638 list_add_tail(&hstream->list, &bus->stream_list);
639 }
640
641 /* create playback streams */
642 for (i = num_capture; i < num_total; i++) {
643 struct sof_intel_hda_stream *hda_stream;
644
645 hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
646 GFP_KERNEL);
647 if (!hda_stream)
648 return -ENOMEM;
649
7623ae79
RS
650 hda_stream->sdev = sdev;
651
a1d1e266
LG
652 stream = &hda_stream->hda_stream;
653
654 /* we always have DSP support */
655 stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
656 SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
657
658 stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
659 SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
660 SOF_HDA_PPLC_INTERVAL * i;
661
662 /* do we support SPIB */
663 if (sdev->bar[HDA_DSP_SPIB_BAR]) {
664 stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
665 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
666 SOF_HDA_SPIB_SPIB;
667
668 stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
669 SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
670 SOF_HDA_SPIB_MAXFIFO;
671 }
672
673 hstream = &stream->hstream;
674 hstream->bus = bus;
675 hstream->sd_int_sta_mask = 1 << i;
676 hstream->index = i;
677 sd_offset = SOF_STREAM_SD_OFFSET(hstream);
678 hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
679 hstream->stream_tag = i - num_capture + 1;
680 hstream->opened = false;
681 hstream->running = false;
682 hstream->direction = SNDRV_PCM_STREAM_PLAYBACK;
683
684 /* mem alloc for stream BDL */
685 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
686 HDA_DSP_BDL_SIZE, &hstream->bdl);
687 if (ret < 0) {
688 dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
689 return -ENOMEM;
690 }
691
692 hstream->posbuf = (__le32 *)(bus->posbuf.area +
693 (hstream->index) * 8);
694
695 list_add_tail(&hstream->list, &bus->stream_list);
696 }
697
e8e55dbe
KJ
698 /* store total stream count (playback + capture) from GCAP */
699 sof_hda->stream_max = num_total;
700
a1d1e266
LG
701 return 0;
702}
703
704void hda_dsp_stream_free(struct snd_sof_dev *sdev)
705{
706 struct hdac_bus *bus = sof_to_bus(sdev);
707 struct hdac_stream *s, *_s;
708 struct hdac_ext_stream *stream;
709 struct sof_intel_hda_stream *hda_stream;
710
711 /* free position buffer */
712 if (bus->posbuf.area)
713 snd_dma_free_pages(&bus->posbuf);
714
715#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
716 /* free position buffer */
717 if (bus->rb.area)
718 snd_dma_free_pages(&bus->rb);
719#endif
720
721 list_for_each_entry_safe(s, _s, &bus->stream_list, list) {
722 /* TODO: decouple */
723
724 /* free bdl buffer */
725 if (s->bdl.area)
726 snd_dma_free_pages(&s->bdl);
727 list_del(&s->list);
728 stream = stream_to_hdac_ext_stream(s);
729 hda_stream = container_of(stream, struct sof_intel_hda_stream,
730 hda_stream);
731 devm_kfree(sdev->dev, hda_stream);
732 }
733}