diff options
author | Misael Lopez Cruz | 2013-07-05 17:10:38 -0500 |
---|---|---|
committer | Misael Lopez Cruz | 2013-07-22 14:43:25 -0500 |
commit | 99a1e07f426e010404b6bdadfbdb9286641a6602 (patch) | |
tree | 6794bbbb1882ab2e4945a209766b8f684fd925a4 | |
parent | 29485e4cd6b4adac3816c5e1809f7998afe633e5 (diff) | |
download | kernel-audio-99a1e07f426e010404b6bdadfbdb9286641a6602.tar.gz kernel-audio-99a1e07f426e010404b6bdadfbdb9286641a6602.tar.xz kernel-audio-99a1e07f426e010404b6bdadfbdb9286641a6602.zip |
ASoC: davinci-mcasp: Wait until TX AFIFO is not empty
Wait until TX AFIFO has at least one audio sample before TXBUF starts
consuming data, otherwise XRUN can be hit immediately at the start of
the stream.
Change-Id: Ie94dcd16f7a00046eb043aec1ceee21ce6009fbc
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 818732de0f75..0aba39e7468d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -304,6 +304,12 @@ | |||
304 | 304 | ||
305 | #define DAVINCI_MCASP_NUM_SERIALIZER 16 | 305 | #define DAVINCI_MCASP_NUM_SERIALIZER 16 |
306 | 306 | ||
307 | /* | ||
308 | * Timeout value of 1 ms was chosen experimentally to account for the initial | ||
309 | * latency to have the first audio sample transferred to AFIFO by DMA | ||
310 | */ | ||
311 | #define MCASP_FIFO_FILL_TIMEOUT 1000 | ||
312 | |||
307 | static inline void mcasp_set_bits(void __iomem *reg, u32 val) | 313 | static inline void mcasp_set_bits(void __iomem *reg, u32 val) |
308 | { | 314 | { |
309 | __raw_writel(__raw_readl(reg) | val, reg); | 315 | __raw_writel(__raw_readl(reg) | val, reg); |
@@ -410,8 +416,11 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev) | |||
410 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); | 416 | mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); |
411 | } | 417 | } |
412 | 418 | ||
413 | static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | 419 | static int davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) |
414 | { | 420 | { |
421 | int i = 0; | ||
422 | u32 val; | ||
423 | |||
415 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 424 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
416 | if (dev->txnumevt) { /* enable FIFO */ | 425 | if (dev->txnumevt) { /* enable FIFO */ |
417 | switch (dev->version) { | 426 | switch (dev->version) { |
@@ -427,6 +436,24 @@ static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | |||
427 | mcasp_set_bits(dev->base + | 436 | mcasp_set_bits(dev->base + |
428 | DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); | 437 | DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); |
429 | } | 438 | } |
439 | |||
440 | /* | ||
441 | * Wait until DMA has loaded at least one sample into | ||
442 | * AFIFO to ensure XRUN is not immediately hit | ||
443 | * Implementation has to use udelay since it's executed | ||
444 | * in atomic context (trigger() callback) | ||
445 | */ | ||
446 | while (++i) { | ||
447 | val = mcasp_get_reg(dev->base + | ||
448 | MCASP_VER3_WFIFOSTS); | ||
449 | if (val > 0) | ||
450 | break; | ||
451 | |||
452 | if (i > MCASP_FIFO_FILL_TIMEOUT) | ||
453 | return -ETIMEDOUT; | ||
454 | |||
455 | udelay(1); | ||
456 | } | ||
430 | } | 457 | } |
431 | mcasp_start_tx(dev); | 458 | mcasp_start_tx(dev); |
432 | } else { | 459 | } else { |
@@ -447,6 +474,8 @@ static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | |||
447 | } | 474 | } |
448 | mcasp_start_rx(dev); | 475 | mcasp_start_rx(dev); |
449 | } | 476 | } |
477 | |||
478 | return 0; | ||
450 | } | 479 | } |
451 | 480 | ||
452 | static void mcasp_stop_rx(struct davinci_audio_dev *dev) | 481 | static void mcasp_stop_rx(struct davinci_audio_dev *dev) |
@@ -967,7 +996,7 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
967 | case SNDRV_PCM_TRIGGER_RESUME: | 996 | case SNDRV_PCM_TRIGGER_RESUME: |
968 | case SNDRV_PCM_TRIGGER_START: | 997 | case SNDRV_PCM_TRIGGER_START: |
969 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 998 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
970 | davinci_mcasp_start(dev, substream->stream); | 999 | ret = davinci_mcasp_start(dev, substream->stream); |
971 | break; | 1000 | break; |
972 | 1001 | ||
973 | case SNDRV_PCM_TRIGGER_SUSPEND: | 1002 | case SNDRV_PCM_TRIGGER_SUSPEND: |