xref: /linux-6.15/include/linux/swiotlb.h (revision c6af2aa9)
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 
16*c6af2aa9SChristoph Hellwig #define SWIOTLB_VERBOSE	(1 << 0) /* verbose initialization */
17*c6af2aa9SChristoph Hellwig #define SWIOTLB_FORCE	(1 << 1) /* force bounce buffering */
18ae7871beSGeert Uytterhoeven 
190016fdeeSIan Campbell /*
200016fdeeSIan Campbell  * Maximum allowable number of contiguous slabs to map,
210016fdeeSIan Campbell  * must be a power of 2.  What is the appropriate value ?
220016fdeeSIan Campbell  * The complexity of {map,unmap}_single is linearly dependent on this value.
230016fdeeSIan Campbell  */
240016fdeeSIan Campbell #define IO_TLB_SEGSIZE	128
250016fdeeSIan Campbell 
260016fdeeSIan Campbell /*
270016fdeeSIan Campbell  * log of the size of each IO TLB slab.  The number of slabs is command line
280016fdeeSIan Campbell  * controllable.
290016fdeeSIan Campbell  */
300016fdeeSIan Campbell #define IO_TLB_SHIFT 11
31b5d7ccb7SChristoph Hellwig #define IO_TLB_SIZE (1 << IO_TLB_SHIFT)
320016fdeeSIan Campbell 
33e998879dSAshish Kalra /* default to 64MB */
34e998879dSAshish Kalra #define IO_TLB_DEFAULT_SIZE (64UL<<20)
35e998879dSAshish Kalra 
36*c6af2aa9SChristoph Hellwig int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, unsigned int flags);
37c729de8fSYinghai Lu unsigned long swiotlb_size_or_default(void);
3874838b75SKonrad Rzeszutek Wilk extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs);
390d5ffd9aSChristoph Hellwig int swiotlb_init_late(size_t size);
40c7753208STom Lendacky extern void __init swiotlb_update_mem_attributes(void);
411648993fSJoerg Roedel 
42fc0021aaSChristoph Hellwig phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, phys_addr_t phys,
43fc0021aaSChristoph Hellwig 		size_t mapping_size, size_t alloc_size,
44e81e99baSDavid Stevens 		unsigned int alloc_aligned_mask, enum dma_data_direction dir,
45e81e99baSDavid Stevens 		unsigned long attrs);
46d7ef1533SKonrad Rzeszutek Wilk 
4761ca08c3SAlexander Duyck extern void swiotlb_tbl_unmap_single(struct device *hwdev,
4861ca08c3SAlexander Duyck 				     phys_addr_t tlb_addr,
493fc1ca00SLu Baolu 				     size_t mapping_size,
503fc1ca00SLu Baolu 				     enum dma_data_direction dir,
510443fa00SAlexander Duyck 				     unsigned long attrs);
52d7ef1533SKonrad Rzeszutek Wilk 
5380808d27SChristoph Hellwig void swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr,
5480808d27SChristoph Hellwig 		size_t size, enum dma_data_direction dir);
5580808d27SChristoph Hellwig void swiotlb_sync_single_for_cpu(struct device *dev, phys_addr_t tlb_addr,
5680808d27SChristoph Hellwig 		size_t size, enum dma_data_direction dir);
574a47cbaeSChristoph Hellwig dma_addr_t swiotlb_map(struct device *dev, phys_addr_t phys,
584a47cbaeSChristoph Hellwig 		size_t size, enum dma_data_direction dir, unsigned long attrs);
594a47cbaeSChristoph Hellwig 
605740afdbSFUJITA Tomonori #ifdef CONFIG_SWIOTLB
6155897af6SChristoph Hellwig extern enum swiotlb_force swiotlb_force;
6273f62095SClaire Chang 
6373f62095SClaire Chang /**
6473f62095SClaire Chang  * struct io_tlb_mem - IO TLB Memory Pool Descriptor
6573f62095SClaire Chang  *
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.
7573f62095SClaire Chang  * @nslabs:	The number of IO TLB blocks (in groups of 64) between @start and
760b84e4f8SClaire Chang  *		@end. For default swiotlb, this is command line adjustable via
770b84e4f8SClaire Chang  *		setup_io_tlb_npages.
7873f62095SClaire Chang  * @used:	The number of used IO TLB block.
7973f62095SClaire Chang  * @list:	The free list describing the number of free entries available
8073f62095SClaire Chang  *		from each index.
8173f62095SClaire Chang  * @index:	The index to start searching in the next round.
8273f62095SClaire Chang  * @orig_addr:	The original address corresponding to a mapped entry.
8373f62095SClaire Chang  * @alloc_size:	Size of the allocated buffer.
8473f62095SClaire Chang  * @lock:	The lock to protect the above data structures in the map and
8573f62095SClaire Chang  *		unmap calls.
8673f62095SClaire Chang  * @debugfs:	The dentry to debugfs.
8773f62095SClaire Chang  * @late_alloc:	%true if allocated using the page allocator
88903cd0f3SClaire Chang  * @force_bounce: %true if swiotlb bouncing is forced
89f4111e39SClaire Chang  * @for_alloc:  %true if the pool is used for memory allocation
9073f62095SClaire Chang  */
9173f62095SClaire Chang struct io_tlb_mem {
9273f62095SClaire Chang 	phys_addr_t start;
9373f62095SClaire Chang 	phys_addr_t end;
941a5e91d8STianyu Lan 	void *vaddr;
9573f62095SClaire Chang 	unsigned long nslabs;
9673f62095SClaire Chang 	unsigned long used;
9773f62095SClaire Chang 	unsigned int index;
9873f62095SClaire Chang 	spinlock_t lock;
9973f62095SClaire Chang 	struct dentry *debugfs;
10073f62095SClaire Chang 	bool late_alloc;
101903cd0f3SClaire Chang 	bool force_bounce;
102f4111e39SClaire Chang 	bool for_alloc;
1032d29960aSChristoph Hellwig 	struct io_tlb_slot {
1042d29960aSChristoph Hellwig 		phys_addr_t orig_addr;
1052d29960aSChristoph Hellwig 		size_t alloc_size;
1062d29960aSChristoph Hellwig 		unsigned int list;
107463e862aSWill Deacon 	} *slots;
10873f62095SClaire Chang };
109463e862aSWill Deacon extern struct io_tlb_mem io_tlb_default_mem;
11055897af6SChristoph Hellwig 
1117fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
11255897af6SChristoph Hellwig {
1137fd856aaSClaire Chang 	struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
11473f62095SClaire Chang 
1152d29960aSChristoph Hellwig 	return mem && paddr >= mem->start && paddr < mem->end;
11655897af6SChristoph Hellwig }
11755897af6SChristoph Hellwig 
118903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
119903cd0f3SClaire Chang {
120903cd0f3SClaire Chang 	struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
121903cd0f3SClaire Chang 
122903cd0f3SClaire Chang 	return mem && mem->force_bounce;
123903cd0f3SClaire Chang }
124903cd0f3SClaire Chang 
125*c6af2aa9SChristoph Hellwig void swiotlb_init(bool addressing_limited, unsigned int flags);
12655897af6SChristoph Hellwig void __init swiotlb_exit(void);
1277453c549SKonrad Rzeszutek Wilk unsigned int swiotlb_max_segment(void);
128abe420bfSJoerg Roedel size_t swiotlb_max_mapping_size(struct device *dev);
1296f2beb26SClaire Chang bool is_swiotlb_active(struct device *dev);
1302d29960aSChristoph Hellwig void __init swiotlb_adjust_size(unsigned long size);
1315740afdbSFUJITA Tomonori #else
132*c6af2aa9SChristoph Hellwig static inline void swiotlb_init(bool addressing_limited, unsigned int flags)
133*c6af2aa9SChristoph Hellwig {
134*c6af2aa9SChristoph Hellwig }
1357fd856aaSClaire Chang static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
13655897af6SChristoph Hellwig {
13755897af6SChristoph Hellwig 	return false;
13855897af6SChristoph Hellwig }
139903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
140903cd0f3SClaire Chang {
141903cd0f3SClaire Chang 	return false;
142903cd0f3SClaire Chang }
14355897af6SChristoph Hellwig static inline void swiotlb_exit(void)
14455897af6SChristoph Hellwig {
14555897af6SChristoph Hellwig }
14655897af6SChristoph Hellwig static inline unsigned int swiotlb_max_segment(void)
14755897af6SChristoph Hellwig {
14855897af6SChristoph Hellwig 	return 0;
14955897af6SChristoph Hellwig }
150abe420bfSJoerg Roedel static inline size_t swiotlb_max_mapping_size(struct device *dev)
151abe420bfSJoerg Roedel {
152abe420bfSJoerg Roedel 	return SIZE_MAX;
153abe420bfSJoerg Roedel }
154492366f7SJoerg Roedel 
1556f2beb26SClaire Chang static inline bool is_swiotlb_active(struct device *dev)
156492366f7SJoerg Roedel {
157492366f7SJoerg Roedel 	return false;
158492366f7SJoerg Roedel }
159e998879dSAshish Kalra 
1602d29960aSChristoph Hellwig static inline void swiotlb_adjust_size(unsigned long size)
161e998879dSAshish Kalra {
162e998879dSAshish Kalra }
16355897af6SChristoph Hellwig #endif /* CONFIG_SWIOTLB */
1645740afdbSFUJITA Tomonori 
165ad32e8cbSFUJITA Tomonori extern void swiotlb_print_info(void);
1669c5a3621SAkinobu Mita 
167f4111e39SClaire Chang #ifdef CONFIG_DMA_RESTRICTED_POOL
168f4111e39SClaire Chang struct page *swiotlb_alloc(struct device *dev, size_t size);
169f4111e39SClaire Chang bool swiotlb_free(struct device *dev, struct page *page, size_t size);
170f4111e39SClaire Chang 
171f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
172f4111e39SClaire Chang {
173f4111e39SClaire Chang 	return dev->dma_io_tlb_mem->for_alloc;
174f4111e39SClaire Chang }
175f4111e39SClaire Chang #else
176f4111e39SClaire Chang static inline struct page *swiotlb_alloc(struct device *dev, size_t size)
177f4111e39SClaire Chang {
178f4111e39SClaire Chang 	return NULL;
179f4111e39SClaire Chang }
180f4111e39SClaire Chang static inline bool swiotlb_free(struct device *dev, struct page *page,
181f4111e39SClaire Chang 				size_t size)
182f4111e39SClaire Chang {
183f4111e39SClaire Chang 	return false;
184f4111e39SClaire Chang }
185f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
186f4111e39SClaire Chang {
187f4111e39SClaire Chang 	return false;
188f4111e39SClaire Chang }
189f4111e39SClaire Chang #endif /* CONFIG_DMA_RESTRICTED_POOL */
190f4111e39SClaire Chang 
1911a5e91d8STianyu Lan extern phys_addr_t swiotlb_unencrypted_base;
1921a5e91d8STianyu Lan 
1931648993fSJoerg Roedel #endif /* __LINUX_SWIOTLB_H */
194