sparc: Remove generic SBUS probing layer.
[linux-2.6.git] / arch / sparc / mm / io-unit.c
1 /*
2  * io-unit.c:  IO-UNIT specific routines for memory management.
3  *
4  * Copyright (C) 1997,1998 Jakub Jelinek    (jj@sunsite.mff.cuni.cz)
5  */
6  
7 #include <linux/kernel.h>
8 #include <linux/init.h>
9 #include <linux/slab.h>
10 #include <linux/spinlock.h>
11 #include <linux/mm.h>
12 #include <linux/highmem.h>      /* pte_offset_map => kmap_atomic */
13 #include <linux/bitops.h>
14 #include <linux/scatterlist.h>
15
16 #include <asm/pgalloc.h>
17 #include <asm/pgtable.h>
18 #include <asm/sbus.h>
19 #include <asm/io.h>
20 #include <asm/io-unit.h>
21 #include <asm/mxcc.h>
22 #include <asm/cacheflush.h>
23 #include <asm/tlbflush.h>
24 #include <asm/dma.h>
25 #include <asm/oplib.h>
26
27 /* #define IOUNIT_DEBUG */
28 #ifdef IOUNIT_DEBUG
29 #define IOD(x) printk(x)
30 #else
31 #define IOD(x) do { } while (0)
32 #endif
33
34 #define IOPERM        (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID)
35 #define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM)
36
37 static void __init iounit_iommu_init(struct of_device *op)
38 {
39         struct iounit_struct *iounit;
40         iopte_t *xpt, *xptend;
41
42         iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
43         if (!iounit) {
44                 prom_printf("SUN4D: Cannot alloc iounit, halting.\n");
45                 prom_halt();
46         }
47
48         iounit->limit[0] = IOUNIT_BMAP1_START;
49         iounit->limit[1] = IOUNIT_BMAP2_START;
50         iounit->limit[2] = IOUNIT_BMAPM_START;
51         iounit->limit[3] = IOUNIT_BMAPM_END;
52         iounit->rotor[1] = IOUNIT_BMAP2_START;
53         iounit->rotor[2] = IOUNIT_BMAPM_START;
54
55         xpt = of_ioremap(&op->resource[2], 0, PAGE_SIZE * 16, "XPT");
56         if (!xpt) {
57                 prom_printf("SUN4D: Cannot map External Page Table.");
58                 prom_halt();
59         }
60         
61         op->dev.archdata.iommu = iounit;
62         iounit->page_table = xpt;
63         spin_lock_init(&iounit->lock);
64         
65         for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t);
66              xpt < xptend;)
67                 iopte_val(*xpt++) = 0;
68 }
69
70 static int __init iounit_init(void)
71 {
72         extern void sun4d_init_sbi_irq(void);
73         struct device_node *dp;
74
75         for_each_node_by_name(dp, "sbi") {
76                 struct of_device *op = of_find_device_by_node(dp);
77
78                 iounit_iommu_init(op);
79                 of_propagate_archdata(op);
80         }
81
82         sun4d_init_sbi_irq();
83
84         return 0;
85 }
86
87 subsys_initcall(iounit_init);
88
89 /* One has to hold iounit->lock to call this */
90 static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size)
91 {
92         int i, j, k, npages;
93         unsigned long rotor, scan, limit;
94         iopte_t iopte;
95
96         npages = ((vaddr & ~PAGE_MASK) + size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
97
98         /* A tiny bit of magic ingredience :) */
99         switch (npages) {
100         case 1: i = 0x0231; break;
101         case 2: i = 0x0132; break;
102         default: i = 0x0213; break;
103         }
104         
105         IOD(("iounit_get_area(%08lx,%d[%d])=", vaddr, size, npages));
106         
107 next:   j = (i & 15);
108         rotor = iounit->rotor[j - 1];
109         limit = iounit->limit[j];
110         scan = rotor;
111 nexti:  scan = find_next_zero_bit(iounit->bmap, limit, scan);
112         if (scan + npages > limit) {
113                 if (limit != rotor) {
114                         limit = rotor;
115                         scan = iounit->limit[j - 1];
116                         goto nexti;
117                 }
118                 i >>= 4;
119                 if (!(i & 15))
120                         panic("iounit_get_area: Couldn't find free iopte slots for (%08lx,%d)\n", vaddr, size);
121                 goto next;
122         }
123         for (k = 1, scan++; k < npages; k++)
124                 if (test_bit(scan++, iounit->bmap))
125                         goto nexti;
126         iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1];
127         scan -= npages;
128         iopte = MKIOPTE(__pa(vaddr & PAGE_MASK));
129         vaddr = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + (vaddr & ~PAGE_MASK);
130         for (k = 0; k < npages; k++, iopte = __iopte(iopte_val(iopte) + 0x100), scan++) {
131                 set_bit(scan, iounit->bmap);
132                 iounit->page_table[scan] = iopte;
133         }
134         IOD(("%08lx\n", vaddr));
135         return vaddr;
136 }
137
138 static __u32 iounit_get_scsi_one(struct device *dev, char *vaddr, unsigned long len)
139 {
140         struct iounit_struct *iounit = dev->archdata.iommu;
141         unsigned long ret, flags;
142         
143         spin_lock_irqsave(&iounit->lock, flags);
144         ret = iounit_get_area(iounit, (unsigned long)vaddr, len);
145         spin_unlock_irqrestore(&iounit->lock, flags);
146         return ret;
147 }
148
149 static void iounit_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
150 {
151         struct iounit_struct *iounit = dev->archdata.iommu;
152         unsigned long flags;
153
154         /* FIXME: Cache some resolved pages - often several sg entries are to the same page */
155         spin_lock_irqsave(&iounit->lock, flags);
156         while (sz != 0) {
157                 --sz;
158                 sg->dvma_address = iounit_get_area(iounit, (unsigned long) sg_virt(sg), sg->length);
159                 sg->dvma_length = sg->length;
160                 sg = sg_next(sg);
161         }
162         spin_unlock_irqrestore(&iounit->lock, flags);
163 }
164
165 static void iounit_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len)
166 {
167         struct iounit_struct *iounit = dev->archdata.iommu;
168         unsigned long flags;
169         
170         spin_lock_irqsave(&iounit->lock, flags);
171         len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT;
172         vaddr = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
173         IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr));
174         for (len += vaddr; vaddr < len; vaddr++)
175                 clear_bit(vaddr, iounit->bmap);
176         spin_unlock_irqrestore(&iounit->lock, flags);
177 }
178
179 static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
180 {
181         struct iounit_struct *iounit = dev->archdata.iommu;
182         unsigned long flags;
183         unsigned long vaddr, len;
184
185         spin_lock_irqsave(&iounit->lock, flags);
186         while (sz != 0) {
187                 --sz;
188                 len = ((sg->dvma_address & ~PAGE_MASK) + sg->length + (PAGE_SIZE-1)) >> PAGE_SHIFT;
189                 vaddr = (sg->dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
190                 IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr));
191                 for (len += vaddr; vaddr < len; vaddr++)
192                         clear_bit(vaddr, iounit->bmap);
193                 sg = sg_next(sg);
194         }
195         spin_unlock_irqrestore(&iounit->lock, flags);
196 }
197
198 #ifdef CONFIG_SBUS
199 static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len)
200 {
201         struct iounit_struct *iounit = dev->archdata.iommu;
202         unsigned long page, end;
203         pgprot_t dvma_prot;
204         iopte_t *iopte;
205
206         *pba = addr;
207
208         dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);
209         end = PAGE_ALIGN((addr + len));
210         while(addr < end) {
211                 page = va;
212                 {
213                         pgd_t *pgdp;
214                         pmd_t *pmdp;
215                         pte_t *ptep;
216                         long i;
217
218                         pgdp = pgd_offset(&init_mm, addr);
219                         pmdp = pmd_offset(pgdp, addr);
220                         ptep = pte_offset_map(pmdp, addr);
221
222                         set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
223                         
224                         i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT);
225
226                         iopte = (iopte_t *)(iounit->page_table + i);
227                         *iopte = MKIOPTE(__pa(page));
228                 }
229                 addr += PAGE_SIZE;
230                 va += PAGE_SIZE;
231         }
232         flush_cache_all();
233         flush_tlb_all();
234
235         return 0;
236 }
237
238 static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int len)
239 {
240         /* XXX Somebody please fill this in */
241 }
242 #endif
243
244 static char *iounit_lockarea(char *vaddr, unsigned long len)
245 {
246 /* FIXME: Write this */
247         return vaddr;
248 }
249
250 static void iounit_unlockarea(char *vaddr, unsigned long len)
251 {
252 /* FIXME: Write this */
253 }
254
255 void __init ld_mmu_iounit(void)
256 {
257         BTFIXUPSET_CALL(mmu_lockarea, iounit_lockarea, BTFIXUPCALL_RETO0);
258         BTFIXUPSET_CALL(mmu_unlockarea, iounit_unlockarea, BTFIXUPCALL_NOP);
259
260         BTFIXUPSET_CALL(mmu_get_scsi_one, iounit_get_scsi_one, BTFIXUPCALL_NORM);
261         BTFIXUPSET_CALL(mmu_get_scsi_sgl, iounit_get_scsi_sgl, BTFIXUPCALL_NORM);
262         BTFIXUPSET_CALL(mmu_release_scsi_one, iounit_release_scsi_one, BTFIXUPCALL_NORM);
263         BTFIXUPSET_CALL(mmu_release_scsi_sgl, iounit_release_scsi_sgl, BTFIXUPCALL_NORM);
264
265 #ifdef CONFIG_SBUS
266         BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM);
267         BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM);
268 #endif
269 }
270
271 __u32 iounit_map_dma_init(struct sbus_bus *sbus, int size)
272 {
273         int i, j, k, npages;
274         unsigned long rotor, scan, limit;
275         unsigned long flags;
276         __u32 ret;
277         struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
278
279         npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
280         i = 0x0213;
281         spin_lock_irqsave(&iounit->lock, flags);
282 next:   j = (i & 15);
283         rotor = iounit->rotor[j - 1];
284         limit = iounit->limit[j];
285         scan = rotor;
286 nexti:  scan = find_next_zero_bit(iounit->bmap, limit, scan);
287         if (scan + npages > limit) {
288                 if (limit != rotor) {
289                         limit = rotor;
290                         scan = iounit->limit[j - 1];
291                         goto nexti;
292                 }
293                 i >>= 4;
294                 if (!(i & 15))
295                         panic("iounit_map_dma_init: Couldn't find free iopte slots for %d bytes\n", size);
296                 goto next;
297         }
298         for (k = 1, scan++; k < npages; k++)
299                 if (test_bit(scan++, iounit->bmap))
300                         goto nexti;
301         iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1];
302         scan -= npages;
303         ret = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT);
304         for (k = 0; k < npages; k++, scan++)
305                 set_bit(scan, iounit->bmap);
306         spin_unlock_irqrestore(&iounit->lock, flags);
307         return ret;
308 }
309
310 __u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus)
311 {
312         int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
313         struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
314         
315         iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK));
316         return vaddr + (((unsigned long)addr) & ~PAGE_MASK);
317 }