Branch data Line data Source code
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 : : 14 : : struct device; 15 : : 16 : : /* 17 : : * buffer device info 18 : : */ 19 : : struct snd_dma_device { 20 : : int type; /* SNDRV_DMA_TYPE_XXX */ 21 : : struct device *dev; /* generic device */ 22 : : }; 23 : : 24 : : #define snd_dma_continuous_data(x) ((struct device *)(__force unsigned long)(x)) 25 : : 26 : : 27 : : /* 28 : : * buffer types 29 : : */ 30 : : #define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */ 31 : : #define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */ 32 : : #define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */ 33 : : #define SNDRV_DMA_TYPE_DEV_UC 5 /* continuous non-cahced */ 34 : : #ifdef CONFIG_SND_DMA_SGBUF 35 : : #define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */ 36 : : #define SNDRV_DMA_TYPE_DEV_UC_SG 6 /* SG non-cached */ 37 : : #else 38 : : #define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */ 39 : : #define SNDRV_DMA_TYPE_DEV_UC_SG SNDRV_DMA_TYPE_DEV_UC 40 : : #endif 41 : : #ifdef CONFIG_GENERIC_ALLOCATOR 42 : : #define SNDRV_DMA_TYPE_DEV_IRAM 4 /* generic device iram-buffer */ 43 : : #else 44 : : #define SNDRV_DMA_TYPE_DEV_IRAM SNDRV_DMA_TYPE_DEV 45 : : #endif 46 : : #define SNDRV_DMA_TYPE_VMALLOC 7 /* vmalloc'ed buffer */ 47 : : 48 : : /* 49 : : * info for buffer allocation 50 : : */ 51 : : struct 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 : : */ 62 : 0 : static inline unsigned int snd_sgbuf_aligned_pages(size_t size) 63 : : { 64 : 0 : return (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 65 : : } 66 : : 67 : : #ifdef CONFIG_SND_DMA_SGBUF 68 : : /* 69 : : * Scatter-Gather generic device pages 70 : : */ 71 : : void *snd_malloc_sgbuf_pages(struct device *device, 72 : : size_t size, struct snd_dma_buffer *dmab, 73 : : size_t *res_size); 74 : : int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab); 75 : : 76 : : struct snd_sg_page { 77 : : void *buf; 78 : : dma_addr_t addr; 79 : : }; 80 : : 81 : : struct 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 : : */ 93 : : static 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 : : */ 105 : : static 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 : : 112 : : unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab, 113 : : unsigned int ofs, unsigned int size); 114 : : #else 115 : : /* non-SG versions */ 116 : : static 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 : : 122 : : static 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 */ 133 : : int snd_dma_alloc_pages(int type, struct device *dev, size_t size, 134 : : struct snd_dma_buffer *dmab); 135 : : int snd_dma_alloc_pages_fallback(int type, struct device *dev, size_t size, 136 : : struct snd_dma_buffer *dmab); 137 : : void snd_dma_free_pages(struct snd_dma_buffer *dmab); 138 : : 139 : : #endif /* __SOUND_MEMALLOC_H */ 140 : :