.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation |
---|
3 | 4 | * Rewrite, cleanup: |
---|
4 | 5 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License as published by |
---|
8 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - * (at your option) any later version. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | | - * |
---|
16 | | - * You should have received a copy of the GNU General Public License |
---|
17 | | - * along with this program; if not, write to the Free Software |
---|
18 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
19 | 6 | */ |
---|
20 | 7 | |
---|
21 | 8 | #ifndef _ASM_IOMMU_H |
---|
.. | .. |
---|
25 | 12 | #include <linux/compiler.h> |
---|
26 | 13 | #include <linux/spinlock.h> |
---|
27 | 14 | #include <linux/device.h> |
---|
28 | | -#include <linux/dma-mapping.h> |
---|
| 15 | +#include <linux/dma-map-ops.h> |
---|
29 | 16 | #include <linux/bitops.h> |
---|
30 | 17 | #include <asm/machdep.h> |
---|
31 | 18 | #include <asm/types.h> |
---|
.. | .. |
---|
35 | 22 | #define IOMMU_PAGE_SHIFT_4K 12 |
---|
36 | 23 | #define IOMMU_PAGE_SIZE_4K (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K) |
---|
37 | 24 | #define IOMMU_PAGE_MASK_4K (~((1 << IOMMU_PAGE_SHIFT_4K) - 1)) |
---|
38 | | -#define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K) |
---|
| 25 | +#define IOMMU_PAGE_ALIGN_4K(addr) ALIGN(addr, IOMMU_PAGE_SIZE_4K) |
---|
39 | 26 | |
---|
40 | 27 | #define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift) |
---|
41 | 28 | #define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1)) |
---|
42 | | -#define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr)) |
---|
| 29 | +#define IOMMU_PAGE_ALIGN(addr, tblptr) ALIGN(addr, IOMMU_PAGE_SIZE(tblptr)) |
---|
43 | 30 | |
---|
44 | 31 | /* Boot time flags */ |
---|
45 | 32 | extern int iommu_is_off; |
---|
.. | .. |
---|
61 | 48 | * returns old TCE and DMA direction mask. |
---|
62 | 49 | * @tce is a physical address. |
---|
63 | 50 | */ |
---|
64 | | - int (*exchange)(struct iommu_table *tbl, |
---|
| 51 | + int (*xchg_no_kill)(struct iommu_table *tbl, |
---|
65 | 52 | long index, |
---|
66 | 53 | unsigned long *hpa, |
---|
67 | | - enum dma_data_direction *direction); |
---|
68 | | - /* Real mode */ |
---|
69 | | - int (*exchange_rm)(struct iommu_table *tbl, |
---|
70 | | - long index, |
---|
71 | | - unsigned long *hpa, |
---|
72 | | - enum dma_data_direction *direction); |
---|
| 54 | + enum dma_data_direction *direction, |
---|
| 55 | + bool realmode); |
---|
| 56 | + |
---|
| 57 | + void (*tce_kill)(struct iommu_table *tbl, |
---|
| 58 | + unsigned long index, |
---|
| 59 | + unsigned long pages, |
---|
| 60 | + bool realmode); |
---|
73 | 61 | |
---|
74 | 62 | __be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc); |
---|
75 | 63 | #endif |
---|
.. | .. |
---|
124 | 112 | struct iommu_table_ops *it_ops; |
---|
125 | 113 | struct kref it_kref; |
---|
126 | 114 | int it_nid; |
---|
| 115 | + unsigned long it_reserved_start; /* Start of not-DMA-able (MMIO) area */ |
---|
| 116 | + unsigned long it_reserved_end; |
---|
127 | 117 | }; |
---|
128 | 118 | |
---|
129 | | -#define IOMMU_TABLE_USERSPACE_ENTRY_RM(tbl, entry) \ |
---|
| 119 | +#define IOMMU_TABLE_USERSPACE_ENTRY_RO(tbl, entry) \ |
---|
130 | 120 | ((tbl)->it_ops->useraddrptr((tbl), (entry), false)) |
---|
131 | 121 | #define IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry) \ |
---|
132 | 122 | ((tbl)->it_ops->useraddrptr((tbl), (entry), true)) |
---|
.. | .. |
---|
142 | 132 | struct scatterlist; |
---|
143 | 133 | |
---|
144 | 134 | #ifdef CONFIG_PPC64 |
---|
145 | | - |
---|
146 | | -#define IOMMU_MAPPING_ERROR (~(dma_addr_t)0x0) |
---|
147 | 135 | |
---|
148 | 136 | static inline void set_iommu_table_base(struct device *dev, |
---|
149 | 137 | struct iommu_table *base) |
---|
.. | .. |
---|
164 | 152 | /* Initializes an iommu_table based in values set in the passed-in |
---|
165 | 153 | * structure |
---|
166 | 154 | */ |
---|
167 | | -extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, |
---|
168 | | - int nid); |
---|
| 155 | +extern struct iommu_table *iommu_init_table(struct iommu_table *tbl, |
---|
| 156 | + int nid, unsigned long res_start, unsigned long res_end); |
---|
| 157 | + |
---|
169 | 158 | #define IOMMU_TABLE_GROUP_MAX_TABLES 2 |
---|
170 | 159 | |
---|
171 | 160 | struct iommu_table_group; |
---|
.. | .. |
---|
215 | 204 | |
---|
216 | 205 | extern void iommu_register_group(struct iommu_table_group *table_group, |
---|
217 | 206 | int pci_domain_number, unsigned long pe_num); |
---|
218 | | -extern int iommu_add_device(struct device *dev); |
---|
| 207 | +extern int iommu_add_device(struct iommu_table_group *table_group, |
---|
| 208 | + struct device *dev); |
---|
219 | 209 | extern void iommu_del_device(struct device *dev); |
---|
220 | | -extern int __init tce_iommu_bus_notifier_init(void); |
---|
221 | | -extern long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry, |
---|
222 | | - unsigned long *hpa, enum dma_data_direction *direction); |
---|
| 210 | +extern long iommu_tce_xchg(struct mm_struct *mm, struct iommu_table *tbl, |
---|
| 211 | + unsigned long entry, unsigned long *hpa, |
---|
| 212 | + enum dma_data_direction *direction); |
---|
| 213 | +extern long iommu_tce_xchg_no_kill(struct mm_struct *mm, |
---|
| 214 | + struct iommu_table *tbl, |
---|
| 215 | + unsigned long entry, unsigned long *hpa, |
---|
| 216 | + enum dma_data_direction *direction); |
---|
| 217 | +extern void iommu_tce_kill(struct iommu_table *tbl, |
---|
| 218 | + unsigned long entry, unsigned long pages); |
---|
223 | 219 | #else |
---|
224 | 220 | static inline void iommu_register_group(struct iommu_table_group *table_group, |
---|
225 | 221 | int pci_domain_number, |
---|
.. | .. |
---|
227 | 223 | { |
---|
228 | 224 | } |
---|
229 | 225 | |
---|
230 | | -static inline int iommu_add_device(struct device *dev) |
---|
| 226 | +static inline int iommu_add_device(struct iommu_table_group *table_group, |
---|
| 227 | + struct device *dev) |
---|
231 | 228 | { |
---|
232 | 229 | return 0; |
---|
233 | 230 | } |
---|
.. | .. |
---|
235 | 232 | static inline void iommu_del_device(struct device *dev) |
---|
236 | 233 | { |
---|
237 | 234 | } |
---|
238 | | - |
---|
239 | | -static inline int __init tce_iommu_bus_notifier_init(void) |
---|
240 | | -{ |
---|
241 | | - return 0; |
---|
242 | | -} |
---|
243 | 235 | #endif /* !CONFIG_IOMMU_API */ |
---|
244 | 236 | |
---|
245 | | -int dma_iommu_mapping_error(struct device *dev, dma_addr_t dma_addr); |
---|
246 | | - |
---|
| 237 | +u64 dma_iommu_get_required_mask(struct device *dev); |
---|
247 | 238 | #else |
---|
248 | 239 | |
---|
249 | 240 | static inline void *get_iommu_table_base(struct device *dev) |
---|
.. | .. |
---|
325 | 316 | extern enum dma_data_direction iommu_tce_direction(unsigned long tce); |
---|
326 | 317 | extern unsigned long iommu_direction_to_tce_perm(enum dma_data_direction dir); |
---|
327 | 318 | |
---|
| 319 | +#ifdef CONFIG_PPC_CELL_NATIVE |
---|
| 320 | +extern bool iommu_fixed_is_weak; |
---|
| 321 | +#else |
---|
| 322 | +#define iommu_fixed_is_weak false |
---|
| 323 | +#endif |
---|
| 324 | + |
---|
| 325 | +extern const struct dma_map_ops dma_iommu_ops; |
---|
| 326 | + |
---|
328 | 327 | #endif /* __KERNEL__ */ |
---|
329 | 328 | #endif /* _ASM_IOMMU_H */ |
---|