| From 90accc58a6946e7245993da6079f88d8c29cb731 Mon Sep 17 00:00:00 2001 |
| From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> |
| Date: Fri, 21 Sep 2012 18:39:06 -0500 |
| Subject: ALSA: hda - use LPIB for delay estimation |
| |
| From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> |
| |
| commit 90accc58a6946e7245993da6079f88d8c29cb731 upstream. |
| |
| DMA Position in Buffer (DPIB) should be used for |
| ring buffer management, while LPIB register provides |
| information on the number of samples transfered on |
| the link. The difference between the two pieces of |
| information corresponds to hardware/DMA buffering. |
| |
| This patch reports this difference in runtime->delay, and |
| removes the use of the COMBO mode on recent Intel hardware. |
| |
| Credits to Takashi Iwai for an initial patch. |
| |
| [rebased to for-next branch and replaced snd_printk() with |
| snd_printdd() by tiwai] |
| |
| Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| sound/pci/hda/hda_intel.c | 36 +++++++++++++++++++++++++++++------- |
| 1 file changed, 29 insertions(+), 7 deletions(-) |
| |
| --- a/sound/pci/hda/hda_intel.c |
| +++ b/sound/pci/hda/hda_intel.c |
| @@ -538,6 +538,7 @@ enum { |
| #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ |
| #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ |
| #define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */ |
| +#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ |
| |
| /* quirks for ATI SB / AMD Hudson */ |
| #define AZX_DCAPS_PRESET_ATI_SB \ |
| @@ -2120,6 +2121,27 @@ static unsigned int azx_get_position(str |
| |
| if (pos >= azx_dev->bufsize) |
| pos = 0; |
| + |
| + /* calculate runtime delay from LPIB */ |
| + if (azx_dev->substream->runtime && |
| + chip->position_fix[stream] == POS_FIX_POSBUF && |
| + (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { |
| + unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB); |
| + int delay; |
| + if (stream == SNDRV_PCM_STREAM_PLAYBACK) |
| + delay = pos - lpib_pos; |
| + else |
| + delay = lpib_pos - pos; |
| + if (delay < 0) |
| + delay += azx_dev->bufsize; |
| + if (delay >= azx_dev->period_bytes) { |
| + snd_printdd("delay %d > period_bytes %d\n", |
| + delay, azx_dev->period_bytes); |
| + delay = 0; /* something is wrong */ |
| + } |
| + azx_dev->substream->runtime->delay = |
| + bytes_to_frames(azx_dev->substream->runtime, delay); |
| + } |
| return pos; |
| } |
| |
| @@ -3260,7 +3282,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) |
| /* CPT */ |
| { PCI_DEVICE(0x8086, 0x1c20), |
| .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, |
| /* PBG */ |
| { PCI_DEVICE(0x8086, 0x1d20), |
| .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| @@ -3268,26 +3290,26 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) |
| /* Panther Point */ |
| { PCI_DEVICE(0x8086, 0x1e20), |
| .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, |
| /* Lynx Point */ |
| { PCI_DEVICE(0x8086, 0x8c20), |
| .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, |
| /* Lynx Point-LP */ |
| { PCI_DEVICE(0x8086, 0x9c20), |
| .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, |
| /* Lynx Point-LP */ |
| { PCI_DEVICE(0x8086, 0x9c21), |
| .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, |
| /* Haswell */ |
| { PCI_DEVICE(0x8086, 0x0c0c), |
| .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
| - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, |
| { PCI_DEVICE(0x8086, 0x0d0c), |
| .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
| - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
| + AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, |
| /* SCH */ |
| { PCI_DEVICE(0x8086, 0x811b), |
| .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |