At Thu, 4 Aug 2011 10:12:56 -0500, Pierre-Louis Bossart wrote:
Add new parameter to disable rounding of buffer/period sizes to multiples of 128 bytes. This is more efficient in terms of memory access but isn't required by the HDA spec and prevents users from specifying exact period/buffer sizes. For example for 44.1kHz, a period size set to 20ms will be rounded to 19.59ms.
Tested and enabled on Intel HDA controllers. Option is disabled by default for other controllers.
Tested-by: Wu Fengguang fengguang.wu@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
Thanks, applied now.
Takashi
Documentation/sound/alsa/ALSA-Configuration.txt | 5 ++ sound/pci/hda/hda_intel.c | 68 ++++++++++++++++++----- 2 files changed, 58 insertions(+), 15 deletions(-)
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 8975701..27126c4 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -886,6 +886,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. disable) power_save_controller - Reset HD-audio controller in power-saving mode (default = on)
align_buffer_size - Force rounding of buffer/period sizes to multiples
of 128 bytes. This is more efficient in terms of memory
access but isn't required by the HDA spec and prevents
users from specifying exact period/buffer sizes.
(default = on)
This module supports multiple cards and autoprobe.
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index be69822..2a8bed9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -116,6 +116,11 @@ module_param(power_save_controller, bool, 0644); MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); #endif
+static int align_buffer_size = 1; +module_param(align_buffer_size, bool, 0644); +MODULE_PARM_DESC(align_buffer_size,
"Force buffer and period sizes to be multiple of 128 bytes.");
MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ICH6M}," @@ -481,6 +486,7 @@ enum { #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ +#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
/* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ @@ -1599,6 +1605,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; unsigned long flags; int err;
int buff_step;
mutex_lock(&chip->open_mutex); azx_dev = azx_assign_device(chip, substream);
@@ -1613,10 +1620,25 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) runtime->hw.rates = hinfo->rates; snd_pcm_limit_hw_rates(runtime); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
- if (align_buffer_size)
/* constrain buffer sizes to be multiple of 128
bytes. This is more efficient in terms of memory
access but isn't required by the HDA spec and
prevents users from specifying exact period/buffer
sizes. For example for 44.1kHz, a period size set
to 20ms will be rounded to 19.59ms. */
buff_step = 128;
- else
/* Don't enforce steps on buffer sizes, still need to
be multiple of 4 bytes (HDA spec). Tested on Intel
HDA controllers, may not work on all devices where
option needs to be disabled */
buff_step = 4;
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
128);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,buff_step);
128);
snd_hda_power_up(apcm->codec); err = hinfo->ops.open(hinfo, apcm->codec, substream); if (err < 0) {buff_step);
@@ -2616,6 +2638,10 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, gcap &= ~ICH6_GCAP_64OK; }
- /* disable buffer size rounding to 128-byte multiples if supported */
- if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
align_buffer_size = 0;
- /* allow 64bit DMA address if supported by H/W */ if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
@@ -2817,37 +2843,49 @@ static void __devexit azx_remove(struct pci_dev *pci) static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* CPT */ { PCI_DEVICE(0x8086, 0x1c20),
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
/* PBG */ { PCI_DEVICE(0x8086, 0x1d20),AZX_DCAPS_BUFSIZE },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
/* Panther Point */ { PCI_DEVICE(0x8086, 0x1e20),AZX_DCAPS_BUFSIZE},
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
/* SCH */ { PCI_DEVICE(0x8086, 0x811b),AZX_DCAPS_BUFSIZE},
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
{ PCI_DEVICE(0x8086, 0x2668),AZX_DCAPS_BUFSIZE},
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
{ PCI_DEVICE(0x8086, 0x27d8),AZX_DCAPS_BUFSIZE }, /* ICH6 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
{ PCI_DEVICE(0x8086, 0x269a),AZX_DCAPS_BUFSIZE }, /* ICH7 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
{ PCI_DEVICE(0x8086, 0x284b),AZX_DCAPS_BUFSIZE }, /* ESB2 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
{ PCI_DEVICE(0x8086, 0x293e),AZX_DCAPS_BUFSIZE }, /* ICH8 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
{ PCI_DEVICE(0x8086, 0x293f),AZX_DCAPS_BUFSIZE }, /* ICH9 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
{ PCI_DEVICE(0x8086, 0x3a3e),AZX_DCAPS_BUFSIZE }, /* ICH9 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
{ PCI_DEVICE(0x8086, 0x3a6e),AZX_DCAPS_BUFSIZE }, /* ICH10 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
/* Generic Intel */ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff,AZX_DCAPS_BUFSIZE }, /* ICH10 */
.driver_data = AZX_DRIVER_ICH },
/* ATI SB 450/600/700/800/900 */ { PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },.driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE },
-- 1.7.6
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel