aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2012-09-21 19:39:06 -0400
committerTakashi Iwai <tiwai@suse.de>2012-09-22 03:31:09 -0400
commit90accc58a6946e7245993da6079f88d8c29cb731 (patch)
tree89eae1d4817843f24836b7ed61e93e202587e30e
parent172d3b209622785ce7c4f4104319df06d9814b62 (diff)
ALSA: hda - use LPIB for delay estimation
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>
-rw-r--r--sound/pci/hda/hda_intel.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index f4070a4f39fd..1c622e5e397c 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -555,6 +555,7 @@ enum {
555#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ 555#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
556#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ 556#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
557#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */ 557#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */
558#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
558 559
559/* quirks for ATI SB / AMD Hudson */ 560/* quirks for ATI SB / AMD Hudson */
560#define AZX_DCAPS_PRESET_ATI_SB \ 561#define AZX_DCAPS_PRESET_ATI_SB \
@@ -2143,6 +2144,27 @@ static unsigned int azx_get_position(struct azx *chip,
2143 2144
2144 if (pos >= azx_dev->bufsize) 2145 if (pos >= azx_dev->bufsize)
2145 pos = 0; 2146 pos = 0;
2147
2148 /* calculate runtime delay from LPIB */
2149 if (azx_dev->substream->runtime &&
2150 chip->position_fix[stream] == POS_FIX_POSBUF &&
2151 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
2152 unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
2153 int delay;
2154 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2155 delay = pos - lpib_pos;
2156 else
2157 delay = lpib_pos - pos;
2158 if (delay < 0)
2159 delay += azx_dev->bufsize;
2160 if (delay >= azx_dev->period_bytes) {
2161 snd_printdd("delay %d > period_bytes %d\n",
2162 delay, azx_dev->period_bytes);
2163 delay = 0; /* something is wrong */
2164 }
2165 azx_dev->substream->runtime->delay =
2166 bytes_to_frames(azx_dev->substream->runtime, delay);
2167 }
2146 return pos; 2168 return pos;
2147} 2169}
2148 2170
@@ -3402,7 +3424,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3402 /* CPT */ 3424 /* CPT */
3403 { PCI_DEVICE(0x8086, 0x1c20), 3425 { PCI_DEVICE(0x8086, 0x1c20),
3404 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3426 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3405 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, 3427 AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
3406 /* PBG */ 3428 /* PBG */
3407 { PCI_DEVICE(0x8086, 0x1d20), 3429 { PCI_DEVICE(0x8086, 0x1d20),
3408 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3430 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
@@ -3410,26 +3432,26 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3410 /* Panther Point */ 3432 /* Panther Point */
3411 { PCI_DEVICE(0x8086, 0x1e20), 3433 { PCI_DEVICE(0x8086, 0x1e20),
3412 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3434 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3413 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, 3435 AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
3414 /* Lynx Point */ 3436 /* Lynx Point */
3415 { PCI_DEVICE(0x8086, 0x8c20), 3437 { PCI_DEVICE(0x8086, 0x8c20),
3416 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3438 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3417 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, 3439 AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
3418 /* Lynx Point-LP */ 3440 /* Lynx Point-LP */
3419 { PCI_DEVICE(0x8086, 0x9c20), 3441 { PCI_DEVICE(0x8086, 0x9c20),
3420 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3442 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3421 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, 3443 AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
3422 /* Lynx Point-LP */ 3444 /* Lynx Point-LP */
3423 { PCI_DEVICE(0x8086, 0x9c21), 3445 { PCI_DEVICE(0x8086, 0x9c21),
3424 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3446 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3425 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, 3447 AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
3426 /* Haswell */ 3448 /* Haswell */
3427 { PCI_DEVICE(0x8086, 0x0c0c), 3449 { PCI_DEVICE(0x8086, 0x0c0c),
3428 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3450 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
3429 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, 3451 AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
3430 { PCI_DEVICE(0x8086, 0x0d0c), 3452 { PCI_DEVICE(0x8086, 0x0d0c),
3431 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3453 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
3432 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, 3454 AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
3433 /* SCH */ 3455 /* SCH */
3434 { PCI_DEVICE(0x8086, 0x811b), 3456 { PCI_DEVICE(0x8086, 0x811b),
3435 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3457 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |