[alsa-devel] [ALSA] ALSA Power Management, Drivers behaving unexpectedly after suspend/resume cycle
I am implementing power management in my ALSA sound drivers. ALSA drivers are not working properly after resume. All registers values are proper and I am able to read back the codec register contents.
If I do a playback after resume then I am getting lots of "underrun".
After a reboot playback is working fine.
Is there any known issues with ALSA power management? Why Ubuntu and Redhat does ALSA modules removal before suspend and insertion after resume?
On Fri, 2007-05-25 at 11:27 +0530, Nobin Mathew wrote:
I am implementing power management in my ALSA sound drivers. ALSA drivers are not working properly after resume. All registers values are proper and I am able to read back the codec register contents.
Iirc, you are using an AC97 codec. This means that the AC97 link is running as expected after resume.
If I do a playback after resume then I am getting lots of "underrun".
Do you hear any audio at all ? The underruns are probably being caused by the AC97 Tx FIFO not being filled quickly enough by DMA. Is your DMA being set up correctly after resume ?
After a reboot playback is working fine.
Is there any known issues with ALSA power management?
ALSA suspend and resume works fine on lots of devices (all the ones I have). I suspect you have a driver problem.
Liam
At Fri, 25 May 2007 11:27:10 +0530, Nobin Mathew wrote:
I am implementing power management in my ALSA sound drivers. ALSA drivers are not working properly after resume. All registers values are proper and I am able to read back the codec register contents.
If I do a playback after resume then I am getting lots of "underrun".
As Liam already pointed, the underrun is usually irrelevant from the codec registers, as codec chips don't control the DMA transfer. So, it's likely a controller side problem.
After a reboot playback is working fine.
Is there any known issues with ALSA power management?
No. Some drivers may have, but no problem in general.
Why Ubuntu and Redhat does ALSA modules removal before suspend and insertion after resume?
They are either too lazy or too conservative :)
Takashi
Every ALSA driver is calling these for suspend
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(pcm[i]);
And for resume snd_power_change_state(card, SNDRV_CTL_POWER_D0)
In ALSA ASoC no driver is calling any of this, even not in soc-core.c
My driver is an ASoC driver and I am also not calling these functions
Will this cause any Issue?
Thanks
On 5/25/07, Takashi Iwai tiwai@suse.de wrote:
At Fri, 25 May 2007 11:27:10 +0530, Nobin Mathew wrote:
I am implementing power management in my ALSA sound drivers. ALSA drivers are not working properly after resume. All registers values are proper and I am able to read back the codec register contents.
If I do a playback after resume then I am getting lots of "underrun".
As Liam already pointed, the underrun is usually irrelevant from the codec registers, as codec chips don't control the DMA transfer. So, it's likely a controller side problem.
After a reboot playback is working fine.
Is there any known issues with ALSA power management?
No. Some drivers may have, but no problem in general.
Why Ubuntu and Redhat does ALSA modules removal before suspend and insertion after resume?
They are either too lazy or too conservative :)
Takashi
On Fri, 2007-05-25 at 17:34 +0530, Nobin Mathew wrote:
Every ALSA driver is calling these for suspend
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(pcm[i]);
And for resume snd_power_change_state(card, SNDRV_CTL_POWER_D0)
In ALSA ASoC no driver is calling any of this, even not in soc-core.c
My driver is an ASoC driver and I am also not calling these functions
Will this cause any Issue?
These should probably be called to inform the upper layers of the PM state. Can you log a bug for this in ALSA bugzilla.
Fwiw, this _shouldn't_ effect your resume. You should still see calls to trigger for your DMA / AC97 to re-start transmission of PCM data.
PM was well tested on pxa2xx, although we did find a few applications were not too happy resuming audio. e.g. mplayer in alsa mode, although this was about 1 year ago and afaik it's been fixed.
It may be best to debug this using aplay and placing some debug in your trigger functions to make sure PCM transmission is restarted correctly.
Liam
after resume when i do playback i am getting same number of DMA interrupt as in the working case (after reboot).
I am using aplay (/usr/share/sounds/alsa/Side_Right.wav)
But i am not getting any sound (3 underruns), my codec register contents and controller register contents are same.
On 5/25/07, Liam Girdwood lg@opensource.wolfsonmicro.com wrote:
On Fri, 2007-05-25 at 17:34 +0530, Nobin Mathew wrote:
Every ALSA driver is calling these for suspend
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(pcm[i]);
And for resume snd_power_change_state(card, SNDRV_CTL_POWER_D0)
In ALSA ASoC no driver is calling any of this, even not in soc-core.c
My driver is an ASoC driver and I am also not calling these functions
Will this cause any Issue?
These should probably be called to inform the upper layers of the PM state. Can you log a bug for this in ALSA bugzilla.
Fwiw, this _shouldn't_ effect your resume. You should still see calls to trigger for your DMA / AC97 to re-start transmission of PCM data.
PM was well tested on pxa2xx, although we did find a few applications were not too happy resuming audio. e.g. mplayer in alsa mode, although this was about 1 year ago and afaik it's been fixed.
It may be best to debug this using aplay and placing some debug in your trigger functions to make sure PCM transmission is restarted correctly.
Liam
On Fri, 2007-05-25 at 18:24 +0530, Nobin Mathew wrote:
after resume when i do playback i am getting same number of DMA interrupt as in the working case (after reboot).
So, does aplay keeps playing until the end of your file or does it stop after a short time due to no periods being transmitted to the codec (io error) ? If it keeps playing then check the codec driver, it's possible it hasn't resumed fully.
I am using aplay (/usr/share/sounds/alsa/Side_Right.wav)
But i am not getting any sound (3 underruns), my codec register contents and controller register contents are same.
Codec drivers cache registers for faster IO, best make sure the cache is refreshed at resume.
Also, what happens when you kill aplay and restart it after resume ? Does audio play or does it still underrun with no audio ? If audio works, then this suggests something in your resume path is missing.
Fwiw, I would expect to sometimes see an underrun at resume due to resume being a busy period for most systems.
Liam
At Fri, 25 May 2007 13:39:40 +0100, Liam Girdwood wrote:
On Fri, 2007-05-25 at 17:34 +0530, Nobin Mathew wrote:
Every ALSA driver is calling these for suspend
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(pcm[i]);
And for resume snd_power_change_state(card, SNDRV_CTL_POWER_D0)
In ALSA ASoC no driver is calling any of this, even not in soc-core.c
My driver is an ASoC driver and I am also not calling these functions
Will this cause any Issue?
These should probably be called to inform the upper layers of the PM state. Can you log a bug for this in ALSA bugzilla.
Fwiw, this _shouldn't_ effect your resume. You should still see calls to trigger for your DMA / AC97 to re-start transmission of PCM data.
I think this does matter. Without calling snd_pcm_suspend*(), the stream is assumed to be still active, thus eventually neither prepare nor trigger is called at resume. If the hardware is perfectly resumed as it was before suspend, it may still work somehow.
However, usually it's impossible to resume the hardware perfectly. Thus, we need one stop the stream via snd_pcm_suspend*(), and let apps (or OSS layer) parepare (if needed) and restart the stream again.
Takashi
I did some more investigation into this issue.
There are two cases, in the first case it is working after resume() and in the second case it is not working after resume
1st Case:
1) boot the system 2)Load sound modules 2)mixer setting (alsactl restore 0) 3)Do power managemnt (sleep) suspend() 4)Come out of suspend, resume() 5) sound is coming out in this case
2nd Case: 1)boot the system 2)load sound modules 3)mixer settings (alsactl restore 0) 4)Do playback aplay -M /usr/share/sounds/alsa/Side_Right.wav 5) Let aplay to completion and kill all alsa apps if any running. 6)Do power managemnt (sleep) suspend() 7)Come out of suspend, resume() 8)Do playback aplay -M /usr/share/sounds/alsa/Side_Right.wav
in this case no sound is coming out and i am getting underrun error.
I am attaching some logs, these are the ac97 codec register values at various stages.
Mainly look at the register 3c.
On 5/25/07, Takashi Iwai tiwai@suse.de wrote:
At Fri, 25 May 2007 13:39:40 +0100, Liam Girdwood wrote:
On Fri, 2007-05-25 at 17:34 +0530, Nobin Mathew wrote:
Every ALSA driver is calling these for suspend
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(pcm[i]);
And for resume snd_power_change_state(card, SNDRV_CTL_POWER_D0)
In ALSA ASoC no driver is calling any of this, even not in soc-core.c
My driver is an ASoC driver and I am also not calling these functions
Will this cause any Issue?
These should probably be called to inform the upper layers of the PM state. Can you log a bug for this in ALSA bugzilla.
Fwiw, this _shouldn't_ effect your resume. You should still see calls to trigger for your DMA / AC97 to re-start transmission of PCM data.
I think this does matter. Without calling snd_pcm_suspend*(), the stream is assumed to be still active, thus eventually neither prepare nor trigger is called at resume. If the hardware is perfectly resumed as it was before suspend, it may still work somehow.
However, usually it's impossible to resume the hardware perfectly. Thus, we need one stop the stream via snd_pcm_suspend*(), and let apps (or OSS layer) parepare (if needed) and restart the stream again.
Takashi
I think i found the issue. Issue is in controller. Soon i will get back with more details
On 5/28/07, Nobin Mathew nobin.mathew@gmail.com wrote:
I did some more investigation into this issue.
There are two cases, in the first case it is working after resume() and in the second case it is not working after resume
1st Case:
- boot the system
2)Load sound modules 2)mixer setting (alsactl restore 0) 3)Do power managemnt (sleep) suspend() 4)Come out of suspend, resume() 5) sound is coming out in this case
2nd Case: 1)boot the system 2)load sound modules 3)mixer settings (alsactl restore 0) 4)Do playback aplay -M /usr/share/sounds/alsa/Side_Right.wav 5) Let aplay to completion and kill all alsa apps if any running. 6)Do power managemnt (sleep) suspend() 7)Come out of suspend, resume() 8)Do playback aplay -M /usr/share/sounds/alsa/Side_Right.wav
in this case no sound is coming out and i am getting underrun error.
I am attaching some logs, these are the ac97 codec register values at various stages.
Mainly look at the register 3c.
On 5/25/07, Takashi Iwai tiwai@suse.de wrote:
At Fri, 25 May 2007 13:39:40 +0100, Liam Girdwood wrote:
On Fri, 2007-05-25 at 17:34 +0530, Nobin Mathew wrote:
Every ALSA driver is calling these for suspend
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(pcm[i]);
And for resume snd_power_change_state(card, SNDRV_CTL_POWER_D0)
In ALSA ASoC no driver is calling any of this, even not in soc-core.c
My driver is an ASoC driver and I am also not calling these functions
Will this cause any Issue?
These should probably be called to inform the upper layers of the PM state. Can you log a bug for this in ALSA bugzilla.
Fwiw, this _shouldn't_ effect your resume. You should still see calls to trigger for your DMA / AC97 to re-start transmission of PCM data.
I think this does matter. Without calling snd_pcm_suspend*(), the stream is assumed to be still active, thus eventually neither prepare nor trigger is called at resume. If the hardware is perfectly resumed as it was before suspend, it may still work somehow.
However, usually it's impossible to resume the hardware perfectly. Thus, we need one stop the stream via snd_pcm_suspend*(), and let apps (or OSS layer) parepare (if needed) and restart the stream again.
Takashi
i was getting those overrun issue because of one controller bug, if i write zero to TXCR/RXCR register to disable both transmit and receive logic before low power mode then i am getting this overrun error after resume.
Thanks a lot for your help
Thanks Nobin Mathew
On 5/28/07, Nobin Mathew nobin.mathew@gmail.com wrote:
I think i found the issue. Issue is in controller. Soon i will get back with more details
On 5/28/07, Nobin Mathew nobin.mathew@gmail.com wrote:
I did some more investigation into this issue.
There are two cases, in the first case it is working after resume() and in the second case it is not working after resume
1st Case:
- boot the system
2)Load sound modules 2)mixer setting (alsactl restore 0) 3)Do power managemnt (sleep) suspend() 4)Come out of suspend, resume() 5) sound is coming out in this case
2nd Case: 1)boot the system 2)load sound modules 3)mixer settings (alsactl restore 0) 4)Do playback aplay -M /usr/share/sounds/alsa/Side_Right.wav 5) Let aplay to completion and kill all alsa apps if any running. 6)Do power managemnt (sleep) suspend() 7)Come out of suspend, resume() 8)Do playback aplay -M /usr/share/sounds/alsa/Side_Right.wav
in this case no sound is coming out and i am getting underrun error.
I am attaching some logs, these are the ac97 codec register values at various stages.
Mainly look at the register 3c.
On 5/25/07, Takashi Iwai tiwai@suse.de wrote:
At Fri, 25 May 2007 13:39:40 +0100, Liam Girdwood wrote:
On Fri, 2007-05-25 at 17:34 +0530, Nobin Mathew wrote:
Every ALSA driver is calling these for suspend
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(pcm[i]);
And for resume snd_power_change_state(card, SNDRV_CTL_POWER_D0)
In ALSA ASoC no driver is calling any of this, even not in soc-core.c
My driver is an ASoC driver and I am also not calling these functions
Will this cause any Issue?
These should probably be called to inform the upper layers of the PM state. Can you log a bug for this in ALSA bugzilla.
Fwiw, this _shouldn't_ effect your resume. You should still see calls to trigger for your DMA / AC97 to re-start transmission of PCM data.
I think this does matter. Without calling snd_pcm_suspend*(), the stream is assumed to be still active, thus eventually neither prepare nor trigger is called at resume. If the hardware is perfectly resumed as it was before suspend, it may still work somehow.
However, usually it's impossible to resume the hardware perfectly. Thus, we need one stop the stream via snd_pcm_suspend*(), and let apps (or OSS layer) parepare (if needed) and restart the stream again.
Takashi
participants (3)
-
Liam Girdwood
-
Nobin Mathew
-
Takashi Iwai