1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21648993fSJoerg Roedel #ifndef __LINUX_SWIOTLB_H 31648993fSJoerg Roedel #define __LINUX_SWIOTLB_H 41648993fSJoerg Roedel 57fd856aaSClaire Chang #include <linux/device.h> 638674442SThierry Reding #include <linux/dma-direction.h> 738674442SThierry Reding #include <linux/init.h> 81648993fSJoerg Roedel #include <linux/types.h> 9f51778dbSStephen Rothwell #include <linux/limits.h> 1073f62095SClaire Chang #include <linux/spinlock.h> 111648993fSJoerg Roedel 121648993fSJoerg Roedel struct device; 1338674442SThierry Reding struct page; 141648993fSJoerg Roedel struct scatterlist; 151648993fSJoerg Roedel 16c6af2aa9SChristoph Hellwig #define SWIOTLB_VERBOSE (1 << 0) /* verbose initialization */ 17c6af2aa9SChristoph Hellwig #define SWIOTLB_FORCE (1 << 1) /* force bounce buffering */ 188ba2ed1bSChristoph Hellwig #define SWIOTLB_ANY (1 << 2) /* allow any memory for the buffer */ 19ae7871beSGeert Uytterhoeven 200016fdeeSIan Campbell /* 210016fdeeSIan Campbell * Maximum allowable number of contiguous slabs to map, 220016fdeeSIan Campbell * must be a power of 2. What is the appropriate value ? 230016fdeeSIan Campbell * The complexity of {map,unmap}_single is linearly dependent on this value. 240016fdeeSIan Campbell */ 250016fdeeSIan Campbell #define IO_TLB_SEGSIZE 128 260016fdeeSIan Campbell 270016fdeeSIan Campbell /* 280016fdeeSIan Campbell * log of the size of each IO TLB slab. The number of slabs is command line 290016fdeeSIan Campbell * controllable. 300016fdeeSIan Campbell */ 310016fdeeSIan Campbell #define IO_TLB_SHIFT 11 32b5d7ccb7SChristoph Hellwig #define IO_TLB_SIZE (1 << IO_TLB_SHIFT) 330016fdeeSIan Campbell 34e998879dSAshish Kalra /* default to 64MB */ 35e998879dSAshish Kalra #define IO_TLB_DEFAULT_SIZE (64UL<<20) 36e998879dSAshish Kalra 37c729de8fSYinghai Lu unsigned long swiotlb_size_or_default(void); 387374153dSChristoph Hellwig void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags, 397374153dSChristoph Hellwig int (*remap)(void *tlb, unsigned long nslabs)); 407374153dSChristoph Hellwig int swiotlb_init_late(size_t size, gfp_t gfp_mask, 417374153dSChristoph Hellwig int (*remap)(void *tlb, unsigned long nslabs)); 42c7753208STom Lendacky extern void __init swiotlb_update_mem_attributes(void); 431648993fSJoerg Roedel 44fc0021aaSChristoph Hellwig phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, phys_addr_t phys, 45fc0021aaSChristoph Hellwig size_t mapping_size, size_t alloc_size, 46e81e99baSDavid Stevens unsigned int alloc_aligned_mask, enum dma_data_direction dir, 47e81e99baSDavid Stevens unsigned long attrs); 48d7ef1533SKonrad Rzeszutek Wilk 4961ca08c3SAlexander Duyck extern void swiotlb_tbl_unmap_single(struct device *hwdev, 5061ca08c3SAlexander Duyck phys_addr_t tlb_addr, 513fc1ca00SLu Baolu size_t mapping_size, 523fc1ca00SLu Baolu enum dma_data_direction dir, 530443fa00SAlexander Duyck unsigned long attrs); 54d7ef1533SKonrad Rzeszutek Wilk 5580808d27SChristoph Hellwig void swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr, 5680808d27SChristoph Hellwig size_t size, enum dma_data_direction dir); 5780808d27SChristoph Hellwig void swiotlb_sync_single_for_cpu(struct device *dev, phys_addr_t tlb_addr, 5880808d27SChristoph Hellwig size_t size, enum dma_data_direction dir); 594a47cbaeSChristoph Hellwig dma_addr_t swiotlb_map(struct device *dev, phys_addr_t phys, 604a47cbaeSChristoph Hellwig size_t size, enum dma_data_direction dir, unsigned long attrs); 614a47cbaeSChristoph Hellwig 625740afdbSFUJITA Tomonori #ifdef CONFIG_SWIOTLB 6373f62095SClaire Chang 6473f62095SClaire Chang /** 65158dbe9cSPetr Tesarik * struct io_tlb_pool - IO TLB memory pool descriptor 6673f62095SClaire Chang * @start: The start address of the swiotlb memory pool. Used to do a quick 6773f62095SClaire Chang * range check to see if the memory was in fact allocated by this 6873f62095SClaire Chang * API. 6973f62095SClaire Chang * @end: The end address of the swiotlb memory pool. Used to do a quick 7073f62095SClaire Chang * range check to see if the memory was in fact allocated by this 7173f62095SClaire Chang * API. 721a5e91d8STianyu Lan * @vaddr: The vaddr of the swiotlb memory pool. The swiotlb memory pool 731a5e91d8STianyu Lan * may be remapped in the memory encrypted case and store virtual 741a5e91d8STianyu Lan * address for bounce buffer operation. 75158dbe9cSPetr Tesarik * @nslabs: The number of IO TLB slots between @start and @end. For the 76158dbe9cSPetr Tesarik * default swiotlb, this can be adjusted with a boot parameter, 77158dbe9cSPetr Tesarik * see setup_io_tlb_npages(). 78158dbe9cSPetr Tesarik * @late_alloc: %true if allocated using the page allocator. 79158dbe9cSPetr Tesarik * @nareas: Number of areas in the pool. 80158dbe9cSPetr Tesarik * @area_nslabs: Number of slots in each area. 81158dbe9cSPetr Tesarik * @areas: Array of memory area descriptors. 82158dbe9cSPetr Tesarik * @slots: Array of slot descriptors. 83158dbe9cSPetr Tesarik */ 84158dbe9cSPetr Tesarik struct io_tlb_pool { 85158dbe9cSPetr Tesarik phys_addr_t start; 86158dbe9cSPetr Tesarik phys_addr_t end; 87158dbe9cSPetr Tesarik void *vaddr; 88158dbe9cSPetr Tesarik unsigned long nslabs; 89158dbe9cSPetr Tesarik bool late_alloc; 90158dbe9cSPetr Tesarik unsigned int nareas; 91158dbe9cSPetr Tesarik unsigned int area_nslabs; 92158dbe9cSPetr Tesarik struct io_tlb_area *areas; 93158dbe9cSPetr Tesarik struct io_tlb_slot *slots; 94158dbe9cSPetr Tesarik }; 95158dbe9cSPetr Tesarik 96158dbe9cSPetr Tesarik /** 97158dbe9cSPetr Tesarik * struct io_tlb_mem - Software IO TLB allocator 98158dbe9cSPetr Tesarik * @defpool: Default (initial) IO TLB memory pool descriptor. 99158dbe9cSPetr Tesarik * @nslabs: Total number of IO TLB slabs in all pools. 10073f62095SClaire Chang * @debugfs: The dentry to debugfs. 101903cd0f3SClaire Chang * @force_bounce: %true if swiotlb bouncing is forced 102f4111e39SClaire Chang * @for_alloc: %true if the pool is used for memory allocation 103*62708b2bSPetr Tesarik * @can_grow: %true if more pools can be allocated dynamically. 1048b0977ecSMichael Kelley * @total_used: The total number of slots in the pool that are currently used 1058b0977ecSMichael Kelley * across all areas. Used only for calculating used_hiwater in 1068b0977ecSMichael Kelley * debugfs. 1078b0977ecSMichael Kelley * @used_hiwater: The high water mark for total_used. Used only for reporting 1088b0977ecSMichael Kelley * in debugfs. 10973f62095SClaire Chang */ 11073f62095SClaire Chang struct io_tlb_mem { 111158dbe9cSPetr Tesarik struct io_tlb_pool defpool; 11273f62095SClaire Chang unsigned long nslabs; 11373f62095SClaire Chang struct dentry *debugfs; 114903cd0f3SClaire Chang bool force_bounce; 115f4111e39SClaire Chang bool for_alloc; 116*62708b2bSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC 117*62708b2bSPetr Tesarik bool can_grow; 118*62708b2bSPetr Tesarik #endif 119ec274affSPetr Tesarik #ifdef CONFIG_DEBUG_FS 1208b0977ecSMichael Kelley atomic_long_t total_used; 1218b0977ecSMichael Kelley atomic_long_t used_hiwater; 122ec274affSPetr Tesarik #endif 12373f62095SClaire Chang }; 12455897af6SChristoph Hellwig 125fea18777SPetr Tesarik /** 126fea18777SPetr Tesarik * is_swiotlb_buffer() - check if a physical address belongs to a swiotlb 127fea18777SPetr Tesarik * @dev: Device which has mapped the buffer. 128fea18777SPetr Tesarik * @paddr: Physical address within the DMA buffer. 129fea18777SPetr Tesarik * 130fea18777SPetr Tesarik * Check if @paddr points into a bounce buffer. 131fea18777SPetr Tesarik * 132fea18777SPetr Tesarik * Return: 133fea18777SPetr Tesarik * * %true if @paddr points into a bounce buffer 134fea18777SPetr Tesarik * * %false otherwise 135fea18777SPetr Tesarik */ 1367fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) 13755897af6SChristoph Hellwig { 1387fd856aaSClaire Chang struct io_tlb_mem *mem = dev->dma_io_tlb_mem; 13973f62095SClaire Chang 140158dbe9cSPetr Tesarik return mem && paddr >= mem->defpool.start && paddr < mem->defpool.end; 14155897af6SChristoph Hellwig } 14255897af6SChristoph Hellwig 143903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev) 144903cd0f3SClaire Chang { 145903cd0f3SClaire Chang struct io_tlb_mem *mem = dev->dma_io_tlb_mem; 146903cd0f3SClaire Chang 147903cd0f3SClaire Chang return mem && mem->force_bounce; 148903cd0f3SClaire Chang } 149903cd0f3SClaire Chang 150c6af2aa9SChristoph Hellwig void swiotlb_init(bool addressing_limited, unsigned int flags); 15155897af6SChristoph Hellwig void __init swiotlb_exit(void); 15205ee7741SPetr Tesarik void swiotlb_dev_init(struct device *dev); 153abe420bfSJoerg Roedel size_t swiotlb_max_mapping_size(struct device *dev); 15405ee7741SPetr Tesarik bool is_swiotlb_allocated(void); 1556f2beb26SClaire Chang bool is_swiotlb_active(struct device *dev); 1562d29960aSChristoph Hellwig void __init swiotlb_adjust_size(unsigned long size); 15705ee7741SPetr Tesarik phys_addr_t default_swiotlb_base(void); 15805ee7741SPetr Tesarik phys_addr_t default_swiotlb_limit(void); 1595740afdbSFUJITA Tomonori #else 160c6af2aa9SChristoph Hellwig static inline void swiotlb_init(bool addressing_limited, unsigned int flags) 161c6af2aa9SChristoph Hellwig { 162c6af2aa9SChristoph Hellwig } 16305ee7741SPetr Tesarik 16405ee7741SPetr Tesarik static inline void swiotlb_dev_init(struct device *dev) 16505ee7741SPetr Tesarik { 16605ee7741SPetr Tesarik } 16705ee7741SPetr Tesarik 1687fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) 16955897af6SChristoph Hellwig { 17055897af6SChristoph Hellwig return false; 17155897af6SChristoph Hellwig } 172903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev) 173903cd0f3SClaire Chang { 174903cd0f3SClaire Chang return false; 175903cd0f3SClaire Chang } 17655897af6SChristoph Hellwig static inline void swiotlb_exit(void) 17755897af6SChristoph Hellwig { 17855897af6SChristoph Hellwig } 179abe420bfSJoerg Roedel static inline size_t swiotlb_max_mapping_size(struct device *dev) 180abe420bfSJoerg Roedel { 181abe420bfSJoerg Roedel return SIZE_MAX; 182abe420bfSJoerg Roedel } 183492366f7SJoerg Roedel 18405ee7741SPetr Tesarik static inline bool is_swiotlb_allocated(void) 18505ee7741SPetr Tesarik { 18605ee7741SPetr Tesarik return false; 18705ee7741SPetr Tesarik } 18805ee7741SPetr Tesarik 1896f2beb26SClaire Chang static inline bool is_swiotlb_active(struct device *dev) 190492366f7SJoerg Roedel { 191492366f7SJoerg Roedel return false; 192492366f7SJoerg Roedel } 193e998879dSAshish Kalra 1942d29960aSChristoph Hellwig static inline void swiotlb_adjust_size(unsigned long size) 195e998879dSAshish Kalra { 196e998879dSAshish Kalra } 19705ee7741SPetr Tesarik 19805ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_base(void) 19905ee7741SPetr Tesarik { 20005ee7741SPetr Tesarik return 0; 20105ee7741SPetr Tesarik } 20205ee7741SPetr Tesarik 20305ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_limit(void) 20405ee7741SPetr Tesarik { 20505ee7741SPetr Tesarik return 0; 20605ee7741SPetr Tesarik } 20755897af6SChristoph Hellwig #endif /* CONFIG_SWIOTLB */ 2085740afdbSFUJITA Tomonori 209ad32e8cbSFUJITA Tomonori extern void swiotlb_print_info(void); 2109c5a3621SAkinobu Mita 211f4111e39SClaire Chang #ifdef CONFIG_DMA_RESTRICTED_POOL 212f4111e39SClaire Chang struct page *swiotlb_alloc(struct device *dev, size_t size); 213f4111e39SClaire Chang bool swiotlb_free(struct device *dev, struct page *page, size_t size); 214f4111e39SClaire Chang 215f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev) 216f4111e39SClaire Chang { 217f4111e39SClaire Chang return dev->dma_io_tlb_mem->for_alloc; 218f4111e39SClaire Chang } 219f4111e39SClaire Chang #else 220f4111e39SClaire Chang static inline struct page *swiotlb_alloc(struct device *dev, size_t size) 221f4111e39SClaire Chang { 222f4111e39SClaire Chang return NULL; 223f4111e39SClaire Chang } 224f4111e39SClaire Chang static inline bool swiotlb_free(struct device *dev, struct page *page, 225f4111e39SClaire Chang size_t size) 226f4111e39SClaire Chang { 227f4111e39SClaire Chang return false; 228f4111e39SClaire Chang } 229f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev) 230f4111e39SClaire Chang { 231f4111e39SClaire Chang return false; 232f4111e39SClaire Chang } 233f4111e39SClaire Chang #endif /* CONFIG_DMA_RESTRICTED_POOL */ 234f4111e39SClaire Chang 2351648993fSJoerg Roedel #endif /* __LINUX_SWIOTLB_H */ 236