aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/sbus.c
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-12-03 06:11:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-04 12:17:21 -0500
commita88b5ba8bd8ac18aad65ee6c6a254e2e74876db3 (patch)
treeeb3d0ffaf53c3f7ec6083752c2097cecd1cb892a /arch/sparc/kernel/sbus.c
parentd670bd4f803c8b646acd20f3ba21e65458293faf (diff)
sparc,sparc64: unify kernel/
o Move all files from sparc64/kernel/ to sparc/kernel - rename as appropriate o Update sparc/Makefile to the changes o Update sparc/kernel/Makefile to include the sparc64 files NOTE: This commit changes link order on sparc64! Link order had to change for either of sparc32 and sparc64. And assuming sparc64 see more testing than sparc32 change link order on sparc64 where issues will be caught faster. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/sbus.c')
-rw-r--r--arch/sparc/kernel/sbus.c674
1 files changed, 674 insertions, 0 deletions
diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c
new file mode 100644
index 000000000000..2ead310066d1
--- /dev/null
+++ b/arch/sparc/kernel/sbus.c
@@ -0,0 +1,674 @@
1/*
2 * sbus.c: UltraSparc SBUS controller support.
3 *
4 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
5 */
6
7#include <linux/kernel.h>
8#include <linux/types.h>
9#include <linux/mm.h>
10#include <linux/spinlock.h>
11#include <linux/slab.h>
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16
17#include <asm/page.h>
18#include <asm/io.h>
19#include <asm/upa.h>
20#include <asm/cache.h>
21#include <asm/dma.h>
22#include <asm/irq.h>
23#include <asm/prom.h>
24#include <asm/oplib.h>
25#include <asm/starfire.h>
26
27#include "iommu_common.h"
28
29#define MAP_BASE ((u32)0xc0000000)
30
31/* Offsets from iommu_regs */
32#define SYSIO_IOMMUREG_BASE 0x2400UL
33#define IOMMU_CONTROL (0x2400UL - 0x2400UL) /* IOMMU control register */
34#define IOMMU_TSBBASE (0x2408UL - 0x2400UL) /* TSB base address register */
35#define IOMMU_FLUSH (0x2410UL - 0x2400UL) /* IOMMU flush register */
36#define IOMMU_VADIAG (0x4400UL - 0x2400UL) /* SBUS virtual address diagnostic */
37#define IOMMU_TAGCMP (0x4408UL - 0x2400UL) /* TLB tag compare diagnostics */
38#define IOMMU_LRUDIAG (0x4500UL - 0x2400UL) /* IOMMU LRU queue diagnostics */
39#define IOMMU_TAGDIAG (0x4580UL - 0x2400UL) /* TLB tag diagnostics */
40#define IOMMU_DRAMDIAG (0x4600UL - 0x2400UL) /* TLB data RAM diagnostics */
41
42#define IOMMU_DRAM_VALID (1UL << 30UL)
43
44/* Offsets from strbuf_regs */
45#define SYSIO_STRBUFREG_BASE 0x2800UL
46#define STRBUF_CONTROL (0x2800UL - 0x2800UL) /* Control */
47#define STRBUF_PFLUSH (0x2808UL - 0x2800UL) /* Page flush/invalidate */
48#define STRBUF_FSYNC (0x2810UL - 0x2800UL) /* Flush synchronization */
49#define STRBUF_DRAMDIAG (0x5000UL - 0x2800UL) /* data RAM diagnostic */
50#define STRBUF_ERRDIAG (0x5400UL - 0x2800UL) /* error status diagnostics */
51#define STRBUF_PTAGDIAG (0x5800UL - 0x2800UL) /* Page tag diagnostics */
52#define STRBUF_LTAGDIAG (0x5900UL - 0x2800UL) /* Line tag diagnostics */
53
54#define STRBUF_TAG_VALID 0x02UL
55
56/* Enable 64-bit DVMA mode for the given device. */
57void sbus_set_sbus64(struct device *dev, int bursts)
58{
59 struct iommu *iommu = dev->archdata.iommu;
60 struct of_device *op = to_of_device(dev);
61 const struct linux_prom_registers *regs;
62 unsigned long cfg_reg;
63 int slot;
64 u64 val;
65
66 regs = of_get_property(op->node, "reg", NULL);
67 if (!regs) {
68 printk(KERN_ERR "sbus_set_sbus64: Cannot find regs for %s\n",
69 op->node->full_name);
70 return;
71 }
72 slot = regs->which_io;
73
74 cfg_reg = iommu->write_complete_reg;
75 switch (slot) {
76 case 0:
77 cfg_reg += 0x20UL;
78 break;
79 case 1:
80 cfg_reg += 0x28UL;
81 break;
82 case 2:
83 cfg_reg += 0x30UL;
84 break;
85 case 3:
86 cfg_reg += 0x38UL;
87 break;
88 case 13:
89 cfg_reg += 0x40UL;
90 break;
91 case 14:
92 cfg_reg += 0x48UL;
93 break;
94 case 15:
95 cfg_reg += 0x50UL;
96 break;
97
98 default:
99 return;
100 };
101
102 val = upa_readq(cfg_reg);
103 if (val & (1UL << 14UL)) {
104 /* Extended transfer mode already enabled. */
105 return;
106 }
107
108 val |= (1UL << 14UL);
109
110 if (bursts & DMA_BURST8)
111 val |= (1UL << 1UL);
112 if (bursts & DMA_BURST16)
113 val |= (1UL << 2UL);
114 if (bursts & DMA_BURST32)
115 val |= (1UL << 3UL);
116 if (bursts & DMA_BURST64)
117 val |= (1UL << 4UL);
118 upa_writeq(val, cfg_reg);
119}
120
121/* INO number to IMAP register offset for SYSIO external IRQ's.
122 * This should conform to both Sunfire/Wildfire server and Fusion
123 * desktop designs.
124 */
125#define SYSIO_IMAP_SLOT0 0x2c00UL
126#define SYSIO_IMAP_SLOT1 0x2c08UL
127#define SYSIO_IMAP_SLOT2 0x2c10UL
128#define SYSIO_IMAP_SLOT3 0x2c18UL
129#define SYSIO_IMAP_SCSI 0x3000UL
130#define SYSIO_IMAP_ETH 0x3008UL
131#define SYSIO_IMAP_BPP 0x3010UL
132#define SYSIO_IMAP_AUDIO 0x3018UL
133#define SYSIO_IMAP_PFAIL 0x3020UL
134#define SYSIO_IMAP_KMS 0x3028UL
135#define SYSIO_IMAP_FLPY 0x3030UL
136#define SYSIO_IMAP_SHW 0x3038UL
137#define SYSIO_IMAP_KBD 0x3040UL
138#define SYSIO_IMAP_MS 0x3048UL
139#define SYSIO_IMAP_SER 0x3050UL
140#define SYSIO_IMAP_TIM0 0x3060UL
141#define SYSIO_IMAP_TIM1 0x3068UL
142#define SYSIO_IMAP_UE 0x3070UL
143#define SYSIO_IMAP_CE 0x3078UL
144#define SYSIO_IMAP_SBERR 0x3080UL
145#define SYSIO_IMAP_PMGMT 0x3088UL
146#define SYSIO_IMAP_GFX 0x3090UL
147#define SYSIO_IMAP_EUPA 0x3098UL
148
149#define bogon ((unsigned long) -1)
150static unsigned long sysio_irq_offsets[] = {
151 /* SBUS Slot 0 --> 3, level 1 --> 7 */
152 SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
153 SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0,
154 SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
155 SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1,
156 SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
157 SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2,
158 SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
159 SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3,
160
161 /* Onboard devices (not relevant/used on SunFire). */
162 SYSIO_IMAP_SCSI,
163 SYSIO_IMAP_ETH,
164 SYSIO_IMAP_BPP,
165 bogon,
166 SYSIO_IMAP_AUDIO,
167 SYSIO_IMAP_PFAIL,
168 bogon,
169 bogon,
170 SYSIO_IMAP_KMS,
171 SYSIO_IMAP_FLPY,
172 SYSIO_IMAP_SHW,
173 SYSIO_IMAP_KBD,
174 SYSIO_IMAP_MS,
175 SYSIO_IMAP_SER,
176 bogon,
177 bogon,
178 SYSIO_IMAP_TIM0,
179 SYSIO_IMAP_TIM1,
180 bogon,
181 bogon,
182 SYSIO_IMAP_UE,
183 SYSIO_IMAP_CE,
184 SYSIO_IMAP_SBERR,
185 SYSIO_IMAP_PMGMT,
186};
187
188#undef bogon
189
190#define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets)
191
192/* Convert Interrupt Mapping register pointer to associated
193 * Interrupt Clear register pointer, SYSIO specific version.
194 */
195#define SYSIO_ICLR_UNUSED0 0x3400UL
196#define SYSIO_ICLR_SLOT0 0x3408UL
197#define SYSIO_ICLR_SLOT1 0x3448UL
198#define SYSIO_ICLR_SLOT2 0x3488UL
199#define SYSIO_ICLR_SLOT3 0x34c8UL
200static unsigned long sysio_imap_to_iclr(unsigned long imap)
201{
202 unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0;
203 return imap + diff;
204}
205
206static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino)
207{
208 struct iommu *iommu = op->dev.archdata.iommu;
209 unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
210 unsigned long imap, iclr;
211 int sbus_level = 0;
212
213 imap = sysio_irq_offsets[ino];
214 if (imap == ((unsigned long)-1)) {
215 prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n",
216 ino);
217 prom_halt();
218 }
219 imap += reg_base;
220
221 /* SYSIO inconsistency. For external SLOTS, we have to select
222 * the right ICLR register based upon the lower SBUS irq level
223 * bits.
224 */
225 if (ino >= 0x20) {
226 iclr = sysio_imap_to_iclr(imap);
227 } else {
228 int sbus_slot = (ino & 0x18)>>3;
229
230 sbus_level = ino & 0x7;
231
232 switch(sbus_slot) {
233 case 0:
234 iclr = reg_base + SYSIO_ICLR_SLOT0;
235 break;
236 case 1:
237 iclr = reg_base + SYSIO_ICLR_SLOT1;
238 break;
239 case 2:
240 iclr = reg_base + SYSIO_ICLR_SLOT2;
241 break;
242 default:
243 case 3:
244 iclr = reg_base + SYSIO_ICLR_SLOT3;
245 break;
246 };
247
248 iclr += ((unsigned long)sbus_level - 1UL) * 8UL;
249 }
250 return build_irq(sbus_level, iclr, imap);
251}
252
253/* Error interrupt handling. */
254#define SYSIO_UE_AFSR 0x0030UL
255#define SYSIO_UE_AFAR 0x0038UL
256#define SYSIO_UEAFSR_PPIO 0x8000000000000000UL /* Primary PIO cause */
257#define SYSIO_UEAFSR_PDRD 0x4000000000000000UL /* Primary DVMA read cause */
258#define SYSIO_UEAFSR_PDWR 0x2000000000000000UL /* Primary DVMA write cause */
259#define SYSIO_UEAFSR_SPIO 0x1000000000000000UL /* Secondary PIO is cause */
260#define SYSIO_UEAFSR_SDRD 0x0800000000000000UL /* Secondary DVMA read cause */
261#define SYSIO_UEAFSR_SDWR 0x0400000000000000UL /* Secondary DVMA write cause*/
262#define SYSIO_UEAFSR_RESV1 0x03ff000000000000UL /* Reserved */
263#define SYSIO_UEAFSR_DOFF 0x0000e00000000000UL /* Doubleword Offset */
264#define SYSIO_UEAFSR_SIZE 0x00001c0000000000UL /* Bad transfer size 2^SIZE */
265#define SYSIO_UEAFSR_MID 0x000003e000000000UL /* UPA MID causing the fault */
266#define SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */
267static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
268{
269 struct of_device *op = dev_id;
270 struct iommu *iommu = op->dev.archdata.iommu;
271 unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
272 unsigned long afsr_reg, afar_reg;
273 unsigned long afsr, afar, error_bits;
274 int reported, portid;
275
276 afsr_reg = reg_base + SYSIO_UE_AFSR;
277 afar_reg = reg_base + SYSIO_UE_AFAR;
278
279 /* Latch error status. */
280 afsr = upa_readq(afsr_reg);
281 afar = upa_readq(afar_reg);
282
283 /* Clear primary/secondary error status bits. */
284 error_bits = afsr &
285 (SYSIO_UEAFSR_PPIO | SYSIO_UEAFSR_PDRD | SYSIO_UEAFSR_PDWR |
286 SYSIO_UEAFSR_SPIO | SYSIO_UEAFSR_SDRD | SYSIO_UEAFSR_SDWR);
287 upa_writeq(error_bits, afsr_reg);
288
289 portid = of_getintprop_default(op->node, "portid", -1);
290
291 /* Log the error. */
292 printk("SYSIO[%x]: Uncorrectable ECC Error, primary error type[%s]\n",
293 portid,
294 (((error_bits & SYSIO_UEAFSR_PPIO) ?
295 "PIO" :
296 ((error_bits & SYSIO_UEAFSR_PDRD) ?
297 "DVMA Read" :
298 ((error_bits & SYSIO_UEAFSR_PDWR) ?
299 "DVMA Write" : "???")))));
300 printk("SYSIO[%x]: DOFF[%lx] SIZE[%lx] MID[%lx]\n",
301 portid,
302 (afsr & SYSIO_UEAFSR_DOFF) >> 45UL,
303 (afsr & SYSIO_UEAFSR_SIZE) >> 42UL,
304 (afsr & SYSIO_UEAFSR_MID) >> 37UL);
305 printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar);
306 printk("SYSIO[%x]: Secondary UE errors [", portid);
307 reported = 0;
308 if (afsr & SYSIO_UEAFSR_SPIO) {
309 reported++;
310 printk("(PIO)");
311 }
312 if (afsr & SYSIO_UEAFSR_SDRD) {
313 reported++;
314 printk("(DVMA Read)");
315 }
316 if (afsr & SYSIO_UEAFSR_SDWR) {
317 reported++;
318 printk("(DVMA Write)");
319 }
320 if (!reported)
321 printk("(none)");
322 printk("]\n");
323
324 return IRQ_HANDLED;
325}
326
327#define SYSIO_CE_AFSR 0x0040UL
328#define SYSIO_CE_AFAR 0x0048UL
329#define SYSIO_CEAFSR_PPIO 0x8000000000000000UL /* Primary PIO cause */
330#define SYSIO_CEAFSR_PDRD 0x4000000000000000UL /* Primary DVMA read cause */
331#define SYSIO_CEAFSR_PDWR 0x2000000000000000UL /* Primary DVMA write cause */
332#define SYSIO_CEAFSR_SPIO 0x1000000000000000UL /* Secondary PIO cause */
333#define SYSIO_CEAFSR_SDRD 0x0800000000000000UL /* Secondary DVMA read cause */
334#define SYSIO_CEAFSR_SDWR 0x0400000000000000UL /* Secondary DVMA write cause*/
335#define SYSIO_CEAFSR_RESV1 0x0300000000000000UL /* Reserved */
336#define SYSIO_CEAFSR_ESYND 0x00ff000000000000UL /* Syndrome Bits */
337#define SYSIO_CEAFSR_DOFF 0x0000e00000000000UL /* Double Offset */
338#define SYSIO_CEAFSR_SIZE 0x00001c0000000000UL /* Bad transfer size 2^SIZE */
339#define SYSIO_CEAFSR_MID 0x000003e000000000UL /* UPA MID causing the fault */
340#define SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */
341static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
342{
343 struct of_device *op = dev_id;
344 struct iommu *iommu = op->dev.archdata.iommu;
345 unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
346 unsigned long afsr_reg, afar_reg;
347 unsigned long afsr, afar, error_bits;
348 int reported, portid;
349
350 afsr_reg = reg_base + SYSIO_CE_AFSR;
351 afar_reg = reg_base + SYSIO_CE_AFAR;
352
353 /* Latch error status. */
354 afsr = upa_readq(afsr_reg);
355 afar = upa_readq(afar_reg);
356
357 /* Clear primary/secondary error status bits. */
358 error_bits = afsr &
359 (SYSIO_CEAFSR_PPIO | SYSIO_CEAFSR_PDRD | SYSIO_CEAFSR_PDWR |
360 SYSIO_CEAFSR_SPIO | SYSIO_CEAFSR_SDRD | SYSIO_CEAFSR_SDWR);
361 upa_writeq(error_bits, afsr_reg);
362
363 portid = of_getintprop_default(op->node, "portid", -1);
364
365 printk("SYSIO[%x]: Correctable ECC Error, primary error type[%s]\n",
366 portid,
367 (((error_bits & SYSIO_CEAFSR_PPIO) ?
368 "PIO" :
369 ((error_bits & SYSIO_CEAFSR_PDRD) ?
370 "DVMA Read" :
371 ((error_bits & SYSIO_CEAFSR_PDWR) ?
372 "DVMA Write" : "???")))));
373
374 /* XXX Use syndrome and afar to print out module string just like
375 * XXX UDB CE trap handler does... -DaveM
376 */
377 printk("SYSIO[%x]: DOFF[%lx] ECC Syndrome[%lx] Size[%lx] MID[%lx]\n",
378 portid,
379 (afsr & SYSIO_CEAFSR_DOFF) >> 45UL,
380 (afsr & SYSIO_CEAFSR_ESYND) >> 48UL,
381 (afsr & SYSIO_CEAFSR_SIZE) >> 42UL,
382 (afsr & SYSIO_CEAFSR_MID) >> 37UL);
383 printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar);
384
385 printk("SYSIO[%x]: Secondary CE errors [", portid);
386 reported = 0;
387 if (afsr & SYSIO_CEAFSR_SPIO) {
388 reported++;
389 printk("(PIO)");
390 }
391 if (afsr & SYSIO_CEAFSR_SDRD) {
392 reported++;
393 printk("(DVMA Read)");
394 }
395 if (afsr & SYSIO_CEAFSR_SDWR) {
396 reported++;
397 printk("(DVMA Write)");
398 }
399 if (!reported)
400 printk("(none)");
401 printk("]\n");
402
403 return IRQ_HANDLED;
404}
405
406#define SYSIO_SBUS_AFSR 0x2010UL
407#define SYSIO_SBUS_AFAR 0x2018UL
408#define SYSIO_SBAFSR_PLE 0x8000000000000000UL /* Primary Late PIO Error */
409#define SYSIO_SBAFSR_PTO 0x4000000000000000UL /* Primary SBUS Timeout */
410#define SYSIO_SBAFSR_PBERR 0x2000000000000000UL /* Primary SBUS Error ACK */
411#define SYSIO_SBAFSR_SLE 0x1000000000000000UL /* Secondary Late PIO Error */
412#define SYSIO_SBAFSR_STO 0x0800000000000000UL /* Secondary SBUS Timeout */
413#define SYSIO_SBAFSR_SBERR 0x0400000000000000UL /* Secondary SBUS Error ACK */
414#define SYSIO_SBAFSR_RESV1 0x03ff000000000000UL /* Reserved */
415#define SYSIO_SBAFSR_RD 0x0000800000000000UL /* Primary was late PIO read */
416#define SYSIO_SBAFSR_RESV2 0x0000600000000000UL /* Reserved */
417#define SYSIO_SBAFSR_SIZE 0x00001c0000000000UL /* Size of transfer */
418#define SYSIO_SBAFSR_MID 0x000003e000000000UL /* MID causing the error */
419#define SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved */
420static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
421{
422 struct of_device *op = dev_id;
423 struct iommu *iommu = op->dev.archdata.iommu;
424 unsigned long afsr_reg, afar_reg, reg_base;
425 unsigned long afsr, afar, error_bits;
426 int reported, portid;
427
428 reg_base = iommu->write_complete_reg - 0x2000UL;
429 afsr_reg = reg_base + SYSIO_SBUS_AFSR;
430 afar_reg = reg_base + SYSIO_SBUS_AFAR;
431
432 afsr = upa_readq(afsr_reg);
433 afar = upa_readq(afar_reg);
434
435 /* Clear primary/secondary error status bits. */
436 error_bits = afsr &
437 (SYSIO_SBAFSR_PLE | SYSIO_SBAFSR_PTO | SYSIO_SBAFSR_PBERR |
438 SYSIO_SBAFSR_SLE | SYSIO_SBAFSR_STO | SYSIO_SBAFSR_SBERR);
439 upa_writeq(error_bits, afsr_reg);
440
441 portid = of_getintprop_default(op->node, "portid", -1);
442
443 /* Log the error. */
444 printk("SYSIO[%x]: SBUS Error, primary error type[%s] read(%d)\n",
445 portid,
446 (((error_bits & SYSIO_SBAFSR_PLE) ?
447 "Late PIO Error" :
448 ((error_bits & SYSIO_SBAFSR_PTO) ?
449 "Time Out" :
450 ((error_bits & SYSIO_SBAFSR_PBERR) ?
451 "Error Ack" : "???")))),
452 (afsr & SYSIO_SBAFSR_RD) ? 1 : 0);
453 printk("SYSIO[%x]: size[%lx] MID[%lx]\n",
454 portid,
455 (afsr & SYSIO_SBAFSR_SIZE) >> 42UL,
456 (afsr & SYSIO_SBAFSR_MID) >> 37UL);
457 printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar);
458 printk("SYSIO[%x]: Secondary SBUS errors [", portid);
459 reported = 0;
460 if (afsr & SYSIO_SBAFSR_SLE) {
461 reported++;
462 printk("(Late PIO Error)");
463 }
464 if (afsr & SYSIO_SBAFSR_STO) {
465 reported++;
466 printk("(Time Out)");
467 }
468 if (afsr & SYSIO_SBAFSR_SBERR) {
469 reported++;
470 printk("(Error Ack)");
471 }
472 if (!reported)
473 printk("(none)");
474 printk("]\n");
475
476 /* XXX check iommu/strbuf for further error status XXX */
477
478 return IRQ_HANDLED;
479}
480
481#define ECC_CONTROL 0x0020UL
482#define SYSIO_ECNTRL_ECCEN 0x8000000000000000UL /* Enable ECC Checking */
483#define SYSIO_ECNTRL_UEEN 0x4000000000000000UL /* Enable UE Interrupts */
484#define SYSIO_ECNTRL_CEEN 0x2000000000000000UL /* Enable CE Interrupts */
485
486#define SYSIO_UE_INO 0x34
487#define SYSIO_CE_INO 0x35
488#define SYSIO_SBUSERR_INO 0x36
489
490static void __init sysio_register_error_handlers(struct of_device *op)
491{
492 struct iommu *iommu = op->dev.archdata.iommu;
493 unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
494 unsigned int irq;
495 u64 control;
496 int portid;
497
498 portid = of_getintprop_default(op->node, "portid", -1);
499
500 irq = sbus_build_irq(op, SYSIO_UE_INO);
501 if (request_irq(irq, sysio_ue_handler, 0,
502 "SYSIO_UE", op) < 0) {
503 prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n",
504 portid);
505 prom_halt();
506 }
507
508 irq = sbus_build_irq(op, SYSIO_CE_INO);
509 if (request_irq(irq, sysio_ce_handler, 0,
510 "SYSIO_CE", op) < 0) {
511 prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n",
512 portid);
513 prom_halt();
514 }
515
516 irq = sbus_build_irq(op, SYSIO_SBUSERR_INO);
517 if (request_irq(irq, sysio_sbus_error_handler, 0,
518 "SYSIO_SBERR", op) < 0) {
519 prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n",
520 portid);
521 prom_halt();
522 }
523
524 /* Now turn the error interrupts on and also enable ECC checking. */
525 upa_writeq((SYSIO_ECNTRL_ECCEN |
526 SYSIO_ECNTRL_UEEN |
527 SYSIO_ECNTRL_CEEN),
528 reg_base + ECC_CONTROL);
529
530 control = upa_readq(iommu->write_complete_reg);
531 control |= 0x100UL; /* SBUS Error Interrupt Enable */
532 upa_writeq(control, iommu->write_complete_reg);
533}
534
535/* Boot time initialization. */
536static void __init sbus_iommu_init(struct of_device *op)
537{
538 const struct linux_prom64_registers *pr;
539 struct device_node *dp = op->node;
540 struct iommu *iommu;
541 struct strbuf *strbuf;
542 unsigned long regs, reg_base;
543 int i, portid;
544 u64 control;
545
546 pr = of_get_property(dp, "reg", NULL);
547 if (!pr) {
548 prom_printf("sbus_iommu_init: Cannot map SYSIO "
549 "control registers.\n");
550 prom_halt();
551 }
552 regs = pr->phys_addr;
553
554 iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC);
555 if (!iommu)
556 goto fatal_memory_error;
557 strbuf = kzalloc(sizeof(*strbuf), GFP_ATOMIC);
558 if (!strbuf)
559 goto fatal_memory_error;
560
561 op->dev.archdata.iommu = iommu;
562 op->dev.archdata.stc = strbuf;
563 op->dev.archdata.numa_node = -1;
564
565 reg_base = regs + SYSIO_IOMMUREG_BASE;
566 iommu->iommu_control = reg_base + IOMMU_CONTROL;
567 iommu->iommu_tsbbase = reg_base + IOMMU_TSBBASE;
568 iommu->iommu_flush = reg_base + IOMMU_FLUSH;
569 iommu->iommu_tags = iommu->iommu_control +
570 (IOMMU_TAGDIAG - IOMMU_CONTROL);
571
572 reg_base = regs + SYSIO_STRBUFREG_BASE;
573 strbuf->strbuf_control = reg_base + STRBUF_CONTROL;
574 strbuf->strbuf_pflush = reg_base + STRBUF_PFLUSH;
575 strbuf->strbuf_fsync = reg_base + STRBUF_FSYNC;
576
577 strbuf->strbuf_enabled = 1;
578
579 strbuf->strbuf_flushflag = (volatile unsigned long *)
580 ((((unsigned long)&strbuf->__flushflag_buf[0])
581 + 63UL)
582 & ~63UL);
583 strbuf->strbuf_flushflag_pa = (unsigned long)
584 __pa(strbuf->strbuf_flushflag);
585
586 /* The SYSIO SBUS control register is used for dummy reads
587 * in order to ensure write completion.
588 */
589 iommu->write_complete_reg = regs + 0x2000UL;
590
591 portid = of_getintprop_default(op->node, "portid", -1);
592 printk(KERN_INFO "SYSIO: UPA portID %x, at %016lx\n",
593 portid, regs);
594
595 /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */
596 if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff, -1))
597 goto fatal_memory_error;
598
599 control = upa_readq(iommu->iommu_control);
600 control = ((7UL << 16UL) |
601 (0UL << 2UL) |
602 (1UL << 1UL) |
603 (1UL << 0UL));
604 upa_writeq(control, iommu->iommu_control);
605
606 /* Clean out any cruft in the IOMMU using
607 * diagnostic accesses.
608 */
609 for (i = 0; i < 16; i++) {
610 unsigned long dram, tag;
611
612 dram = iommu->iommu_control + (IOMMU_DRAMDIAG - IOMMU_CONTROL);
613 tag = iommu->iommu_control + (IOMMU_TAGDIAG - IOMMU_CONTROL);
614
615 dram += (unsigned long)i * 8UL;
616 tag += (unsigned long)i * 8UL;
617 upa_writeq(0, dram);
618 upa_writeq(0, tag);
619 }
620 upa_readq(iommu->write_complete_reg);
621
622 /* Give the TSB to SYSIO. */
623 upa_writeq(__pa(iommu->page_table), iommu->iommu_tsbbase);
624
625 /* Setup streaming buffer, DE=1 SB_EN=1 */
626 control = (1UL << 1UL) | (1UL << 0UL);
627 upa_writeq(control, strbuf->strbuf_control);
628
629 /* Clear out the tags using diagnostics. */
630 for (i = 0; i < 16; i++) {
631 unsigned long ptag, ltag;
632
633 ptag = strbuf->strbuf_control +
634 (STRBUF_PTAGDIAG - STRBUF_CONTROL);
635 ltag = strbuf->strbuf_control +
636 (STRBUF_LTAGDIAG - STRBUF_CONTROL);
637 ptag += (unsigned long)i * 8UL;
638 ltag += (unsigned long)i * 8UL;
639
640 upa_writeq(0UL, ptag);
641 upa_writeq(0UL, ltag);
642 }
643
644 /* Enable DVMA arbitration for all devices/slots. */
645 control = upa_readq(iommu->write_complete_reg);
646 control |= 0x3fUL;
647 upa_writeq(control, iommu->write_complete_reg);
648
649 /* Now some Xfire specific grot... */
650 if (this_is_starfire)
651 starfire_hookup(portid);
652
653 sysio_register_error_handlers(op);
654 return;
655
656fatal_memory_error:
657 prom_printf("sbus_iommu_init: Fatal memory allocation error.\n");
658}
659
660static int __init sbus_init(void)
661{
662 struct device_node *dp;
663
664 for_each_node_by_name(dp, "sbus") {
665 struct of_device *op = of_find_device_by_node(dp);
666
667 sbus_iommu_init(op);
668 of_propagate_archdata(op);
669 }
670
671 return 0;
672}
673
674subsys_initcall(sbus_init);