[alsa-devel] [PATCH] ALSA: hda: option to enable arbitrary buffer/period sizes

Takashi Iwai tiwai at suse.de
Thu Aug 4 17:46:16 CEST 2011


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 at intel.com>
> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at 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);
> +				   buff_step);
>  	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
> -				   128);
> +				   buff_step);
>  	snd_hda_power_up(apcm->codec);
>  	err = hinfo->ops.open(hinfo, apcm->codec, substream);
>  	if (err < 0) {
> @@ -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 |
> +	  AZX_DCAPS_BUFSIZE },
>  	/* PBG */
>  	{ PCI_DEVICE(0x8086, 0x1d20),
> -	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
> +	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
> +	  AZX_DCAPS_BUFSIZE},
>  	/* Panther Point */
>  	{ PCI_DEVICE(0x8086, 0x1e20),
> -	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
> +	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
> +	  AZX_DCAPS_BUFSIZE},
>  	/* SCH */
>  	{ PCI_DEVICE(0x8086, 0x811b),
> -	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
> +	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
> +	  AZX_DCAPS_BUFSIZE},
>  	{ PCI_DEVICE(0x8086, 0x2668),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH6 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ICH6 */
>  	{ PCI_DEVICE(0x8086, 0x27d8),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH7 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ICH7 */
>  	{ PCI_DEVICE(0x8086, 0x269a),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ESB2 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ESB2 */
>  	{ PCI_DEVICE(0x8086, 0x284b),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH8 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ICH8 */
>  	{ PCI_DEVICE(0x8086, 0x293e),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH9 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ICH9 */
>  	{ PCI_DEVICE(0x8086, 0x293f),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH9 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ICH9 */
>  	{ PCI_DEVICE(0x8086, 0x3a3e),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH10 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ICH10 */
>  	{ PCI_DEVICE(0x8086, 0x3a6e),
> -	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC },  /* ICH10 */
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
> +	  AZX_DCAPS_BUFSIZE },  /* ICH10 */
>  	/* Generic Intel */
>  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
>  	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
>  	  .class_mask = 0xffffff,
> -	  .driver_data = AZX_DRIVER_ICH },
> +	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE },
>  	/* ATI SB 450/600/700/800/900 */
>  	{ PCI_DEVICE(0x1002, 0x437b),
>  	  .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
> -- 
> 1.7.6
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 


More information about the Alsa-devel mailing list