linux/include/sound/memalloc.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   4 *                   Takashi Iwai <tiwai@suse.de>
   5 * 
   6 *  Generic memory allocators
   7 */
   8
   9#ifndef __SOUND_MEMALLOC_H
  10#define __SOUND_MEMALLOC_H
  11
  12#include <asm/page.h>
  13
  14struct device;
  15
  16/*
  17 * buffer device info
  18 */
  19struct snd_dma_device {
  20        int type;                       /* SNDRV_DMA_TYPE_XXX */
  21        struct device *dev;             /* generic device */
  22};
  23
  24#define snd_dma_pci_data(pci)   (&(pci)->dev)
  25#define snd_dma_continuous_data(x)      ((struct device *)(__force unsigned long)(x))
  26
  27
  28/*
  29 * buffer types
  30 */
  31#define SNDRV_DMA_TYPE_UNKNOWN          0       /* not defined */
  32#define SNDRV_DMA_TYPE_CONTINUOUS       1       /* continuous no-DMA memory */
  33#define SNDRV_DMA_TYPE_DEV              2       /* generic device continuous */
  34#define SNDRV_DMA_TYPE_DEV_UC           5       /* continuous non-cahced */
  35#ifdef CONFIG_SND_DMA_SGBUF
  36#define SNDRV_DMA_TYPE_DEV_SG           3       /* generic device SG-buffer */
  37#define SNDRV_DMA_TYPE_DEV_UC_SG        6       /* SG non-cached */
  38#else
  39#define SNDRV_DMA_TYPE_DEV_SG   SNDRV_DMA_TYPE_DEV /* no SG-buf support */
  40#define SNDRV_DMA_TYPE_DEV_UC_SG        SNDRV_DMA_TYPE_DEV_UC
  41#endif
  42#ifdef CONFIG_GENERIC_ALLOCATOR
  43#define SNDRV_DMA_TYPE_DEV_IRAM         4       /* generic device iram-buffer */
  44#else
  45#define SNDRV_DMA_TYPE_DEV_IRAM SNDRV_DMA_TYPE_DEV
  46#endif
  47
  48/*
  49 * info for buffer allocation
  50 */
  51struct snd_dma_buffer {
  52        struct snd_dma_device dev;      /* device type */
  53        unsigned char *area;    /* virtual pointer */
  54        dma_addr_t addr;        /* physical address */
  55        size_t bytes;           /* buffer size in bytes */
  56        void *private_data;     /* private for allocator; don't touch */
  57};
  58
  59/*
  60 * return the pages matching with the given byte size
  61 */
  62static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
  63{
  64        return (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  65}
  66
  67#ifdef CONFIG_SND_DMA_SGBUF
  68/*
  69 * Scatter-Gather generic device pages
  70 */
  71void *snd_malloc_sgbuf_pages(struct device *device,
  72                             size_t size, struct snd_dma_buffer *dmab,
  73                             size_t *res_size);
  74int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
  75
  76struct snd_sg_page {
  77        void *buf;
  78        dma_addr_t addr;
  79};
  80
  81struct snd_sg_buf {
  82        int size;       /* allocated byte size */
  83        int pages;      /* allocated pages */
  84        int tblsize;    /* allocated table size */
  85        struct snd_sg_page *table;      /* address table */
  86        struct page **page_table;       /* page table (for vmap/vunmap) */
  87        struct device *dev;
  88};
  89
  90/*
  91 * return the physical address at the corresponding offset
  92 */
  93static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
  94                                           size_t offset)
  95{
  96        struct snd_sg_buf *sgbuf = dmab->private_data;
  97        dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
  98        addr &= ~((dma_addr_t)PAGE_SIZE - 1);
  99        return addr + offset % PAGE_SIZE;
 100}
 101
 102/*
 103 * return the virtual address at the corresponding offset
 104 */
 105static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
 106                                     size_t offset)
 107{
 108        struct snd_sg_buf *sgbuf = dmab->private_data;
 109        return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
 110}
 111
 112unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
 113                                      unsigned int ofs, unsigned int size);
 114#else
 115/* non-SG versions */
 116static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
 117                                            size_t offset)
 118{
 119        return dmab->addr + offset;
 120}
 121
 122static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
 123                                      size_t offset)
 124{
 125        return dmab->area + offset;
 126}
 127
 128#define snd_sgbuf_get_chunk_size(dmab, ofs, size)       (size)
 129
 130#endif /* CONFIG_SND_DMA_SGBUF */
 131
 132/* allocate/release a buffer */
 133int snd_dma_alloc_pages(int type, struct device *dev, size_t size,
 134                        struct snd_dma_buffer *dmab);
 135int snd_dma_alloc_pages_fallback(int type, struct device *dev, size_t size,
 136                                 struct snd_dma_buffer *dmab);
 137void snd_dma_free_pages(struct snd_dma_buffer *dmab);
 138
 139#endif /* __SOUND_MEMALLOC_H */
 140
 141