Blame view

arch/sparc/kernel/pci_schizo.c 47.8 KB
9fd8b6476   David S. Miller   [SPARC64]: Consol...
1
  /* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
   *
6d19c88f5   David S. Miller   sparc64: Convert ...
3
   * Copyright (C) 2001, 2002, 2003, 2007, 2008 David S. Miller (davem@davemloft.net)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
   */
  
  #include <linux/kernel.h>
  #include <linux/types.h>
  #include <linux/pci.h>
  #include <linux/init.h>
  #include <linux/slab.h>
7b64db608   Paul Gortmaker   sparc: add export...
11
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
  #include <linux/interrupt.h>
764f2579d   Stephen Rothwell   sparc: don't use ...
13
  #include <linux/of_device.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
  #include <asm/iommu.h>
  #include <asm/irq.h>
bb6743f4f   David S. Miller   [SPARC64]: Do pro...
17
  #include <asm/pstate.h>
e87dc3502   David S. Miller   [SPARC64]: Use in...
18
  #include <asm/prom.h>
87395fc67   David S. Miller   sparc64: Kill han...
19
  #include <asm/upa.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
  
  #include "pci_impl.h"
  #include "iommu_common.h"
6d19c88f5   David S. Miller   sparc64: Convert ...
23
24
  #define DRIVER_NAME	"schizo"
  #define PFX		DRIVER_NAME ": "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  /* This is a convention that at least Excalibur and Merlin
   * follow.  I suppose the SCHIZO used in Starcat and friends
   * will do similar.
   *
   * The only way I could see this changing is if the newlink
   * block requires more space in Schizo's address space than
   * they predicted, thus requiring an address space reorg when
   * the newer Schizo is taped out.
   */
  
  /* Streaming buffer control register. */
  #define SCHIZO_STRBUF_CTRL_LPTR    0x00000000000000f0UL /* LRU Lock Pointer */
  #define SCHIZO_STRBUF_CTRL_LENAB   0x0000000000000008UL /* LRU Lock Enable */
  #define SCHIZO_STRBUF_CTRL_RRDIS   0x0000000000000004UL /* Rerun Disable */
  #define SCHIZO_STRBUF_CTRL_DENAB   0x0000000000000002UL /* Diagnostic Mode Enable */
  #define SCHIZO_STRBUF_CTRL_ENAB    0x0000000000000001UL /* Streaming Buffer Enable */
  
  /* IOMMU control register. */
  #define SCHIZO_IOMMU_CTRL_RESV     0xfffffffff9000000UL /* Reserved                      */
  #define SCHIZO_IOMMU_CTRL_XLTESTAT 0x0000000006000000UL /* Translation Error Status      */
  #define SCHIZO_IOMMU_CTRL_XLTEERR  0x0000000001000000UL /* Translation Error encountered */
  #define SCHIZO_IOMMU_CTRL_LCKEN    0x0000000000800000UL /* Enable translation locking    */
  #define SCHIZO_IOMMU_CTRL_LCKPTR   0x0000000000780000UL /* Translation lock pointer      */
  #define SCHIZO_IOMMU_CTRL_TSBSZ    0x0000000000070000UL /* TSB Size                      */
  #define SCHIZO_IOMMU_TSBSZ_1K      0x0000000000000000UL /* TSB Table 1024 8-byte entries */
  #define SCHIZO_IOMMU_TSBSZ_2K      0x0000000000010000UL /* TSB Table 2048 8-byte entries */
  #define SCHIZO_IOMMU_TSBSZ_4K      0x0000000000020000UL /* TSB Table 4096 8-byte entries */
  #define SCHIZO_IOMMU_TSBSZ_8K      0x0000000000030000UL /* TSB Table 8192 8-byte entries */
  #define SCHIZO_IOMMU_TSBSZ_16K     0x0000000000040000UL /* TSB Table 16k 8-byte entries  */
  #define SCHIZO_IOMMU_TSBSZ_32K     0x0000000000050000UL /* TSB Table 32k 8-byte entries  */
  #define SCHIZO_IOMMU_TSBSZ_64K     0x0000000000060000UL /* TSB Table 64k 8-byte entries  */
  #define SCHIZO_IOMMU_TSBSZ_128K    0x0000000000070000UL /* TSB Table 128k 8-byte entries */
  #define SCHIZO_IOMMU_CTRL_RESV2    0x000000000000fff8UL /* Reserved                      */
  #define SCHIZO_IOMMU_CTRL_TBWSZ    0x0000000000000004UL /* Assumed page size, 0=8k 1=64k */
  #define SCHIZO_IOMMU_CTRL_DENAB    0x0000000000000002UL /* Diagnostic mode enable        */
  #define SCHIZO_IOMMU_CTRL_ENAB     0x0000000000000001UL /* IOMMU Enable                  */
  
  /* Schizo config space address format is nearly identical to
   * that of PSYCHO:
   *
   *  32             24 23 16 15    11 10       8 7   2  1 0
   * ---------------------------------------------------------
   * |0 0 0 0 0 0 0 0 0| bus | device | function | reg | 0 0 |
   * ---------------------------------------------------------
   */
  #define SCHIZO_CONFIG_BASE(PBM)	((PBM)->config_space)
  #define SCHIZO_CONFIG_ENCODE(BUS, DEVFN, REG)	\
  	(((unsigned long)(BUS)   << 16) |	\
  	 ((unsigned long)(DEVFN) << 8)  |	\
  	 ((unsigned long)(REG)))
  
  static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm,
  				      unsigned char bus,
  				      unsigned int devfn,
  				      int where)
  {
  	if (!pbm)
  		return NULL;
  	bus -= pbm->pci_first_busno;
  	return (void *)
  		(SCHIZO_CONFIG_BASE(pbm) |
  		 SCHIZO_CONFIG_ENCODE(bus, devfn, where));
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  /* SCHIZO error handling support. */
  enum schizo_error_type {
  	UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR
  };
  
  static DEFINE_SPINLOCK(stc_buf_lock);
  static unsigned long stc_error_buf[128];
  static unsigned long stc_tag_buf[16];
  static unsigned long stc_line_buf[16];
  
  #define SCHIZO_UE_INO		0x30 /* Uncorrectable ECC error */
  #define SCHIZO_CE_INO		0x31 /* Correctable ECC error */
  #define SCHIZO_PCIERR_A_INO	0x32 /* PBM A PCI bus error */
  #define SCHIZO_PCIERR_B_INO	0x33 /* PBM B PCI bus error */
  #define SCHIZO_SERR_INO		0x34 /* Safari interface error */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  #define SCHIZO_STC_ERR	0xb800UL /* --> 0xba00 */
  #define SCHIZO_STC_TAG	0xba00UL /* --> 0xba80 */
  #define SCHIZO_STC_LINE	0xbb00UL /* --> 0xbb80 */
  
  #define SCHIZO_STCERR_WRITE	0x2UL
  #define SCHIZO_STCERR_READ	0x1UL
  
  #define SCHIZO_STCTAG_PPN	0x3fffffff00000000UL
  #define SCHIZO_STCTAG_VPN	0x00000000ffffe000UL
  #define SCHIZO_STCTAG_VALID	0x8000000000000000UL
  #define SCHIZO_STCTAG_READ	0x4000000000000000UL
  
  #define SCHIZO_STCLINE_LINDX	0x0000000007800000UL
  #define SCHIZO_STCLINE_SPTR	0x000000000007e000UL
  #define SCHIZO_STCLINE_LADDR	0x0000000000001fc0UL
  #define SCHIZO_STCLINE_EPTR	0x000000000000003fUL
  #define SCHIZO_STCLINE_VALID	0x0000000000600000UL
  #define SCHIZO_STCLINE_FOFN	0x0000000000180000UL
  
  static void __schizo_check_stc_error_pbm(struct pci_pbm_info *pbm,
  					 enum schizo_error_type type)
  {
16ce82d84   David S. Miller   [SPARC64]: Conver...
125
  	struct strbuf *strbuf = &pbm->stc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  	unsigned long regbase = pbm->pbm_regs;
  	unsigned long err_base, tag_base, line_base;
  	u64 control;
  	int i;
  
  	err_base = regbase + SCHIZO_STC_ERR;
  	tag_base = regbase + SCHIZO_STC_TAG;
  	line_base = regbase + SCHIZO_STC_LINE;
  
  	spin_lock(&stc_buf_lock);
  
  	/* This is __REALLY__ dangerous.  When we put the
  	 * streaming buffer into diagnostic mode to probe
  	 * it's tags and error status, we _must_ clear all
  	 * of the line tag valid bits before re-enabling
  	 * the streaming buffer.  If any dirty data lives
  	 * in the STC when we do this, we will end up
  	 * invalidating it before it has a chance to reach
  	 * main memory.
  	 */
87395fc67   David S. Miller   sparc64: Kill han...
146
147
148
  	control = upa_readq(strbuf->strbuf_control);
  	upa_writeq((control | SCHIZO_STRBUF_CTRL_DENAB),
  		   strbuf->strbuf_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
  	for (i = 0; i < 128; i++) {
  		unsigned long val;
87395fc67   David S. Miller   sparc64: Kill han...
151
152
  		val = upa_readq(err_base + (i * 8UL));
  		upa_writeq(0UL, err_base + (i * 8UL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
154
155
  		stc_error_buf[i] = val;
  	}
  	for (i = 0; i < 16; i++) {
87395fc67   David S. Miller   sparc64: Kill han...
156
157
158
159
  		stc_tag_buf[i] = upa_readq(tag_base + (i * 8UL));
  		stc_line_buf[i] = upa_readq(line_base + (i * 8UL));
  		upa_writeq(0UL, tag_base + (i * 8UL));
  		upa_writeq(0UL, line_base + (i * 8UL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
  	}
  
  	/* OK, state is logged, exit diagnostic mode. */
87395fc67   David S. Miller   sparc64: Kill han...
163
  	upa_writeq(control, strbuf->strbuf_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
  
  	for (i = 0; i < 16; i++) {
  		int j, saw_error, first, last;
  
  		saw_error = 0;
  		first = i * 8;
  		last = first + 8;
  		for (j = first; j < last; j++) {
  			unsigned long errval = stc_error_buf[j];
  			if (errval != 0) {
  				saw_error++;
  				printk("%s: STC_ERR(%d)[wr(%d)rd(%d)]
  ",
  				       pbm->name,
  				       j,
  				       (errval & SCHIZO_STCERR_WRITE) ? 1 : 0,
  				       (errval & SCHIZO_STCERR_READ) ? 1 : 0);
  			}
  		}
  		if (saw_error != 0) {
  			unsigned long tagval = stc_tag_buf[i];
  			unsigned long lineval = stc_line_buf[i];
  			printk("%s: STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)R(%d)]
  ",
  			       pbm->name,
  			       i,
  			       ((tagval & SCHIZO_STCTAG_PPN) >> 19UL),
  			       (tagval & SCHIZO_STCTAG_VPN),
  			       ((tagval & SCHIZO_STCTAG_VALID) ? 1 : 0),
  			       ((tagval & SCHIZO_STCTAG_READ) ? 1 : 0));
  
  			/* XXX Should spit out per-bank error information... -DaveM */
  			printk("%s: STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)"
  			       "V(%d)FOFN(%d)]
  ",
  			       pbm->name,
  			       i,
  			       ((lineval & SCHIZO_STCLINE_LINDX) >> 23UL),
  			       ((lineval & SCHIZO_STCLINE_SPTR) >> 13UL),
  			       ((lineval & SCHIZO_STCLINE_LADDR) >> 6UL),
  			       ((lineval & SCHIZO_STCLINE_EPTR) >> 0UL),
  			       ((lineval & SCHIZO_STCLINE_VALID) ? 1 : 0),
  			       ((lineval & SCHIZO_STCLINE_FOFN) ? 1 : 0));
  		}
  	}
  
  	spin_unlock(&stc_buf_lock);
  }
  
  /* IOMMU is per-PBM in Schizo, so interrogate both for anonymous
   * controller level errors.
   */
  
  #define SCHIZO_IOMMU_TAG	0xa580UL
  #define SCHIZO_IOMMU_DATA	0xa600UL
  
  #define SCHIZO_IOMMU_TAG_CTXT	0x0000001ffe000000UL
  #define SCHIZO_IOMMU_TAG_ERRSTS	0x0000000001800000UL
  #define SCHIZO_IOMMU_TAG_ERR	0x0000000000400000UL
  #define SCHIZO_IOMMU_TAG_WRITE	0x0000000000200000UL
  #define SCHIZO_IOMMU_TAG_STREAM	0x0000000000100000UL
  #define SCHIZO_IOMMU_TAG_SIZE	0x0000000000080000UL
  #define SCHIZO_IOMMU_TAG_VPAGE	0x000000000007ffffUL
  
  #define SCHIZO_IOMMU_DATA_VALID	0x0000000100000000UL
  #define SCHIZO_IOMMU_DATA_CACHE	0x0000000040000000UL
  #define SCHIZO_IOMMU_DATA_PPAGE	0x000000003fffffffUL
  
  static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm,
  					 enum schizo_error_type type)
  {
16ce82d84   David S. Miller   [SPARC64]: Conver...
235
  	struct iommu *iommu = pbm->iommu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
239
240
241
242
  	unsigned long iommu_tag[16];
  	unsigned long iommu_data[16];
  	unsigned long flags;
  	u64 control;
  	int i;
  
  	spin_lock_irqsave(&iommu->lock, flags);
87395fc67   David S. Miller   sparc64: Kill han...
243
  	control = upa_readq(iommu->iommu_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
246
247
248
249
  	if (control & SCHIZO_IOMMU_CTRL_XLTEERR) {
  		unsigned long base;
  		char *type_string;
  
  		/* Clear the error encountered bit. */
  		control &= ~SCHIZO_IOMMU_CTRL_XLTEERR;
87395fc67   David S. Miller   sparc64: Kill han...
250
  		upa_writeq(control, iommu->iommu_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  
  		switch((control & SCHIZO_IOMMU_CTRL_XLTESTAT) >> 25UL) {
  		case 0:
  			type_string = "Protection Error";
  			break;
  		case 1:
  			type_string = "Invalid Error";
  			break;
  		case 2:
  			type_string = "TimeOut Error";
  			break;
  		case 3:
  		default:
  			type_string = "ECC Error";
  			break;
6cb79b3f3   Joe Perches   sparc: Remove unn...
266
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  		printk("%s: IOMMU Error, type[%s]
  ",
  		       pbm->name, type_string);
  
  		/* Put the IOMMU into diagnostic mode and probe
  		 * it's TLB for entries with error status.
  		 *
  		 * It is very possible for another DVMA to occur
  		 * while we do this probe, and corrupt the system
  		 * further.  But we are so screwed at this point
  		 * that we are likely to crash hard anyways, so
  		 * get as much diagnostic information to the
  		 * console as we can.
  		 */
87395fc67   David S. Miller   sparc64: Kill han...
281
282
  		upa_writeq(control | SCHIZO_IOMMU_CTRL_DENAB,
  			   iommu->iommu_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
285
286
287
  
  		base = pbm->pbm_regs;
  
  		for (i = 0; i < 16; i++) {
  			iommu_tag[i] =
87395fc67   David S. Miller   sparc64: Kill han...
288
  				upa_readq(base + SCHIZO_IOMMU_TAG + (i * 8UL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
  			iommu_data[i] =
87395fc67   David S. Miller   sparc64: Kill han...
290
  				upa_readq(base + SCHIZO_IOMMU_DATA + (i * 8UL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
  
  			/* Now clear out the entry. */
87395fc67   David S. Miller   sparc64: Kill han...
293
294
  			upa_writeq(0, base + SCHIZO_IOMMU_TAG + (i * 8UL));
  			upa_writeq(0, base + SCHIZO_IOMMU_DATA + (i * 8UL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
296
297
  		}
  
  		/* Leave diagnostic mode. */
87395fc67   David S. Miller   sparc64: Kill han...
298
  		upa_writeq(control, iommu->iommu_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
  
  		for (i = 0; i < 16; i++) {
  			unsigned long tag, data;
  
  			tag = iommu_tag[i];
  			if (!(tag & SCHIZO_IOMMU_TAG_ERR))
  				continue;
  
  			data = iommu_data[i];
  			switch((tag & SCHIZO_IOMMU_TAG_ERRSTS) >> 23UL) {
  			case 0:
  				type_string = "Protection Error";
  				break;
  			case 1:
  				type_string = "Invalid Error";
  				break;
  			case 2:
  				type_string = "TimeOut Error";
  				break;
  			case 3:
  			default:
  				type_string = "ECC Error";
  				break;
6cb79b3f3   Joe Perches   sparc: Remove unn...
322
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  			printk("%s: IOMMU TAG(%d)[error(%s) ctx(%x) wr(%d) str(%d) "
  			       "sz(%dK) vpg(%08lx)]
  ",
  			       pbm->name, i, type_string,
  			       (int)((tag & SCHIZO_IOMMU_TAG_CTXT) >> 25UL),
  			       ((tag & SCHIZO_IOMMU_TAG_WRITE) ? 1 : 0),
  			       ((tag & SCHIZO_IOMMU_TAG_STREAM) ? 1 : 0),
  			       ((tag & SCHIZO_IOMMU_TAG_SIZE) ? 64 : 8),
  			       (tag & SCHIZO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT);
  			printk("%s: IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]
  ",
  			       pbm->name, i,
  			       ((data & SCHIZO_IOMMU_DATA_VALID) ? 1 : 0),
  			       ((data & SCHIZO_IOMMU_DATA_CACHE) ? 1 : 0),
  			       (data & SCHIZO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);
  		}
  	}
  	if (pbm->stc.strbuf_enabled)
  		__schizo_check_stc_error_pbm(pbm, type);
  	spin_unlock_irqrestore(&iommu->lock, flags);
  }
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
344
  static void schizo_check_iommu_error(struct pci_pbm_info *pbm,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
  				     enum schizo_error_type type)
  {
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
347
348
349
  	schizo_check_iommu_error_pbm(pbm, type);
  	if (pbm->sibling)
  		schizo_check_iommu_error_pbm(pbm->sibling, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  }
  
  /* Uncorrectable ECC error status gathering. */
  #define SCHIZO_UE_AFSR	0x10030UL
  #define SCHIZO_UE_AFAR	0x10038UL
  
  #define SCHIZO_UEAFSR_PPIO	0x8000000000000000UL /* Safari */
  #define SCHIZO_UEAFSR_PDRD	0x4000000000000000UL /* Safari/Tomatillo */
  #define SCHIZO_UEAFSR_PDWR	0x2000000000000000UL /* Safari */
  #define SCHIZO_UEAFSR_SPIO	0x1000000000000000UL /* Safari */
  #define SCHIZO_UEAFSR_SDMA	0x0800000000000000UL /* Safari/Tomatillo */
  #define SCHIZO_UEAFSR_ERRPNDG	0x0300000000000000UL /* Safari */
  #define SCHIZO_UEAFSR_BMSK	0x000003ff00000000UL /* Safari */
  #define SCHIZO_UEAFSR_QOFF	0x00000000c0000000UL /* Safari/Tomatillo */
  #define SCHIZO_UEAFSR_AID	0x000000001f000000UL /* Safari/Tomatillo */
  #define SCHIZO_UEAFSR_PARTIAL	0x0000000000800000UL /* Safari */
  #define SCHIZO_UEAFSR_OWNEDIN	0x0000000000400000UL /* Safari */
  #define SCHIZO_UEAFSR_MTAGSYND	0x00000000000f0000UL /* Safari */
  #define SCHIZO_UEAFSR_MTAG	0x000000000000e000UL /* Safari */
  #define SCHIZO_UEAFSR_ECCSYND	0x00000000000001ffUL /* Safari */
6d24c8dc2   Al Viro   [PATCH] sparc64 p...
370
  static irqreturn_t schizo_ue_intr(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371
  {
34768bc83   David S. Miller   [SPARC64] PCI: Us...
372
  	struct pci_pbm_info *pbm = dev_id;
34768bc83   David S. Miller   [SPARC64] PCI: Us...
373
374
  	unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR;
  	unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
376
377
378
  	unsigned long afsr, afar, error_bits;
  	int reported, limit;
  
  	/* Latch uncorrectable error status. */
87395fc67   David S. Miller   sparc64: Kill han...
379
  	afar = upa_readq(afar_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
381
382
383
384
385
386
  
  	/* If either of the error pending bits are set in the
  	 * AFSR, the error status is being actively updated by
  	 * the hardware and we must re-read to get a clean value.
  	 */
  	limit = 1000;
  	do {
87395fc67   David S. Miller   sparc64: Kill han...
387
  		afsr = upa_readq(afsr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
389
390
391
392
393
394
395
  	} while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit);
  
  	/* Clear the primary/secondary error status bits. */
  	error_bits = afsr &
  		(SCHIZO_UEAFSR_PPIO | SCHIZO_UEAFSR_PDRD | SCHIZO_UEAFSR_PDWR |
  		 SCHIZO_UEAFSR_SPIO | SCHIZO_UEAFSR_SDMA);
  	if (!error_bits)
  		return IRQ_NONE;
87395fc67   David S. Miller   sparc64: Kill han...
396
  	upa_writeq(error_bits, afsr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
  
  	/* Log the error. */
6c108f129   David S. Miller   [SPARC64]: Move i...
399
400
401
  	printk("%s: Uncorrectable Error, primary error type[%s]
  ",
  	       pbm->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
405
406
407
  	       (((error_bits & SCHIZO_UEAFSR_PPIO) ?
  		 "PIO" :
  		 ((error_bits & SCHIZO_UEAFSR_PDRD) ?
  		  "DMA Read" :
  		  ((error_bits & SCHIZO_UEAFSR_PDWR) ?
  		   "DMA Write" : "???")))));
6c108f129   David S. Miller   [SPARC64]: Move i...
408
409
410
  	printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]
  ",
  	       pbm->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
412
413
  	       (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL,
  	       (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL,
  	       (afsr & SCHIZO_UEAFSR_AID) >> 24UL);
6c108f129   David S. Miller   [SPARC64]: Move i...
414
415
416
  	printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]
  ",
  	       pbm->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
418
419
420
421
  	       (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0,
  	       (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0,
  	       (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL,
  	       (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL,
  	       (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL);
6c108f129   David S. Miller   [SPARC64]: Move i...
422
423
424
  	printk("%s: UE AFAR [%016lx]
  ", pbm->name, afar);
  	printk("%s: UE Secondary errors [", pbm->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  	reported = 0;
  	if (afsr & SCHIZO_UEAFSR_SPIO) {
  		reported++;
  		printk("(PIO)");
  	}
  	if (afsr & SCHIZO_UEAFSR_SDMA) {
  		reported++;
  		printk("(DMA)");
  	}
  	if (!reported)
  		printk("(none)");
  	printk("]
  ");
  
  	/* Interrogate IOMMU for error status. */
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
440
  	schizo_check_iommu_error(pbm, UE_ERR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
  	return IRQ_HANDLED;
  }
  
  #define SCHIZO_CE_AFSR	0x10040UL
  #define SCHIZO_CE_AFAR	0x10048UL
  
  #define SCHIZO_CEAFSR_PPIO	0x8000000000000000UL
  #define SCHIZO_CEAFSR_PDRD	0x4000000000000000UL
  #define SCHIZO_CEAFSR_PDWR	0x2000000000000000UL
  #define SCHIZO_CEAFSR_SPIO	0x1000000000000000UL
  #define SCHIZO_CEAFSR_SDMA	0x0800000000000000UL
  #define SCHIZO_CEAFSR_ERRPNDG	0x0300000000000000UL
  #define SCHIZO_CEAFSR_BMSK	0x000003ff00000000UL
  #define SCHIZO_CEAFSR_QOFF	0x00000000c0000000UL
  #define SCHIZO_CEAFSR_AID	0x000000001f000000UL
  #define SCHIZO_CEAFSR_PARTIAL	0x0000000000800000UL
  #define SCHIZO_CEAFSR_OWNEDIN	0x0000000000400000UL
  #define SCHIZO_CEAFSR_MTAGSYND	0x00000000000f0000UL
  #define SCHIZO_CEAFSR_MTAG	0x000000000000e000UL
  #define SCHIZO_CEAFSR_ECCSYND	0x00000000000001ffUL
6d24c8dc2   Al Viro   [PATCH] sparc64 p...
462
  static irqreturn_t schizo_ce_intr(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  {
34768bc83   David S. Miller   [SPARC64] PCI: Us...
464
  	struct pci_pbm_info *pbm = dev_id;
34768bc83   David S. Miller   [SPARC64] PCI: Us...
465
466
  	unsigned long afsr_reg = pbm->controller_regs + SCHIZO_CE_AFSR;
  	unsigned long afar_reg = pbm->controller_regs + SCHIZO_CE_AFAR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
468
469
470
  	unsigned long afsr, afar, error_bits;
  	int reported, limit;
  
  	/* Latch error status. */
87395fc67   David S. Miller   sparc64: Kill han...
471
  	afar = upa_readq(afar_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
474
475
476
477
478
  
  	/* If either of the error pending bits are set in the
  	 * AFSR, the error status is being actively updated by
  	 * the hardware and we must re-read to get a clean value.
  	 */
  	limit = 1000;
  	do {
87395fc67   David S. Miller   sparc64: Kill han...
479
  		afsr = upa_readq(afsr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
481
482
483
484
485
486
487
  	} while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit);
  
  	/* Clear primary/secondary error status bits. */
  	error_bits = afsr &
  		(SCHIZO_CEAFSR_PPIO | SCHIZO_CEAFSR_PDRD | SCHIZO_CEAFSR_PDWR |
  		 SCHIZO_CEAFSR_SPIO | SCHIZO_CEAFSR_SDMA);
  	if (!error_bits)
  		return IRQ_NONE;
87395fc67   David S. Miller   sparc64: Kill han...
488
  	upa_writeq(error_bits, afsr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
  
  	/* Log the error. */
6c108f129   David S. Miller   [SPARC64]: Move i...
491
492
493
  	printk("%s: Correctable Error, primary error type[%s]
  ",
  	       pbm->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
496
497
498
499
500
501
502
503
  	       (((error_bits & SCHIZO_CEAFSR_PPIO) ?
  		 "PIO" :
  		 ((error_bits & SCHIZO_CEAFSR_PDRD) ?
  		  "DMA Read" :
  		  ((error_bits & SCHIZO_CEAFSR_PDWR) ?
  		   "DMA Write" : "???")))));
  
  	/* XXX Use syndrome and afar to print out module string just like
  	 * XXX UDB CE trap handler does... -DaveM
  	 */
6c108f129   David S. Miller   [SPARC64]: Move i...
504
505
506
  	printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]
  ",
  	       pbm->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
509
  	       (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL,
  	       (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL,
  	       (afsr & SCHIZO_UEAFSR_AID) >> 24UL);
6c108f129   David S. Miller   [SPARC64]: Move i...
510
511
512
  	printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]
  ",
  	       pbm->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
514
515
516
517
  	       (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0,
  	       (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0,
  	       (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL,
  	       (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL,
  	       (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL);
6c108f129   David S. Miller   [SPARC64]: Move i...
518
519
520
  	printk("%s: CE AFAR [%016lx]
  ", pbm->name, afar);
  	printk("%s: CE Secondary errors [", pbm->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
521
522
523
524
525
526
527
528
529
530
531
532
533
  	reported = 0;
  	if (afsr & SCHIZO_CEAFSR_SPIO) {
  		reported++;
  		printk("(PIO)");
  	}
  	if (afsr & SCHIZO_CEAFSR_SDMA) {
  		reported++;
  		printk("(DMA)");
  	}
  	if (!reported)
  		printk("(none)");
  	printk("]
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
  	return IRQ_HANDLED;
  }
  
  #define SCHIZO_PCI_AFSR	0x2010UL
  #define SCHIZO_PCI_AFAR	0x2018UL
  
  #define SCHIZO_PCIAFSR_PMA	0x8000000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_PTA	0x4000000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_PRTRY	0x2000000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_PPERR	0x1000000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_PTTO	0x0800000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_PUNUS	0x0400000000000000UL /* Schizo */
  #define SCHIZO_PCIAFSR_SMA	0x0200000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_STA	0x0100000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_SRTRY	0x0080000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_SPERR	0x0040000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_STTO	0x0020000000000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_SUNUS	0x0010000000000000UL /* Schizo */
  #define SCHIZO_PCIAFSR_BMSK	0x000003ff00000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_BLK	0x0000000080000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_CFG	0x0000000040000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_MEM	0x0000000020000000UL /* Schizo/Tomatillo */
  #define SCHIZO_PCIAFSR_IO	0x0000000010000000UL /* Schizo/Tomatillo */
  
  #define SCHIZO_PCI_CTRL		(0x2000UL)
  #define SCHIZO_PCICTRL_BUS_UNUS	(1UL << 63UL) /* Safari */
9fba62a59   David S. Miller   [SPARC64]: Small ...
560
  #define SCHIZO_PCICTRL_DTO_INT	(1UL << 61UL) /* Tomatillo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
  #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_ESLCK	(1UL << 51UL) /* Safari */
  #define SCHIZO_PCICTRL_ERRSLOT	(7UL << 48UL) /* Safari */
  #define SCHIZO_PCICTRL_TTO_ERR	(1UL << 38UL) /* Safari/Tomatillo */
  #define SCHIZO_PCICTRL_RTRY_ERR	(1UL << 37UL) /* Safari/Tomatillo */
  #define SCHIZO_PCICTRL_DTO_ERR	(1UL << 36UL) /* Safari/Tomatillo */
  #define SCHIZO_PCICTRL_SBH_ERR	(1UL << 35UL) /* Safari */
  #define SCHIZO_PCICTRL_SERR	(1UL << 34UL) /* Safari/Tomatillo */
  #define SCHIZO_PCICTRL_PCISPD	(1UL << 33UL) /* Safari */
  #define SCHIZO_PCICTRL_MRM_PREF	(1UL << 30UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_RDO_PREF	(1UL << 29UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_RDL_PREF	(1UL << 28UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_PTO	(3UL << 24UL) /* Safari/Tomatillo */
  #define SCHIZO_PCICTRL_PTO_SHIFT 24UL
  #define SCHIZO_PCICTRL_TRWSW	(7UL << 21UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_F_TGT_A	(1UL << 20UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_S_DTO_INT (1UL << 19UL) /* Safari */
  #define SCHIZO_PCICTRL_F_TGT_RT	(1UL << 19UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_SBH_INT	(1UL << 18UL) /* Safari */
  #define SCHIZO_PCICTRL_T_DTO_INT (1UL << 18UL) /* Tomatillo */
  #define SCHIZO_PCICTRL_EEN	(1UL << 17UL) /* Safari/Tomatillo */
  #define SCHIZO_PCICTRL_PARK	(1UL << 16UL) /* Safari/Tomatillo */
  #define SCHIZO_PCICTRL_PCIRST	(1UL <<  8UL) /* Safari */
  #define SCHIZO_PCICTRL_ARB_S	(0x3fUL << 0UL) /* Safari */
  #define SCHIZO_PCICTRL_ARB_T	(0xffUL << 0UL) /* Tomatillo */
  
  static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
  {
  	unsigned long csr_reg, csr, csr_error_bits;
  	irqreturn_t ret = IRQ_NONE;
  	u16 stat;
  
  	csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
87395fc67   David S. Miller   sparc64: Kill han...
594
  	csr = upa_readq(csr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
596
597
598
599
600
601
602
603
  	csr_error_bits =
  		csr & (SCHIZO_PCICTRL_BUS_UNUS |
  		       SCHIZO_PCICTRL_TTO_ERR |
  		       SCHIZO_PCICTRL_RTRY_ERR |
  		       SCHIZO_PCICTRL_DTO_ERR |
  		       SCHIZO_PCICTRL_SBH_ERR |
  		       SCHIZO_PCICTRL_SERR);
  	if (csr_error_bits) {
  		/* Clear the errors.  */
87395fc67   David S. Miller   sparc64: Kill han...
604
  		upa_writeq(csr, csr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  
  		/* Log 'em.  */
  		if (csr_error_bits & SCHIZO_PCICTRL_BUS_UNUS)
  			printk("%s: Bus unusable error asserted.
  ",
  			       pbm->name);
  		if (csr_error_bits & SCHIZO_PCICTRL_TTO_ERR)
  			printk("%s: PCI TRDY# timeout error asserted.
  ",
  			       pbm->name);
  		if (csr_error_bits & SCHIZO_PCICTRL_RTRY_ERR)
  			printk("%s: PCI excessive retry error asserted.
  ",
  			       pbm->name);
  		if (csr_error_bits & SCHIZO_PCICTRL_DTO_ERR)
  			printk("%s: PCI discard timeout error asserted.
  ",
  			       pbm->name);
  		if (csr_error_bits & SCHIZO_PCICTRL_SBH_ERR)
  			printk("%s: PCI streaming byte hole error asserted.
  ",
  			       pbm->name);
  		if (csr_error_bits & SCHIZO_PCICTRL_SERR)
  			printk("%s: PCI SERR signal asserted.
  ",
  			       pbm->name);
  		ret = IRQ_HANDLED;
  	}
  	pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
  	if (stat & (PCI_STATUS_PARITY |
  		    PCI_STATUS_SIG_TARGET_ABORT |
  		    PCI_STATUS_REC_TARGET_ABORT |
  		    PCI_STATUS_REC_MASTER_ABORT |
  		    PCI_STATUS_SIG_SYSTEM_ERROR)) {
  		printk("%s: PCI bus error, PCI_STATUS[%04x]
  ",
  		       pbm->name, stat);
  		pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
  		ret = IRQ_HANDLED;
  	}
  	return ret;
  }
6d24c8dc2   Al Viro   [PATCH] sparc64 p...
647
  static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
649
  {
  	struct pci_pbm_info *pbm = dev_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
652
653
654
655
656
657
658
659
  	unsigned long afsr_reg, afar_reg, base;
  	unsigned long afsr, afar, error_bits;
  	int reported;
  
  	base = pbm->pbm_regs;
  
  	afsr_reg = base + SCHIZO_PCI_AFSR;
  	afar_reg = base + SCHIZO_PCI_AFAR;
  
  	/* Latch error status. */
87395fc67   David S. Miller   sparc64: Kill han...
660
661
  	afar = upa_readq(afar_reg);
  	afsr = upa_readq(afsr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
664
665
666
667
668
669
670
671
672
  
  	/* Clear primary/secondary error status bits. */
  	error_bits = afsr &
  		(SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |
  		 SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |
  		 SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |
  		 SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |
  		 SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
  		 SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS);
  	if (!error_bits)
  		return schizo_pcierr_intr_other(pbm);
87395fc67   David S. Miller   sparc64: Kill han...
673
  	upa_writeq(error_bits, afsr_reg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
  
  	/* Log the error. */
  	printk("%s: PCI Error, primary error type[%s]
  ",
  	       pbm->name,
  	       (((error_bits & SCHIZO_PCIAFSR_PMA) ?
  		 "Master Abort" :
  		 ((error_bits & SCHIZO_PCIAFSR_PTA) ?
  		  "Target Abort" :
  		  ((error_bits & SCHIZO_PCIAFSR_PRTRY) ?
  		   "Excessive Retries" :
  		   ((error_bits & SCHIZO_PCIAFSR_PPERR) ?
  		    "Parity Error" :
  		    ((error_bits & SCHIZO_PCIAFSR_PTTO) ?
  		     "Timeout" :
  		     ((error_bits & SCHIZO_PCIAFSR_PUNUS) ?
  		      "Bus Unusable" : "???"))))))));
  	printk("%s: bytemask[%04lx] was_block(%d) space(%s)
  ",
  	       pbm->name,
  	       (afsr & SCHIZO_PCIAFSR_BMSK) >> 32UL,
  	       (afsr & SCHIZO_PCIAFSR_BLK) ? 1 : 0,
  	       ((afsr & SCHIZO_PCIAFSR_CFG) ?
  		"Config" :
  		((afsr & SCHIZO_PCIAFSR_MEM) ?
  		 "Memory" :
  		 ((afsr & SCHIZO_PCIAFSR_IO) ?
  		  "I/O" : "???"))));
  	printk("%s: PCI AFAR [%016lx]
  ",
  	       pbm->name, afar);
  	printk("%s: PCI Secondary errors [",
  	       pbm->name);
  	reported = 0;
  	if (afsr & SCHIZO_PCIAFSR_SMA) {
  		reported++;
  		printk("(Master Abort)");
  	}
  	if (afsr & SCHIZO_PCIAFSR_STA) {
  		reported++;
  		printk("(Target Abort)");
  	}
  	if (afsr & SCHIZO_PCIAFSR_SRTRY) {
  		reported++;
  		printk("(Excessive Retries)");
  	}
  	if (afsr & SCHIZO_PCIAFSR_SPERR) {
  		reported++;
  		printk("(Parity Error)");
  	}
  	if (afsr & SCHIZO_PCIAFSR_STTO) {
  		reported++;
  		printk("(Timeout)");
  	}
  	if (afsr & SCHIZO_PCIAFSR_SUNUS) {
  		reported++;
  		printk("(Bus Unusable)");
  	}
  	if (!reported)
  		printk("(none)");
  	printk("]
  ");
  
  	/* For the error types shown, scan PBM's PCI bus for devices
  	 * which have logged that error type.
  	 */
  
  	/* If we see a Target Abort, this could be the result of an
  	 * IOMMU translation error of some sort.  It is extremely
  	 * useful to log this information as usually it indicates
  	 * a bug in the IOMMU support code or a PCI device driver.
  	 */
  	if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) {
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
747
  		schizo_check_iommu_error(pbm, PCI_ERR);
6c108f129   David S. Miller   [SPARC64]: Move i...
748
  		pci_scan_for_target_abort(pbm, pbm->pci_bus);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
750
  	}
  	if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA))
6c108f129   David S. Miller   [SPARC64]: Move i...
751
  		pci_scan_for_master_abort(pbm, pbm->pci_bus);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
753
754
755
756
757
758
759
760
  
  	/* For excessive retries, PSYCHO/PBM will abort the device
  	 * and there is no way to specifically check for excessive
  	 * retries in the config space status registers.  So what
  	 * we hope is that we'll catch it via the master/target
  	 * abort events.
  	 */
  
  	if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR))
6c108f129   David S. Miller   [SPARC64]: Move i...
761
  		pci_scan_for_parity_error(pbm, pbm->pci_bus);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
  	return IRQ_HANDLED;
  }
  
  #define SCHIZO_SAFARI_ERRLOG	0x10018UL
  
  #define SAFARI_ERRLOG_ERROUT	0x8000000000000000UL
  
  #define BUS_ERROR_BADCMD	0x4000000000000000UL /* Schizo/Tomatillo */
  #define BUS_ERROR_SSMDIS	0x2000000000000000UL /* Safari */
  #define BUS_ERROR_BADMA		0x1000000000000000UL /* Safari */
  #define BUS_ERROR_BADMB		0x0800000000000000UL /* Safari */
  #define BUS_ERROR_BADMC		0x0400000000000000UL /* Safari */
  #define BUS_ERROR_SNOOP_GR	0x0000000000200000UL /* Tomatillo */
  #define BUS_ERROR_SNOOP_PCI	0x0000000000100000UL /* Tomatillo */
  #define BUS_ERROR_SNOOP_RD	0x0000000000080000UL /* Tomatillo */
  #define BUS_ERROR_SNOOP_RDS	0x0000000000020000UL /* Tomatillo */
  #define BUS_ERROR_SNOOP_RDSA	0x0000000000010000UL /* Tomatillo */
  #define BUS_ERROR_SNOOP_OWN	0x0000000000008000UL /* Tomatillo */
  #define BUS_ERROR_SNOOP_RDO	0x0000000000004000UL /* Tomatillo */
  #define BUS_ERROR_CPU1PS	0x0000000000002000UL /* Safari */
  #define BUS_ERROR_WDATA_PERR	0x0000000000002000UL /* Tomatillo */
  #define BUS_ERROR_CPU1PB	0x0000000000001000UL /* Safari */
  #define BUS_ERROR_CTRL_PERR	0x0000000000001000UL /* Tomatillo */
  #define BUS_ERROR_CPU0PS	0x0000000000000800UL /* Safari */
  #define BUS_ERROR_SNOOP_ERR	0x0000000000000800UL /* Tomatillo */
  #define BUS_ERROR_CPU0PB	0x0000000000000400UL /* Safari */
  #define BUS_ERROR_JBUS_ILL_B	0x0000000000000400UL /* Tomatillo */
  #define BUS_ERROR_CIQTO		0x0000000000000200UL /* Safari */
  #define BUS_ERROR_LPQTO		0x0000000000000100UL /* Safari */
  #define BUS_ERROR_JBUS_ILL_C	0x0000000000000100UL /* Tomatillo */
  #define BUS_ERROR_SFPQTO	0x0000000000000080UL /* Safari */
  #define BUS_ERROR_UFPQTO	0x0000000000000040UL /* Safari */
  #define BUS_ERROR_RD_PERR	0x0000000000000040UL /* Tomatillo */
  #define BUS_ERROR_APERR		0x0000000000000020UL /* Safari/Tomatillo */
  #define BUS_ERROR_UNMAP		0x0000000000000010UL /* Safari/Tomatillo */
  #define BUS_ERROR_BUSERR	0x0000000000000004UL /* Safari/Tomatillo */
  #define BUS_ERROR_TIMEOUT	0x0000000000000002UL /* Safari/Tomatillo */
  #define BUS_ERROR_ILL		0x0000000000000001UL /* Safari */
  
  /* We only expect UNMAP errors here.  The rest of the Safari errors
   * are marked fatal and thus cause a system reset.
   */
6d24c8dc2   Al Viro   [PATCH] sparc64 p...
805
  static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
  {
34768bc83   David S. Miller   [SPARC64] PCI: Us...
807
  	struct pci_pbm_info *pbm = dev_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
  	u64 errlog;
87395fc67   David S. Miller   sparc64: Kill han...
809
810
811
  	errlog = upa_readq(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG);
  	upa_writeq(errlog & ~(SAFARI_ERRLOG_ERROUT),
  		   pbm->controller_regs + SCHIZO_SAFARI_ERRLOG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
813
  
  	if (!(errlog & BUS_ERROR_UNMAP)) {
901811364   Sam Ravnborg   sparc64: Use unsi...
814
815
  		printk("%s: Unexpected Safari/JBUS error interrupt, errlog[%016llx]
  ",
6c108f129   David S. Miller   [SPARC64]: Move i...
816
  		       pbm->name, errlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
819
  		return IRQ_HANDLED;
  	}
6c108f129   David S. Miller   [SPARC64]: Move i...
820
821
822
  	printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.
  ",
  	       pbm->name);
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
823
  	schizo_check_iommu_error(pbm, SAFARI_ERR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
826
827
828
829
830
831
832
833
834
835
836
837
  	return IRQ_HANDLED;
  }
  
  /* Nearly identical to PSYCHO equivalents... */
  #define SCHIZO_ECC_CTRL		0x10020UL
  #define  SCHIZO_ECCCTRL_EE	 0x8000000000000000UL /* Enable ECC Checking */
  #define  SCHIZO_ECCCTRL_UE	 0x4000000000000000UL /* Enable UE Interrupts */
  #define  SCHIZO_ECCCTRL_CE	 0x2000000000000000UL /* Enable CE INterrupts */
  
  #define SCHIZO_SAFARI_ERRCTRL	0x10008UL
  #define  SCHIZO_SAFERRCTRL_EN	 0x8000000000000000UL
  #define SCHIZO_SAFARI_IRQCTRL	0x10010UL
  #define  SCHIZO_SAFIRQCTRL_EN	 0x8000000000000000UL
34768bc83   David S. Miller   [SPARC64] PCI: Us...
838
839
840
841
842
843
844
845
846
  static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino)
  {
  	ino &= IMAP_INO;
  
  	if (pbm->ino_bitmap & (1UL << ino))
  		return 1;
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
848
849
  /* How the Tomatillo IRQs are routed around is pure guesswork here.
   *
   * All the Tomatillo devices I see in prtconf dumps seem to have only
33ccc190d   Joe Perches   [SPARC64]: Spelli...
850
   * a single PCI bus unit attached to it.  It would seem they are separate
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
852
853
854
855
856
857
858
859
860
   * devices because their PortID (ie. JBUS ID) values are all different
   * and thus the registers are mapped to totally different locations.
   *
   * However, two Tomatillo's look "similar" in that the only difference
   * in their PortID is the lowest bit.
   *
   * So if we were to ignore this lower bit, it certainly looks like two
   * PCI bus units of the same Tomatillo.  I still have not really
   * figured this out...
   */
34768bc83   David S. Miller   [SPARC64] PCI: Us...
861
  static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
  {
cd4cd7306   Grant Likely   sparc: remove ref...
863
  	struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
  	u64 tmp, err_mask, err_no_mask;
af80318eb   David S. Miller   [SPARC64]: Fix re...
865
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
866

2b1e59787   David S. Miller   [SPARC64]: of_dev...
867
868
869
870
871
872
873
  	/* Tomatillo IRQ property layout is:
  	 * 0: PCIERR
  	 * 1: UE ERR
  	 * 2: CE ERR
  	 * 3: SERR
  	 * 4: POWER FAIL?
  	 */
af80318eb   David S. Miller   [SPARC64]: Fix re...
874
  	if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
875
  		err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
876
877
878
879
880
881
882
  				  "TOMATILLO_UE", pbm);
  		if (err)
  			printk(KERN_WARNING "%s: Could not register UE, "
  			       "err=%d
  ", pbm->name, err);
  	}
  	if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
883
  		err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
884
885
886
887
888
889
890
891
  				  "TOMATILLO_CE", pbm);
  		if (err)
  			printk(KERN_WARNING "%s: Could not register CE, "
  			       "err=%d
  ", pbm->name, err);
  	}
  	err = 0;
  	if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
892
  		err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
893
894
  				  "TOMATILLO_PCIERR", pbm);
  	} else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
895
  		err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
896
897
898
899
900
901
902
903
  				  "TOMATILLO_PCIERR", pbm);
  	}
  	if (err)
  		printk(KERN_WARNING "%s: Could not register PCIERR, "
  		       "err=%d
  ", pbm->name, err);
  
  	if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
904
  		err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
905
906
907
908
909
910
  				  "TOMATILLO_SERR", pbm);
  		if (err)
  			printk(KERN_WARNING "%s: Could not register SERR, "
  			       "err=%d
  ", pbm->name, err);
  	}
34768bc83   David S. Miller   [SPARC64] PCI: Us...
911
912
  
  	/* Enable UE and CE interrupts for controller. */
87395fc67   David S. Miller   sparc64: Kill han...
913
914
915
  	upa_writeq((SCHIZO_ECCCTRL_EE |
  		    SCHIZO_ECCCTRL_UE |
  		    SCHIZO_ECCCTRL_CE), pbm->controller_regs + SCHIZO_ECC_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
916
917
918
919
920
921
922
923
924
925
926
  
  	/* Enable PCI Error interrupts and clear error
  	 * bits.
  	 */
  	err_mask = (SCHIZO_PCICTRL_BUS_UNUS |
  		    SCHIZO_PCICTRL_TTO_ERR |
  		    SCHIZO_PCICTRL_RTRY_ERR |
  		    SCHIZO_PCICTRL_SERR |
  		    SCHIZO_PCICTRL_EEN);
  
  	err_no_mask = SCHIZO_PCICTRL_DTO_ERR;
87395fc67   David S. Miller   sparc64: Kill han...
927
  	tmp = upa_readq(pbm->pbm_regs + SCHIZO_PCI_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
928
929
  	tmp |= err_mask;
  	tmp &= ~err_no_mask;
87395fc67   David S. Miller   sparc64: Kill han...
930
  	upa_writeq(tmp, pbm->pbm_regs + SCHIZO_PCI_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
931
932
933
934
935
936
937
  
  	err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |
  		    SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |
  		    SCHIZO_PCIAFSR_PTTO |
  		    SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |
  		    SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
  		    SCHIZO_PCIAFSR_STTO);
87395fc67   David S. Miller   sparc64: Kill han...
938
  	upa_writeq(err_mask, pbm->pbm_regs + SCHIZO_PCI_AFSR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
939
940
941
942
943
944
945
946
947
948
  
  	err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR |
  		    BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD |
  		    BUS_ERROR_SNOOP_RDS | BUS_ERROR_SNOOP_RDSA |
  		    BUS_ERROR_SNOOP_OWN | BUS_ERROR_SNOOP_RDO |
  		    BUS_ERROR_WDATA_PERR | BUS_ERROR_CTRL_PERR |
  		    BUS_ERROR_SNOOP_ERR | BUS_ERROR_JBUS_ILL_B |
  		    BUS_ERROR_JBUS_ILL_C | BUS_ERROR_RD_PERR |
  		    BUS_ERROR_APERR | BUS_ERROR_UNMAP |
  		    BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT);
87395fc67   David S. Miller   sparc64: Kill han...
949
950
  	upa_writeq((SCHIZO_SAFERRCTRL_EN | err_mask),
  		   pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951

87395fc67   David S. Miller   sparc64: Kill han...
952
953
  	upa_writeq((SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP)),
  		   pbm->controller_regs + SCHIZO_SAFARI_IRQCTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954
  }
34768bc83   David S. Miller   [SPARC64] PCI: Us...
955
  static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
  {
cd4cd7306   Grant Likely   sparc: remove ref...
957
  	struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
958
  	u64 tmp, err_mask, err_no_mask;
af80318eb   David S. Miller   [SPARC64]: Fix re...
959
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960

2b1e59787   David S. Miller   [SPARC64]: of_dev...
961
962
963
964
965
966
967
  	/* Schizo IRQ property layout is:
  	 * 0: PCIERR
  	 * 1: UE ERR
  	 * 2: CE ERR
  	 * 3: SERR
  	 * 4: POWER FAIL?
  	 */
af80318eb   David S. Miller   [SPARC64]: Fix re...
968
  	if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
969
  		err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
970
971
972
973
974
975
976
  				  "SCHIZO_UE", pbm);
  		if (err)
  			printk(KERN_WARNING "%s: Could not register UE, "
  			       "err=%d
  ", pbm->name, err);
  	}
  	if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
977
  		err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
978
979
980
981
982
983
984
985
  				  "SCHIZO_CE", pbm);
  		if (err)
  			printk(KERN_WARNING "%s: Could not register CE, "
  			       "err=%d
  ", pbm->name, err);
  	}
  	err = 0;
  	if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
986
  		err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
987
988
  				  "SCHIZO_PCIERR", pbm);
  	} else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
989
  		err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
990
991
992
993
994
995
996
997
  				  "SCHIZO_PCIERR", pbm);
  	}
  	if (err)
  		printk(KERN_WARNING "%s: Could not register PCIERR, "
  		       "err=%d
  ", pbm->name, err);
  
  	if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
1636f8ac2   Grant Likely   sparc/of: Move of...
998
  		err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
af80318eb   David S. Miller   [SPARC64]: Fix re...
999
1000
1001
1002
1003
1004
  				  "SCHIZO_SERR", pbm);
  		if (err)
  			printk(KERN_WARNING "%s: Could not register SERR, "
  			       "err=%d
  ", pbm->name, err);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
1006
  
  	/* Enable UE and CE interrupts for controller. */
87395fc67   David S. Miller   sparc64: Kill han...
1007
1008
1009
  	upa_writeq((SCHIZO_ECCCTRL_EE |
  		    SCHIZO_ECCCTRL_UE |
  		    SCHIZO_ECCCTRL_CE), pbm->controller_regs + SCHIZO_ECC_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
  
  	err_mask = (SCHIZO_PCICTRL_BUS_UNUS |
  		    SCHIZO_PCICTRL_ESLCK |
  		    SCHIZO_PCICTRL_TTO_ERR |
  		    SCHIZO_PCICTRL_RTRY_ERR |
  		    SCHIZO_PCICTRL_SBH_ERR |
  		    SCHIZO_PCICTRL_SERR |
  		    SCHIZO_PCICTRL_EEN);
  
  	err_no_mask = (SCHIZO_PCICTRL_DTO_ERR |
  		       SCHIZO_PCICTRL_SBH_INT);
  
  	/* Enable PCI Error interrupts and clear error
  	 * bits for each PBM.
  	 */
87395fc67   David S. Miller   sparc64: Kill han...
1025
  	tmp = upa_readq(pbm->pbm_regs + SCHIZO_PCI_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
1027
  	tmp |= err_mask;
  	tmp &= ~err_no_mask;
87395fc67   David S. Miller   sparc64: Kill han...
1028
  	upa_writeq(tmp, pbm->pbm_regs + SCHIZO_PCI_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029

87395fc67   David S. Miller   sparc64: Kill han...
1030
1031
1032
1033
1034
1035
1036
  	upa_writeq((SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |
  		    SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |
  		    SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |
  		    SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |
  		    SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
  		    SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS),
  		   pbm->pbm_regs + SCHIZO_PCI_AFSR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
  
  	/* Make all Safari error conditions fatal except unmapped
  	 * errors which we make generate interrupts.
  	 */
  	err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SSMDIS |
  		    BUS_ERROR_BADMA | BUS_ERROR_BADMB |
  		    BUS_ERROR_BADMC |
  		    BUS_ERROR_CPU1PS | BUS_ERROR_CPU1PB |
  		    BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB |
  		    BUS_ERROR_CIQTO |
  		    BUS_ERROR_LPQTO | BUS_ERROR_SFPQTO |
  		    BUS_ERROR_UFPQTO | BUS_ERROR_APERR |
  		    BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT |
  		    BUS_ERROR_ILL);
  #if 1
  	/* XXX Something wrong with some Excalibur systems
  	 * XXX Sun is shipping.  The behavior on a 2-cpu
  	 * XXX machine is that both CPU1 parity error bits
  	 * XXX are set and are immediately set again when
  	 * XXX their error status bits are cleared.  Just
  	 * XXX ignore them for now.  -DaveM
  	 */
  	err_mask &= ~(BUS_ERROR_CPU1PS | BUS_ERROR_CPU1PB |
  		      BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB);
  #endif
87395fc67   David S. Miller   sparc64: Kill han...
1062
1063
  	upa_writeq((SCHIZO_SAFERRCTRL_EN | err_mask),
  		   pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
  }
085ae41f6   David S. Miller   [PATCH] Make spar...
1065
  static void pbm_config_busmastering(struct pci_pbm_info *pbm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
  {
  	u8 *addr;
  
  	/* Set cache-line size to 64 bytes, this is actually
  	 * a nop but I do it for completeness.
  	 */
  	addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,
  					0, PCI_CACHE_LINE_SIZE);
  	pci_config_write8(addr, 64 / sizeof(u32));
  
  	/* Set PBM latency timer to 64 PCI clocks. */
  	addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,
  					0, PCI_LATENCY_TIMER);
  	pci_config_write8(addr, 64);
  }
e822358ac   David S. Miller   sparc64: Pass pro...
1081
1082
  static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm,
  				      struct device *parent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1083
  {
34768bc83   David S. Miller   [SPARC64] PCI: Us...
1084
1085
  	pbm_config_busmastering(pbm);
  	pbm->is_66mhz_capable =
61c7a080a   Grant Likely   of: Always use 's...
1086
  		(of_find_property(pbm->op->dev.of_node, "66mhz-capable", NULL)
e87dc3502   David S. Miller   [SPARC64]: Use in...
1087
  		 != NULL);
bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1088

e822358ac   David S. Miller   sparc64: Pass pro...
1089
  	pbm->pci_bus = pci_scan_one_pbm(pbm, parent);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090

34768bc83   David S. Miller   [SPARC64] PCI: Us...
1091
1092
  	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO)
  		tomatillo_register_error_handlers(pbm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093
  	else
34768bc83   David S. Miller   [SPARC64] PCI: Us...
1094
  		schizo_register_error_handlers(pbm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
  #define SCHIZO_STRBUF_CONTROL		(0x02800UL)
  #define SCHIZO_STRBUF_FLUSH		(0x02808UL)
  #define SCHIZO_STRBUF_FSYNC		(0x02810UL)
  #define SCHIZO_STRBUF_CTXFLUSH		(0x02818UL)
  #define SCHIZO_STRBUF_CTXMATCH		(0x10000UL)
  
  static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm)
  {
  	unsigned long base = pbm->pbm_regs;
  	u64 control;
  
  	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
  		/* TOMATILLO lacks streaming cache.  */
  		return;
  	}
  
  	/* SCHIZO has context flushing. */
  	pbm->stc.strbuf_control		= base + SCHIZO_STRBUF_CONTROL;
  	pbm->stc.strbuf_pflush		= base + SCHIZO_STRBUF_FLUSH;
  	pbm->stc.strbuf_fsync		= base + SCHIZO_STRBUF_FSYNC;
  	pbm->stc.strbuf_ctxflush	= base + SCHIZO_STRBUF_CTXFLUSH;
  	pbm->stc.strbuf_ctxmatch_base	= base + SCHIZO_STRBUF_CTXMATCH;
  
  	pbm->stc.strbuf_flushflag = (volatile unsigned long *)
  		((((unsigned long)&pbm->stc.__flushflag_buf[0])
  		  + 63UL)
  		 & ~63UL);
  	pbm->stc.strbuf_flushflag_pa = (unsigned long)
  		__pa(pbm->stc.strbuf_flushflag);
  
  	/* Turn off LRU locking and diag mode, enable the
  	 * streaming buffer and leave the rerun-disable
  	 * setting however OBP set it.
  	 */
87395fc67   David S. Miller   sparc64: Kill han...
1130
  	control = upa_readq(pbm->stc.strbuf_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
1132
1133
1134
  	control &= ~(SCHIZO_STRBUF_CTRL_LPTR |
  		     SCHIZO_STRBUF_CTRL_LENAB |
  		     SCHIZO_STRBUF_CTRL_DENAB);
  	control |= SCHIZO_STRBUF_CTRL_ENAB;
87395fc67   David S. Miller   sparc64: Kill han...
1135
  	upa_writeq(control, pbm->stc.strbuf_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
1137
1138
1139
1140
1141
1142
1143
  
  	pbm->stc.strbuf_enabled = 1;
  }
  
  #define SCHIZO_IOMMU_CONTROL		(0x00200UL)
  #define SCHIZO_IOMMU_TSBBASE		(0x00208UL)
  #define SCHIZO_IOMMU_FLUSH		(0x00210UL)
  #define SCHIZO_IOMMU_CTXFLUSH		(0x00218UL)
ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1144
  static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1145
  {
463801b3a   David S. Miller   pci_schizo: Use o...
1146
  	static const u32 vdma_default[] = { 0xc0000000, 0x40000000 };
51e851361   David S. Miller   [SPARC64]: Consol...
1147
  	unsigned long i, tagbase, database;
463801b3a   David S. Miller   pci_schizo: Use o...
1148
  	struct iommu *iommu = pbm->iommu;
ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1149
  	int tsbsize, err;
463801b3a   David S. Miller   pci_schizo: Use o...
1150
1151
  	const u32 *vdma;
  	u32 dma_mask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
  	u64 control;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153

61c7a080a   Grant Likely   of: Always use 's...
1154
  	vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma", NULL);
463801b3a   David S. Miller   pci_schizo: Use o...
1155
1156
  	if (!vdma)
  		vdma = vdma_default;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
  
  	dma_mask = vdma[0];
  	switch (vdma[1]) {
  		case 0x20000000:
  			dma_mask |= 0x1fffffff;
  			tsbsize = 64;
  			break;
  
  		case 0x40000000:
  			dma_mask |= 0x3fffffff;
  			tsbsize = 128;
  			break;
  
  		case 0x80000000:
  			dma_mask |= 0x7fffffff;
  			tsbsize = 128;
  			break;
  
  		default:
6d19c88f5   David S. Miller   sparc64: Convert ...
1176
1177
1178
1179
  			printk(KERN_ERR PFX "Strange virtual-dma size.
  ");
  			return -EINVAL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1180

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1181
1182
1183
1184
  	/* Register addresses, SCHIZO has iommu ctx flushing. */
  	iommu->iommu_control  = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
  	iommu->iommu_tsbbase  = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
  	iommu->iommu_flush    = pbm->pbm_regs + SCHIZO_IOMMU_FLUSH;
ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1185
  	iommu->iommu_tags     = iommu->iommu_flush + (0xa580UL - 0x0210UL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
  	iommu->iommu_ctxflush = pbm->pbm_regs + SCHIZO_IOMMU_CTXFLUSH;
  
  	/* We use the main control/status register of SCHIZO as the write
  	 * completion register.
  	 */
  	iommu->write_complete_reg = pbm->controller_regs + 0x10000UL;
  
  	/*
  	 * Invalidate TLB Entries.
  	 */
87395fc67   David S. Miller   sparc64: Kill han...
1196
  	control = upa_readq(iommu->iommu_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1197
  	control |= SCHIZO_IOMMU_CTRL_DENAB;
87395fc67   David S. Miller   sparc64: Kill han...
1198
  	upa_writeq(control, iommu->iommu_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1199
1200
  
  	tagbase = SCHIZO_IOMMU_TAG, database = SCHIZO_IOMMU_DATA;
6d19c88f5   David S. Miller   sparc64: Convert ...
1201
  	for (i = 0; i < 16; i++) {
87395fc67   David S. Miller   sparc64: Kill han...
1202
1203
  		upa_writeq(0, pbm->pbm_regs + tagbase + (i * 8UL));
  		upa_writeq(0, pbm->pbm_regs + database + (i * 8UL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
1205
1206
1207
1208
  	}
  
  	/* Leave diag mode enabled for full-flushing done
  	 * in pci_iommu.c
  	 */
c1b1a5f1f   David S. Miller   [SPARC64]: NUMA d...
1209
1210
  	err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask,
  			       pbm->numa_node);
6d19c88f5   David S. Miller   sparc64: Convert ...
1211
1212
1213
  	if (err) {
  		printk(KERN_ERR PFX "iommu_table_init() fails with %d
  ", err);
ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1214
  		return err;
6d19c88f5   David S. Miller   sparc64: Convert ...
1215
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1216

87395fc67   David S. Miller   sparc64: Kill han...
1217
  	upa_writeq(__pa(iommu->page_table), iommu->iommu_tsbbase);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1218

87395fc67   David S. Miller   sparc64: Kill han...
1219
  	control = upa_readq(iommu->iommu_control);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220
1221
1222
1223
1224
1225
1226
1227
  	control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);
  	switch (tsbsize) {
  	case 64:
  		control |= SCHIZO_IOMMU_TSBSZ_64K;
  		break;
  	case 128:
  		control |= SCHIZO_IOMMU_TSBSZ_128K;
  		break;
6d19c88f5   David S. Miller   sparc64: Convert ...
1228
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1229
1230
  
  	control |= SCHIZO_IOMMU_CTRL_ENAB;
87395fc67   David S. Miller   sparc64: Kill han...
1231
  	upa_writeq(control, iommu->iommu_control);
ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1232
1233
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
  }
  
  #define SCHIZO_PCI_IRQ_RETRY	(0x1a00UL)
  #define  SCHIZO_IRQ_RETRY_INF	 0xffUL
  
  #define SCHIZO_PCI_DIAG			(0x2020UL)
  #define  SCHIZO_PCIDIAG_D_BADECC	(1UL << 10UL) /* Disable BAD ECC errors (Schizo) */
  #define  SCHIZO_PCIDIAG_D_BYPASS	(1UL <<  9UL) /* Disable MMU bypass mode (Schizo/Tomatillo) */
  #define  SCHIZO_PCIDIAG_D_TTO		(1UL <<  8UL) /* Disable TTO errors (Schizo/Tomatillo) */
  #define  SCHIZO_PCIDIAG_D_RTRYARB	(1UL <<  7UL) /* Disable retry arbitration (Schizo) */
  #define  SCHIZO_PCIDIAG_D_RETRY		(1UL <<  6UL) /* Disable retry limit (Schizo/Tomatillo) */
  #define  SCHIZO_PCIDIAG_D_INTSYNC	(1UL <<  5UL) /* Disable interrupt/DMA synch (Schizo/Tomatillo) */
  #define  SCHIZO_PCIDIAG_I_DMA_PARITY	(1UL <<  3UL) /* Invert DMA parity (Schizo/Tomatillo) */
  #define  SCHIZO_PCIDIAG_I_PIOD_PARITY	(1UL <<  2UL) /* Invert PIO data parity (Schizo/Tomatillo) */
  #define  SCHIZO_PCIDIAG_I_PIOA_PARITY	(1UL <<  1UL) /* Invert PIO address parity (Schizo/Tomatillo) */
  
  #define TOMATILLO_PCI_IOC_CSR		(0x2248UL)
  #define TOMATILLO_IOC_PART_WPENAB	0x0000000000080000UL
  #define TOMATILLO_IOC_RDMULT_PENAB	0x0000000000040000UL
  #define TOMATILLO_IOC_RDONE_PENAB	0x0000000000020000UL
  #define TOMATILLO_IOC_RDLINE_PENAB	0x0000000000010000UL
  #define TOMATILLO_IOC_RDMULT_PLEN	0x000000000000c000UL
  #define TOMATILLO_IOC_RDMULT_PLEN_SHIFT	14UL
  #define TOMATILLO_IOC_RDONE_PLEN	0x0000000000003000UL
  #define TOMATILLO_IOC_RDONE_PLEN_SHIFT	12UL
  #define TOMATILLO_IOC_RDLINE_PLEN	0x0000000000000c00UL
  #define TOMATILLO_IOC_RDLINE_PLEN_SHIFT	10UL
  #define TOMATILLO_IOC_PREF_OFF		0x00000000000003f8UL
  #define TOMATILLO_IOC_PREF_OFF_SHIFT	3UL
  #define TOMATILLO_IOC_RDMULT_CPENAB	0x0000000000000004UL
  #define TOMATILLO_IOC_RDONE_CPENAB	0x0000000000000002UL
  #define TOMATILLO_IOC_RDLINE_CPENAB	0x0000000000000001UL
  
  #define TOMATILLO_PCI_IOC_TDIAG		(0x2250UL)
  #define TOMATILLO_PCI_IOC_DDIAG		(0x2290UL)
085ae41f6   David S. Miller   [PATCH] Make spar...
1269
  static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1270
1271
  {
  	u64 tmp;
87395fc67   David S. Miller   sparc64: Kill han...
1272
  	upa_writeq(5, pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1273

87395fc67   David S. Miller   sparc64: Kill han...
1274
  	tmp = upa_readq(pbm->pbm_regs + SCHIZO_PCI_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275

9fba62a59   David S. Miller   [SPARC64]: Small ...
1276
1277
  	/* Enable arbiter for all PCI slots.  */
  	tmp |= 0xff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1278
1279
1280
  	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
  	    pbm->chip_version >= 0x2)
  		tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281

61c7a080a   Grant Likely   of: Always use 's...
1282
  	if (!of_find_property(pbm->op->dev.of_node, "no-bus-parking", NULL))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
  		tmp |= SCHIZO_PCICTRL_PARK;
9fba62a59   David S. Miller   [SPARC64]: Small ...
1284
1285
  	else
  		tmp &= ~SCHIZO_PCICTRL_PARK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286
1287
1288
  
  	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
  	    pbm->chip_version <= 0x1)
9fba62a59   David S. Miller   [SPARC64]: Small ...
1289
  		tmp |= SCHIZO_PCICTRL_DTO_INT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1290
  	else
9fba62a59   David S. Miller   [SPARC64]: Small ...
1291
  		tmp &= ~SCHIZO_PCICTRL_DTO_INT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1292
1293
1294
1295
1296
  
  	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO)
  		tmp |= (SCHIZO_PCICTRL_MRM_PREF |
  			SCHIZO_PCICTRL_RDO_PREF |
  			SCHIZO_PCICTRL_RDL_PREF);
87395fc67   David S. Miller   sparc64: Kill han...
1297
  	upa_writeq(tmp, pbm->pbm_regs + SCHIZO_PCI_CTRL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1298

87395fc67   David S. Miller   sparc64: Kill han...
1299
  	tmp = upa_readq(pbm->pbm_regs + SCHIZO_PCI_DIAG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300
1301
1302
  	tmp &= ~(SCHIZO_PCIDIAG_D_RTRYARB |
  		 SCHIZO_PCIDIAG_D_RETRY |
  		 SCHIZO_PCIDIAG_D_INTSYNC);
87395fc67   David S. Miller   sparc64: Kill han...
1303
  	upa_writeq(tmp, pbm->pbm_regs + SCHIZO_PCI_DIAG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
  
  	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
  		/* Clear prefetch lengths to workaround a bug in
  		 * Jalapeno...
  		 */
  		tmp = (TOMATILLO_IOC_PART_WPENAB |
  		       (1 << TOMATILLO_IOC_PREF_OFF_SHIFT) |
  		       TOMATILLO_IOC_RDMULT_CPENAB |
  		       TOMATILLO_IOC_RDONE_CPENAB |
  		       TOMATILLO_IOC_RDLINE_CPENAB);
87395fc67   David S. Miller   sparc64: Kill han...
1314
  		upa_writeq(tmp, pbm->pbm_regs + TOMATILLO_PCI_IOC_CSR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1315
1316
  	}
  }
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1317
  static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm,
cd4cd7306   Grant Likely   sparc: remove ref...
1318
  				     struct platform_device *op, u32 portid,
6d19c88f5   David S. Miller   sparc64: Convert ...
1319
  				     int chip_type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320
  {
a165b4205   David S. Miller   [SPARC64]: Fix PC...
1321
  	const struct linux_prom64_registers *regs;
61c7a080a   Grant Likely   of: Always use 's...
1322
  	struct device_node *dp = op->dev.of_node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1323
  	const char *chipset_name;
c6fee0810   David S. Miller   sparc64: Fix buil...
1324
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
  
  	switch (chip_type) {
  	case PBM_CHIP_TYPE_TOMATILLO:
  		chipset_name = "TOMATILLO";
  		break;
  
  	case PBM_CHIP_TYPE_SCHIZO_PLUS:
  		chipset_name = "SCHIZO+";
  		break;
  
  	case PBM_CHIP_TYPE_SCHIZO:
  	default:
  		chipset_name = "SCHIZO";
  		break;
6cb79b3f3   Joe Perches   sparc: Remove unn...
1339
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
  
  	/* For SCHIZO, three OBP regs:
  	 * 1) PBM controller regs
  	 * 2) Schizo front-end controller regs (same for both PBMs)
  	 * 3) PBM PCI config space
  	 *
  	 * For TOMATILLO, four OBP regs:
  	 * 1) PBM controller regs
  	 * 2) Tomatillo front-end controller regs
  	 * 3) PBM PCI config space
  	 * 4) Ichip regs
  	 */
bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1352
  	regs = of_get_property(dp, "reg", NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353

34768bc83   David S. Miller   [SPARC64] PCI: Us...
1354
1355
  	pbm->next = pci_pbm_root;
  	pci_pbm_root = pbm;
c1b1a5f1f   David S. Miller   [SPARC64]: NUMA d...
1356
  	pbm->numa_node = -1;
ca3dd88e4   David S. Miller   [SPARC64] PCI: Co...
1357
1358
  	pbm->pci_ops = &sun4u_pci_ops;
  	pbm->config_space_reg_bits = 8;
34768bc83   David S. Miller   [SPARC64] PCI: Us...
1359

6c108f129   David S. Miller   [SPARC64]: Move i...
1360
  	pbm->index = pci_num_pbms++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1361
  	pbm->portid = portid;
22fecbae4   David S. Miller   sparc64: Record O...
1362
  	pbm->op = op;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1363
1364
  
  	pbm->chip_type = chip_type;
bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1365
1366
  	pbm->chip_version = of_getintprop_default(dp, "version#", 0);
  	pbm->chip_revision = of_getintprop_default(dp, "module-version#", 0);
e87dc3502   David S. Miller   [SPARC64]: Use in...
1367
1368
1369
  
  	pbm->pbm_regs = regs[0].phys_addr;
  	pbm->controller_regs = regs[1].phys_addr - 0x10000UL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1370

bb6743f4f   David S. Miller   [SPARC64]: Do pro...
1371
  	if (chip_type == PBM_CHIP_TYPE_TOMATILLO)
e87dc3502   David S. Miller   [SPARC64]: Use in...
1372
  		pbm->sync_reg = regs[3].phys_addr + 0x1a18UL;
bb6743f4f   David S. Miller   [SPARC64]: Do pro...
1373

e87dc3502   David S. Miller   [SPARC64]: Use in...
1374
  	pbm->name = dp->full_name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1375

e87dc3502   David S. Miller   [SPARC64]: Use in...
1376
1377
  	printk("%s: %s PCI Bus Module ver[%x:%x]
  ",
bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1378
  	       pbm->name, chipset_name,
e87dc3502   David S. Miller   [SPARC64]: Use in...
1379
  	       pbm->chip_version, pbm->chip_revision);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1380
1381
  
  	schizo_pbm_hw_init(pbm);
9fd8b6476   David S. Miller   [SPARC64]: Consol...
1382
  	pci_determine_mem_io_space(pbm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1383

cfa0652c4   David S. Miller   [SPARC64] PCI: Us...
1384
  	pci_get_pbm_props(pbm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1385

ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1386
1387
1388
  	err = schizo_pbm_iommu_init(pbm);
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1389
  	schizo_pbm_strbuf_init(pbm);
ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1390

e822358ac   David S. Miller   sparc64: Pass pro...
1391
  	schizo_scan_bus(pbm, &op->dev);
6d19c88f5   David S. Miller   sparc64: Convert ...
1392

ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1393
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
  }
  
  static inline int portid_compare(u32 x, u32 y, int chip_type)
  {
  	if (chip_type == PBM_CHIP_TYPE_TOMATILLO) {
  		if (x == (y ^ 1))
  			return 1;
  		return 0;
  	}
  	return (x == y);
  }
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
  static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid,
  							   int chip_type)
  {
  	struct pci_pbm_info *pbm;
  
  	for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
  		if (portid_compare(pbm->portid, portid, chip_type))
  			return pbm;
  	}
  	return NULL;
  }
cd4cd7306   Grant Likely   sparc: remove ref...
1416
  static int __devinit __schizo_init(struct platform_device *op, unsigned long chip_type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1417
  {
61c7a080a   Grant Likely   of: Always use 's...
1418
  	struct device_node *dp = op->dev.of_node;
34768bc83   David S. Miller   [SPARC64] PCI: Us...
1419
  	struct pci_pbm_info *pbm;
16ce82d84   David S. Miller   [SPARC64]: Conver...
1420
  	struct iommu *iommu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1421
  	u32 portid;
d7472c389   David S. Miller   sparc64: Simplify...
1422
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1423

bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1424
  	portid = of_getintprop_default(dp, "portid", 0xff);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1425

d7472c389   David S. Miller   sparc64: Simplify...
1426
  	err = -ENOMEM;
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1427
1428
1429
1430
  	pbm = kzalloc(sizeof(*pbm), GFP_KERNEL);
  	if (!pbm) {
  		printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.
  ");
d7472c389   David S. Miller   sparc64: Simplify...
1431
  		goto out_err;
6d19c88f5   David S. Miller   sparc64: Convert ...
1432
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1433

d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1434
1435
1436
  	pbm->sibling = schizo_find_sibling(portid, chip_type);
  
  	iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL);
6d19c88f5   David S. Miller   sparc64: Convert ...
1437
1438
1439
  	if (!iommu) {
  		printk(KERN_ERR PFX "Cannot allocate PBM A iommu.
  ");
d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1440
  		goto out_free_pbm;
6d19c88f5   David S. Miller   sparc64: Convert ...
1441
  	}
bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1442

d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1443
  	pbm->iommu = iommu;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444

d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1445
1446
  	if (schizo_pbm_init(pbm, op, portid, chip_type))
  		goto out_free_iommu;
bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1447

d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1448
1449
  	if (pbm->sibling)
  		pbm->sibling->sibling = pbm;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1450

d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1451
  	dev_set_drvdata(&op->dev, pbm);
ad7ad57c6   David S. Miller   [SPARC64]: Fix co...
1452

6d19c88f5   David S. Miller   sparc64: Convert ...
1453
  	return 0;
bc606f3c9   David S. Miller   [SPARC64]: Minor ...
1454

d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1455
1456
  out_free_iommu:
  	kfree(pbm->iommu);
d7472c389   David S. Miller   sparc64: Simplify...
1457

d3ae4b5bc   David S. Miller   sparc64: Get rid ...
1458
1459
  out_free_pbm:
  	kfree(pbm);
d7472c389   David S. Miller   sparc64: Simplify...
1460
1461
1462
  
  out_err:
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1463
  }
b1608d69c   Grant Likely   drivercore: rever...
1464
  static const struct of_device_id schizo_match[];
4ebb24f70   Grant Likely   dt/sparc: Elimina...
1465
  static int __devinit schizo_probe(struct platform_device *op)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1466
  {
b1608d69c   Grant Likely   drivercore: rever...
1467
1468
1469
1470
  	const struct of_device_id *match;
  
  	match = of_match_device(schizo_match, &op->dev);
  	if (!match)
4ebb24f70   Grant Likely   dt/sparc: Elimina...
1471
  		return -EINVAL;
b1608d69c   Grant Likely   drivercore: rever...
1472
  	return __schizo_init(op, (unsigned long)match->data);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1473
  }
6d19c88f5   David S. Miller   sparc64: Convert ...
1474
1475
1476
1477
1478
  /* The ordering of this table is very important.  Some Tomatillo
   * nodes announce that they are compatible with both pci108e,a801
   * and pci108e,8001.  So list the chips in reverse chronological
   * order.
   */
3628aa065   David S. Miller   sparc64: Fix sect...
1479
  static const struct of_device_id schizo_match[] = {
6d19c88f5   David S. Miller   sparc64: Convert ...
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
  	{
  		.name = "pci",
  		.compatible = "pci108e,a801",
  		.data = (void *) PBM_CHIP_TYPE_TOMATILLO,
  	},
  	{
  		.name = "pci",
  		.compatible = "pci108e,8002",
  		.data = (void *) PBM_CHIP_TYPE_SCHIZO_PLUS,
  	},
  	{
  		.name = "pci",
  		.compatible = "pci108e,8001",
  		.data = (void *) PBM_CHIP_TYPE_SCHIZO,
  	},
  	{},
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497

4ebb24f70   Grant Likely   dt/sparc: Elimina...
1498
  static struct platform_driver schizo_driver = {
4018294b5   Grant Likely   of: Remove duplic...
1499
1500
1501
1502
1503
  	.driver = {
  		.name = DRIVER_NAME,
  		.owner = THIS_MODULE,
  		.of_match_table = schizo_match,
  	},
6d19c88f5   David S. Miller   sparc64: Convert ...
1504
1505
1506
1507
  	.probe		= schizo_probe,
  };
  
  static int __init schizo_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1508
  {
4ebb24f70   Grant Likely   dt/sparc: Elimina...
1509
  	return platform_driver_register(&schizo_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510
  }
6d19c88f5   David S. Miller   sparc64: Convert ...
1511
1512
  
  subsys_initcall(schizo_init);