Lines Matching +full:dual +full:- +full:direction
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
23 #include "../sof-audio.h"
44 if (stream->frags >= HDA_DSP_MAX_BDL_ENTRIES) { in hda_setup_bdle()
45 dev_err(sdev->dev, "error: stream frags exceeded\n"); in hda_setup_bdle()
46 return -EINVAL; in hda_setup_bdle()
51 bdl->addr_l = cpu_to_le32(lower_32_bits(addr)); in hda_setup_bdle()
52 bdl->addr_h = cpu_to_le32(upper_32_bits(addr)); in hda_setup_bdle()
56 if (bus->align_bdle_4k) { in hda_setup_bdle()
57 u32 remain = 0x1000 - (offset & 0xfff); in hda_setup_bdle()
62 bdl->size = cpu_to_le32(chunk); in hda_setup_bdle()
64 size -= chunk; in hda_setup_bdle()
65 bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01); in hda_setup_bdle()
67 stream->frags++; in hda_setup_bdle()
70 dev_vdbg(sdev->dev, "bdl, frags:%d, chunk size:0x%x;\n", in hda_setup_bdle()
71 stream->frags, chunk); in hda_setup_bdle()
86 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; in hda_dsp_stream_setup_bdl()
91 period_bytes = stream->period_bytes; in hda_dsp_stream_setup_bdl()
92 dev_dbg(sdev->dev, "period_bytes:0x%x\n", period_bytes); in hda_dsp_stream_setup_bdl()
94 period_bytes = stream->bufsize; in hda_dsp_stream_setup_bdl()
96 periods = stream->bufsize / period_bytes; in hda_dsp_stream_setup_bdl()
98 dev_dbg(sdev->dev, "periods:%d\n", periods); in hda_dsp_stream_setup_bdl()
100 remain = stream->bufsize % period_bytes; in hda_dsp_stream_setup_bdl()
105 bdl = (struct sof_intel_dsp_bdl *)stream->bdl.area; in hda_dsp_stream_setup_bdl()
107 stream->frags = 0; in hda_dsp_stream_setup_bdl()
113 ioc = hda->no_ipc_position ? in hda_dsp_stream_setup_bdl()
114 !stream->no_period_wakeup : 0; in hda_dsp_stream_setup_bdl()
117 if (i == (periods - 1) && remain) in hda_dsp_stream_setup_bdl()
135 struct hdac_stream *hstream = &stream->hstream; in hda_dsp_stream_spib_config()
138 if (!sdev->bar[HDA_DSP_SPIB_BAR]) { in hda_dsp_stream_spib_config()
139 dev_err(sdev->dev, "error: address of spib capability is NULL\n"); in hda_dsp_stream_spib_config()
140 return -EINVAL; in hda_dsp_stream_spib_config()
143 mask = (1 << hstream->index); in hda_dsp_stream_spib_config()
148 enable << hstream->index); in hda_dsp_stream_spib_config()
151 sof_io_write(sdev, stream->spib_addr, size); in hda_dsp_stream_spib_config()
158 hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) in hda_dsp_stream_get() argument
165 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_get()
168 list_for_each_entry(s, &bus->stream_list, list) { in hda_dsp_stream_get()
169 if (s->direction == direction && !s->opened) { in hda_dsp_stream_get()
175 if (hda_stream->host_reserved) in hda_dsp_stream_get()
178 s->opened = true; in hda_dsp_stream_get()
183 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_get()
187 dev_err(sdev->dev, "error: no free %s streams\n", in hda_dsp_stream_get()
188 direction == SNDRV_PCM_STREAM_PLAYBACK ? in hda_dsp_stream_get()
197 if (stream && direction == SNDRV_PCM_STREAM_CAPTURE) in hda_dsp_stream_get()
206 int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) in hda_dsp_stream_put() argument
213 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_put()
219 list_for_each_entry(s, &bus->stream_list, list) { in hda_dsp_stream_put()
220 if (!s->opened) in hda_dsp_stream_put()
223 if (s->direction == direction && s->stream_tag == stream_tag) { in hda_dsp_stream_put()
224 s->opened = false; in hda_dsp_stream_put()
226 } else if (s->direction == SNDRV_PCM_STREAM_CAPTURE) { in hda_dsp_stream_put()
231 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_put()
242 dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag); in hda_dsp_stream_put()
243 return -ENODEV; in hda_dsp_stream_put()
252 struct hdac_stream *hstream = &stream->hstream; in hda_dsp_stream_trigger()
264 1 << hstream->index, in hda_dsp_stream_trigger()
265 1 << hstream->index); in hda_dsp_stream_trigger()
282 dev_err(sdev->dev, in hda_dsp_stream_trigger()
288 hstream->running = true; in hda_dsp_stream_trigger()
305 dev_err(sdev->dev, in hda_dsp_stream_trigger()
315 hstream->running = false; in hda_dsp_stream_trigger()
317 1 << hstream->index, 0x0); in hda_dsp_stream_trigger()
320 dev_err(sdev->dev, "error: unknown command: %d\n", cmd); in hda_dsp_stream_trigger()
321 return -EINVAL; in hda_dsp_stream_trigger()
333 struct hdac_stream *hstream = &stream->hstream; in hda_dsp_iccmax_stream_hw_params()
336 u32 mask = 0x1 << hstream->index; in hda_dsp_iccmax_stream_hw_params()
339 dev_err(sdev->dev, "error: no stream available\n"); in hda_dsp_iccmax_stream_hw_params()
340 return -ENODEV; in hda_dsp_iccmax_stream_hw_params()
343 if (hstream->posbuf) in hda_dsp_iccmax_stream_hw_params()
344 *hstream->posbuf = 0; in hda_dsp_iccmax_stream_hw_params()
354 hstream->frags = 0; in hda_dsp_iccmax_stream_hw_params()
358 dev_err(sdev->dev, "error: set up of BDL failed\n"); in hda_dsp_iccmax_stream_hw_params()
365 (u32)hstream->bdl.addr); in hda_dsp_iccmax_stream_hw_params()
368 upper_32_bits(hstream->bdl.addr)); in hda_dsp_iccmax_stream_hw_params()
373 hstream->bufsize); in hda_dsp_iccmax_stream_hw_params()
378 0xffff, (hstream->frags - 1)); in hda_dsp_iccmax_stream_hw_params()
404 struct hdac_stream *hstream = &stream->hstream; in hda_dsp_stream_hw_params()
412 dev_err(sdev->dev, "error: no stream available\n"); in hda_dsp_stream_hw_params()
413 return -ENODEV; in hda_dsp_stream_hw_params()
417 mask = 0x1 << hstream->index; in hda_dsp_stream_hw_params()
422 dev_err(sdev->dev, "error: no dma buffer allocated!\n"); in hda_dsp_stream_hw_params()
423 return -ENODEV; in hda_dsp_stream_hw_params()
438 dev_err(sdev->dev, in hda_dsp_stream_hw_params()
458 } while (--timeout); in hda_dsp_stream_hw_params()
460 dev_err(sdev->dev, "error: stream reset failed\n"); in hda_dsp_stream_hw_params()
461 return -ETIMEDOUT; in hda_dsp_stream_hw_params()
475 } while (--timeout); in hda_dsp_stream_hw_params()
477 dev_err(sdev->dev, "error: timeout waiting for stream reset\n"); in hda_dsp_stream_hw_params()
478 return -ETIMEDOUT; in hda_dsp_stream_hw_params()
481 if (hstream->posbuf) in hda_dsp_stream_hw_params()
482 *hstream->posbuf = 0; in hda_dsp_stream_hw_params()
504 dev_err(sdev->dev, in hda_dsp_stream_hw_params()
515 hstream->frags = 0; in hda_dsp_stream_hw_params()
519 dev_err(sdev->dev, "error: set up of BDL failed\n"); in hda_dsp_stream_hw_params()
526 hstream->stream_tag << in hda_dsp_stream_hw_params()
532 hstream->bufsize); in hda_dsp_stream_hw_params()
553 0xffff, hstream->format_val); in hda_dsp_stream_hw_params()
562 0xffff, (hstream->frags - 1)); in hda_dsp_stream_hw_params()
567 (u32)hstream->bdl.addr); in hda_dsp_stream_hw_params()
570 upper_32_bits(hstream->bdl.addr)); in hda_dsp_stream_hw_params()
576 upper_32_bits(bus->posbuf.addr)); in hda_dsp_stream_hw_params()
578 (u32)bus->posbuf.addr | in hda_dsp_stream_hw_params()
588 if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) { in hda_dsp_stream_hw_params()
589 hstream->fifo_size = in hda_dsp_stream_hw_params()
593 hstream->fifo_size &= 0xffff; in hda_dsp_stream_hw_params()
594 hstream->fifo_size += 1; in hda_dsp_stream_hw_params()
596 hstream->fifo_size = 0; in hda_dsp_stream_hw_params()
605 struct hdac_stream *stream = substream->runtime->private_data; in hda_dsp_stream_hw_free()
610 u32 mask = 0x1 << stream->index; in hda_dsp_stream_hw_free()
612 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_hw_free()
614 if (!link_dev->link_locked) in hda_dsp_stream_hw_free()
617 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_hw_free()
619 stream->substream = NULL; in hda_dsp_stream_hw_free()
631 spin_lock_irq(&bus->reg_lock); in hda_dsp_check_stream_irq()
634 dev_vdbg(bus->dev, "stream irq, INTSTS status: 0x%x\n", status); in hda_dsp_check_stream_irq()
640 spin_unlock_irq(&bus->reg_lock); in hda_dsp_check_stream_irq()
650 div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos); in hda_dsp_set_bytes_transferred()
654 num_bytes = (buffer_size - prev_pos) + pos; in hda_dsp_set_bytes_transferred()
656 num_bytes = pos - prev_pos; in hda_dsp_set_bytes_transferred()
658 hstream->curr_pos += num_bytes; in hda_dsp_set_bytes_transferred()
668 list_for_each_entry(s, &bus->stream_list, list) { in hda_dsp_stream_check()
669 if (status & BIT(s->index) && s->opened) { in hda_dsp_stream_check()
672 dev_vdbg(bus->dev, "stream %d status 0x%x\n", in hda_dsp_stream_check()
673 s->index, sd_status); in hda_dsp_stream_check()
678 if ((!s->substream && !s->cstream) || in hda_dsp_stream_check()
679 !s->running || in hda_dsp_stream_check()
684 if (s->substream && sof_hda->no_ipc_position) { in hda_dsp_stream_check()
685 snd_sof_pcm_period_elapsed(s->substream); in hda_dsp_stream_check()
686 } else if (s->cstream) { in hda_dsp_stream_check()
688 s->cstream->runtime->buffer_size); in hda_dsp_stream_check()
689 snd_compr_fragment_elapsed(s->cstream); in hda_dsp_stream_check()
713 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_threaded_handler()
738 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_threaded_handler()
749 struct pci_dev *pci = to_pci_dev(sdev->dev); in hda_dsp_stream_init()
756 dev_dbg(sdev->dev, "hda global caps = 0x%x\n", gcap); in hda_dsp_stream_init()
763 dev_dbg(sdev->dev, "detected %d playback and %d capture streams\n", in hda_dsp_stream_init()
767 dev_err(sdev->dev, "error: too many playback streams %d\n", in hda_dsp_stream_init()
769 return -EINVAL; in hda_dsp_stream_init()
773 dev_err(sdev->dev, "error: too many capture streams %d\n", in hda_dsp_stream_init()
775 return -EINVAL; in hda_dsp_stream_init()
782 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, in hda_dsp_stream_init()
784 &bus->posbuf); in hda_dsp_stream_init()
786 dev_err(sdev->dev, "error: posbuffer dma alloc failed\n"); in hda_dsp_stream_init()
787 return -ENOMEM; in hda_dsp_stream_init()
792 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, in hda_dsp_stream_init()
793 PAGE_SIZE, &bus->rb); in hda_dsp_stream_init()
795 dev_err(sdev->dev, "error: RB alloc failed\n"); in hda_dsp_stream_init()
796 return -ENOMEM; in hda_dsp_stream_init()
804 hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream), in hda_dsp_stream_init()
807 return -ENOMEM; in hda_dsp_stream_init()
809 hda_stream->sdev = sdev; in hda_dsp_stream_init()
811 stream = &hda_stream->hda_stream; in hda_dsp_stream_init()
813 stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + in hda_dsp_stream_init()
816 stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] + in hda_dsp_stream_init()
821 if (sdev->bar[HDA_DSP_SPIB_BAR]) { in hda_dsp_stream_init()
822 stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] + in hda_dsp_stream_init()
826 stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] + in hda_dsp_stream_init()
831 hstream = &stream->hstream; in hda_dsp_stream_init()
832 hstream->bus = bus; in hda_dsp_stream_init()
833 hstream->sd_int_sta_mask = 1 << i; in hda_dsp_stream_init()
834 hstream->index = i; in hda_dsp_stream_init()
836 hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset; in hda_dsp_stream_init()
837 hstream->stream_tag = i + 1; in hda_dsp_stream_init()
838 hstream->opened = false; in hda_dsp_stream_init()
839 hstream->running = false; in hda_dsp_stream_init()
840 hstream->direction = SNDRV_PCM_STREAM_CAPTURE; in hda_dsp_stream_init()
843 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, in hda_dsp_stream_init()
844 HDA_DSP_BDL_SIZE, &hstream->bdl); in hda_dsp_stream_init()
846 dev_err(sdev->dev, "error: stream bdl dma alloc failed\n"); in hda_dsp_stream_init()
847 return -ENOMEM; in hda_dsp_stream_init()
849 hstream->posbuf = (__le32 *)(bus->posbuf.area + in hda_dsp_stream_init()
850 (hstream->index) * 8); in hda_dsp_stream_init()
852 list_add_tail(&hstream->list, &bus->stream_list); in hda_dsp_stream_init()
859 hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream), in hda_dsp_stream_init()
862 return -ENOMEM; in hda_dsp_stream_init()
864 hda_stream->sdev = sdev; in hda_dsp_stream_init()
866 stream = &hda_stream->hda_stream; in hda_dsp_stream_init()
869 stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + in hda_dsp_stream_init()
872 stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] + in hda_dsp_stream_init()
877 if (sdev->bar[HDA_DSP_SPIB_BAR]) { in hda_dsp_stream_init()
878 stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] + in hda_dsp_stream_init()
882 stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] + in hda_dsp_stream_init()
887 hstream = &stream->hstream; in hda_dsp_stream_init()
888 hstream->bus = bus; in hda_dsp_stream_init()
889 hstream->sd_int_sta_mask = 1 << i; in hda_dsp_stream_init()
890 hstream->index = i; in hda_dsp_stream_init()
892 hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset; in hda_dsp_stream_init()
893 hstream->stream_tag = i - num_capture + 1; in hda_dsp_stream_init()
894 hstream->opened = false; in hda_dsp_stream_init()
895 hstream->running = false; in hda_dsp_stream_init()
896 hstream->direction = SNDRV_PCM_STREAM_PLAYBACK; in hda_dsp_stream_init()
899 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, in hda_dsp_stream_init()
900 HDA_DSP_BDL_SIZE, &hstream->bdl); in hda_dsp_stream_init()
902 dev_err(sdev->dev, "error: stream bdl dma alloc failed\n"); in hda_dsp_stream_init()
903 return -ENOMEM; in hda_dsp_stream_init()
906 hstream->posbuf = (__le32 *)(bus->posbuf.area + in hda_dsp_stream_init()
907 (hstream->index) * 8); in hda_dsp_stream_init()
909 list_add_tail(&hstream->list, &bus->stream_list); in hda_dsp_stream_init()
913 sof_hda->stream_max = num_total; in hda_dsp_stream_init()
926 if (bus->posbuf.area) in hda_dsp_stream_free()
927 snd_dma_free_pages(&bus->posbuf); in hda_dsp_stream_free()
931 if (bus->rb.area) in hda_dsp_stream_free()
932 snd_dma_free_pages(&bus->rb); in hda_dsp_stream_free()
935 list_for_each_entry_safe(s, _s, &bus->stream_list, list) { in hda_dsp_stream_free()
939 if (s->bdl.area) in hda_dsp_stream_free()
940 snd_dma_free_pages(&s->bdl); in hda_dsp_stream_free()
941 list_del(&s->list); in hda_dsp_stream_free()
945 devm_kfree(sdev->dev, hda_stream); in hda_dsp_stream_free()