diff options
Diffstat (limited to 'arch/sparc/kernel/iommu.c')
-rw-r--r-- | arch/sparc/kernel/iommu.c | 866 |
1 files changed, 866 insertions, 0 deletions
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c new file mode 100644 index 000000000000..1cc1995531e2 --- /dev/null +++ b/arch/sparc/kernel/iommu.c | |||
@@ -0,0 +1,866 @@ | |||
1 | /* iommu.c: Generic sparc64 IOMMU support. | ||
2 | * | ||
3 | * Copyright (C) 1999, 2007, 2008 David S. Miller (davem@davemloft.net) | ||
4 | * Copyright (C) 1999, 2000 Jakub Jelinek (jakub@redhat.com) | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/delay.h> | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/dma-mapping.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/iommu-helper.h> | ||
14 | |||
15 | #ifdef CONFIG_PCI | ||
16 | #include <linux/pci.h> | ||
17 | #endif | ||
18 | |||
19 | #include <asm/iommu.h> | ||
20 | |||
21 | #include "iommu_common.h" | ||
22 | |||
23 | #define STC_CTXMATCH_ADDR(STC, CTX) \ | ||
24 | ((STC)->strbuf_ctxmatch_base + ((CTX) << 3)) | ||
25 | #define STC_FLUSHFLAG_INIT(STC) \ | ||
26 | (*((STC)->strbuf_flushflag) = 0UL) | ||
27 | #define STC_FLUSHFLAG_SET(STC) \ | ||
28 | (*((STC)->strbuf_flushflag) != 0UL) | ||
29 | |||
30 | #define iommu_read(__reg) \ | ||
31 | ({ u64 __ret; \ | ||
32 | __asm__ __volatile__("ldxa [%1] %2, %0" \ | ||
33 | : "=r" (__ret) \ | ||
34 | : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \ | ||
35 | : "memory"); \ | ||
36 | __ret; \ | ||
37 | }) | ||
38 | #define iommu_write(__reg, __val) \ | ||
39 | __asm__ __volatile__("stxa %0, [%1] %2" \ | ||
40 | : /* no outputs */ \ | ||
41 | : "r" (__val), "r" (__reg), \ | ||
42 | "i" (ASI_PHYS_BYPASS_EC_E)) | ||
43 | |||
44 | /* Must be invoked under the IOMMU lock. */ | ||
45 | static void iommu_flushall(struct iommu *iommu) | ||
46 | { | ||
47 | if (iommu->iommu_flushinv) { | ||
48 | iommu_write(iommu->iommu_flushinv, ~(u64)0); | ||
49 | } else { | ||
50 | unsigned long tag; | ||
51 | int entry; | ||
52 | |||
53 | tag = iommu->iommu_tags; | ||
54 | for (entry = 0; entry < 16; entry++) { | ||
55 | iommu_write(tag, 0); | ||
56 | tag += 8; | ||
57 | } | ||
58 | |||
59 | /* Ensure completion of previous PIO writes. */ | ||
60 | (void) iommu_read(iommu->write_complete_reg); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | #define IOPTE_CONSISTENT(CTX) \ | ||
65 | (IOPTE_VALID | IOPTE_CACHE | \ | ||
66 | (((CTX) << 47) & IOPTE_CONTEXT)) | ||
67 | |||
68 | #define IOPTE_STREAMING(CTX) \ | ||
69 | (IOPTE_CONSISTENT(CTX) | IOPTE_STBUF) | ||
70 | |||
71 | /* Existing mappings are never marked invalid, instead they | ||
72 | * are pointed to a dummy page. | ||
73 | */ | ||
74 | #define IOPTE_IS_DUMMY(iommu, iopte) \ | ||
75 | ((iopte_val(*iopte) & IOPTE_PAGE) == (iommu)->dummy_page_pa) | ||
76 | |||
77 | static inline void iopte_make_dummy(struct iommu *iommu, iopte_t *iopte) | ||
78 | { | ||
79 | unsigned long val = iopte_val(*iopte); | ||
80 | |||
81 | val &= ~IOPTE_PAGE; | ||
82 | val |= iommu->dummy_page_pa; | ||
83 | |||
84 | iopte_val(*iopte) = val; | ||
85 | } | ||
86 | |||
87 | /* Based almost entirely upon the ppc64 iommu allocator. If you use the 'handle' | ||
88 | * facility it must all be done in one pass while under the iommu lock. | ||
89 | * | ||
90 | * On sun4u platforms, we only flush the IOMMU once every time we've passed | ||
91 | * over the entire page table doing allocations. Therefore we only ever advance | ||
92 | * the hint and cannot backtrack it. | ||
93 | */ | ||
94 | unsigned long iommu_range_alloc(struct device *dev, | ||
95 | struct iommu *iommu, | ||
96 | unsigned long npages, | ||
97 | unsigned long *handle) | ||
98 | { | ||
99 | unsigned long n, end, start, limit, boundary_size; | ||
100 | struct iommu_arena *arena = &iommu->arena; | ||
101 | int pass = 0; | ||
102 | |||
103 | /* This allocator was derived from x86_64's bit string search */ | ||
104 | |||
105 | /* Sanity check */ | ||
106 | if (unlikely(npages == 0)) { | ||
107 | if (printk_ratelimit()) | ||
108 | WARN_ON(1); | ||
109 | return DMA_ERROR_CODE; | ||
110 | } | ||
111 | |||
112 | if (handle && *handle) | ||
113 | start = *handle; | ||
114 | else | ||
115 | start = arena->hint; | ||
116 | |||
117 | limit = arena->limit; | ||
118 | |||
119 | /* The case below can happen if we have a small segment appended | ||
120 | * to a large, or when the previous alloc was at the very end of | ||
121 | * the available space. If so, go back to the beginning and flush. | ||
122 | */ | ||
123 | if (start >= limit) { | ||
124 | start = 0; | ||
125 | if (iommu->flush_all) | ||
126 | iommu->flush_all(iommu); | ||
127 | } | ||
128 | |||
129 | again: | ||
130 | |||
131 | if (dev) | ||
132 | boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, | ||
133 | 1 << IO_PAGE_SHIFT); | ||
134 | else | ||
135 | boundary_size = ALIGN(1UL << 32, 1 << IO_PAGE_SHIFT); | ||
136 | |||
137 | n = iommu_area_alloc(arena->map, limit, start, npages, | ||
138 | iommu->page_table_map_base >> IO_PAGE_SHIFT, | ||
139 | boundary_size >> IO_PAGE_SHIFT, 0); | ||
140 | if (n == -1) { | ||
141 | if (likely(pass < 1)) { | ||
142 | /* First failure, rescan from the beginning. */ | ||
143 | start = 0; | ||
144 | if (iommu->flush_all) | ||
145 | iommu->flush_all(iommu); | ||
146 | pass++; | ||
147 | goto again; | ||
148 | } else { | ||
149 | /* Second failure, give up */ | ||
150 | return DMA_ERROR_CODE; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | end = n + npages; | ||
155 | |||
156 | arena->hint = end; | ||
157 | |||
158 | /* Update handle for SG allocations */ | ||
159 | if (handle) | ||
160 | *handle = end; | ||
161 | |||
162 | return n; | ||
163 | } | ||
164 | |||
165 | void iommu_range_free(struct iommu *iommu, dma_addr_t dma_addr, unsigned long npages) | ||
166 | { | ||
167 | struct iommu_arena *arena = &iommu->arena; | ||
168 | unsigned long entry; | ||
169 | |||
170 | entry = (dma_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT; | ||
171 | |||
172 | iommu_area_free(arena->map, entry, npages); | ||
173 | } | ||
174 | |||
175 | int iommu_table_init(struct iommu *iommu, int tsbsize, | ||
176 | u32 dma_offset, u32 dma_addr_mask, | ||
177 | int numa_node) | ||
178 | { | ||
179 | unsigned long i, order, sz, num_tsb_entries; | ||
180 | struct page *page; | ||
181 | |||
182 | num_tsb_entries = tsbsize / sizeof(iopte_t); | ||
183 | |||
184 | /* Setup initial software IOMMU state. */ | ||
185 | spin_lock_init(&iommu->lock); | ||
186 | iommu->ctx_lowest_free = 1; | ||
187 | iommu->page_table_map_base = dma_offset; | ||
188 | iommu->dma_addr_mask = dma_addr_mask; | ||
189 | |||
190 | /* Allocate and initialize the free area map. */ | ||
191 | sz = num_tsb_entries / 8; | ||
192 | sz = (sz + 7UL) & ~7UL; | ||
193 | iommu->arena.map = kmalloc_node(sz, GFP_KERNEL, numa_node); | ||
194 | if (!iommu->arena.map) { | ||
195 | printk(KERN_ERR "IOMMU: Error, kmalloc(arena.map) failed.\n"); | ||
196 | return -ENOMEM; | ||
197 | } | ||
198 | memset(iommu->arena.map, 0, sz); | ||
199 | iommu->arena.limit = num_tsb_entries; | ||
200 | |||
201 | if (tlb_type != hypervisor) | ||
202 | iommu->flush_all = iommu_flushall; | ||
203 | |||
204 | /* Allocate and initialize the dummy page which we | ||
205 | * set inactive IO PTEs to point to. | ||
206 | */ | ||
207 | page = alloc_pages_node(numa_node, GFP_KERNEL, 0); | ||
208 | if (!page) { | ||
209 | printk(KERN_ERR "IOMMU: Error, gfp(dummy_page) failed.\n"); | ||
210 | goto out_free_map; | ||
211 | } | ||
212 | iommu->dummy_page = (unsigned long) page_address(page); | ||
213 | memset((void *)iommu->dummy_page, 0, PAGE_SIZE); | ||
214 | iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page); | ||
215 | |||
216 | /* Now allocate and setup the IOMMU page table itself. */ | ||
217 | order = get_order(tsbsize); | ||
218 | page = alloc_pages_node(numa_node, GFP_KERNEL, order); | ||
219 | if (!page) { | ||
220 | printk(KERN_ERR "IOMMU: Error, gfp(tsb) failed.\n"); | ||
221 | goto out_free_dummy_page; | ||
222 | } | ||
223 | iommu->page_table = (iopte_t *)page_address(page); | ||
224 | |||
225 | for (i = 0; i < num_tsb_entries; i++) | ||
226 | iopte_make_dummy(iommu, &iommu->page_table[i]); | ||
227 | |||
228 | return 0; | ||
229 | |||
230 | out_free_dummy_page: | ||
231 | free_page(iommu->dummy_page); | ||
232 | iommu->dummy_page = 0UL; | ||
233 | |||
234 | out_free_map: | ||
235 | kfree(iommu->arena.map); | ||
236 | iommu->arena.map = NULL; | ||
237 | |||
238 | return -ENOMEM; | ||
239 | } | ||
240 | |||
241 | static inline iopte_t *alloc_npages(struct device *dev, struct iommu *iommu, | ||
242 | unsigned long npages) | ||
243 | { | ||
244 | unsigned long entry; | ||
245 | |||
246 | entry = iommu_range_alloc(dev, iommu, npages, NULL); | ||
247 | if (unlikely(entry == DMA_ERROR_CODE)) | ||
248 | return NULL; | ||
249 | |||
250 | return iommu->page_table + entry; | ||
251 | } | ||
252 | |||
253 | static int iommu_alloc_ctx(struct iommu *iommu) | ||
254 | { | ||
255 | int lowest = iommu->ctx_lowest_free; | ||
256 | int sz = IOMMU_NUM_CTXS - lowest; | ||
257 | int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest); | ||
258 | |||
259 | if (unlikely(n == sz)) { | ||
260 | n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1); | ||
261 | if (unlikely(n == lowest)) { | ||
262 | printk(KERN_WARNING "IOMMU: Ran out of contexts.\n"); | ||
263 | n = 0; | ||
264 | } | ||
265 | } | ||
266 | if (n) | ||
267 | __set_bit(n, iommu->ctx_bitmap); | ||
268 | |||
269 | return n; | ||
270 | } | ||
271 | |||
272 | static inline void iommu_free_ctx(struct iommu *iommu, int ctx) | ||
273 | { | ||
274 | if (likely(ctx)) { | ||
275 | __clear_bit(ctx, iommu->ctx_bitmap); | ||
276 | if (ctx < iommu->ctx_lowest_free) | ||
277 | iommu->ctx_lowest_free = ctx; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | static void *dma_4u_alloc_coherent(struct device *dev, size_t size, | ||
282 | dma_addr_t *dma_addrp, gfp_t gfp) | ||
283 | { | ||
284 | unsigned long flags, order, first_page; | ||
285 | struct iommu *iommu; | ||
286 | struct page *page; | ||
287 | int npages, nid; | ||
288 | iopte_t *iopte; | ||
289 | void *ret; | ||
290 | |||
291 | size = IO_PAGE_ALIGN(size); | ||
292 | order = get_order(size); | ||
293 | if (order >= 10) | ||
294 | return NULL; | ||
295 | |||
296 | nid = dev->archdata.numa_node; | ||
297 | page = alloc_pages_node(nid, gfp, order); | ||
298 | if (unlikely(!page)) | ||
299 | return NULL; | ||
300 | |||
301 | first_page = (unsigned long) page_address(page); | ||
302 | memset((char *)first_page, 0, PAGE_SIZE << order); | ||
303 | |||
304 | iommu = dev->archdata.iommu; | ||
305 | |||
306 | spin_lock_irqsave(&iommu->lock, flags); | ||
307 | iopte = alloc_npages(dev, iommu, size >> IO_PAGE_SHIFT); | ||
308 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
309 | |||
310 | if (unlikely(iopte == NULL)) { | ||
311 | free_pages(first_page, order); | ||
312 | return NULL; | ||
313 | } | ||
314 | |||
315 | *dma_addrp = (iommu->page_table_map_base + | ||
316 | ((iopte - iommu->page_table) << IO_PAGE_SHIFT)); | ||
317 | ret = (void *) first_page; | ||
318 | npages = size >> IO_PAGE_SHIFT; | ||
319 | first_page = __pa(first_page); | ||
320 | while (npages--) { | ||
321 | iopte_val(*iopte) = (IOPTE_CONSISTENT(0UL) | | ||
322 | IOPTE_WRITE | | ||
323 | (first_page & IOPTE_PAGE)); | ||
324 | iopte++; | ||
325 | first_page += IO_PAGE_SIZE; | ||
326 | } | ||
327 | |||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | static void dma_4u_free_coherent(struct device *dev, size_t size, | ||
332 | void *cpu, dma_addr_t dvma) | ||
333 | { | ||
334 | struct iommu *iommu; | ||
335 | iopte_t *iopte; | ||
336 | unsigned long flags, order, npages; | ||
337 | |||
338 | npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; | ||
339 | iommu = dev->archdata.iommu; | ||
340 | iopte = iommu->page_table + | ||
341 | ((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | ||
342 | |||
343 | spin_lock_irqsave(&iommu->lock, flags); | ||
344 | |||
345 | iommu_range_free(iommu, dvma, npages); | ||
346 | |||
347 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
348 | |||
349 | order = get_order(size); | ||
350 | if (order < 10) | ||
351 | free_pages((unsigned long)cpu, order); | ||
352 | } | ||
353 | |||
354 | static dma_addr_t dma_4u_map_single(struct device *dev, void *ptr, size_t sz, | ||
355 | enum dma_data_direction direction) | ||
356 | { | ||
357 | struct iommu *iommu; | ||
358 | struct strbuf *strbuf; | ||
359 | iopte_t *base; | ||
360 | unsigned long flags, npages, oaddr; | ||
361 | unsigned long i, base_paddr, ctx; | ||
362 | u32 bus_addr, ret; | ||
363 | unsigned long iopte_protection; | ||
364 | |||
365 | iommu = dev->archdata.iommu; | ||
366 | strbuf = dev->archdata.stc; | ||
367 | |||
368 | if (unlikely(direction == DMA_NONE)) | ||
369 | goto bad_no_ctx; | ||
370 | |||
371 | oaddr = (unsigned long)ptr; | ||
372 | npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); | ||
373 | npages >>= IO_PAGE_SHIFT; | ||
374 | |||
375 | spin_lock_irqsave(&iommu->lock, flags); | ||
376 | base = alloc_npages(dev, iommu, npages); | ||
377 | ctx = 0; | ||
378 | if (iommu->iommu_ctxflush) | ||
379 | ctx = iommu_alloc_ctx(iommu); | ||
380 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
381 | |||
382 | if (unlikely(!base)) | ||
383 | goto bad; | ||
384 | |||
385 | bus_addr = (iommu->page_table_map_base + | ||
386 | ((base - iommu->page_table) << IO_PAGE_SHIFT)); | ||
387 | ret = bus_addr | (oaddr & ~IO_PAGE_MASK); | ||
388 | base_paddr = __pa(oaddr & IO_PAGE_MASK); | ||
389 | if (strbuf->strbuf_enabled) | ||
390 | iopte_protection = IOPTE_STREAMING(ctx); | ||
391 | else | ||
392 | iopte_protection = IOPTE_CONSISTENT(ctx); | ||
393 | if (direction != DMA_TO_DEVICE) | ||
394 | iopte_protection |= IOPTE_WRITE; | ||
395 | |||
396 | for (i = 0; i < npages; i++, base++, base_paddr += IO_PAGE_SIZE) | ||
397 | iopte_val(*base) = iopte_protection | base_paddr; | ||
398 | |||
399 | return ret; | ||
400 | |||
401 | bad: | ||
402 | iommu_free_ctx(iommu, ctx); | ||
403 | bad_no_ctx: | ||
404 | if (printk_ratelimit()) | ||
405 | WARN_ON(1); | ||
406 | return DMA_ERROR_CODE; | ||
407 | } | ||
408 | |||
409 | static void strbuf_flush(struct strbuf *strbuf, struct iommu *iommu, | ||
410 | u32 vaddr, unsigned long ctx, unsigned long npages, | ||
411 | enum dma_data_direction direction) | ||
412 | { | ||
413 | int limit; | ||
414 | |||
415 | if (strbuf->strbuf_ctxflush && | ||
416 | iommu->iommu_ctxflush) { | ||
417 | unsigned long matchreg, flushreg; | ||
418 | u64 val; | ||
419 | |||
420 | flushreg = strbuf->strbuf_ctxflush; | ||
421 | matchreg = STC_CTXMATCH_ADDR(strbuf, ctx); | ||
422 | |||
423 | iommu_write(flushreg, ctx); | ||
424 | val = iommu_read(matchreg); | ||
425 | val &= 0xffff; | ||
426 | if (!val) | ||
427 | goto do_flush_sync; | ||
428 | |||
429 | while (val) { | ||
430 | if (val & 0x1) | ||
431 | iommu_write(flushreg, ctx); | ||
432 | val >>= 1; | ||
433 | } | ||
434 | val = iommu_read(matchreg); | ||
435 | if (unlikely(val)) { | ||
436 | printk(KERN_WARNING "strbuf_flush: ctx flush " | ||
437 | "timeout matchreg[%lx] ctx[%lx]\n", | ||
438 | val, ctx); | ||
439 | goto do_page_flush; | ||
440 | } | ||
441 | } else { | ||
442 | unsigned long i; | ||
443 | |||
444 | do_page_flush: | ||
445 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | ||
446 | iommu_write(strbuf->strbuf_pflush, vaddr); | ||
447 | } | ||
448 | |||
449 | do_flush_sync: | ||
450 | /* If the device could not have possibly put dirty data into | ||
451 | * the streaming cache, no flush-flag synchronization needs | ||
452 | * to be performed. | ||
453 | */ | ||
454 | if (direction == DMA_TO_DEVICE) | ||
455 | return; | ||
456 | |||
457 | STC_FLUSHFLAG_INIT(strbuf); | ||
458 | iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
459 | (void) iommu_read(iommu->write_complete_reg); | ||
460 | |||
461 | limit = 100000; | ||
462 | while (!STC_FLUSHFLAG_SET(strbuf)) { | ||
463 | limit--; | ||
464 | if (!limit) | ||
465 | break; | ||
466 | udelay(1); | ||
467 | rmb(); | ||
468 | } | ||
469 | if (!limit) | ||
470 | printk(KERN_WARNING "strbuf_flush: flushflag timeout " | ||
471 | "vaddr[%08x] ctx[%lx] npages[%ld]\n", | ||
472 | vaddr, ctx, npages); | ||
473 | } | ||
474 | |||
475 | static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr, | ||
476 | size_t sz, enum dma_data_direction direction) | ||
477 | { | ||
478 | struct iommu *iommu; | ||
479 | struct strbuf *strbuf; | ||
480 | iopte_t *base; | ||
481 | unsigned long flags, npages, ctx, i; | ||
482 | |||
483 | if (unlikely(direction == DMA_NONE)) { | ||
484 | if (printk_ratelimit()) | ||
485 | WARN_ON(1); | ||
486 | return; | ||
487 | } | ||
488 | |||
489 | iommu = dev->archdata.iommu; | ||
490 | strbuf = dev->archdata.stc; | ||
491 | |||
492 | npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); | ||
493 | npages >>= IO_PAGE_SHIFT; | ||
494 | base = iommu->page_table + | ||
495 | ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | ||
496 | bus_addr &= IO_PAGE_MASK; | ||
497 | |||
498 | spin_lock_irqsave(&iommu->lock, flags); | ||
499 | |||
500 | /* Record the context, if any. */ | ||
501 | ctx = 0; | ||
502 | if (iommu->iommu_ctxflush) | ||
503 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; | ||
504 | |||
505 | /* Step 1: Kick data out of streaming buffers if necessary. */ | ||
506 | if (strbuf->strbuf_enabled) | ||
507 | strbuf_flush(strbuf, iommu, bus_addr, ctx, | ||
508 | npages, direction); | ||
509 | |||
510 | /* Step 2: Clear out TSB entries. */ | ||
511 | for (i = 0; i < npages; i++) | ||
512 | iopte_make_dummy(iommu, base + i); | ||
513 | |||
514 | iommu_range_free(iommu, bus_addr, npages); | ||
515 | |||
516 | iommu_free_ctx(iommu, ctx); | ||
517 | |||
518 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
519 | } | ||
520 | |||
521 | static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, | ||
522 | int nelems, enum dma_data_direction direction) | ||
523 | { | ||
524 | struct scatterlist *s, *outs, *segstart; | ||
525 | unsigned long flags, handle, prot, ctx; | ||
526 | dma_addr_t dma_next = 0, dma_addr; | ||
527 | unsigned int max_seg_size; | ||
528 | unsigned long seg_boundary_size; | ||
529 | int outcount, incount, i; | ||
530 | struct strbuf *strbuf; | ||
531 | struct iommu *iommu; | ||
532 | unsigned long base_shift; | ||
533 | |||
534 | BUG_ON(direction == DMA_NONE); | ||
535 | |||
536 | iommu = dev->archdata.iommu; | ||
537 | strbuf = dev->archdata.stc; | ||
538 | if (nelems == 0 || !iommu) | ||
539 | return 0; | ||
540 | |||
541 | spin_lock_irqsave(&iommu->lock, flags); | ||
542 | |||
543 | ctx = 0; | ||
544 | if (iommu->iommu_ctxflush) | ||
545 | ctx = iommu_alloc_ctx(iommu); | ||
546 | |||
547 | if (strbuf->strbuf_enabled) | ||
548 | prot = IOPTE_STREAMING(ctx); | ||
549 | else | ||
550 | prot = IOPTE_CONSISTENT(ctx); | ||
551 | if (direction != DMA_TO_DEVICE) | ||
552 | prot |= IOPTE_WRITE; | ||
553 | |||
554 | outs = s = segstart = &sglist[0]; | ||
555 | outcount = 1; | ||
556 | incount = nelems; | ||
557 | handle = 0; | ||
558 | |||
559 | /* Init first segment length for backout at failure */ | ||
560 | outs->dma_length = 0; | ||
561 | |||
562 | max_seg_size = dma_get_max_seg_size(dev); | ||
563 | seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, | ||
564 | IO_PAGE_SIZE) >> IO_PAGE_SHIFT; | ||
565 | base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT; | ||
566 | for_each_sg(sglist, s, nelems, i) { | ||
567 | unsigned long paddr, npages, entry, out_entry = 0, slen; | ||
568 | iopte_t *base; | ||
569 | |||
570 | slen = s->length; | ||
571 | /* Sanity check */ | ||
572 | if (slen == 0) { | ||
573 | dma_next = 0; | ||
574 | continue; | ||
575 | } | ||
576 | /* Allocate iommu entries for that segment */ | ||
577 | paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s); | ||
578 | npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE); | ||
579 | entry = iommu_range_alloc(dev, iommu, npages, &handle); | ||
580 | |||
581 | /* Handle failure */ | ||
582 | if (unlikely(entry == DMA_ERROR_CODE)) { | ||
583 | if (printk_ratelimit()) | ||
584 | printk(KERN_INFO "iommu_alloc failed, iommu %p paddr %lx" | ||
585 | " npages %lx\n", iommu, paddr, npages); | ||
586 | goto iommu_map_failed; | ||
587 | } | ||
588 | |||
589 | base = iommu->page_table + entry; | ||
590 | |||
591 | /* Convert entry to a dma_addr_t */ | ||
592 | dma_addr = iommu->page_table_map_base + | ||
593 | (entry << IO_PAGE_SHIFT); | ||
594 | dma_addr |= (s->offset & ~IO_PAGE_MASK); | ||
595 | |||
596 | /* Insert into HW table */ | ||
597 | paddr &= IO_PAGE_MASK; | ||
598 | while (npages--) { | ||
599 | iopte_val(*base) = prot | paddr; | ||
600 | base++; | ||
601 | paddr += IO_PAGE_SIZE; | ||
602 | } | ||
603 | |||
604 | /* If we are in an open segment, try merging */ | ||
605 | if (segstart != s) { | ||
606 | /* We cannot merge if: | ||
607 | * - allocated dma_addr isn't contiguous to previous allocation | ||
608 | */ | ||
609 | if ((dma_addr != dma_next) || | ||
610 | (outs->dma_length + s->length > max_seg_size) || | ||
611 | (is_span_boundary(out_entry, base_shift, | ||
612 | seg_boundary_size, outs, s))) { | ||
613 | /* Can't merge: create a new segment */ | ||
614 | segstart = s; | ||
615 | outcount++; | ||
616 | outs = sg_next(outs); | ||
617 | } else { | ||
618 | outs->dma_length += s->length; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | if (segstart == s) { | ||
623 | /* This is a new segment, fill entries */ | ||
624 | outs->dma_address = dma_addr; | ||
625 | outs->dma_length = slen; | ||
626 | out_entry = entry; | ||
627 | } | ||
628 | |||
629 | /* Calculate next page pointer for contiguous check */ | ||
630 | dma_next = dma_addr + slen; | ||
631 | } | ||
632 | |||
633 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
634 | |||
635 | if (outcount < incount) { | ||
636 | outs = sg_next(outs); | ||
637 | outs->dma_address = DMA_ERROR_CODE; | ||
638 | outs->dma_length = 0; | ||
639 | } | ||
640 | |||
641 | return outcount; | ||
642 | |||
643 | iommu_map_failed: | ||
644 | for_each_sg(sglist, s, nelems, i) { | ||
645 | if (s->dma_length != 0) { | ||
646 | unsigned long vaddr, npages, entry, j; | ||
647 | iopte_t *base; | ||
648 | |||
649 | vaddr = s->dma_address & IO_PAGE_MASK; | ||
650 | npages = iommu_num_pages(s->dma_address, s->dma_length, | ||
651 | IO_PAGE_SIZE); | ||
652 | iommu_range_free(iommu, vaddr, npages); | ||
653 | |||
654 | entry = (vaddr - iommu->page_table_map_base) | ||
655 | >> IO_PAGE_SHIFT; | ||
656 | base = iommu->page_table + entry; | ||
657 | |||
658 | for (j = 0; j < npages; j++) | ||
659 | iopte_make_dummy(iommu, base + j); | ||
660 | |||
661 | s->dma_address = DMA_ERROR_CODE; | ||
662 | s->dma_length = 0; | ||
663 | } | ||
664 | if (s == outs) | ||
665 | break; | ||
666 | } | ||
667 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
668 | |||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | /* If contexts are being used, they are the same in all of the mappings | ||
673 | * we make for a particular SG. | ||
674 | */ | ||
675 | static unsigned long fetch_sg_ctx(struct iommu *iommu, struct scatterlist *sg) | ||
676 | { | ||
677 | unsigned long ctx = 0; | ||
678 | |||
679 | if (iommu->iommu_ctxflush) { | ||
680 | iopte_t *base; | ||
681 | u32 bus_addr; | ||
682 | |||
683 | bus_addr = sg->dma_address & IO_PAGE_MASK; | ||
684 | base = iommu->page_table + | ||
685 | ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | ||
686 | |||
687 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; | ||
688 | } | ||
689 | return ctx; | ||
690 | } | ||
691 | |||
692 | static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, | ||
693 | int nelems, enum dma_data_direction direction) | ||
694 | { | ||
695 | unsigned long flags, ctx; | ||
696 | struct scatterlist *sg; | ||
697 | struct strbuf *strbuf; | ||
698 | struct iommu *iommu; | ||
699 | |||
700 | BUG_ON(direction == DMA_NONE); | ||
701 | |||
702 | iommu = dev->archdata.iommu; | ||
703 | strbuf = dev->archdata.stc; | ||
704 | |||
705 | ctx = fetch_sg_ctx(iommu, sglist); | ||
706 | |||
707 | spin_lock_irqsave(&iommu->lock, flags); | ||
708 | |||
709 | sg = sglist; | ||
710 | while (nelems--) { | ||
711 | dma_addr_t dma_handle = sg->dma_address; | ||
712 | unsigned int len = sg->dma_length; | ||
713 | unsigned long npages, entry; | ||
714 | iopte_t *base; | ||
715 | int i; | ||
716 | |||
717 | if (!len) | ||
718 | break; | ||
719 | npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE); | ||
720 | iommu_range_free(iommu, dma_handle, npages); | ||
721 | |||
722 | entry = ((dma_handle - iommu->page_table_map_base) | ||
723 | >> IO_PAGE_SHIFT); | ||
724 | base = iommu->page_table + entry; | ||
725 | |||
726 | dma_handle &= IO_PAGE_MASK; | ||
727 | if (strbuf->strbuf_enabled) | ||
728 | strbuf_flush(strbuf, iommu, dma_handle, ctx, | ||
729 | npages, direction); | ||
730 | |||
731 | for (i = 0; i < npages; i++) | ||
732 | iopte_make_dummy(iommu, base + i); | ||
733 | |||
734 | sg = sg_next(sg); | ||
735 | } | ||
736 | |||
737 | iommu_free_ctx(iommu, ctx); | ||
738 | |||
739 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
740 | } | ||
741 | |||
742 | static void dma_4u_sync_single_for_cpu(struct device *dev, | ||
743 | dma_addr_t bus_addr, size_t sz, | ||
744 | enum dma_data_direction direction) | ||
745 | { | ||
746 | struct iommu *iommu; | ||
747 | struct strbuf *strbuf; | ||
748 | unsigned long flags, ctx, npages; | ||
749 | |||
750 | iommu = dev->archdata.iommu; | ||
751 | strbuf = dev->archdata.stc; | ||
752 | |||
753 | if (!strbuf->strbuf_enabled) | ||
754 | return; | ||
755 | |||
756 | spin_lock_irqsave(&iommu->lock, flags); | ||
757 | |||
758 | npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); | ||
759 | npages >>= IO_PAGE_SHIFT; | ||
760 | bus_addr &= IO_PAGE_MASK; | ||
761 | |||
762 | /* Step 1: Record the context, if any. */ | ||
763 | ctx = 0; | ||
764 | if (iommu->iommu_ctxflush && | ||
765 | strbuf->strbuf_ctxflush) { | ||
766 | iopte_t *iopte; | ||
767 | |||
768 | iopte = iommu->page_table + | ||
769 | ((bus_addr - iommu->page_table_map_base)>>IO_PAGE_SHIFT); | ||
770 | ctx = (iopte_val(*iopte) & IOPTE_CONTEXT) >> 47UL; | ||
771 | } | ||
772 | |||
773 | /* Step 2: Kick data out of streaming buffers. */ | ||
774 | strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); | ||
775 | |||
776 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
777 | } | ||
778 | |||
779 | static void dma_4u_sync_sg_for_cpu(struct device *dev, | ||
780 | struct scatterlist *sglist, int nelems, | ||
781 | enum dma_data_direction direction) | ||
782 | { | ||
783 | struct iommu *iommu; | ||
784 | struct strbuf *strbuf; | ||
785 | unsigned long flags, ctx, npages, i; | ||
786 | struct scatterlist *sg, *sgprv; | ||
787 | u32 bus_addr; | ||
788 | |||
789 | iommu = dev->archdata.iommu; | ||
790 | strbuf = dev->archdata.stc; | ||
791 | |||
792 | if (!strbuf->strbuf_enabled) | ||
793 | return; | ||
794 | |||
795 | spin_lock_irqsave(&iommu->lock, flags); | ||
796 | |||
797 | /* Step 1: Record the context, if any. */ | ||
798 | ctx = 0; | ||
799 | if (iommu->iommu_ctxflush && | ||
800 | strbuf->strbuf_ctxflush) { | ||
801 | iopte_t *iopte; | ||
802 | |||
803 | iopte = iommu->page_table + | ||
804 | ((sglist[0].dma_address - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | ||
805 | ctx = (iopte_val(*iopte) & IOPTE_CONTEXT) >> 47UL; | ||
806 | } | ||
807 | |||
808 | /* Step 2: Kick data out of streaming buffers. */ | ||
809 | bus_addr = sglist[0].dma_address & IO_PAGE_MASK; | ||
810 | sgprv = NULL; | ||
811 | for_each_sg(sglist, sg, nelems, i) { | ||
812 | if (sg->dma_length == 0) | ||
813 | break; | ||
814 | sgprv = sg; | ||
815 | } | ||
816 | |||
817 | npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) | ||
818 | - bus_addr) >> IO_PAGE_SHIFT; | ||
819 | strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); | ||
820 | |||
821 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
822 | } | ||
823 | |||
824 | static const struct dma_ops sun4u_dma_ops = { | ||
825 | .alloc_coherent = dma_4u_alloc_coherent, | ||
826 | .free_coherent = dma_4u_free_coherent, | ||
827 | .map_single = dma_4u_map_single, | ||
828 | .unmap_single = dma_4u_unmap_single, | ||
829 | .map_sg = dma_4u_map_sg, | ||
830 | .unmap_sg = dma_4u_unmap_sg, | ||
831 | .sync_single_for_cpu = dma_4u_sync_single_for_cpu, | ||
832 | .sync_sg_for_cpu = dma_4u_sync_sg_for_cpu, | ||
833 | }; | ||
834 | |||
835 | const struct dma_ops *dma_ops = &sun4u_dma_ops; | ||
836 | EXPORT_SYMBOL(dma_ops); | ||
837 | |||
838 | int dma_supported(struct device *dev, u64 device_mask) | ||
839 | { | ||
840 | struct iommu *iommu = dev->archdata.iommu; | ||
841 | u64 dma_addr_mask = iommu->dma_addr_mask; | ||
842 | |||
843 | if (device_mask >= (1UL << 32UL)) | ||
844 | return 0; | ||
845 | |||
846 | if ((device_mask & dma_addr_mask) == dma_addr_mask) | ||
847 | return 1; | ||
848 | |||
849 | #ifdef CONFIG_PCI | ||
850 | if (dev->bus == &pci_bus_type) | ||
851 | return pci_dma_supported(to_pci_dev(dev), device_mask); | ||
852 | #endif | ||
853 | |||
854 | return 0; | ||
855 | } | ||
856 | EXPORT_SYMBOL(dma_supported); | ||
857 | |||
858 | int dma_set_mask(struct device *dev, u64 dma_mask) | ||
859 | { | ||
860 | #ifdef CONFIG_PCI | ||
861 | if (dev->bus == &pci_bus_type) | ||
862 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | ||
863 | #endif | ||
864 | return -EINVAL; | ||
865 | } | ||
866 | EXPORT_SYMBOL(dma_set_mask); | ||