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>
111aaa7368SPetr Tesarik #include <linux/workqueue.h>
121648993fSJoerg Roedel
131648993fSJoerg Roedel struct device;
1438674442SThierry Reding struct page;
151648993fSJoerg Roedel struct scatterlist;
161648993fSJoerg Roedel
17c6af2aa9SChristoph Hellwig #define SWIOTLB_VERBOSE (1 << 0) /* verbose initialization */
18c6af2aa9SChristoph Hellwig #define SWIOTLB_FORCE (1 << 1) /* force bounce buffering */
198ba2ed1bSChristoph Hellwig #define SWIOTLB_ANY (1 << 2) /* allow any memory for the buffer */
20ae7871beSGeert Uytterhoeven
210016fdeeSIan Campbell /*
220016fdeeSIan Campbell * Maximum allowable number of contiguous slabs to map,
230016fdeeSIan Campbell * must be a power of 2. What is the appropriate value ?
240016fdeeSIan Campbell * The complexity of {map,unmap}_single is linearly dependent on this value.
250016fdeeSIan Campbell */
260016fdeeSIan Campbell #define IO_TLB_SEGSIZE 128
270016fdeeSIan Campbell
280016fdeeSIan Campbell /*
290016fdeeSIan Campbell * log of the size of each IO TLB slab. The number of slabs is command line
300016fdeeSIan Campbell * controllable.
310016fdeeSIan Campbell */
320016fdeeSIan Campbell #define IO_TLB_SHIFT 11
33b5d7ccb7SChristoph Hellwig #define IO_TLB_SIZE (1 << IO_TLB_SHIFT)
340016fdeeSIan Campbell
35e998879dSAshish Kalra /* default to 64MB */
36e998879dSAshish Kalra #define IO_TLB_DEFAULT_SIZE (64UL<<20)
37e998879dSAshish Kalra
38c729de8fSYinghai Lu unsigned long swiotlb_size_or_default(void);
397374153dSChristoph Hellwig void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
407374153dSChristoph Hellwig int (*remap)(void *tlb, unsigned long nslabs));
417374153dSChristoph Hellwig int swiotlb_init_late(size_t size, gfp_t gfp_mask,
427374153dSChristoph Hellwig int (*remap)(void *tlb, unsigned long nslabs));
43c7753208STom Lendacky extern void __init swiotlb_update_mem_attributes(void);
441648993fSJoerg Roedel
455740afdbSFUJITA Tomonori #ifdef CONFIG_SWIOTLB
4673f62095SClaire Chang
4773f62095SClaire Chang /**
48158dbe9cSPetr Tesarik * struct io_tlb_pool - IO TLB memory pool descriptor
4973f62095SClaire Chang * @start: The start address of the swiotlb memory pool. Used to do a quick
5073f62095SClaire Chang * range check to see if the memory was in fact allocated by this
5173f62095SClaire Chang * API.
5273f62095SClaire Chang * @end: The end address of the swiotlb memory pool. Used to do a quick
5373f62095SClaire Chang * range check to see if the memory was in fact allocated by this
5473f62095SClaire Chang * API.
551a5e91d8STianyu Lan * @vaddr: The vaddr of the swiotlb memory pool. The swiotlb memory pool
561a5e91d8STianyu Lan * may be remapped in the memory encrypted case and store virtual
571a5e91d8STianyu Lan * address for bounce buffer operation.
58158dbe9cSPetr Tesarik * @nslabs: The number of IO TLB slots between @start and @end. For the
59158dbe9cSPetr Tesarik * default swiotlb, this can be adjusted with a boot parameter,
60158dbe9cSPetr Tesarik * see setup_io_tlb_npages().
61158dbe9cSPetr Tesarik * @late_alloc: %true if allocated using the page allocator.
62158dbe9cSPetr Tesarik * @nareas: Number of areas in the pool.
63158dbe9cSPetr Tesarik * @area_nslabs: Number of slots in each area.
64158dbe9cSPetr Tesarik * @areas: Array of memory area descriptors.
65158dbe9cSPetr Tesarik * @slots: Array of slot descriptors.
6679636caaSPetr Tesarik * @node: Member of the IO TLB memory pool list.
6779636caaSPetr Tesarik * @rcu: RCU head for swiotlb_dyn_free().
6879636caaSPetr Tesarik * @transient: %true if transient memory pool.
69158dbe9cSPetr Tesarik */
70158dbe9cSPetr Tesarik struct io_tlb_pool {
71158dbe9cSPetr Tesarik phys_addr_t start;
72158dbe9cSPetr Tesarik phys_addr_t end;
73158dbe9cSPetr Tesarik void *vaddr;
74158dbe9cSPetr Tesarik unsigned long nslabs;
75158dbe9cSPetr Tesarik bool late_alloc;
76158dbe9cSPetr Tesarik unsigned int nareas;
77158dbe9cSPetr Tesarik unsigned int area_nslabs;
78158dbe9cSPetr Tesarik struct io_tlb_area *areas;
79158dbe9cSPetr Tesarik struct io_tlb_slot *slots;
8079636caaSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC
8179636caaSPetr Tesarik struct list_head node;
8279636caaSPetr Tesarik struct rcu_head rcu;
8379636caaSPetr Tesarik bool transient;
8479636caaSPetr Tesarik #endif
85158dbe9cSPetr Tesarik };
86158dbe9cSPetr Tesarik
87158dbe9cSPetr Tesarik /**
88158dbe9cSPetr Tesarik * struct io_tlb_mem - Software IO TLB allocator
89158dbe9cSPetr Tesarik * @defpool: Default (initial) IO TLB memory pool descriptor.
901aaa7368SPetr Tesarik * @pool: IO TLB memory pool descriptor (if not dynamic).
91158dbe9cSPetr Tesarik * @nslabs: Total number of IO TLB slabs in all pools.
9273f62095SClaire Chang * @debugfs: The dentry to debugfs.
93903cd0f3SClaire Chang * @force_bounce: %true if swiotlb bouncing is forced
94f4111e39SClaire Chang * @for_alloc: %true if the pool is used for memory allocation
9562708b2bSPetr Tesarik * @can_grow: %true if more pools can be allocated dynamically.
96ad96ce32SPetr Tesarik * @phys_limit: Maximum allowed physical address.
971aaa7368SPetr Tesarik * @lock: Lock to synchronize changes to the list.
981aaa7368SPetr Tesarik * @pools: List of IO TLB memory pool descriptors (if dynamic).
991aaa7368SPetr Tesarik * @dyn_alloc: Dynamic IO TLB pool allocation work.
1008b0977ecSMichael Kelley * @total_used: The total number of slots in the pool that are currently used
1018b0977ecSMichael Kelley * across all areas. Used only for calculating used_hiwater in
1028b0977ecSMichael Kelley * debugfs.
1038b0977ecSMichael Kelley * @used_hiwater: The high water mark for total_used. Used only for reporting
1048b0977ecSMichael Kelley * in debugfs.
10502e76569SZhangPeng * @transient_nslabs: The total number of slots in all transient pools that
10602e76569SZhangPeng * are currently used across all areas.
10773f62095SClaire Chang */
10873f62095SClaire Chang struct io_tlb_mem {
109158dbe9cSPetr Tesarik struct io_tlb_pool defpool;
11073f62095SClaire Chang unsigned long nslabs;
11173f62095SClaire Chang struct dentry *debugfs;
112903cd0f3SClaire Chang bool force_bounce;
113f4111e39SClaire Chang bool for_alloc;
11462708b2bSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC
11562708b2bSPetr Tesarik bool can_grow;
116ad96ce32SPetr Tesarik u64 phys_limit;
1171aaa7368SPetr Tesarik spinlock_t lock;
1181aaa7368SPetr Tesarik struct list_head pools;
1191aaa7368SPetr Tesarik struct work_struct dyn_alloc;
12062708b2bSPetr Tesarik #endif
121ec274affSPetr Tesarik #ifdef CONFIG_DEBUG_FS
1228b0977ecSMichael Kelley atomic_long_t total_used;
1238b0977ecSMichael Kelley atomic_long_t used_hiwater;
12402e76569SZhangPeng atomic_long_t transient_nslabs;
125ec274affSPetr Tesarik #endif
12673f62095SClaire Chang };
12755897af6SChristoph Hellwig
128*7296f230SMichael Kelley struct io_tlb_pool *__swiotlb_find_pool(struct device *dev, phys_addr_t paddr);
12979636caaSPetr Tesarik
130fea18777SPetr Tesarik /**
131*7296f230SMichael Kelley * swiotlb_find_pool() - find swiotlb pool to which a physical address belongs
132fea18777SPetr Tesarik * @dev: Device which has mapped the buffer.
133fea18777SPetr Tesarik * @paddr: Physical address within the DMA buffer.
134fea18777SPetr Tesarik *
135*7296f230SMichael Kelley * Find the swiotlb pool that @paddr points into.
136fea18777SPetr Tesarik *
137fea18777SPetr Tesarik * Return:
138*7296f230SMichael Kelley * * pool address if @paddr points into a bounce buffer
139*7296f230SMichael Kelley * * NULL if @paddr does not point into a bounce buffer. As such, this function
140*7296f230SMichael Kelley * can be used to determine if @paddr denotes a swiotlb bounce buffer.
141fea18777SPetr Tesarik */
swiotlb_find_pool(struct device * dev,phys_addr_t paddr)142*7296f230SMichael Kelley static inline struct io_tlb_pool *swiotlb_find_pool(struct device *dev,
143*7296f230SMichael Kelley phys_addr_t paddr)
14455897af6SChristoph Hellwig {
1457fd856aaSClaire Chang struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
14673f62095SClaire Chang
14779636caaSPetr Tesarik if (!mem)
148*7296f230SMichael Kelley return NULL;
14979636caaSPetr Tesarik
1502d5780bbSPetr Tesarik #ifdef CONFIG_SWIOTLB_DYNAMIC
1512d5780bbSPetr Tesarik /*
1522d5780bbSPetr Tesarik * All SWIOTLB buffer addresses must have been returned by
1532d5780bbSPetr Tesarik * swiotlb_tbl_map_single() and passed to a device driver.
1542d5780bbSPetr Tesarik * If a SWIOTLB address is checked on another CPU, then it was
1552d5780bbSPetr Tesarik * presumably loaded by the device driver from an unspecified private
1562d5780bbSPetr Tesarik * data structure. Make sure that this load is ordered before reading
157*7296f230SMichael Kelley * dev->dma_uses_io_tlb here and mem->pools in __swiotlb_find_pool().
1582d5780bbSPetr Tesarik *
1592d5780bbSPetr Tesarik * This barrier pairs with smp_mb() in swiotlb_find_slots().
1601395706aSPetr Tesarik */
1611395706aSPetr Tesarik smp_rmb();
162*7296f230SMichael Kelley if (READ_ONCE(dev->dma_uses_io_tlb))
163*7296f230SMichael Kelley return __swiotlb_find_pool(dev, paddr);
1642d5780bbSPetr Tesarik #else
165*7296f230SMichael Kelley if (paddr >= mem->defpool.start && paddr < mem->defpool.end)
166*7296f230SMichael Kelley return &mem->defpool;
1672d5780bbSPetr Tesarik #endif
168*7296f230SMichael Kelley
169*7296f230SMichael Kelley return NULL;
17055897af6SChristoph Hellwig }
17155897af6SChristoph Hellwig
is_swiotlb_force_bounce(struct device * dev)172903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
173903cd0f3SClaire Chang {
174903cd0f3SClaire Chang struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
175903cd0f3SClaire Chang
176903cd0f3SClaire Chang return mem && mem->force_bounce;
177903cd0f3SClaire Chang }
178903cd0f3SClaire Chang
179c6af2aa9SChristoph Hellwig void swiotlb_init(bool addressing_limited, unsigned int flags);
18055897af6SChristoph Hellwig void __init swiotlb_exit(void);
18105ee7741SPetr Tesarik void swiotlb_dev_init(struct device *dev);
182abe420bfSJoerg Roedel size_t swiotlb_max_mapping_size(struct device *dev);
18305ee7741SPetr Tesarik bool is_swiotlb_allocated(void);
1846f2beb26SClaire Chang bool is_swiotlb_active(struct device *dev);
1852d29960aSChristoph Hellwig void __init swiotlb_adjust_size(unsigned long size);
18605ee7741SPetr Tesarik phys_addr_t default_swiotlb_base(void);
18705ee7741SPetr Tesarik phys_addr_t default_swiotlb_limit(void);
1885740afdbSFUJITA Tomonori #else
swiotlb_init(bool addressing_limited,unsigned int flags)189c6af2aa9SChristoph Hellwig static inline void swiotlb_init(bool addressing_limited, unsigned int flags)
190c6af2aa9SChristoph Hellwig {
191c6af2aa9SChristoph Hellwig }
19205ee7741SPetr Tesarik
swiotlb_dev_init(struct device * dev)19305ee7741SPetr Tesarik static inline void swiotlb_dev_init(struct device *dev)
19405ee7741SPetr Tesarik {
19505ee7741SPetr Tesarik }
19605ee7741SPetr Tesarik
swiotlb_find_pool(struct device * dev,phys_addr_t paddr)197*7296f230SMichael Kelley static inline struct io_tlb_pool *swiotlb_find_pool(struct device *dev,
198*7296f230SMichael Kelley phys_addr_t paddr)
19955897af6SChristoph Hellwig {
200*7296f230SMichael Kelley return NULL;
20155897af6SChristoph Hellwig }
is_swiotlb_force_bounce(struct device * dev)202903cd0f3SClaire Chang static inline bool is_swiotlb_force_bounce(struct device *dev)
203903cd0f3SClaire Chang {
204903cd0f3SClaire Chang return false;
205903cd0f3SClaire Chang }
swiotlb_exit(void)20655897af6SChristoph Hellwig static inline void swiotlb_exit(void)
20755897af6SChristoph Hellwig {
20855897af6SChristoph Hellwig }
swiotlb_max_mapping_size(struct device * dev)209abe420bfSJoerg Roedel static inline size_t swiotlb_max_mapping_size(struct device *dev)
210abe420bfSJoerg Roedel {
211abe420bfSJoerg Roedel return SIZE_MAX;
212abe420bfSJoerg Roedel }
213492366f7SJoerg Roedel
is_swiotlb_allocated(void)21405ee7741SPetr Tesarik static inline bool is_swiotlb_allocated(void)
21505ee7741SPetr Tesarik {
21605ee7741SPetr Tesarik return false;
21705ee7741SPetr Tesarik }
21805ee7741SPetr Tesarik
is_swiotlb_active(struct device * dev)2196f2beb26SClaire Chang static inline bool is_swiotlb_active(struct device *dev)
220492366f7SJoerg Roedel {
221492366f7SJoerg Roedel return false;
222492366f7SJoerg Roedel }
223e998879dSAshish Kalra
swiotlb_adjust_size(unsigned long size)2242d29960aSChristoph Hellwig static inline void swiotlb_adjust_size(unsigned long size)
225e998879dSAshish Kalra {
226e998879dSAshish Kalra }
22705ee7741SPetr Tesarik
default_swiotlb_base(void)22805ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_base(void)
22905ee7741SPetr Tesarik {
23005ee7741SPetr Tesarik return 0;
23105ee7741SPetr Tesarik }
23205ee7741SPetr Tesarik
default_swiotlb_limit(void)23305ee7741SPetr Tesarik static inline phys_addr_t default_swiotlb_limit(void)
23405ee7741SPetr Tesarik {
23505ee7741SPetr Tesarik return 0;
23605ee7741SPetr Tesarik }
23755897af6SChristoph Hellwig #endif /* CONFIG_SWIOTLB */
2385740afdbSFUJITA Tomonori
239*7296f230SMichael Kelley phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, phys_addr_t phys,
240*7296f230SMichael Kelley size_t mapping_size, unsigned int alloc_aligned_mask,
241*7296f230SMichael Kelley enum dma_data_direction dir, unsigned long attrs);
242*7296f230SMichael Kelley dma_addr_t swiotlb_map(struct device *dev, phys_addr_t phys,
243*7296f230SMichael Kelley size_t size, enum dma_data_direction dir, unsigned long attrs);
244*7296f230SMichael Kelley
245*7296f230SMichael Kelley void __swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
246*7296f230SMichael Kelley size_t mapping_size, enum dma_data_direction dir,
247*7296f230SMichael Kelley unsigned long attrs, struct io_tlb_pool *pool);
swiotlb_tbl_unmap_single(struct device * dev,phys_addr_t addr,size_t size,enum dma_data_direction dir,unsigned long attrs)248*7296f230SMichael Kelley static inline void swiotlb_tbl_unmap_single(struct device *dev,
249*7296f230SMichael Kelley phys_addr_t addr, size_t size, enum dma_data_direction dir,
250*7296f230SMichael Kelley unsigned long attrs)
251*7296f230SMichael Kelley {
252*7296f230SMichael Kelley struct io_tlb_pool *pool = swiotlb_find_pool(dev, addr);
253*7296f230SMichael Kelley
254*7296f230SMichael Kelley if (unlikely(pool))
255*7296f230SMichael Kelley __swiotlb_tbl_unmap_single(dev, addr, size, dir, attrs, pool);
256*7296f230SMichael Kelley }
257*7296f230SMichael Kelley
258*7296f230SMichael Kelley void __swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr,
259*7296f230SMichael Kelley size_t size, enum dma_data_direction dir,
260*7296f230SMichael Kelley struct io_tlb_pool *pool);
swiotlb_sync_single_for_device(struct device * dev,phys_addr_t addr,size_t size,enum dma_data_direction dir)261*7296f230SMichael Kelley static inline void swiotlb_sync_single_for_device(struct device *dev,
262*7296f230SMichael Kelley phys_addr_t addr, size_t size, enum dma_data_direction dir)
263*7296f230SMichael Kelley {
264*7296f230SMichael Kelley struct io_tlb_pool *pool = swiotlb_find_pool(dev, addr);
265*7296f230SMichael Kelley
266*7296f230SMichael Kelley if (unlikely(pool))
267*7296f230SMichael Kelley __swiotlb_sync_single_for_device(dev, addr, size, dir, pool);
268*7296f230SMichael Kelley }
269*7296f230SMichael Kelley
270*7296f230SMichael Kelley void __swiotlb_sync_single_for_cpu(struct device *dev, phys_addr_t tlb_addr,
271*7296f230SMichael Kelley size_t size, enum dma_data_direction dir,
272*7296f230SMichael Kelley struct io_tlb_pool *pool);
swiotlb_sync_single_for_cpu(struct device * dev,phys_addr_t addr,size_t size,enum dma_data_direction dir)273*7296f230SMichael Kelley static inline void swiotlb_sync_single_for_cpu(struct device *dev,
274*7296f230SMichael Kelley phys_addr_t addr, size_t size, enum dma_data_direction dir)
275*7296f230SMichael Kelley {
276*7296f230SMichael Kelley struct io_tlb_pool *pool = swiotlb_find_pool(dev, addr);
277*7296f230SMichael Kelley
278*7296f230SMichael Kelley if (unlikely(pool))
279*7296f230SMichael Kelley __swiotlb_sync_single_for_cpu(dev, addr, size, dir, pool);
280*7296f230SMichael Kelley }
281*7296f230SMichael Kelley
282ad32e8cbSFUJITA Tomonori extern void swiotlb_print_info(void);
2839c5a3621SAkinobu Mita
284f4111e39SClaire Chang #ifdef CONFIG_DMA_RESTRICTED_POOL
285f4111e39SClaire Chang struct page *swiotlb_alloc(struct device *dev, size_t size);
286f4111e39SClaire Chang bool swiotlb_free(struct device *dev, struct page *page, size_t size);
287f4111e39SClaire Chang
is_swiotlb_for_alloc(struct device * dev)288f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
289f4111e39SClaire Chang {
290f4111e39SClaire Chang return dev->dma_io_tlb_mem->for_alloc;
291f4111e39SClaire Chang }
292f4111e39SClaire Chang #else
swiotlb_alloc(struct device * dev,size_t size)293f4111e39SClaire Chang static inline struct page *swiotlb_alloc(struct device *dev, size_t size)
294f4111e39SClaire Chang {
295f4111e39SClaire Chang return NULL;
296f4111e39SClaire Chang }
swiotlb_free(struct device * dev,struct page * page,size_t size)297f4111e39SClaire Chang static inline bool swiotlb_free(struct device *dev, struct page *page,
298f4111e39SClaire Chang size_t size)
299f4111e39SClaire Chang {
300f4111e39SClaire Chang return false;
301f4111e39SClaire Chang }
is_swiotlb_for_alloc(struct device * dev)302f4111e39SClaire Chang static inline bool is_swiotlb_for_alloc(struct device *dev)
303f4111e39SClaire Chang {
304f4111e39SClaire Chang return false;
305f4111e39SClaire Chang }
306f4111e39SClaire Chang #endif /* CONFIG_DMA_RESTRICTED_POOL */
307f4111e39SClaire Chang
3081648993fSJoerg Roedel #endif /* __LINUX_SWIOTLB_H */
309