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"
30 if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) in hda_hstream_direction_str()
40 if (hstream->substream) in hda_hstream_dbg_get_stream_info_str()
41 rtd = asoc_substream_to_rtd(hstream->substream); in hda_hstream_dbg_get_stream_info_str()
42 else if (hstream->cstream) in hda_hstream_dbg_get_stream_info_str()
43 rtd = hstream->cstream->private_data; in hda_hstream_dbg_get_stream_info_str()
45 /* Non audio DMA user, like dma-trace */ in hda_hstream_dbg_get_stream_info_str()
46 return kasprintf(GFP_KERNEL, "-- (%s, stream_tag: %u)", in hda_hstream_dbg_get_stream_info_str()
48 hstream->stream_tag); in hda_hstream_dbg_get_stream_info_str()
51 rtd->dai_link->name, hda_hstream_direction_str(hstream), in hda_hstream_dbg_get_stream_info_str()
52 hstream->stream_tag); in hda_hstream_dbg_get_stream_info_str()
71 if (hstream->frags >= HDA_DSP_MAX_BDL_ENTRIES) { in hda_setup_bdle()
72 dev_err(sdev->dev, "error: stream frags exceeded\n"); in hda_setup_bdle()
73 return -EINVAL; in hda_setup_bdle()
78 bdl->addr_l = cpu_to_le32(lower_32_bits(addr)); in hda_setup_bdle()
79 bdl->addr_h = cpu_to_le32(upper_32_bits(addr)); in hda_setup_bdle()
83 if (bus->align_bdle_4k) { in hda_setup_bdle()
84 u32 remain = 0x1000 - (offset & 0xfff); in hda_setup_bdle()
89 bdl->size = cpu_to_le32(chunk); in hda_setup_bdle()
91 size -= chunk; in hda_setup_bdle()
92 bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01); in hda_setup_bdle()
94 hstream->frags++; in hda_setup_bdle()
110 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; in hda_dsp_stream_setup_bdl()
115 period_bytes = hstream->period_bytes; in hda_dsp_stream_setup_bdl()
116 dev_dbg(sdev->dev, "period_bytes:0x%x\n", period_bytes); in hda_dsp_stream_setup_bdl()
118 period_bytes = hstream->bufsize; in hda_dsp_stream_setup_bdl()
120 periods = hstream->bufsize / period_bytes; in hda_dsp_stream_setup_bdl()
122 dev_dbg(sdev->dev, "periods:%d\n", periods); in hda_dsp_stream_setup_bdl()
124 remain = hstream->bufsize % period_bytes; in hda_dsp_stream_setup_bdl()
129 bdl = (struct sof_intel_dsp_bdl *)hstream->bdl.area; in hda_dsp_stream_setup_bdl()
131 hstream->frags = 0; in hda_dsp_stream_setup_bdl()
137 ioc = hda->no_ipc_position ? in hda_dsp_stream_setup_bdl()
138 !hstream->no_period_wakeup : 0; in hda_dsp_stream_setup_bdl()
141 if (i == (periods - 1) && remain) in hda_dsp_stream_setup_bdl()
159 struct hdac_stream *hstream = &hext_stream->hstream; in hda_dsp_stream_spib_config()
162 if (!sdev->bar[HDA_DSP_SPIB_BAR]) { in hda_dsp_stream_spib_config()
163 dev_err(sdev->dev, "error: address of spib capability is NULL\n"); in hda_dsp_stream_spib_config()
164 return -EINVAL; in hda_dsp_stream_spib_config()
167 mask = (1 << hstream->index); in hda_dsp_stream_spib_config()
172 enable << hstream->index); in hda_dsp_stream_spib_config()
175 sof_io_write(sdev, hstream->spib_addr, size); in hda_dsp_stream_spib_config()
182 hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags) in hda_dsp_stream_get() argument
184 const struct sof_intel_dsp_desc *chip_info = get_chip_info(sdev->pdata); in hda_dsp_stream_get()
185 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; in hda_dsp_stream_get()
191 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_get()
194 list_for_each_entry(s, &bus->stream_list, list) { in hda_dsp_stream_get()
195 if (s->direction == direction && !s->opened) { in hda_dsp_stream_get()
201 if (hda_stream->host_reserved) in hda_dsp_stream_get()
204 s->opened = true; in hda_dsp_stream_get()
209 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_get()
213 dev_err(sdev->dev, "error: no free %s streams\n", in hda_dsp_stream_get()
214 direction == SNDRV_PCM_STREAM_PLAYBACK ? in hda_dsp_stream_get()
219 hda_stream->flags = flags; in hda_dsp_stream_get()
226 if (chip_info->hw_ip_version < SOF_INTEL_ACE_1_0 && in hda_dsp_stream_get()
231 hda->l1_disabled = true; in hda_dsp_stream_get()
238 int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) in hda_dsp_stream_put() argument
240 const struct sof_intel_dsp_desc *chip_info = get_chip_info(sdev->pdata); in hda_dsp_stream_put()
241 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; in hda_dsp_stream_put()
249 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_put()
255 list_for_each_entry(s, &bus->stream_list, list) { in hda_dsp_stream_put()
259 if (!s->opened) in hda_dsp_stream_put()
262 if (s->direction == direction && s->stream_tag == stream_tag) { in hda_dsp_stream_put()
263 s->opened = false; in hda_dsp_stream_put()
265 } else if (!(hda_stream->flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) { in hda_dsp_stream_put()
270 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_put()
273 if (chip_info->hw_ip_version < SOF_INTEL_ACE_1_0 && dmi_l1_enable) { in hda_dsp_stream_put()
276 hda->l1_disabled = false; in hda_dsp_stream_put()
280 dev_err(sdev->dev, "%s: stream_tag %d not opened!\n", in hda_dsp_stream_put()
282 return -ENODEV; in hda_dsp_stream_put()
301 } while (--timeout); in hda_dsp_stream_reset()
303 dev_err(sdev->dev, "timeout waiting for stream reset\n"); in hda_dsp_stream_reset()
304 return -ETIMEDOUT; in hda_dsp_stream_reset()
318 } while (--timeout); in hda_dsp_stream_reset()
320 dev_err(sdev->dev, "timeout waiting for stream to exit reset\n"); in hda_dsp_stream_reset()
321 return -ETIMEDOUT; in hda_dsp_stream_reset()
330 struct hdac_stream *hstream = &hext_stream->hstream; in hda_dsp_stream_trigger()
339 if (!sdev->dspless_mode_selected) in hda_dsp_stream_trigger()
343 if (hstream->running) in hda_dsp_stream_trigger()
347 1 << hstream->index, in hda_dsp_stream_trigger()
348 1 << hstream->index); in hda_dsp_stream_trigger()
365 hstream->running = true; in hda_dsp_stream_trigger()
369 if (!sdev->dspless_mode_selected) in hda_dsp_stream_trigger()
390 hstream->running = false; in hda_dsp_stream_trigger()
393 1 << hstream->index, 0x0); in hda_dsp_stream_trigger()
397 dev_err(sdev->dev, "error: unknown command: %d\n", cmd); in hda_dsp_stream_trigger()
398 return -EINVAL; in hda_dsp_stream_trigger()
404 dev_err(sdev->dev, in hda_dsp_stream_trigger()
418 struct hdac_stream *hstream = &hext_stream->hstream; in hda_dsp_iccmax_stream_hw_params()
421 u32 mask = 0x1 << hstream->index; in hda_dsp_iccmax_stream_hw_params()
424 dev_err(sdev->dev, "error: no stream available\n"); in hda_dsp_iccmax_stream_hw_params()
425 return -ENODEV; in hda_dsp_iccmax_stream_hw_params()
429 dev_err(sdev->dev, "error: no dma buffer allocated!\n"); in hda_dsp_iccmax_stream_hw_params()
430 return -ENODEV; in hda_dsp_iccmax_stream_hw_params()
433 if (hstream->posbuf) in hda_dsp_iccmax_stream_hw_params()
434 *hstream->posbuf = 0; in hda_dsp_iccmax_stream_hw_params()
444 hstream->frags = 0; in hda_dsp_iccmax_stream_hw_params()
448 dev_err(sdev->dev, "error: set up of BDL failed\n"); in hda_dsp_iccmax_stream_hw_params()
455 (u32)hstream->bdl.addr); in hda_dsp_iccmax_stream_hw_params()
458 upper_32_bits(hstream->bdl.addr)); in hda_dsp_iccmax_stream_hw_params()
463 hstream->bufsize); in hda_dsp_iccmax_stream_hw_params()
468 0xffff, (hstream->frags - 1)); in hda_dsp_iccmax_stream_hw_params()
494 const struct sof_intel_dsp_desc *chip = get_chip_info(sdev->pdata); in hda_dsp_stream_hw_params()
503 dev_err(sdev->dev, "error: no stream available\n"); in hda_dsp_stream_hw_params()
504 return -ENODEV; in hda_dsp_stream_hw_params()
508 dev_err(sdev->dev, "error: no dma buffer allocated!\n"); in hda_dsp_stream_hw_params()
509 return -ENODEV; in hda_dsp_stream_hw_params()
512 hstream = &hext_stream->hstream; in hda_dsp_stream_hw_params()
514 mask = BIT(hstream->index); in hda_dsp_stream_hw_params()
517 if (!sdev->dspless_mode_selected) in hda_dsp_stream_hw_params()
535 dev_err(sdev->dev, in hda_dsp_stream_hw_params()
552 if (hstream->posbuf) in hda_dsp_stream_hw_params()
553 *hstream->posbuf = 0; in hda_dsp_stream_hw_params()
577 dev_err(sdev->dev, in hda_dsp_stream_hw_params()
589 hstream->frags = 0; in hda_dsp_stream_hw_params()
593 dev_err(sdev->dev, "error: set up of BDL failed\n"); in hda_dsp_stream_hw_params()
600 hstream->stream_tag << in hda_dsp_stream_hw_params()
606 hstream->bufsize); in hda_dsp_stream_hw_params()
610 * on earlier platforms - this is not needed on newer platforms in hda_dsp_stream_hw_params()
620 if (!sdev->dspless_mode_selected && (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) in hda_dsp_stream_hw_params()
629 0xffff, hstream->format_val); in hda_dsp_stream_hw_params()
631 if (!sdev->dspless_mode_selected && (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) in hda_dsp_stream_hw_params()
639 0xffff, (hstream->frags - 1)); in hda_dsp_stream_hw_params()
644 (u32)hstream->bdl.addr); in hda_dsp_stream_hw_params()
647 upper_32_bits(hstream->bdl.addr)); in hda_dsp_stream_hw_params()
650 if (bus->use_posbuf && bus->posbuf.addr && in hda_dsp_stream_hw_params()
654 upper_32_bits(bus->posbuf.addr)); in hda_dsp_stream_hw_params()
656 (u32)bus->posbuf.addr | in hda_dsp_stream_hw_params()
666 if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) { in hda_dsp_stream_hw_params()
667 hstream->fifo_size = in hda_dsp_stream_hw_params()
671 hstream->fifo_size &= 0xffff; in hda_dsp_stream_hw_params()
672 hstream->fifo_size += 1; in hda_dsp_stream_hw_params()
674 hstream->fifo_size = 0; in hda_dsp_stream_hw_params()
683 struct hdac_stream *hstream = substream->runtime->private_data; in hda_dsp_stream_hw_free()
693 if (!sdev->dspless_mode_selected) { in hda_dsp_stream_hw_free()
695 u32 mask = BIT(hstream->index); in hda_dsp_stream_hw_free()
697 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_hw_free()
699 if (!hext_stream->link_locked) in hda_dsp_stream_hw_free()
702 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_hw_free()
707 hstream->substream = NULL; in hda_dsp_stream_hw_free()
719 spin_lock_irq(&bus->reg_lock); in hda_dsp_check_stream_irq()
729 spin_unlock_irq(&bus->reg_lock); in hda_dsp_check_stream_irq()
735 hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction) in hda_dsp_compr_bytes_transferred() argument
737 u64 buffer_size = hstream->bufsize; in hda_dsp_compr_bytes_transferred()
740 div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos); in hda_dsp_compr_bytes_transferred()
741 pos = hda_dsp_stream_get_position(hstream, direction, false); in hda_dsp_compr_bytes_transferred()
744 num_bytes = (buffer_size - prev_pos) + pos; in hda_dsp_compr_bytes_transferred()
746 num_bytes = pos - prev_pos; in hda_dsp_compr_bytes_transferred()
748 hstream->curr_pos += num_bytes; in hda_dsp_compr_bytes_transferred()
758 list_for_each_entry(s, &bus->stream_list, list) { in hda_dsp_stream_check()
759 if (status & BIT(s->index) && s->opened) { in hda_dsp_stream_check()
760 sd_status = readb(s->sd_addr + SOF_HDA_ADSP_REG_SD_STS); in hda_dsp_stream_check()
762 trace_sof_intel_hda_dsp_stream_status(bus->dev, s, sd_status); in hda_dsp_stream_check()
764 writeb(sd_status, s->sd_addr + SOF_HDA_ADSP_REG_SD_STS); in hda_dsp_stream_check()
767 if ((!s->substream && !s->cstream) || in hda_dsp_stream_check()
768 !s->running || in hda_dsp_stream_check()
773 if (s->substream && sof_hda->no_ipc_position) { in hda_dsp_stream_check()
774 snd_sof_pcm_period_elapsed(s->substream); in hda_dsp_stream_check()
775 } else if (s->cstream) { in hda_dsp_stream_check()
776 hda_dsp_compr_bytes_transferred(s, s->cstream->direction); in hda_dsp_stream_check()
777 snd_compr_fragment_elapsed(s->cstream); in hda_dsp_stream_check()
798 spin_lock_irq(&bus->reg_lock); in hda_dsp_stream_threaded_handler()
809 spin_unlock_irq(&bus->reg_lock); in hda_dsp_stream_threaded_handler()
820 struct pci_dev *pci = to_pci_dev(sdev->dev); in hda_dsp_stream_init()
827 dev_dbg(sdev->dev, "hda global caps = 0x%x\n", gcap); in hda_dsp_stream_init()
834 dev_dbg(sdev->dev, "detected %d playback and %d capture streams\n", in hda_dsp_stream_init()
838 dev_err(sdev->dev, "error: too many playback streams %d\n", in hda_dsp_stream_init()
840 return -EINVAL; in hda_dsp_stream_init()
844 dev_err(sdev->dev, "error: too many capture streams %d\n", in hda_dsp_stream_init()
846 return -EINVAL; in hda_dsp_stream_init()
853 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, in hda_dsp_stream_init()
855 &bus->posbuf); in hda_dsp_stream_init()
857 dev_err(sdev->dev, "error: posbuffer dma alloc failed\n"); in hda_dsp_stream_init()
858 return -ENOMEM; in hda_dsp_stream_init()
862 * mem alloc for the CORB/RIRB ringbuffers - this will be used only for in hda_dsp_stream_init()
865 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, in hda_dsp_stream_init()
866 PAGE_SIZE, &bus->rb); in hda_dsp_stream_init()
868 dev_err(sdev->dev, "error: RB alloc failed\n"); in hda_dsp_stream_init()
869 return -ENOMEM; in hda_dsp_stream_init()
876 hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream), in hda_dsp_stream_init()
879 return -ENOMEM; in hda_dsp_stream_init()
881 hda_stream->sdev = sdev; in hda_dsp_stream_init()
883 hext_stream = &hda_stream->hext_stream; in hda_dsp_stream_init()
885 if (sdev->bar[HDA_DSP_PP_BAR]) { in hda_dsp_stream_init()
886 hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + in hda_dsp_stream_init()
889 hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] + in hda_dsp_stream_init()
894 hstream = &hext_stream->hstream; in hda_dsp_stream_init()
897 if (sdev->bar[HDA_DSP_SPIB_BAR]) { in hda_dsp_stream_init()
898 hstream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] + in hda_dsp_stream_init()
902 hstream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] + in hda_dsp_stream_init()
907 hstream->bus = bus; in hda_dsp_stream_init()
908 hstream->sd_int_sta_mask = 1 << i; in hda_dsp_stream_init()
909 hstream->index = i; in hda_dsp_stream_init()
911 hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset; in hda_dsp_stream_init()
912 hstream->opened = false; in hda_dsp_stream_init()
913 hstream->running = false; in hda_dsp_stream_init()
916 hstream->stream_tag = i + 1; in hda_dsp_stream_init()
917 hstream->direction = SNDRV_PCM_STREAM_CAPTURE; in hda_dsp_stream_init()
919 hstream->stream_tag = i - num_capture + 1; in hda_dsp_stream_init()
920 hstream->direction = SNDRV_PCM_STREAM_PLAYBACK; in hda_dsp_stream_init()
924 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, in hda_dsp_stream_init()
925 HDA_DSP_BDL_SIZE, &hstream->bdl); in hda_dsp_stream_init()
927 dev_err(sdev->dev, "error: stream bdl dma alloc failed\n"); in hda_dsp_stream_init()
928 return -ENOMEM; in hda_dsp_stream_init()
931 hstream->posbuf = (__le32 *)(bus->posbuf.area + in hda_dsp_stream_init()
932 (hstream->index) * 8); in hda_dsp_stream_init()
934 list_add_tail(&hstream->list, &bus->stream_list); in hda_dsp_stream_init()
938 sof_hda->stream_max = num_total; in hda_dsp_stream_init()
951 if (bus->posbuf.area) in hda_dsp_stream_free()
952 snd_dma_free_pages(&bus->posbuf); in hda_dsp_stream_free()
954 /* free CORB/RIRB buffer - only used for HDaudio codecs */ in hda_dsp_stream_free()
955 if (bus->rb.area) in hda_dsp_stream_free()
956 snd_dma_free_pages(&bus->rb); in hda_dsp_stream_free()
958 list_for_each_entry_safe(s, _s, &bus->stream_list, list) { in hda_dsp_stream_free()
962 if (s->bdl.area) in hda_dsp_stream_free()
963 snd_dma_free_pages(&s->bdl); in hda_dsp_stream_free()
964 list_del(&s->list); in hda_dsp_stream_free()
968 devm_kfree(sdev->dev, hda_stream); in hda_dsp_stream_free()
973 int direction, bool can_sleep) in hda_dsp_stream_get_position() argument
977 struct snd_sof_dev *sdev = hda_stream->sdev; in hda_dsp_stream_get_position()
988 * what traffic class is used, and on all SOF-enabled platforms in hda_dsp_stream_get_position()
989 * only VC0 is supported so the work-around was likely not necessary in hda_dsp_stream_get_position()
1000 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { in hda_dsp_stream_get_position()
1004 hstream->index)); in hda_dsp_stream_get_position()
1024 hstream->index)); in hda_dsp_stream_get_position()
1035 hstream->index)); in hda_dsp_stream_get_position()
1046 dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n", in hda_dsp_stream_get_position()
1052 if (pos >= hstream->bufsize) in hda_dsp_stream_get_position()