s5pv210 audio dma分配

来源:互联网 发布:c语言乘法口诀表 编辑:程序博客网 时间:2024/06/10 05:36

s5pv210 audio dma分配

1. 音频播放

      这里我们使用内部DMA,就是将CPU内部SRAM地址0xc0000000(MP3_SRAM output buffer),通过ioremap映射到内核地址空间上进行操作。

<5>[    0.000000] Virtual kernel memory layout:
<5>[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
<5>[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
<5>[    0.000000]     DMA     : 0xff000000 - 0xffe00000   (  14 MB)
<5>[    0.000000]     vmalloc : 0xf0800000 - 0xfc000000   ( 184 MB)
<5>[    0.000000]     lowmem  : 0xc0000000 - 0xf0000000   ( 768 MB)
<5>[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
<5>[    0.000000]       .init : 0xc0008000 - 0xc002d000   ( 148 kB)
<5>[    0.000000]       .text : 0xc002d000 - 0xc0579000   (5424 kB)
<5>[    0.000000]       .data : 0xc057a000 - 0xc05c0ec0   ( 284 kB)


<6>[    0.245925] s3c_idma_preallocate_buffer:  VA-f08c0000  PA-C0000000  163840bytes

<6>[ 1133.522560] DmaAddr=@c0000000 Total=16384bytes PrdSz=4096 #Prds=4 dma_area=0xf08c0000

      上面红色地址在vmalloc中,说明ioremap是将物理地址映射到vmalloc区。


linux/sound/soc/s3c24xx/s3c-idma.c

static int s3c_idma_preallocate_buffer(struct snd_pcm *pcm, int stream){    struct snd_pcm_substream *substream = pcm->streams[stream].substream;    struct snd_dma_buffer *buf = &substream->dma_buffer;    pr_debug("Entered %s\n", __func__);    buf->dev.dev = pcm->card->dev;    buf->private_data = NULL;    /* Assign PCM buffer pointers */    buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS;    buf->addr = LP_TXBUFF_ADDR;    buf->bytes = s3c_idma_hardware.buffer_bytes_max;    buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes);    pr_info("%s:  VA-%p  PA-%X  %ubytes\n",            __func__, buf->area, buf->addr, buf->bytes);    return 0;}
linux/sound/soc/s3c24xx/s3c-idma.h
#define LP_TXBUFF_ADDR    (0xC0000000)

    如下图为s5pv210中的地址分布图,其中0xC000_0000~0xCFFFF_FFFF为Low Power Audio SRAM.



2. 录音

      录音使用外部DMA方式,申请的是外部RAM,就是我们的物理内存。

<6>[ 1358.710296] DmaAddr=@2fe80000 Total=16384bytes PrdSz=4096 #Prds=4 dma_area=0xff007000

      通过上面log可以知道申请的物理地址为0x2fe80000,映射linux内核地址0xff007000,可以知道这是内核

DMA虚拟地址。

      申请DMA函数:dma_alloc_writecombine()

linux/sound/soc/s3c24xx/s3c-dma.c

static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream){    struct snd_pcm_substream *substream = pcm->streams[stream].substream;    struct snd_dma_buffer *buf = &substream->dma_buffer;    size_t size = s3c_dma_hardware.buffer_bytes_max;    pr_debug("Entered %s\n", __func__);    buf->dev.type = SNDRV_DMA_TYPE_DEV;    buf->dev.dev = pcm->card->dev;    buf->private_data = NULL;    buf->area = dma_alloc_writecombine(pcm->card->dev, size,                       &buf->addr, GFP_KERNEL);    if (!buf->area)        return -ENOMEM;    buf->bytes = size;    return 0;}