11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21da177e4SLinus Torvalds /* 3c1017a4cSJaroslav Kysela * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 41da177e4SLinus Torvalds * Takashi Iwai <tiwai@suse.de> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Generic memory allocators 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds 91da177e4SLinus Torvalds #ifndef __SOUND_MEMALLOC_H 101da177e4SLinus Torvalds #define __SOUND_MEMALLOC_H 111da177e4SLinus Torvalds 12*a25684a9STakashi Iwai #include <linux/dma-direction.h> 1383fbcaedSTakashi Iwai #include <asm/page.h> 1483fbcaedSTakashi Iwai 151da177e4SLinus Torvalds struct device; 16a202bd1aSTakashi Iwai struct vm_area_struct; 17*a25684a9STakashi Iwai struct sg_table; 181da177e4SLinus Torvalds 191da177e4SLinus Torvalds /* 201da177e4SLinus Torvalds * buffer device info 211da177e4SLinus Torvalds */ 221da177e4SLinus Torvalds struct snd_dma_device { 231da177e4SLinus Torvalds int type; /* SNDRV_DMA_TYPE_XXX */ 24*a25684a9STakashi Iwai enum dma_data_direction dir; /* DMA direction */ 25*a25684a9STakashi Iwai bool need_sync; /* explicit sync needed? */ 261da177e4SLinus Torvalds struct device *dev; /* generic device */ 271da177e4SLinus Torvalds }; 281da177e4SLinus Torvalds 29019d80dbSAntonio Ospite #define snd_dma_continuous_data(x) ((struct device *)(__force unsigned long)(x)) 301da177e4SLinus Torvalds 311da177e4SLinus Torvalds 321da177e4SLinus Torvalds /* 331da177e4SLinus Torvalds * buffer types 341da177e4SLinus Torvalds */ 351da177e4SLinus Torvalds #define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */ 361da177e4SLinus Torvalds #define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */ 371da177e4SLinus Torvalds #define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */ 3858a95dfaSTakashi Iwai #define SNDRV_DMA_TYPE_DEV_WC 5 /* continuous write-combined */ 39cc6a8acdSTakashi Iwai #ifdef CONFIG_SND_DMA_SGBUF 401da177e4SLinus Torvalds #define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */ 4158a95dfaSTakashi Iwai #define SNDRV_DMA_TYPE_DEV_WC_SG 6 /* SG write-combined */ 42cc6a8acdSTakashi Iwai #else 43cc6a8acdSTakashi Iwai #define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */ 4458a95dfaSTakashi Iwai #define SNDRV_DMA_TYPE_DEV_WC_SG SNDRV_DMA_TYPE_DEV_WC 45cc6a8acdSTakashi Iwai #endif 46a5606f85STakashi Iwai #ifdef CONFIG_GENERIC_ALLOCATOR 4705503214SNicolin Chen #define SNDRV_DMA_TYPE_DEV_IRAM 4 /* generic device iram-buffer */ 48a5606f85STakashi Iwai #else 49a5606f85STakashi Iwai #define SNDRV_DMA_TYPE_DEV_IRAM SNDRV_DMA_TYPE_DEV 50a5606f85STakashi Iwai #endif 511fe7f397STakashi Iwai #define SNDRV_DMA_TYPE_VMALLOC 7 /* vmalloc'ed buffer */ 52*a25684a9STakashi Iwai #define SNDRV_DMA_TYPE_NONCONTIG 8 /* non-coherent SG buffer */ 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds /* 551da177e4SLinus Torvalds * info for buffer allocation 561da177e4SLinus Torvalds */ 571da177e4SLinus Torvalds struct snd_dma_buffer { 581da177e4SLinus Torvalds struct snd_dma_device dev; /* device type */ 591da177e4SLinus Torvalds unsigned char *area; /* virtual pointer */ 601da177e4SLinus Torvalds dma_addr_t addr; /* physical address */ 611da177e4SLinus Torvalds size_t bytes; /* buffer size in bytes */ 621da177e4SLinus Torvalds void *private_data; /* private for allocator; don't touch */ 631da177e4SLinus Torvalds }; 641da177e4SLinus Torvalds 654cae99d9SPierre-Louis Bossart /* 664cae99d9SPierre-Louis Bossart * return the pages matching with the given byte size 674cae99d9SPierre-Louis Bossart */ 684cae99d9SPierre-Louis Bossart static inline unsigned int snd_sgbuf_aligned_pages(size_t size) 694cae99d9SPierre-Louis Bossart { 704cae99d9SPierre-Louis Bossart return (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 714cae99d9SPierre-Louis Bossart } 724cae99d9SPierre-Louis Bossart 731da177e4SLinus Torvalds /* allocate/release a buffer */ 74*a25684a9STakashi Iwai int snd_dma_alloc_dir_pages(int type, struct device *dev, 75*a25684a9STakashi Iwai enum dma_data_direction dir, size_t size, 761da177e4SLinus Torvalds struct snd_dma_buffer *dmab); 77*a25684a9STakashi Iwai 78*a25684a9STakashi Iwai static inline int snd_dma_alloc_pages(int type, struct device *dev, 79*a25684a9STakashi Iwai size_t size, struct snd_dma_buffer *dmab) 80*a25684a9STakashi Iwai { 81*a25684a9STakashi Iwai return snd_dma_alloc_dir_pages(type, dev, DMA_BIDIRECTIONAL, size, dmab); 82*a25684a9STakashi Iwai } 83*a25684a9STakashi Iwai 841da177e4SLinus Torvalds int snd_dma_alloc_pages_fallback(int type, struct device *dev, size_t size, 851da177e4SLinus Torvalds struct snd_dma_buffer *dmab); 861da177e4SLinus Torvalds void snd_dma_free_pages(struct snd_dma_buffer *dmab); 87a202bd1aSTakashi Iwai int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab, 88a202bd1aSTakashi Iwai struct vm_area_struct *area); 891da177e4SLinus Torvalds 90*a25684a9STakashi Iwai enum snd_dma_sync_mode { SNDRV_DMA_SYNC_CPU, SNDRV_DMA_SYNC_DEVICE }; 91*a25684a9STakashi Iwai #ifdef CONFIG_HAS_DMA 92*a25684a9STakashi Iwai void snd_dma_buffer_sync(struct snd_dma_buffer *dmab, 93*a25684a9STakashi Iwai enum snd_dma_sync_mode mode); 94*a25684a9STakashi Iwai #else 95*a25684a9STakashi Iwai static inline void snd_dma_buffer_sync(struct snd_dma_buffer *dmab, 96*a25684a9STakashi Iwai enum snd_dma_sync_mode mode) {} 97*a25684a9STakashi Iwai #endif 98*a25684a9STakashi Iwai 99*a25684a9STakashi Iwai void snd_dma_buffer_sync(struct snd_dma_buffer *dmab, 100*a25684a9STakashi Iwai enum snd_dma_sync_mode mode); 101*a25684a9STakashi Iwai 10237af81c5STakashi Iwai dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, size_t offset); 10337af81c5STakashi Iwai struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset); 10437af81c5STakashi Iwai unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab, 10537af81c5STakashi Iwai unsigned int ofs, unsigned int size); 10637af81c5STakashi Iwai 107427ae268STakashi Iwai /* device-managed memory allocator */ 108*a25684a9STakashi Iwai struct snd_dma_buffer *snd_devm_alloc_dir_pages(struct device *dev, int type, 109*a25684a9STakashi Iwai enum dma_data_direction dir, 110427ae268STakashi Iwai size_t size); 111427ae268STakashi Iwai 112*a25684a9STakashi Iwai static inline struct snd_dma_buffer * 113*a25684a9STakashi Iwai snd_devm_alloc_pages(struct device *dev, int type, size_t size) 114*a25684a9STakashi Iwai { 115*a25684a9STakashi Iwai return snd_devm_alloc_dir_pages(dev, type, DMA_BIDIRECTIONAL, size); 116*a25684a9STakashi Iwai } 117*a25684a9STakashi Iwai 118*a25684a9STakashi Iwai static inline struct sg_table * 119*a25684a9STakashi Iwai snd_dma_noncontig_sg_table(struct snd_dma_buffer *dmab) 120*a25684a9STakashi Iwai { 121*a25684a9STakashi Iwai return dmab->private_data; 122*a25684a9STakashi Iwai } 123*a25684a9STakashi Iwai 1241da177e4SLinus Torvalds #endif /* __SOUND_MEMALLOC_H */ 1251da177e4SLinus Torvalds 126