cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hdac_stream.c (21621B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * HD-audio stream operations
      4 */
      5
      6#include <linux/kernel.h>
      7#include <linux/delay.h>
      8#include <linux/export.h>
      9#include <linux/clocksource.h>
     10#include <sound/core.h>
     11#include <sound/pcm.h>
     12#include <sound/hdaudio.h>
     13#include <sound/hda_register.h>
     14#include "trace.h"
     15
     16/**
     17 * snd_hdac_get_stream_stripe_ctl - get stripe control value
     18 * @bus: HD-audio core bus
     19 * @substream: PCM substream
     20 */
     21int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
     22				   struct snd_pcm_substream *substream)
     23{
     24	struct snd_pcm_runtime *runtime = substream->runtime;
     25	unsigned int channels = runtime->channels,
     26		     rate = runtime->rate,
     27		     bits_per_sample = runtime->sample_bits,
     28		     max_sdo_lines, value, sdo_line;
     29
     30	/* T_AZA_GCAP_NSDO is 1:2 bitfields in GCAP */
     31	max_sdo_lines = snd_hdac_chip_readl(bus, GCAP) & AZX_GCAP_NSDO;
     32
     33	/* following is from HD audio spec */
     34	for (sdo_line = max_sdo_lines; sdo_line > 0; sdo_line >>= 1) {
     35		if (rate > 48000)
     36			value = (channels * bits_per_sample *
     37					(rate / 48000)) / sdo_line;
     38		else
     39			value = (channels * bits_per_sample) / sdo_line;
     40
     41		if (value >= bus->sdo_limit)
     42			break;
     43	}
     44
     45	/* stripe value: 0 for 1SDO, 1 for 2SDO, 2 for 4SDO lines */
     46	return sdo_line >> 1;
     47}
     48EXPORT_SYMBOL_GPL(snd_hdac_get_stream_stripe_ctl);
     49
     50/**
     51 * snd_hdac_stream_init - initialize each stream (aka device)
     52 * @bus: HD-audio core bus
     53 * @azx_dev: HD-audio core stream object to initialize
     54 * @idx: stream index number
     55 * @direction: stream direction (SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE)
     56 * @tag: the tag id to assign
     57 *
     58 * Assign the starting bdl address to each stream (device) and initialize.
     59 */
     60void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev,
     61			  int idx, int direction, int tag)
     62{
     63	azx_dev->bus = bus;
     64	/* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
     65	azx_dev->sd_addr = bus->remap_addr + (0x20 * idx + 0x80);
     66	/* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
     67	azx_dev->sd_int_sta_mask = 1 << idx;
     68	azx_dev->index = idx;
     69	azx_dev->direction = direction;
     70	azx_dev->stream_tag = tag;
     71	snd_hdac_dsp_lock_init(azx_dev);
     72	list_add_tail(&azx_dev->list, &bus->stream_list);
     73}
     74EXPORT_SYMBOL_GPL(snd_hdac_stream_init);
     75
     76/**
     77 * snd_hdac_stream_start - start a stream
     78 * @azx_dev: HD-audio core stream to start
     79 * @fresh_start: false = wallclock timestamp relative to period wallclock
     80 *
     81 * Start a stream, set start_wallclk and set the running flag.
     82 */
     83void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start)
     84{
     85	struct hdac_bus *bus = azx_dev->bus;
     86	int stripe_ctl;
     87
     88	trace_snd_hdac_stream_start(bus, azx_dev);
     89
     90	azx_dev->start_wallclk = snd_hdac_chip_readl(bus, WALLCLK);
     91	if (!fresh_start)
     92		azx_dev->start_wallclk -= azx_dev->period_wallclk;
     93
     94	/* enable SIE */
     95	snd_hdac_chip_updatel(bus, INTCTL,
     96			      1 << azx_dev->index,
     97			      1 << azx_dev->index);
     98	/* set stripe control */
     99	if (azx_dev->stripe) {
    100		if (azx_dev->substream)
    101			stripe_ctl = snd_hdac_get_stream_stripe_ctl(bus, azx_dev->substream);
    102		else
    103			stripe_ctl = 0;
    104		snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK,
    105					stripe_ctl);
    106	}
    107	/* set DMA start and interrupt mask */
    108	snd_hdac_stream_updateb(azx_dev, SD_CTL,
    109				0, SD_CTL_DMA_START | SD_INT_MASK);
    110	azx_dev->running = true;
    111}
    112EXPORT_SYMBOL_GPL(snd_hdac_stream_start);
    113
    114/**
    115 * snd_hdac_stream_clear - stop a stream DMA
    116 * @azx_dev: HD-audio core stream to stop
    117 */
    118void snd_hdac_stream_clear(struct hdac_stream *azx_dev)
    119{
    120	snd_hdac_stream_updateb(azx_dev, SD_CTL,
    121				SD_CTL_DMA_START | SD_INT_MASK, 0);
    122	snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */
    123	if (azx_dev->stripe)
    124		snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0);
    125	azx_dev->running = false;
    126}
    127EXPORT_SYMBOL_GPL(snd_hdac_stream_clear);
    128
    129/**
    130 * snd_hdac_stream_stop - stop a stream
    131 * @azx_dev: HD-audio core stream to stop
    132 *
    133 * Stop a stream DMA and disable stream interrupt
    134 */
    135void snd_hdac_stream_stop(struct hdac_stream *azx_dev)
    136{
    137	trace_snd_hdac_stream_stop(azx_dev->bus, azx_dev);
    138
    139	snd_hdac_stream_clear(azx_dev);
    140	/* disable SIE */
    141	snd_hdac_chip_updatel(azx_dev->bus, INTCTL, 1 << azx_dev->index, 0);
    142}
    143EXPORT_SYMBOL_GPL(snd_hdac_stream_stop);
    144
    145/**
    146 * snd_hdac_stop_streams_and_chip - stop all streams and chip if running
    147 * @bus: HD-audio core bus
    148 */
    149void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus)
    150{
    151	struct hdac_stream *stream;
    152
    153	if (bus->chip_init) {
    154		list_for_each_entry(stream, &bus->stream_list, list)
    155			snd_hdac_stream_stop(stream);
    156		snd_hdac_bus_stop_chip(bus);
    157	}
    158}
    159EXPORT_SYMBOL_GPL(snd_hdac_stop_streams_and_chip);
    160
    161/**
    162 * snd_hdac_stream_reset - reset a stream
    163 * @azx_dev: HD-audio core stream to reset
    164 */
    165void snd_hdac_stream_reset(struct hdac_stream *azx_dev)
    166{
    167	unsigned char val;
    168	int timeout;
    169	int dma_run_state;
    170
    171	snd_hdac_stream_clear(azx_dev);
    172
    173	dma_run_state = snd_hdac_stream_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START;
    174
    175	snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET);
    176	udelay(3);
    177	timeout = 300;
    178	do {
    179		val = snd_hdac_stream_readb(azx_dev, SD_CTL) &
    180			SD_CTL_STREAM_RESET;
    181		if (val)
    182			break;
    183	} while (--timeout);
    184
    185	if (azx_dev->bus->dma_stop_delay && dma_run_state)
    186		udelay(azx_dev->bus->dma_stop_delay);
    187
    188	val &= ~SD_CTL_STREAM_RESET;
    189	snd_hdac_stream_writeb(azx_dev, SD_CTL, val);
    190	udelay(3);
    191
    192	timeout = 300;
    193	/* waiting for hardware to report that the stream is out of reset */
    194	do {
    195		val = snd_hdac_stream_readb(azx_dev, SD_CTL) &
    196			SD_CTL_STREAM_RESET;
    197		if (!val)
    198			break;
    199	} while (--timeout);
    200
    201	/* reset first position - may not be synced with hw at this time */
    202	if (azx_dev->posbuf)
    203		*azx_dev->posbuf = 0;
    204}
    205EXPORT_SYMBOL_GPL(snd_hdac_stream_reset);
    206
    207/**
    208 * snd_hdac_stream_setup -  set up the SD for streaming
    209 * @azx_dev: HD-audio core stream to set up
    210 */
    211int snd_hdac_stream_setup(struct hdac_stream *azx_dev)
    212{
    213	struct hdac_bus *bus = azx_dev->bus;
    214	struct snd_pcm_runtime *runtime;
    215	unsigned int val;
    216
    217	if (azx_dev->substream)
    218		runtime = azx_dev->substream->runtime;
    219	else
    220		runtime = NULL;
    221	/* make sure the run bit is zero for SD */
    222	snd_hdac_stream_clear(azx_dev);
    223	/* program the stream_tag */
    224	val = snd_hdac_stream_readl(azx_dev, SD_CTL);
    225	val = (val & ~SD_CTL_STREAM_TAG_MASK) |
    226		(azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT);
    227	if (!bus->snoop)
    228		val |= SD_CTL_TRAFFIC_PRIO;
    229	snd_hdac_stream_writel(azx_dev, SD_CTL, val);
    230
    231	/* program the length of samples in cyclic buffer */
    232	snd_hdac_stream_writel(azx_dev, SD_CBL, azx_dev->bufsize);
    233
    234	/* program the stream format */
    235	/* this value needs to be the same as the one programmed */
    236	snd_hdac_stream_writew(azx_dev, SD_FORMAT, azx_dev->format_val);
    237
    238	/* program the stream LVI (last valid index) of the BDL */
    239	snd_hdac_stream_writew(azx_dev, SD_LVI, azx_dev->frags - 1);
    240
    241	/* program the BDL address */
    242	/* lower BDL address */
    243	snd_hdac_stream_writel(azx_dev, SD_BDLPL, (u32)azx_dev->bdl.addr);
    244	/* upper BDL address */
    245	snd_hdac_stream_writel(azx_dev, SD_BDLPU,
    246			       upper_32_bits(azx_dev->bdl.addr));
    247
    248	/* enable the position buffer */
    249	if (bus->use_posbuf && bus->posbuf.addr) {
    250		if (!(snd_hdac_chip_readl(bus, DPLBASE) & AZX_DPLBASE_ENABLE))
    251			snd_hdac_chip_writel(bus, DPLBASE,
    252				(u32)bus->posbuf.addr | AZX_DPLBASE_ENABLE);
    253	}
    254
    255	/* set the interrupt enable bits in the descriptor control register */
    256	snd_hdac_stream_updatel(azx_dev, SD_CTL, 0, SD_INT_MASK);
    257
    258	azx_dev->fifo_size = snd_hdac_stream_readw(azx_dev, SD_FIFOSIZE) + 1;
    259
    260	/* when LPIB delay correction gives a small negative value,
    261	 * we ignore it; currently set the threshold statically to
    262	 * 64 frames
    263	 */
    264	if (runtime && runtime->period_size > 64)
    265		azx_dev->delay_negative_threshold =
    266			-frames_to_bytes(runtime, 64);
    267	else
    268		azx_dev->delay_negative_threshold = 0;
    269
    270	/* wallclk has 24Mhz clock source */
    271	if (runtime)
    272		azx_dev->period_wallclk = (((runtime->period_size * 24000) /
    273				    runtime->rate) * 1000);
    274
    275	return 0;
    276}
    277EXPORT_SYMBOL_GPL(snd_hdac_stream_setup);
    278
    279/**
    280 * snd_hdac_stream_cleanup - cleanup a stream
    281 * @azx_dev: HD-audio core stream to clean up
    282 */
    283void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev)
    284{
    285	snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0);
    286	snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
    287	snd_hdac_stream_writel(azx_dev, SD_CTL, 0);
    288	azx_dev->bufsize = 0;
    289	azx_dev->period_bytes = 0;
    290	azx_dev->format_val = 0;
    291}
    292EXPORT_SYMBOL_GPL(snd_hdac_stream_cleanup);
    293
    294/**
    295 * snd_hdac_stream_assign - assign a stream for the PCM
    296 * @bus: HD-audio core bus
    297 * @substream: PCM substream to assign
    298 *
    299 * Look for an unused stream for the given PCM substream, assign it
    300 * and return the stream object.  If no stream is free, returns NULL.
    301 * The function tries to keep using the same stream object when it's used
    302 * beforehand.  Also, when bus->reverse_assign flag is set, the last free
    303 * or matching entry is returned.  This is needed for some strange codecs.
    304 */
    305struct hdac_stream *snd_hdac_stream_assign(struct hdac_bus *bus,
    306					   struct snd_pcm_substream *substream)
    307{
    308	struct hdac_stream *azx_dev;
    309	struct hdac_stream *res = NULL;
    310
    311	/* make a non-zero unique key for the substream */
    312	int key = (substream->pcm->device << 16) | (substream->number << 2) |
    313		(substream->stream + 1);
    314
    315	spin_lock_irq(&bus->reg_lock);
    316	list_for_each_entry(azx_dev, &bus->stream_list, list) {
    317		if (azx_dev->direction != substream->stream)
    318			continue;
    319		if (azx_dev->opened)
    320			continue;
    321		if (azx_dev->assigned_key == key) {
    322			res = azx_dev;
    323			break;
    324		}
    325		if (!res || bus->reverse_assign)
    326			res = azx_dev;
    327	}
    328	if (res) {
    329		res->opened = 1;
    330		res->running = 0;
    331		res->assigned_key = key;
    332		res->substream = substream;
    333	}
    334	spin_unlock_irq(&bus->reg_lock);
    335	return res;
    336}
    337EXPORT_SYMBOL_GPL(snd_hdac_stream_assign);
    338
    339/**
    340 * snd_hdac_stream_release - release the assigned stream
    341 * @azx_dev: HD-audio core stream to release
    342 *
    343 * Release the stream that has been assigned by snd_hdac_stream_assign().
    344 */
    345void snd_hdac_stream_release(struct hdac_stream *azx_dev)
    346{
    347	struct hdac_bus *bus = azx_dev->bus;
    348
    349	spin_lock_irq(&bus->reg_lock);
    350	azx_dev->opened = 0;
    351	azx_dev->running = 0;
    352	azx_dev->substream = NULL;
    353	spin_unlock_irq(&bus->reg_lock);
    354}
    355EXPORT_SYMBOL_GPL(snd_hdac_stream_release);
    356
    357/**
    358 * snd_hdac_get_stream - return hdac_stream based on stream_tag and
    359 * direction
    360 *
    361 * @bus: HD-audio core bus
    362 * @dir: direction for the stream to be found
    363 * @stream_tag: stream tag for stream to be found
    364 */
    365struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus,
    366					int dir, int stream_tag)
    367{
    368	struct hdac_stream *s;
    369
    370	list_for_each_entry(s, &bus->stream_list, list) {
    371		if (s->direction == dir && s->stream_tag == stream_tag)
    372			return s;
    373	}
    374
    375	return NULL;
    376}
    377EXPORT_SYMBOL_GPL(snd_hdac_get_stream);
    378
    379/*
    380 * set up a BDL entry
    381 */
    382static int setup_bdle(struct hdac_bus *bus,
    383		      struct snd_dma_buffer *dmab,
    384		      struct hdac_stream *azx_dev, __le32 **bdlp,
    385		      int ofs, int size, int with_ioc)
    386{
    387	__le32 *bdl = *bdlp;
    388
    389	while (size > 0) {
    390		dma_addr_t addr;
    391		int chunk;
    392
    393		if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
    394			return -EINVAL;
    395
    396		addr = snd_sgbuf_get_addr(dmab, ofs);
    397		/* program the address field of the BDL entry */
    398		bdl[0] = cpu_to_le32((u32)addr);
    399		bdl[1] = cpu_to_le32(upper_32_bits(addr));
    400		/* program the size field of the BDL entry */
    401		chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size);
    402		/* one BDLE cannot cross 4K boundary on CTHDA chips */
    403		if (bus->align_bdle_4k) {
    404			u32 remain = 0x1000 - (ofs & 0xfff);
    405
    406			if (chunk > remain)
    407				chunk = remain;
    408		}
    409		bdl[2] = cpu_to_le32(chunk);
    410		/* program the IOC to enable interrupt
    411		 * only when the whole fragment is processed
    412		 */
    413		size -= chunk;
    414		bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01);
    415		bdl += 4;
    416		azx_dev->frags++;
    417		ofs += chunk;
    418	}
    419	*bdlp = bdl;
    420	return ofs;
    421}
    422
    423/**
    424 * snd_hdac_stream_setup_periods - set up BDL entries
    425 * @azx_dev: HD-audio core stream to set up
    426 *
    427 * Set up the buffer descriptor table of the given stream based on the
    428 * period and buffer sizes of the assigned PCM substream.
    429 */
    430int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
    431{
    432	struct hdac_bus *bus = azx_dev->bus;
    433	struct snd_pcm_substream *substream = azx_dev->substream;
    434	struct snd_pcm_runtime *runtime = substream->runtime;
    435	__le32 *bdl;
    436	int i, ofs, periods, period_bytes;
    437	int pos_adj, pos_align;
    438
    439	/* reset BDL address */
    440	snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0);
    441	snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
    442
    443	period_bytes = azx_dev->period_bytes;
    444	periods = azx_dev->bufsize / period_bytes;
    445
    446	/* program the initial BDL entries */
    447	bdl = (__le32 *)azx_dev->bdl.area;
    448	ofs = 0;
    449	azx_dev->frags = 0;
    450
    451	pos_adj = bus->bdl_pos_adj;
    452	if (!azx_dev->no_period_wakeup && pos_adj > 0) {
    453		pos_align = pos_adj;
    454		pos_adj = DIV_ROUND_UP(pos_adj * runtime->rate, 48000);
    455		if (!pos_adj)
    456			pos_adj = pos_align;
    457		else
    458			pos_adj = roundup(pos_adj, pos_align);
    459		pos_adj = frames_to_bytes(runtime, pos_adj);
    460		if (pos_adj >= period_bytes) {
    461			dev_warn(bus->dev, "Too big adjustment %d\n",
    462				 pos_adj);
    463			pos_adj = 0;
    464		} else {
    465			ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
    466					 azx_dev,
    467					 &bdl, ofs, pos_adj, true);
    468			if (ofs < 0)
    469				goto error;
    470		}
    471	} else
    472		pos_adj = 0;
    473
    474	for (i = 0; i < periods; i++) {
    475		if (i == periods - 1 && pos_adj)
    476			ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
    477					 azx_dev, &bdl, ofs,
    478					 period_bytes - pos_adj, 0);
    479		else
    480			ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
    481					 azx_dev, &bdl, ofs,
    482					 period_bytes,
    483					 !azx_dev->no_period_wakeup);
    484		if (ofs < 0)
    485			goto error;
    486	}
    487	return 0;
    488
    489 error:
    490	dev_err(bus->dev, "Too many BDL entries: buffer=%d, period=%d\n",
    491		azx_dev->bufsize, period_bytes);
    492	return -EINVAL;
    493}
    494EXPORT_SYMBOL_GPL(snd_hdac_stream_setup_periods);
    495
    496/**
    497 * snd_hdac_stream_set_params - set stream parameters
    498 * @azx_dev: HD-audio core stream for which parameters are to be set
    499 * @format_val: format value parameter
    500 *
    501 * Setup the HD-audio core stream parameters from substream of the stream
    502 * and passed format value
    503 */
    504int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
    505				 unsigned int format_val)
    506{
    507
    508	unsigned int bufsize, period_bytes;
    509	struct snd_pcm_substream *substream = azx_dev->substream;
    510	struct snd_pcm_runtime *runtime;
    511	int err;
    512
    513	if (!substream)
    514		return -EINVAL;
    515	runtime = substream->runtime;
    516	bufsize = snd_pcm_lib_buffer_bytes(substream);
    517	period_bytes = snd_pcm_lib_period_bytes(substream);
    518
    519	if (bufsize != azx_dev->bufsize ||
    520	    period_bytes != azx_dev->period_bytes ||
    521	    format_val != azx_dev->format_val ||
    522	    runtime->no_period_wakeup != azx_dev->no_period_wakeup) {
    523		azx_dev->bufsize = bufsize;
    524		azx_dev->period_bytes = period_bytes;
    525		azx_dev->format_val = format_val;
    526		azx_dev->no_period_wakeup = runtime->no_period_wakeup;
    527		err = snd_hdac_stream_setup_periods(azx_dev);
    528		if (err < 0)
    529			return err;
    530	}
    531	return 0;
    532}
    533EXPORT_SYMBOL_GPL(snd_hdac_stream_set_params);
    534
    535static u64 azx_cc_read(const struct cyclecounter *cc)
    536{
    537	struct hdac_stream *azx_dev = container_of(cc, struct hdac_stream, cc);
    538
    539	return snd_hdac_chip_readl(azx_dev->bus, WALLCLK);
    540}
    541
    542static void azx_timecounter_init(struct hdac_stream *azx_dev,
    543				 bool force, u64 last)
    544{
    545	struct timecounter *tc = &azx_dev->tc;
    546	struct cyclecounter *cc = &azx_dev->cc;
    547	u64 nsec;
    548
    549	cc->read = azx_cc_read;
    550	cc->mask = CLOCKSOURCE_MASK(32);
    551
    552	/*
    553	 * Calculate the optimal mult/shift values. The counter wraps
    554	 * around after ~178.9 seconds.
    555	 */
    556	clocks_calc_mult_shift(&cc->mult, &cc->shift, 24000000,
    557			       NSEC_PER_SEC, 178);
    558
    559	nsec = 0; /* audio time is elapsed time since trigger */
    560	timecounter_init(tc, cc, nsec);
    561	if (force) {
    562		/*
    563		 * force timecounter to use predefined value,
    564		 * used for synchronized starts
    565		 */
    566		tc->cycle_last = last;
    567	}
    568}
    569
    570/**
    571 * snd_hdac_stream_timecounter_init - initialize time counter
    572 * @azx_dev: HD-audio core stream (master stream)
    573 * @streams: bit flags of streams to set up
    574 *
    575 * Initializes the time counter of streams marked by the bit flags (each
    576 * bit corresponds to the stream index).
    577 * The trigger timestamp of PCM substream assigned to the given stream is
    578 * updated accordingly, too.
    579 */
    580void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev,
    581				      unsigned int streams)
    582{
    583	struct hdac_bus *bus = azx_dev->bus;
    584	struct snd_pcm_runtime *runtime = azx_dev->substream->runtime;
    585	struct hdac_stream *s;
    586	bool inited = false;
    587	u64 cycle_last = 0;
    588	int i = 0;
    589
    590	list_for_each_entry(s, &bus->stream_list, list) {
    591		if (streams & (1 << i)) {
    592			azx_timecounter_init(s, inited, cycle_last);
    593			if (!inited) {
    594				inited = true;
    595				cycle_last = s->tc.cycle_last;
    596			}
    597		}
    598		i++;
    599	}
    600
    601	snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
    602	runtime->trigger_tstamp_latched = true;
    603}
    604EXPORT_SYMBOL_GPL(snd_hdac_stream_timecounter_init);
    605
    606/**
    607 * snd_hdac_stream_sync_trigger - turn on/off stream sync register
    608 * @azx_dev: HD-audio core stream (master stream)
    609 * @set: true = set, false = clear
    610 * @streams: bit flags of streams to sync
    611 * @reg: the stream sync register address
    612 */
    613void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
    614				  unsigned int streams, unsigned int reg)
    615{
    616	struct hdac_bus *bus = azx_dev->bus;
    617	unsigned int val;
    618
    619	if (!reg)
    620		reg = AZX_REG_SSYNC;
    621	val = _snd_hdac_chip_readl(bus, reg);
    622	if (set)
    623		val |= streams;
    624	else
    625		val &= ~streams;
    626	_snd_hdac_chip_writel(bus, reg, val);
    627}
    628EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger);
    629
    630/**
    631 * snd_hdac_stream_sync - sync with start/stop trigger operation
    632 * @azx_dev: HD-audio core stream (master stream)
    633 * @start: true = start, false = stop
    634 * @streams: bit flags of streams to sync
    635 *
    636 * For @start = true, wait until all FIFOs get ready.
    637 * For @start = false, wait until all RUN bits are cleared.
    638 */
    639void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
    640			  unsigned int streams)
    641{
    642	struct hdac_bus *bus = azx_dev->bus;
    643	int i, nwait, timeout;
    644	struct hdac_stream *s;
    645
    646	for (timeout = 5000; timeout; timeout--) {
    647		nwait = 0;
    648		i = 0;
    649		list_for_each_entry(s, &bus->stream_list, list) {
    650			if (!(streams & (1 << i++)))
    651				continue;
    652
    653			if (start) {
    654				/* check FIFO gets ready */
    655				if (!(snd_hdac_stream_readb(s, SD_STS) &
    656				      SD_STS_FIFO_READY))
    657					nwait++;
    658			} else {
    659				/* check RUN bit is cleared */
    660				if (snd_hdac_stream_readb(s, SD_CTL) &
    661				    SD_CTL_DMA_START) {
    662					nwait++;
    663					/*
    664					 * Perform stream reset if DMA RUN
    665					 * bit not cleared within given timeout
    666					 */
    667					if (timeout == 1)
    668						snd_hdac_stream_reset(s);
    669				}
    670			}
    671		}
    672		if (!nwait)
    673			break;
    674		cpu_relax();
    675	}
    676}
    677EXPORT_SYMBOL_GPL(snd_hdac_stream_sync);
    678
    679#ifdef CONFIG_SND_HDA_DSP_LOADER
    680/**
    681 * snd_hdac_dsp_prepare - prepare for DSP loading
    682 * @azx_dev: HD-audio core stream used for DSP loading
    683 * @format: HD-audio stream format
    684 * @byte_size: data chunk byte size
    685 * @bufp: allocated buffer
    686 *
    687 * Allocate the buffer for the given size and set up the given stream for
    688 * DSP loading.  Returns the stream tag (>= 0), or a negative error code.
    689 */
    690int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format,
    691			 unsigned int byte_size, struct snd_dma_buffer *bufp)
    692{
    693	struct hdac_bus *bus = azx_dev->bus;
    694	__le32 *bdl;
    695	int err;
    696
    697	snd_hdac_dsp_lock(azx_dev);
    698	spin_lock_irq(&bus->reg_lock);
    699	if (azx_dev->running || azx_dev->locked) {
    700		spin_unlock_irq(&bus->reg_lock);
    701		err = -EBUSY;
    702		goto unlock;
    703	}
    704	azx_dev->locked = true;
    705	spin_unlock_irq(&bus->reg_lock);
    706
    707	err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, bus->dev,
    708				  byte_size, bufp);
    709	if (err < 0)
    710		goto err_alloc;
    711
    712	azx_dev->substream = NULL;
    713	azx_dev->bufsize = byte_size;
    714	azx_dev->period_bytes = byte_size;
    715	azx_dev->format_val = format;
    716
    717	snd_hdac_stream_reset(azx_dev);
    718
    719	/* reset BDL address */
    720	snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0);
    721	snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
    722
    723	azx_dev->frags = 0;
    724	bdl = (__le32 *)azx_dev->bdl.area;
    725	err = setup_bdle(bus, bufp, azx_dev, &bdl, 0, byte_size, 0);
    726	if (err < 0)
    727		goto error;
    728
    729	snd_hdac_stream_setup(azx_dev);
    730	snd_hdac_dsp_unlock(azx_dev);
    731	return azx_dev->stream_tag;
    732
    733 error:
    734	snd_dma_free_pages(bufp);
    735 err_alloc:
    736	spin_lock_irq(&bus->reg_lock);
    737	azx_dev->locked = false;
    738	spin_unlock_irq(&bus->reg_lock);
    739 unlock:
    740	snd_hdac_dsp_unlock(azx_dev);
    741	return err;
    742}
    743EXPORT_SYMBOL_GPL(snd_hdac_dsp_prepare);
    744
    745/**
    746 * snd_hdac_dsp_trigger - start / stop DSP loading
    747 * @azx_dev: HD-audio core stream used for DSP loading
    748 * @start: trigger start or stop
    749 */
    750void snd_hdac_dsp_trigger(struct hdac_stream *azx_dev, bool start)
    751{
    752	if (start)
    753		snd_hdac_stream_start(azx_dev, true);
    754	else
    755		snd_hdac_stream_stop(azx_dev);
    756}
    757EXPORT_SYMBOL_GPL(snd_hdac_dsp_trigger);
    758
    759/**
    760 * snd_hdac_dsp_cleanup - clean up the stream from DSP loading to normal
    761 * @azx_dev: HD-audio core stream used for DSP loading
    762 * @dmab: buffer used by DSP loading
    763 */
    764void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
    765			  struct snd_dma_buffer *dmab)
    766{
    767	struct hdac_bus *bus = azx_dev->bus;
    768
    769	if (!dmab->area || !azx_dev->locked)
    770		return;
    771
    772	snd_hdac_dsp_lock(azx_dev);
    773	/* reset BDL address */
    774	snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0);
    775	snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
    776	snd_hdac_stream_writel(azx_dev, SD_CTL, 0);
    777	azx_dev->bufsize = 0;
    778	azx_dev->period_bytes = 0;
    779	azx_dev->format_val = 0;
    780
    781	snd_dma_free_pages(dmab);
    782	dmab->area = NULL;
    783
    784	spin_lock_irq(&bus->reg_lock);
    785	azx_dev->locked = false;
    786	spin_unlock_irq(&bus->reg_lock);
    787	snd_hdac_dsp_unlock(azx_dev);
    788}
    789EXPORT_SYMBOL_GPL(snd_hdac_dsp_cleanup);
    790#endif /* CONFIG_SND_HDA_DSP_LOADER */