Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
0004  *                   Takashi Iwai <tiwai@suse.de>
0005  * 
0006  *  Generic memory allocators
0007  */
0008 
0009 #ifndef __SOUND_MEMALLOC_H
0010 #define __SOUND_MEMALLOC_H
0011 
0012 #include <linux/dma-direction.h>
0013 #include <asm/page.h>
0014 
0015 struct device;
0016 struct vm_area_struct;
0017 struct sg_table;
0018 
0019 /*
0020  * buffer device info
0021  */
0022 struct snd_dma_device {
0023     int type;           /* SNDRV_DMA_TYPE_XXX */
0024     enum dma_data_direction dir;    /* DMA direction */
0025     bool need_sync;         /* explicit sync needed? */
0026     struct device *dev;     /* generic device */
0027 };
0028 
0029 #define snd_dma_continuous_data(x)  ((struct device *)(__force unsigned long)(x))
0030 
0031 
0032 /*
0033  * buffer types
0034  */
0035 #define SNDRV_DMA_TYPE_UNKNOWN      0   /* not defined */
0036 #define SNDRV_DMA_TYPE_CONTINUOUS   1   /* continuous no-DMA memory */
0037 #define SNDRV_DMA_TYPE_DEV      2   /* generic device continuous */
0038 #define SNDRV_DMA_TYPE_DEV_WC       5   /* continuous write-combined */
0039 #ifdef CONFIG_GENERIC_ALLOCATOR
0040 #define SNDRV_DMA_TYPE_DEV_IRAM     4   /* generic device iram-buffer */
0041 #else
0042 #define SNDRV_DMA_TYPE_DEV_IRAM SNDRV_DMA_TYPE_DEV
0043 #endif
0044 #define SNDRV_DMA_TYPE_VMALLOC      7   /* vmalloc'ed buffer */
0045 #define SNDRV_DMA_TYPE_NONCONTIG    8   /* non-coherent SG buffer */
0046 #define SNDRV_DMA_TYPE_NONCOHERENT  9   /* non-coherent buffer */
0047 #ifdef CONFIG_SND_DMA_SGBUF
0048 #define SNDRV_DMA_TYPE_DEV_SG       SNDRV_DMA_TYPE_NONCONTIG
0049 #define SNDRV_DMA_TYPE_DEV_WC_SG    6   /* SG write-combined */
0050 #else
0051 #define SNDRV_DMA_TYPE_DEV_SG   SNDRV_DMA_TYPE_DEV /* no SG-buf support */
0052 #define SNDRV_DMA_TYPE_DEV_WC_SG    SNDRV_DMA_TYPE_DEV_WC
0053 #endif
0054 /* fallback types, don't use those directly */
0055 #ifdef CONFIG_SND_DMA_SGBUF
0056 #define SNDRV_DMA_TYPE_DEV_SG_FALLBACK      10
0057 #define SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK   11
0058 #endif
0059 
0060 /*
0061  * info for buffer allocation
0062  */
0063 struct snd_dma_buffer {
0064     struct snd_dma_device dev;  /* device type */
0065     unsigned char *area;    /* virtual pointer */
0066     dma_addr_t addr;    /* physical address */
0067     size_t bytes;       /* buffer size in bytes */
0068     void *private_data; /* private for allocator; don't touch */
0069 };
0070 
0071 /*
0072  * return the pages matching with the given byte size
0073  */
0074 static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
0075 {
0076     return (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
0077 }
0078 
0079 /* allocate/release a buffer */
0080 int snd_dma_alloc_dir_pages(int type, struct device *dev,
0081                 enum dma_data_direction dir, size_t size,
0082                 struct snd_dma_buffer *dmab);
0083 
0084 static inline int snd_dma_alloc_pages(int type, struct device *dev,
0085                       size_t size, struct snd_dma_buffer *dmab)
0086 {
0087     return snd_dma_alloc_dir_pages(type, dev, DMA_BIDIRECTIONAL, size, dmab);
0088 }
0089 
0090 int snd_dma_alloc_pages_fallback(int type, struct device *dev, size_t size,
0091                                  struct snd_dma_buffer *dmab);
0092 void snd_dma_free_pages(struct snd_dma_buffer *dmab);
0093 int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab,
0094             struct vm_area_struct *area);
0095 
0096 enum snd_dma_sync_mode { SNDRV_DMA_SYNC_CPU, SNDRV_DMA_SYNC_DEVICE };
0097 #ifdef CONFIG_HAS_DMA
0098 void snd_dma_buffer_sync(struct snd_dma_buffer *dmab,
0099              enum snd_dma_sync_mode mode);
0100 #else
0101 static inline void snd_dma_buffer_sync(struct snd_dma_buffer *dmab,
0102                        enum snd_dma_sync_mode mode) {}
0103 #endif
0104 
0105 dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, size_t offset);
0106 struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset);
0107 unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
0108                       unsigned int ofs, unsigned int size);
0109 
0110 /* device-managed memory allocator */
0111 struct snd_dma_buffer *snd_devm_alloc_dir_pages(struct device *dev, int type,
0112                         enum dma_data_direction dir,
0113                         size_t size);
0114 
0115 static inline struct snd_dma_buffer *
0116 snd_devm_alloc_pages(struct device *dev, int type, size_t size)
0117 {
0118     return snd_devm_alloc_dir_pages(dev, type, DMA_BIDIRECTIONAL, size);
0119 }
0120 
0121 static inline struct sg_table *
0122 snd_dma_noncontig_sg_table(struct snd_dma_buffer *dmab)
0123 {
0124     return dmab->private_data;
0125 }
0126 
0127 #endif /* __SOUND_MEMALLOC_H */
0128