All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: Nicolin Chen <b42378@freescale.com>
Cc: tiwai@suse.de, alsa-devel@alsa-project.org, broonie@kernel.org,
	lgirdwood@gmail.com
Subject: Re: [PATCH v7] ALSA: Add SoC on-chip internal ram support for DMA buffer allocation
Date: Wed, 23 Oct 2013 17:02:32 +0200	[thread overview]
Message-ID: <5267E508.7050104@metafoo.de> (raw)
In-Reply-To: <1382500063-15422-1-git-send-email-b42378@freescale.com>

On 10/23/2013 05:47 AM, Nicolin Chen wrote:
> Now it's quite common that an SoC contains its on-chip internal RAM.
> By using this RAM space for DMA buffer during audio playback/record,
> we can shutdown the voltage for external RAM to save power.
> 
> So add new DEV type with iram malloc()/free() and accordingly modify
> current default mmap() for the iram circumstance.
> 
> Signed-off-by: Nicolin Chen <b42378@freescale.com>

Looks good to me.

Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>

> ---
> Changelog
> v6->v7:
>  * Assigned pool to private_data field and accordingly refined helper functions.
> v5->v6:
>  * Dropped remaining OF dependency bacause no need to add them:
>    of_node doesn't care about OF; of_get_named_gen_pool() returns NULL if !OF.
> v4->v5:
>  * Minimized the OF dependency.
> v3->v4:
>  * Appropriately placed '#ifdef CONFIG_OF'
>  * Tested by adding '#undef CONFIG_OF' to modified files, and passed compiling.
> v2->v3:
>  * Moved iram specific mmap procedure out of ifdef ARCH_HAS_DMA_MMAP_COHERENT
> v1->v2:
>  * Added of_node check
>  * Dropped noops and unused physical addr in snd_free_dev_iram()
> 
> ---
>  include/sound/memalloc.h |  1 +
>  sound/core/memalloc.c    | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
>  sound/core/pcm_native.c  |  6 ++++++
>  3 files changed, 59 insertions(+)
> 
> diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
> index cf15b82..510aec4 100644
> --- a/include/sound/memalloc.h
> +++ b/include/sound/memalloc.h
> @@ -52,6 +52,7 @@ struct snd_dma_device {
>  #else
>  #define SNDRV_DMA_TYPE_DEV_SG	SNDRV_DMA_TYPE_DEV /* no SG-buf support */
>  #endif
> +#define SNDRV_DMA_TYPE_DEV_IRAM		4	/* generic device iram-buffer */
>  
>  /*
>   * info for buffer allocation
> diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
> index bdf826f..18c1d47 100644
> --- a/sound/core/memalloc.c
> +++ b/sound/core/memalloc.c
> @@ -30,6 +30,7 @@
>  #include <linux/seq_file.h>
>  #include <asm/uaccess.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/genalloc.h>
>  #include <linux/moduleparam.h>
>  #include <linux/mutex.h>
>  #include <sound/memalloc.h>
> @@ -157,6 +158,46 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
>  	dec_snd_pages(pg);
>  	dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
>  }
> +
> +/**
> + * snd_malloc_dev_iram - allocate memory from on-chip internal ram
> + * @dmab: buffer allocation record to store the allocated data
> + * @size: number of bytes to allocate from the iram
> + *
> + * This function requires iram phandle provided via of_node
> + */
> +void snd_malloc_dev_iram(struct snd_dma_buffer *dmab, size_t size)
> +{
> +	struct device *dev = dmab->dev.dev;
> +	struct gen_pool *pool = NULL;
> +
> +	if (dev->of_node)
> +		pool = of_get_named_gen_pool(dev->of_node, "iram", 0);
> +
> +	if (!pool)
> +		return;
> +
> +	/* Assign the pool into private_data field */
> +	dmab->private_data = pool;
> +
> +	dmab->area = (void *)gen_pool_alloc(pool, size);
> +	if (!dmab->area)
> +		return;
> +
> +	dmab->addr = gen_pool_virt_to_phys(pool, (unsigned long)dmab->area);
> +}
> +
> +/**
> + * snd_free_dev_iram - free allocated specific memory from on-chip internal ram
> + * @dmab: buffer allocation record to store the allocated data
> + */
> +void snd_free_dev_iram(struct snd_dma_buffer *dmab)
> +{
> +	struct gen_pool *pool = dmab->private_data;
> +
> +	if (pool && dmab->area)
> +		gen_pool_free(pool, (unsigned long)dmab->area, dmab->bytes);
> +}
>  #endif /* CONFIG_HAS_DMA */
>  
>  /*
> @@ -197,6 +238,14 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
>  		dmab->addr = 0;
>  		break;
>  #ifdef CONFIG_HAS_DMA
> +	case SNDRV_DMA_TYPE_DEV_IRAM:
> +		snd_malloc_dev_iram(dmab, size);
> +		if (dmab->area)
> +			break;
> +		/* Internal memory might have limited size and no enough space,
> +		 * so if we fail to malloc, try to fetch memory traditionally.
> +		 */
> +		dmab->dev.type = SNDRV_DMA_TYPE_DEV;
>  	case SNDRV_DMA_TYPE_DEV:
>  		dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
>  		break;
> @@ -269,6 +318,9 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
>  		snd_free_pages(dmab->area, dmab->bytes);
>  		break;
>  #ifdef CONFIG_HAS_DMA
> +	case SNDRV_DMA_TYPE_DEV_IRAM:
> +		snd_free_dev_iram(dmab);
> +		break;
>  	case SNDRV_DMA_TYPE_DEV:
>  		snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
>  		break;
> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
> index a68d4c6..513f095 100644
> --- a/sound/core/pcm_native.c
> +++ b/sound/core/pcm_native.c
> @@ -3199,6 +3199,12 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
>  			     struct vm_area_struct *area)
>  {
>  	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
> +	if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_IRAM) {
> +		area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
> +		return remap_pfn_range(area, area->vm_start,
> +				substream->dma_buffer.addr >> PAGE_SHIFT,
> +				area->vm_end - area->vm_start, area->vm_page_prot);
> +	}
>  #ifdef ARCH_HAS_DMA_MMAP_COHERENT
>  	if (!substream->ops->page &&
>  	    substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
> 

  reply	other threads:[~2013-10-23 15:02 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-23  3:47 [PATCH v7] ALSA: Add SoC on-chip internal ram support for DMA buffer allocation Nicolin Chen
2013-10-23 15:02 ` Lars-Peter Clausen [this message]
2013-10-24  7:22 ` Takashi Iwai
2013-10-24  8:05   ` Nicolin Chen
2013-10-24  9:15     ` Takashi Iwai
2013-10-24  8:54       ` Nicolin Chen
2013-10-24 12:38   ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5267E508.7050104@metafoo.de \
    --to=lars@metafoo.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=b42378@freescale.com \
    --cc=broonie@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.