xref: /linux-6.15/include/linux/swiotlb.h (revision 158dbe9c)
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 /**
65*158dbe9cSPetr 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.
75*158dbe9cSPetr Tesarik  * @nslabs:	The number of IO TLB slots between @start and @end. For the
76*158dbe9cSPetr Tesarik  *		default swiotlb, this can be adjusted with a boot parameter,
77*158dbe9cSPetr Tesarik  *		see setup_io_tlb_npages().
78*158dbe9cSPetr Tesarik  * @late_alloc:	%true if allocated using the page allocator.
79*158dbe9cSPetr Tesarik  * @nareas:	Number of areas in the pool.
80*158dbe9cSPetr Tesarik  * @area_nslabs: Number of slots in each area.
81*158dbe9cSPetr Tesarik  * @areas:	Array of memory area descriptors.
82*158dbe9cSPetr Tesarik  * @slots:	Array of slot descriptors.
83*158dbe9cSPetr Tesarik  */
84*158dbe9cSPetr Tesarik struct io_tlb_pool {
85*158dbe9cSPetr Tesarik 	phys_addr_t start;
86*158dbe9cSPetr Tesarik 	phys_addr_t end;
87*158dbe9cSPetr Tesarik 	void *vaddr;
88*158dbe9cSPetr Tesarik 	unsigned long nslabs;
89*158dbe9cSPetr Tesarik 	bool late_alloc;
90*158dbe9cSPetr Tesarik 	unsigned int nareas;
91*158dbe9cSPetr Tesarik 	unsigned int area_nslabs;
92*158dbe9cSPetr Tesarik 	struct io_tlb_area *areas;
93*158dbe9cSPetr Tesarik 	struct io_tlb_slot *slots;
94*158dbe9cSPetr Tesarik };
95*158dbe9cSPetr Tesarik 
96*158dbe9cSPetr Tesarik /**
97*158dbe9cSPetr Tesarik  * struct io_tlb_mem - Software IO TLB allocator
98*158dbe9cSPetr Tesarik  * @defpool:	Default (initial) IO TLB memory pool descriptor.
99*158dbe9cSPetr 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
1038b0977ecSMichael Kelley  * @total_used:	The total number of slots in the pool that are currently used
1048b0977ecSMichael Kelley  *		across all areas. Used only for calculating used_hiwater in
1058b0977ecSMichael Kelley  *		debugfs.
1068b0977ecSMichael Kelley  * @used_hiwater: The high water mark for total_used.  Used only for reporting
1078b0977ecSMichael Kelley  *		in debugfs.
10873f62095SClaire Chang  */
10973f62095SClaire Chang struct io_tlb_mem {
110*158dbe9cSPetr Tesarik 	struct io_tlb_pool defpool;
11173f62095SClaire Chang 	unsigned long nslabs;
11273f62095SClaire Chang 	struct dentry *debugfs;
113903cd0f3SClaire Chang 	bool force_bounce;
114f4111e39SClaire Chang 	bool for_alloc;
115ec274affSPetr Tesarik #ifdef CONFIG_DEBUG_FS
1168b0977ecSMichael Kelley 	atomic_long_t total_used;
1178b0977ecSMichael Kelley 	atomic_long_t used_hiwater;
118ec274affSPetr Tesarik #endif
11973f62095SClaire Chang };
12055897af6SChristoph Hellwig 
121fea18777SPetr Tesarik /**
122fea18777SPetr Tesarik  * is_swiotlb_buffer() - check if a physical address belongs to a swiotlb
123fea18777SPetr Tesarik  * @dev:        Device which has mapped the buffer.
124fea18777SPetr Tesarik  * @paddr:      Physical address within the DMA buffer.
125fea18777SPetr Tesarik  *
126fea18777SPetr Tesarik  * Check if @paddr points into a bounce buffer.
127fea18777SPetr Tesarik  *
128fea18777SPetr Tesarik  * Return:
129fea18777SPetr Tesarik  * * %true if @paddr points into a bounce buffer
130fea18777SPetr Tesarik  * * %false otherwise
131fea18777SPetr Tesarik  */
1327fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
13355897af6SChristoph Hellwig {
1347fd856aaSClaire Chang 	struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
13573f62095SClaire Chang 
136*158dbe9cSPetr Tesarik 	return mem && paddr >= mem->defpool.start && paddr < mem->defpool.end;
13755897af6SChristoph Hellwig }
13855897af6SChristoph Hellwig 
139903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
140903cd0f3SClaire Chang {
141903cd0f3SClaire Chang 	struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
142903cd0f3SClaire Chang 
143903cd0f3SClaire Chang 	return mem && mem->force_bounce;
144903cd0f3SClaire Chang }
145903cd0f3SClaire Chang 
146c6af2aa9SChristoph Hellwig void swiotlb_init(bool addressing_limited, unsigned int flags);
14755897af6SChristoph Hellwig void __init swiotlb_exit(void);
14805ee7741SPetr Tesarik void swiotlb_dev_init(struct device *dev);
149abe420bfSJoerg Roedel size_t swiotlb_max_mapping_size(struct device *dev);
15005ee7741SPetr Tesarik bool is_swiotlb_allocated(void);
1516f2beb26SClaire Chang bool is_swiotlb_active(struct device *dev);
1522d29960aSChristoph Hellwig void __init swiotlb_adjust_size(unsigned long size);
15305ee7741SPetr Tesarik phys_addr_t default_swiotlb_base(void);
15405ee7741SPetr Tesarik phys_addr_t default_swiotlb_limit(void);
1555740afdbSFUJITA Tomonori #else
156c6af2aa9SChristoph Hellwig static inline void swiotlb_init(bool addressing_limited, unsigned int flags)
157c6af2aa9SChristoph Hellwig {
158c6af2aa9SChristoph Hellwig }
15905ee7741SPetr Tesarik 
16005ee7741SPetr Tesarik static inline void swiotlb_dev_init(struct device *dev)
16105ee7741SPetr Tesarik {
16205ee7741SPetr Tesarik }
16305ee7741SPetr Tesarik 
1647fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
16555897af6SChristoph Hellwig {
16655897af6SChristoph Hellwig 	return false;
16755897af6SChristoph Hellwig }
168903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
169903cd0f3SClaire Chang {
170903cd0f3SClaire Chang 	return false;
171903cd0f3SClaire Chang }
17255897af6SChristoph Hellwig static inline void swiotlb_exit(void)
17355897af6SChristoph Hellwig {
17455897af6SChristoph Hellwig }
175abe420bfSJoerg Roedel static inline size_t swiotlb_max_mapping_size(struct device *dev)
176abe420bfSJoerg Roedel {
177abe420bfSJoerg Roedel 	return SIZE_MAX;
178abe420bfSJoerg Roedel }
179492366f7SJoerg Roedel 
18005ee7741SPetr Tesarik static inline bool is_swiotlb_allocated(void)
18105ee7741SPetr Tesarik {
18205ee7741SPetr Tesarik 	return false;
18305ee7741SPetr Tesarik }
18405ee7741SPetr Tesarik 
1856f2beb26SClaire Chang static inline bool is_swiotlb_active(struct device *dev)
186492366f7SJoerg Roedel {
187492366f7SJoerg Roedel 	return false;
188492366f7SJoerg Roedel }
189e998879dSAshish Kalra 
1902d29960aSChristoph Hellwig static inline void swiotlb_adjust_size(unsigned long size)
191e998879dSAshish Kalra {
192e998879dSAshish Kalra }
19305ee7741SPetr Tesarik 
19405ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_base(void)
19505ee7741SPetr Tesarik {
19605ee7741SPetr Tesarik 	return 0;
19705ee7741SPetr Tesarik }
19805ee7741SPetr Tesarik 
19905ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_limit(void)
20005ee7741SPetr Tesarik {
20105ee7741SPetr Tesarik 	return 0;
20205ee7741SPetr Tesarik }
20355897af6SChristoph Hellwig #endif /* CONFIG_SWIOTLB */
2045740afdbSFUJITA Tomonori 
205ad32e8cbSFUJITA Tomonori extern void swiotlb_print_info(void);
2069c5a3621SAkinobu Mita 
207f4111e39SClaire Chang #ifdef CONFIG_DMA_RESTRICTED_POOL
208f4111e39SClaire Chang struct page *swiotlb_alloc(struct device *dev, size_t size);
209f4111e39SClaire Chang bool swiotlb_free(struct device *dev, struct page *page, size_t size);
210f4111e39SClaire Chang 
211f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
212f4111e39SClaire Chang {
213f4111e39SClaire Chang 	return dev->dma_io_tlb_mem->for_alloc;
214f4111e39SClaire Chang }
215f4111e39SClaire Chang #else
216f4111e39SClaire Chang static inline struct page *swiotlb_alloc(struct device *dev, size_t size)
217f4111e39SClaire Chang {
218f4111e39SClaire Chang 	return NULL;
219f4111e39SClaire Chang }
220f4111e39SClaire Chang static inline bool swiotlb_free(struct device *dev, struct page *page,
221f4111e39SClaire Chang 				size_t size)
222f4111e39SClaire Chang {
223f4111e39SClaire Chang 	return false;
224f4111e39SClaire Chang }
225f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
226f4111e39SClaire Chang {
227f4111e39SClaire Chang 	return false;
228f4111e39SClaire Chang }
229f4111e39SClaire Chang #endif /* CONFIG_DMA_RESTRICTED_POOL */
230f4111e39SClaire Chang 
2311648993fSJoerg Roedel #endif /* __LINUX_SWIOTLB_H */
232