| 1 |
From b98a9f6d1619b7fe32c2a6a4e5190121830f979b Mon Sep 17 00:00:00 2001
|
| 2 |
From: Takashi Iwai <tiwai@suse.de>
|
| 3 |
Date: Wed, 18 Mar 2009 15:09:13 +0100
|
| 4 |
Subject: ALSA: hda - Don't reset BDL unnecessarily
|
| 5 |
|
| 6 |
So far, the prepare callback is called multiple times, BDL entries
|
| 7 |
are reset and re-programmed at each time.
|
| 8 |
|
| 9 |
This patch adds the check to avoid the reset of BDL entries when the
|
| 10 |
same parameters are used.
|
| 11 |
|
| 12 |
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
| 13 |
---
|
| 14 |
sound/pci/hda/hda_intel.c | 46 +++++++++++++++++++++++++++++++-------------
|
| 15 |
1 files changed, 32 insertions(+), 14 deletions(-)
|
| 16 |
|
| 17 |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
| 18 |
index f3b5723..b7a61a1 100644
|
| 19 |
--- a/sound/pci/hda/hda_intel.c
|
| 20 |
+++ b/sound/pci/hda/hda_intel.c
|
| 21 |
@@ -1075,8 +1075,7 @@ static int azx_setup_periods(struct azx *chip,
|
| 22 |
azx_sd_writel(azx_dev, SD_BDLPL, 0);
|
| 23 |
azx_sd_writel(azx_dev, SD_BDLPU, 0);
|
| 24 |
|
| 25 |
- period_bytes = snd_pcm_lib_period_bytes(substream);
|
| 26 |
- azx_dev->period_bytes = period_bytes;
|
| 27 |
+ period_bytes = azx_dev->period_bytes;
|
| 28 |
periods = azx_dev->bufsize / period_bytes;
|
| 29 |
|
| 30 |
/* program the initial BDL entries */
|
| 31 |
@@ -1123,9 +1122,6 @@ static int azx_setup_periods(struct azx *chip,
|
| 32 |
error:
|
| 33 |
snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n",
|
| 34 |
azx_dev->bufsize, period_bytes);
|
| 35 |
- /* reset */
|
| 36 |
- azx_sd_writel(azx_dev, SD_BDLPL, 0);
|
| 37 |
- azx_sd_writel(azx_dev, SD_BDLPU, 0);
|
| 38 |
return -EINVAL;
|
| 39 |
}
|
| 40 |
|
| 41 |
@@ -1429,6 +1425,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
|
| 42 |
static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
|
| 43 |
struct snd_pcm_hw_params *hw_params)
|
| 44 |
{
|
| 45 |
+ struct azx_dev *azx_dev = get_azx_dev(substream);
|
| 46 |
+
|
| 47 |
+ azx_dev->bufsize = 0;
|
| 48 |
+ azx_dev->period_bytes = 0;
|
| 49 |
+ azx_dev->format_val = 0;
|
| 50 |
return snd_pcm_lib_malloc_pages(substream,
|
| 51 |
params_buffer_bytes(hw_params));
|
| 52 |
}
|
| 53 |
@@ -1443,6 +1444,9 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
|
| 54 |
azx_sd_writel(azx_dev, SD_BDLPL, 0);
|
| 55 |
azx_sd_writel(azx_dev, SD_BDLPU, 0);
|
| 56 |
azx_sd_writel(azx_dev, SD_CTL, 0);
|
| 57 |
+ azx_dev->bufsize = 0;
|
| 58 |
+ azx_dev->period_bytes = 0;
|
| 59 |
+ azx_dev->format_val = 0;
|
| 60 |
|
| 61 |
hinfo->ops.cleanup(hinfo, apcm->codec, substream);
|
| 62 |
|
| 63 |
@@ -1456,23 +1460,37 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
|
| 64 |
struct azx_dev *azx_dev = get_azx_dev(substream);
|
| 65 |
struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
|
| 66 |
struct snd_pcm_runtime *runtime = substream->runtime;
|
| 67 |
+ unsigned int bufsize, period_bytes, format_val;
|
| 68 |
+ int err;
|
| 69 |
|
| 70 |
- azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream);
|
| 71 |
- azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate,
|
| 72 |
- runtime->channels,
|
| 73 |
- runtime->format,
|
| 74 |
- hinfo->maxbps);
|
| 75 |
- if (!azx_dev->format_val) {
|
| 76 |
+ format_val = snd_hda_calc_stream_format(runtime->rate,
|
| 77 |
+ runtime->channels,
|
| 78 |
+ runtime->format,
|
| 79 |
+ hinfo->maxbps);
|
| 80 |
+ if (!format_val) {
|
| 81 |
snd_printk(KERN_ERR SFX
|
| 82 |
"invalid format_val, rate=%d, ch=%d, format=%d\n",
|
| 83 |
runtime->rate, runtime->channels, runtime->format);
|
| 84 |
return -EINVAL;
|
| 85 |
}
|
| 86 |
|
| 87 |
+ bufsize = snd_pcm_lib_buffer_bytes(substream);
|
| 88 |
+ period_bytes = snd_pcm_lib_period_bytes(substream);
|
| 89 |
+
|
| 90 |
snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
|
| 91 |
- azx_dev->bufsize, azx_dev->format_val);
|
| 92 |
- if (azx_setup_periods(chip, substream, azx_dev) < 0)
|
| 93 |
- return -EINVAL;
|
| 94 |
+ bufsize, format_val);
|
| 95 |
+
|
| 96 |
+ if (bufsize != azx_dev->bufsize ||
|
| 97 |
+ period_bytes != azx_dev->period_bytes ||
|
| 98 |
+ format_val != azx_dev->format_val) {
|
| 99 |
+ azx_dev->bufsize = bufsize;
|
| 100 |
+ azx_dev->period_bytes = period_bytes;
|
| 101 |
+ azx_dev->format_val = format_val;
|
| 102 |
+ err = azx_setup_periods(chip, substream, azx_dev);
|
| 103 |
+ if (err < 0)
|
| 104 |
+ return err;
|
| 105 |
+ }
|
| 106 |
+
|
| 107 |
azx_setup_controller(chip, azx_dev);
|
| 108 |
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
| 109 |
azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
|
| 110 |
--
|
| 111 |
1.6.2.2
|
| 112 |
|