ANDROID: GKI: ASoC: core: Update ALSA core to issue restart in underrun.

When compressed and pcm session is started the buffer pull will
Be from the DSP, in mmap mode for the scenario Hardware pointer
Is same as application pointer implies application has not filled the
Buffer to be send to DSP, and platform driver has to break and restart
The de queue process when the application has sufficient buffers.

When hardware pointer is same as application pointer it is an under run
Scenario where the ALSA framework has to trigger the under run and in HAL
The session has to re-prepare and re-triggered. based on the stop
Threshold, but in our system the stop threshold is INT_MAX which
Indicates that under run is not triggered in practical cases.

We have a brodcast usecase in which the mentioned under run case
Is hit mulitple times, and every time re-prepare and re-trigger will be
Expensive

Update the ASoC core framework to restart de queue process stopped
By platform Driver when the under run is hit, based on the available
Buffer and render flag, so the System will recover from the hang state.

To restart de queue process the ASoC core will be calling the restart
Callback registered by platform driver and this callback will be running in
Atomic context.

Test: build
Bug: 151372815
Change-Id: Ic9ea05a0dc6246346e9913493232882e2f5447d1
Signed-off-by: Santosh Mardi <gsantosh@codeaurora.org>
Signed-off-by: Meng Wang <mwang@codeaurora.org>
(cherry picked from commit ddbe60b879175f7260a910e77fc8e9e9369de84f)
Signed-off-by: Hridya Valsaraju <hridya@google.com>
This commit is contained in:
Santosh Mardi
2012-10-09 10:32:42 +05:30
committed by Hridya Valsaraju
parent 699c2634b6
commit bd84ac72c1
2 changed files with 17 additions and 0 deletions

View File

@@ -123,6 +123,11 @@ struct snd_pcm_ops {
#define SNDRV_PCM_POS_XRUN ((snd_pcm_uframes_t)-1)
#define SNDRV_DMA_MODE (0)
#define SNDRV_NON_DMA_MODE (1 << 0)
#define SNDRV_RENDER_STOPPED (1 << 1)
#define SNDRV_RENDER_RUNNING (1 << 2)
/* If you change this don't forget to change rates[] table in pcm_native.c */
#define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */
#define SNDRV_PCM_RATE_8000 (1<<1) /* 8000Hz */
@@ -390,6 +395,7 @@ struct snd_pcm_runtime {
unsigned int rate_num;
unsigned int rate_den;
unsigned int no_period_wakeup: 1;
unsigned int render_flag;
/* -- SW params -- */
int tstamp_mode; /* mmap timestamp is updated */

View File

@@ -2728,6 +2728,7 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
volatile struct snd_pcm_mmap_status *status;
volatile struct snd_pcm_mmap_control *control;
int err;
snd_pcm_uframes_t hw_avail;
memset(&sync_ptr, 0, sizeof(sync_ptr));
if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
@@ -2756,6 +2757,16 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
control->avail_min = sync_ptr.c.control.avail_min;
else
sync_ptr.c.control.avail_min = control->avail_min;
if (runtime->render_flag & SNDRV_NON_DMA_MODE) {
hw_avail = snd_pcm_playback_hw_avail(runtime);
if ((hw_avail >= runtime->start_threshold)
&& (runtime->render_flag &
SNDRV_RENDER_STOPPED)) {
if (substream->ops->restart)
substream->ops->restart(substream);
}
}
sync_ptr.s.status.state = status->state;
sync_ptr.s.status.hw_ptr = status->hw_ptr;
sync_ptr.s.status.tstamp = status->tstamp;