diff mbox

[V2,7/7] ALSA: x86: hdmi: continue playback even when display resolution changes

Message ID 20170107012109.25744-8-jerome.anand@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jerome Anand Jan. 7, 2017, 1:21 a.m. UTC
When the display resolution changes, the drm disables the
display pipes due to which audio rendering stops. At this
time, we need to ensure the existing audio pointers and
buffers are cleared out so that the playback can restarted
once the display pipe is enabled with a different N/CTS values

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Jerome Anand <jerome.anand@intel.com>
---
 sound/x86/intel_hdmi_audio.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

Comments

Pierre-Louis Bossart Jan. 6, 2017, 8:43 p.m. UTC | #1
On 1/6/17 7:21 PM, Jerome Anand wrote:
> When the display resolution changes, the drm disables the
> display pipes due to which audio rendering stops. At this
> time, we need to ensure the existing audio pointers and
> buffers are cleared out so that the playback can restarted
> once the display pipe is enabled with a different N/CTS values

Add comment that this patch series has only been tested on hardware with 
a single HDMI connector/pipe and additional work may be needed for newer 
machines with 2 connectors.

>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Signed-off-by: Jerome Anand <jerome.anand@intel.com>
> ---
>  sound/x86/intel_hdmi_audio.c | 21 ++++++++++++++++++---
>  1 file changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
> index 91efbeb..f4042f8 100644
> --- a/sound/x86/intel_hdmi_audio.c
> +++ b/sound/x86/intel_hdmi_audio.c
> @@ -43,6 +43,7 @@ static DEFINE_MUTEX(had_mutex);
>  static int hdmi_card_index = SNDRV_DEFAULT_IDX1;
>  static char *hdmi_card_id = SNDRV_DEFAULT_STR1;
>  static struct snd_intelhad *had_data;
> +static int underrun_count;
>
>  module_param_named(index, hdmi_card_index, int, 0444);
>  MODULE_PARM_DESC(index,
> @@ -1114,6 +1115,7 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream)
>  	intelhaddata = snd_pcm_substream_chip(substream);
>  	had_stream = intelhaddata->private_data;
>  	runtime = substream->runtime;
> +	underrun_count = 0;
>
>  	pm_runtime_get(intelhaddata->dev);
>
> @@ -1503,10 +1505,23 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer(
>
>  	buf_id = intelhaddata->curr_buf % 4;
>  	had_read_register(AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &t);
> -	if (t == 0) {
> -		pr_debug("discovered buffer done for buf %d\n", buf_id);
> -		/* had_process_buffer_done(intelhaddata); */
> +
> +	if ((t == 0) || (t == ((u32)-1L))) {
> +		underrun_count++;
> +		pr_debug("discovered buffer done for buf %d, count = %d\n",
> +			buf_id, underrun_count);
> +
> +		if (underrun_count > (HAD_MIN_PERIODS/2)) {
> +			pr_debug("assume audio_codec_reset, underrun = %d - do xrun\n",
> +				underrun_count);
> +			underrun_count = 0;
> +			return SNDRV_PCM_POS_XRUN;
> +		}
> +	} else {
> +		/* Reset Counter */
> +		underrun_count = 0;
>  	}
> +
>  	t = intelhaddata->buf_info[buf_id].buf_size - t;
>
>  	if (intelhaddata->stream_info.buffer_rendered)
>
Jerome Anand Jan. 7, 2017, 4:58 a.m. UTC | #2
> -----Original Message-----
> From: Pierre-Louis Bossart [mailto:pierre-louis.bossart@linux.intel.com]
> Sent: Saturday, January 7, 2017 2:13 AM
> To: Anand, Jerome <jerome.anand@intel.com>; intel-
> gfx@lists.freedesktop.org; alsa-devel@alsa-project.org
> Cc: tiwai@suse.de; broonie@kernel.org; Ughreja, Rakesh A
> <rakesh.a.ughreja@intel.com>; ville.syrjala@linux.intel.com
> Subject: Re: [alsa-devel] [PATCH V2 7/7] ALSA: x86: hdmi: continue playback
> even when display resolution changes
> 
> On 1/6/17 7:21 PM, Jerome Anand wrote:
> > When the display resolution changes, the drm disables the display
> > pipes due to which audio rendering stops. At this time, we need to
> > ensure the existing audio pointers and buffers are cleared out so that
> > the playback can restarted once the display pipe is enabled with a
> > different N/CTS values
> 
> Add comment that this patch series has only been tested on hardware with a
> single HDMI connector/pipe and additional work may be needed for newer
> machines with 2 connectors.
> 

OK

> >
> > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> > Signed-off-by: Jerome Anand <jerome.anand@intel.com>
> > ---
> >  sound/x86/intel_hdmi_audio.c | 21 ++++++++++++++++++---
> >  1 file changed, 18 insertions(+), 3 deletions(-)
> >
> > diff --git a/sound/x86/intel_hdmi_audio.c
> b/sound/x86/intel_hdmi_audio.c
> > index 91efbeb..f4042f8 100644
> > --- a/sound/x86/intel_hdmi_audio.c
> > +++ b/sound/x86/intel_hdmi_audio.c
> > @@ -43,6 +43,7 @@ static DEFINE_MUTEX(had_mutex);
> >  static int hdmi_card_index = SNDRV_DEFAULT_IDX1;
> >  static char *hdmi_card_id = SNDRV_DEFAULT_STR1;
> >  static struct snd_intelhad *had_data;
> > +static int underrun_count;
> >
> >  module_param_named(index, hdmi_card_index, int, 0444);
> >  MODULE_PARM_DESC(index,
> > @@ -1114,6 +1115,7 @@ static int snd_intelhad_open(struct
> snd_pcm_substream *substream)
> >  	intelhaddata = snd_pcm_substream_chip(substream);
> >  	had_stream = intelhaddata->private_data;
> >  	runtime = substream->runtime;
> > +	underrun_count = 0;
> >
> >  	pm_runtime_get(intelhaddata->dev);
> >
> > @@ -1503,10 +1505,23 @@ static snd_pcm_uframes_t
> snd_intelhad_pcm_pointer(
> >
> >  	buf_id = intelhaddata->curr_buf % 4;
> >  	had_read_register(AUD_BUF_A_LENGTH + (buf_id *
> HAD_REG_WIDTH), &t);
> > -	if (t == 0) {
> > -		pr_debug("discovered buffer done for buf %d\n", buf_id);
> > -		/* had_process_buffer_done(intelhaddata); */
> > +
> > +	if ((t == 0) || (t == ((u32)-1L))) {
> > +		underrun_count++;
> > +		pr_debug("discovered buffer done for buf %d, count =
> %d\n",
> > +			buf_id, underrun_count);
> > +
> > +		if (underrun_count > (HAD_MIN_PERIODS/2)) {
> > +			pr_debug("assume audio_codec_reset, underrun =
> %d - do xrun\n",
> > +				underrun_count);
> > +			underrun_count = 0;
> > +			return SNDRV_PCM_POS_XRUN;
> > +		}
> > +	} else {
> > +		/* Reset Counter */
> > +		underrun_count = 0;
> >  	}
> > +
> >  	t = intelhaddata->buf_info[buf_id].buf_size - t;
> >
> >  	if (intelhaddata->stream_info.buffer_rendered)
> >
diff mbox

Patch

diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index 91efbeb..f4042f8 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -43,6 +43,7 @@  static DEFINE_MUTEX(had_mutex);
 static int hdmi_card_index = SNDRV_DEFAULT_IDX1;
 static char *hdmi_card_id = SNDRV_DEFAULT_STR1;
 static struct snd_intelhad *had_data;
+static int underrun_count;
 
 module_param_named(index, hdmi_card_index, int, 0444);
 MODULE_PARM_DESC(index,
@@ -1114,6 +1115,7 @@  static int snd_intelhad_open(struct snd_pcm_substream *substream)
 	intelhaddata = snd_pcm_substream_chip(substream);
 	had_stream = intelhaddata->private_data;
 	runtime = substream->runtime;
+	underrun_count = 0;
 
 	pm_runtime_get(intelhaddata->dev);
 
@@ -1503,10 +1505,23 @@  static snd_pcm_uframes_t snd_intelhad_pcm_pointer(
 
 	buf_id = intelhaddata->curr_buf % 4;
 	had_read_register(AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &t);
-	if (t == 0) {
-		pr_debug("discovered buffer done for buf %d\n", buf_id);
-		/* had_process_buffer_done(intelhaddata); */
+
+	if ((t == 0) || (t == ((u32)-1L))) {
+		underrun_count++;
+		pr_debug("discovered buffer done for buf %d, count = %d\n",
+			buf_id, underrun_count);
+
+		if (underrun_count > (HAD_MIN_PERIODS/2)) {
+			pr_debug("assume audio_codec_reset, underrun = %d - do xrun\n",
+				underrun_count);
+			underrun_count = 0;
+			return SNDRV_PCM_POS_XRUN;
+		}
+	} else {
+		/* Reset Counter */
+		underrun_count = 0;
 	}
+
 	t = intelhaddata->buf_info[buf_id].buf_size - t;
 
 	if (intelhaddata->stream_info.buffer_rendered)