Lines Matching +full:start +full:- +full:up
2 * HD-audio stream operations
16 * snd_hdac_stream_init - initialize each stream (aka device)
17 * @bus: HD-audio core bus
18 * @azx_dev: HD-audio core stream object to initialize
28 azx_dev->bus = bus; in snd_hdac_stream_init()
30 azx_dev->sd_addr = bus->remap_addr + (0x20 * idx + 0x80); in snd_hdac_stream_init()
32 azx_dev->sd_int_sta_mask = 1 << idx; in snd_hdac_stream_init()
33 azx_dev->index = idx; in snd_hdac_stream_init()
34 azx_dev->direction = direction; in snd_hdac_stream_init()
35 azx_dev->stream_tag = tag; in snd_hdac_stream_init()
37 list_add_tail(&azx_dev->list, &bus->stream_list); in snd_hdac_stream_init()
42 * snd_hdac_stream_start - start a stream
43 * @azx_dev: HD-audio core stream to start
46 * Start a stream, set start_wallclk and set the running flag.
50 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_stream_start()
54 azx_dev->start_wallclk = snd_hdac_chip_readl(bus, WALLCLK); in snd_hdac_stream_start()
56 azx_dev->start_wallclk -= azx_dev->period_wallclk; in snd_hdac_stream_start()
59 snd_hdac_chip_updatel(bus, INTCTL, 0, 1 << azx_dev->index); in snd_hdac_stream_start()
60 /* set DMA start and interrupt mask */ in snd_hdac_stream_start()
63 azx_dev->running = true; in snd_hdac_stream_start()
68 * snd_hdac_stream_clear - stop a stream DMA
69 * @azx_dev: HD-audio core stream to stop
76 azx_dev->running = false; in snd_hdac_stream_clear()
81 * snd_hdac_stream_stop - stop a stream
82 * @azx_dev: HD-audio core stream to stop
88 trace_snd_hdac_stream_stop(azx_dev->bus, azx_dev); in snd_hdac_stream_stop()
92 snd_hdac_chip_updatel(azx_dev->bus, INTCTL, 1 << azx_dev->index, 0); in snd_hdac_stream_stop()
97 * snd_hdac_stream_reset - reset a stream
98 * @azx_dev: HD-audio core stream to reset
115 } while (--timeout); in snd_hdac_stream_reset()
127 } while (--timeout); in snd_hdac_stream_reset()
129 /* reset first position - may not be synced with hw at this time */ in snd_hdac_stream_reset()
130 if (azx_dev->posbuf) in snd_hdac_stream_reset()
131 *azx_dev->posbuf = 0; in snd_hdac_stream_reset()
136 * snd_hdac_stream_setup - set up the SD for streaming
137 * @azx_dev: HD-audio core stream to set up
141 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_stream_setup()
145 if (azx_dev->substream) in snd_hdac_stream_setup()
146 runtime = azx_dev->substream->runtime; in snd_hdac_stream_setup()
154 (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT); in snd_hdac_stream_setup()
155 if (!bus->snoop) in snd_hdac_stream_setup()
160 snd_hdac_stream_writel(azx_dev, SD_CBL, azx_dev->bufsize); in snd_hdac_stream_setup()
164 snd_hdac_stream_writew(azx_dev, SD_FORMAT, azx_dev->format_val); in snd_hdac_stream_setup()
167 snd_hdac_stream_writew(azx_dev, SD_LVI, azx_dev->frags - 1); in snd_hdac_stream_setup()
171 snd_hdac_stream_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr); in snd_hdac_stream_setup()
174 upper_32_bits(azx_dev->bdl.addr)); in snd_hdac_stream_setup()
177 if (bus->use_posbuf && bus->posbuf.addr) { in snd_hdac_stream_setup()
180 (u32)bus->posbuf.addr | AZX_DPLBASE_ENABLE); in snd_hdac_stream_setup()
186 if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK) in snd_hdac_stream_setup()
187 azx_dev->fifo_size = in snd_hdac_stream_setup()
190 azx_dev->fifo_size = 0; in snd_hdac_stream_setup()
196 if (runtime && runtime->period_size > 64) in snd_hdac_stream_setup()
197 azx_dev->delay_negative_threshold = in snd_hdac_stream_setup()
198 -frames_to_bytes(runtime, 64); in snd_hdac_stream_setup()
200 azx_dev->delay_negative_threshold = 0; in snd_hdac_stream_setup()
204 azx_dev->period_wallclk = (((runtime->period_size * 24000) / in snd_hdac_stream_setup()
205 runtime->rate) * 1000); in snd_hdac_stream_setup()
212 * snd_hdac_stream_cleanup - cleanup a stream
213 * @azx_dev: HD-audio core stream to clean up
220 azx_dev->bufsize = 0; in snd_hdac_stream_cleanup()
221 azx_dev->period_bytes = 0; in snd_hdac_stream_cleanup()
222 azx_dev->format_val = 0; in snd_hdac_stream_cleanup()
227 * snd_hdac_stream_assign - assign a stream for the PCM
228 * @bus: HD-audio core bus
234 * beforehand. Also, when bus->reverse_assign flag is set, the last free
243 /* make a non-zero unique key for the substream */ in snd_hdac_stream_assign()
244 int key = (substream->pcm->device << 16) | (substream->number << 2) | in snd_hdac_stream_assign()
245 (substream->stream + 1); in snd_hdac_stream_assign()
247 list_for_each_entry(azx_dev, &bus->stream_list, list) { in snd_hdac_stream_assign()
248 if (azx_dev->direction != substream->stream) in snd_hdac_stream_assign()
250 if (azx_dev->opened) in snd_hdac_stream_assign()
252 if (azx_dev->assigned_key == key) { in snd_hdac_stream_assign()
256 if (!res || bus->reverse_assign) in snd_hdac_stream_assign()
260 spin_lock_irq(&bus->reg_lock); in snd_hdac_stream_assign()
261 res->opened = 1; in snd_hdac_stream_assign()
262 res->running = 0; in snd_hdac_stream_assign()
263 res->assigned_key = key; in snd_hdac_stream_assign()
264 res->substream = substream; in snd_hdac_stream_assign()
265 spin_unlock_irq(&bus->reg_lock); in snd_hdac_stream_assign()
272 * snd_hdac_stream_release - release the assigned stream
273 * @azx_dev: HD-audio core stream to release
279 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_stream_release()
281 spin_lock_irq(&bus->reg_lock); in snd_hdac_stream_release()
282 azx_dev->opened = 0; in snd_hdac_stream_release()
283 azx_dev->running = 0; in snd_hdac_stream_release()
284 azx_dev->substream = NULL; in snd_hdac_stream_release()
285 spin_unlock_irq(&bus->reg_lock); in snd_hdac_stream_release()
290 * snd_hdac_get_stream - return hdac_stream based on stream_tag and
293 * @bus: HD-audio core bus
302 list_for_each_entry(s, &bus->stream_list, list) { in snd_hdac_get_stream()
303 if (s->direction == dir && s->stream_tag == stream_tag) in snd_hdac_get_stream()
312 * set up a BDL entry
325 if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) in setup_bdle()
326 return -EINVAL; in setup_bdle()
335 if (bus->align_bdle_4k) { in setup_bdle()
336 u32 remain = 0x1000 - (ofs & 0xfff); in setup_bdle()
345 size -= chunk; in setup_bdle()
348 azx_dev->frags++; in setup_bdle()
356 * snd_hdac_stream_setup_periods - set up BDL entries
357 * @azx_dev: HD-audio core stream to set up
359 * Set up the buffer descriptor table of the given stream based on the
364 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_stream_setup_periods()
365 struct snd_pcm_substream *substream = azx_dev->substream; in snd_hdac_stream_setup_periods()
366 struct snd_pcm_runtime *runtime = substream->runtime; in snd_hdac_stream_setup_periods()
375 period_bytes = azx_dev->period_bytes; in snd_hdac_stream_setup_periods()
376 periods = azx_dev->bufsize / period_bytes; in snd_hdac_stream_setup_periods()
379 bdl = (__le32 *)azx_dev->bdl.area; in snd_hdac_stream_setup_periods()
381 azx_dev->frags = 0; in snd_hdac_stream_setup_periods()
383 pos_adj = bus->bdl_pos_adj; in snd_hdac_stream_setup_periods()
384 if (!azx_dev->no_period_wakeup && pos_adj > 0) { in snd_hdac_stream_setup_periods()
386 pos_adj = (pos_adj * runtime->rate + 47999) / 48000; in snd_hdac_stream_setup_periods()
390 pos_adj = ((pos_adj + pos_align - 1) / pos_align) * in snd_hdac_stream_setup_periods()
394 dev_warn(bus->dev, "Too big adjustment %d\n", in snd_hdac_stream_setup_periods()
408 if (i == periods - 1 && pos_adj) in snd_hdac_stream_setup_periods()
411 period_bytes - pos_adj, 0); in snd_hdac_stream_setup_periods()
416 !azx_dev->no_period_wakeup); in snd_hdac_stream_setup_periods()
423 dev_err(bus->dev, "Too many BDL entries: buffer=%d, period=%d\n", in snd_hdac_stream_setup_periods()
424 azx_dev->bufsize, period_bytes); in snd_hdac_stream_setup_periods()
425 return -EINVAL; in snd_hdac_stream_setup_periods()
430 * snd_hdac_stream_set_params - set stream parameters
431 * @azx_dev: HD-audio core stream for which parameters are to be set
434 * Setup the HD-audio core stream parameters from substream of the stream
442 struct snd_pcm_substream *substream = azx_dev->substream; in snd_hdac_stream_set_params()
447 return -EINVAL; in snd_hdac_stream_set_params()
448 runtime = substream->runtime; in snd_hdac_stream_set_params()
452 if (bufsize != azx_dev->bufsize || in snd_hdac_stream_set_params()
453 period_bytes != azx_dev->period_bytes || in snd_hdac_stream_set_params()
454 format_val != azx_dev->format_val || in snd_hdac_stream_set_params()
455 runtime->no_period_wakeup != azx_dev->no_period_wakeup) { in snd_hdac_stream_set_params()
456 azx_dev->bufsize = bufsize; in snd_hdac_stream_set_params()
457 azx_dev->period_bytes = period_bytes; in snd_hdac_stream_set_params()
458 azx_dev->format_val = format_val; in snd_hdac_stream_set_params()
459 azx_dev->no_period_wakeup = runtime->no_period_wakeup; in snd_hdac_stream_set_params()
472 return snd_hdac_chip_readl(azx_dev->bus, WALLCLK); in azx_cc_read()
478 struct timecounter *tc = &azx_dev->tc; in azx_timecounter_init()
479 struct cyclecounter *cc = &azx_dev->cc; in azx_timecounter_init()
482 cc->read = azx_cc_read; in azx_timecounter_init()
483 cc->mask = CLOCKSOURCE_MASK(32); in azx_timecounter_init()
495 cc->mult = 125; /* saturation after 195 years */ in azx_timecounter_init()
496 cc->shift = 0; in azx_timecounter_init()
505 tc->cycle_last = last; in azx_timecounter_init()
510 * snd_hdac_stream_timecounter_init - initialize time counter
511 * @azx_dev: HD-audio core stream (master stream)
512 * @streams: bit flags of streams to set up
522 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_stream_timecounter_init()
523 struct snd_pcm_runtime *runtime = azx_dev->substream->runtime; in snd_hdac_stream_timecounter_init()
529 list_for_each_entry(s, &bus->stream_list, list) { in snd_hdac_stream_timecounter_init()
534 cycle_last = s->tc.cycle_last; in snd_hdac_stream_timecounter_init()
540 snd_pcm_gettime(runtime, &runtime->trigger_tstamp); in snd_hdac_stream_timecounter_init()
541 runtime->trigger_tstamp_latched = true; in snd_hdac_stream_timecounter_init()
546 * snd_hdac_stream_sync_trigger - turn on/off stream sync register
547 * @azx_dev: HD-audio core stream (master stream)
553 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_stream_sync_trigger()
568 * snd_hdac_stream_sync - sync with start/strop trigger operation
569 * @azx_dev: HD-audio core stream (master stream)
570 * @start: true = start, false = stop
573 * For @start = true, wait until all FIFOs get ready.
574 * For @start = false, wait until all RUN bits are cleared.
576 void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, in snd_hdac_stream_sync() argument
579 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_stream_sync()
583 for (timeout = 5000; timeout; timeout--) { in snd_hdac_stream_sync()
586 list_for_each_entry(s, &bus->stream_list, list) { in snd_hdac_stream_sync()
588 if (start) { in snd_hdac_stream_sync()
611 * snd_hdac_dsp_prepare - prepare for DSP loading
612 * @azx_dev: HD-audio core stream used for DSP loading
613 * @format: HD-audio stream format
617 * Allocate the buffer for the given size and set up the given stream for
623 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_dsp_prepare()
628 spin_lock_irq(&bus->reg_lock); in snd_hdac_dsp_prepare()
629 if (azx_dev->running || azx_dev->locked) { in snd_hdac_dsp_prepare()
630 spin_unlock_irq(&bus->reg_lock); in snd_hdac_dsp_prepare()
631 err = -EBUSY; in snd_hdac_dsp_prepare()
634 azx_dev->locked = true; in snd_hdac_dsp_prepare()
635 spin_unlock_irq(&bus->reg_lock); in snd_hdac_dsp_prepare()
637 err = bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV_SG, in snd_hdac_dsp_prepare()
642 azx_dev->substream = NULL; in snd_hdac_dsp_prepare()
643 azx_dev->bufsize = byte_size; in snd_hdac_dsp_prepare()
644 azx_dev->period_bytes = byte_size; in snd_hdac_dsp_prepare()
645 azx_dev->format_val = format; in snd_hdac_dsp_prepare()
653 azx_dev->frags = 0; in snd_hdac_dsp_prepare()
654 bdl = (__le32 *)azx_dev->bdl.area; in snd_hdac_dsp_prepare()
661 return azx_dev->stream_tag; in snd_hdac_dsp_prepare()
664 bus->io_ops->dma_free_pages(bus, bufp); in snd_hdac_dsp_prepare()
666 spin_lock_irq(&bus->reg_lock); in snd_hdac_dsp_prepare()
667 azx_dev->locked = false; in snd_hdac_dsp_prepare()
668 spin_unlock_irq(&bus->reg_lock); in snd_hdac_dsp_prepare()
676 * snd_hdac_dsp_trigger - start / stop DSP loading
677 * @azx_dev: HD-audio core stream used for DSP loading
678 * @start: trigger start or stop
680 void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start) in snd_hdac_dsp_trigger() argument
682 if (start) in snd_hdac_dsp_trigger()
690 * snd_hdac_dsp_cleanup - clean up the stream from DSP loading to normal
691 * @azx_dev: HD-audio core stream used for DSP loading
697 struct hdac_bus *bus = azx_dev->bus; in snd_hdac_dsp_cleanup()
699 if (!dmab->area || !azx_dev->locked) in snd_hdac_dsp_cleanup()
707 azx_dev->bufsize = 0; in snd_hdac_dsp_cleanup()
708 azx_dev->period_bytes = 0; in snd_hdac_dsp_cleanup()
709 azx_dev->format_val = 0; in snd_hdac_dsp_cleanup()
711 bus->io_ops->dma_free_pages(bus, dmab); in snd_hdac_dsp_cleanup()
712 dmab->area = NULL; in snd_hdac_dsp_cleanup()
714 spin_lock_irq(&bus->reg_lock); in snd_hdac_dsp_cleanup()
715 azx_dev->locked = false; in snd_hdac_dsp_cleanup()
716 spin_unlock_irq(&bus->reg_lock); in snd_hdac_dsp_cleanup()