aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/pci_common.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/pci_common.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/pci_common.c')
-rw-r--r--arch/sparc/kernel/pci_common.c545
1 files changed, 545 insertions, 0 deletions
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
new file mode 100644
index 000000000000..23b88082d0b2
--- /dev/null
+++ b/arch/sparc/kernel/pci_common.c
@@ -0,0 +1,545 @@
1/* pci_common.c: PCI controller common support.
2 *
3 * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
4 */
5
6#include <linux/string.h>
7#include <linux/slab.h>
8#include <linux/init.h>
9#include <linux/pci.h>
10#include <linux/device.h>
11#include <linux/of_device.h>
12
13#include <asm/prom.h>
14#include <asm/oplib.h>
15
16#include "pci_impl.h"
17#include "pci_sun4v.h"
18
19static int config_out_of_range(struct pci_pbm_info *pbm,
20 unsigned long bus,
21 unsigned long devfn,
22 unsigned long reg)
23{
24 if (bus < pbm->pci_first_busno ||
25 bus > pbm->pci_last_busno)
26 return 1;
27 return 0;
28}
29
30static void *sun4u_config_mkaddr(struct pci_pbm_info *pbm,
31 unsigned long bus,
32 unsigned long devfn,
33 unsigned long reg)
34{
35 unsigned long rbits = pbm->config_space_reg_bits;
36
37 if (config_out_of_range(pbm, bus, devfn, reg))
38 return NULL;
39
40 reg = (reg & ((1 << rbits) - 1));
41 devfn <<= rbits;
42 bus <<= rbits + 8;
43
44 return (void *) (pbm->config_space | bus | devfn | reg);
45}
46
47/* At least on Sabre, it is necessary to access all PCI host controller
48 * registers at their natural size, otherwise zeros are returned.
49 * Strange but true, and I see no language in the UltraSPARC-IIi
50 * programmer's manual that mentions this even indirectly.
51 */
52static int sun4u_read_pci_cfg_host(struct pci_pbm_info *pbm,
53 unsigned char bus, unsigned int devfn,
54 int where, int size, u32 *value)
55{
56 u32 tmp32, *addr;
57 u16 tmp16;
58 u8 tmp8;
59
60 addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
61 if (!addr)
62 return PCIBIOS_SUCCESSFUL;
63
64 switch (size) {
65 case 1:
66 if (where < 8) {
67 unsigned long align = (unsigned long) addr;
68
69 align &= ~1;
70 pci_config_read16((u16 *)align, &tmp16);
71 if (where & 1)
72 *value = tmp16 >> 8;
73 else
74 *value = tmp16 & 0xff;
75 } else {
76 pci_config_read8((u8 *)addr, &tmp8);
77 *value = (u32) tmp8;
78 }
79 break;
80
81 case 2:
82 if (where < 8) {
83 pci_config_read16((u16 *)addr, &tmp16);
84 *value = (u32) tmp16;
85 } else {
86 pci_config_read8((u8 *)addr, &tmp8);
87 *value = (u32) tmp8;
88 pci_config_read8(((u8 *)addr) + 1, &tmp8);
89 *value |= ((u32) tmp8) << 8;
90 }
91 break;
92
93 case 4:
94 tmp32 = 0xffffffff;
95 sun4u_read_pci_cfg_host(pbm, bus, devfn,
96 where, 2, &tmp32);
97 *value = tmp32;
98
99 tmp32 = 0xffffffff;
100 sun4u_read_pci_cfg_host(pbm, bus, devfn,
101 where + 2, 2, &tmp32);
102 *value |= tmp32 << 16;
103 break;
104 }
105 return PCIBIOS_SUCCESSFUL;
106}
107
108static int sun4u_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
109 int where, int size, u32 *value)
110{
111 struct pci_pbm_info *pbm = bus_dev->sysdata;
112 unsigned char bus = bus_dev->number;
113 u32 *addr;
114 u16 tmp16;
115 u8 tmp8;
116
117 switch (size) {
118 case 1:
119 *value = 0xff;
120 break;
121 case 2:
122 *value = 0xffff;
123 break;
124 case 4:
125 *value = 0xffffffff;
126 break;
127 }
128
129 if (!bus_dev->number && !PCI_SLOT(devfn))
130 return sun4u_read_pci_cfg_host(pbm, bus, devfn, where,
131 size, value);
132
133 addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
134 if (!addr)
135 return PCIBIOS_SUCCESSFUL;
136
137 switch (size) {
138 case 1:
139 pci_config_read8((u8 *)addr, &tmp8);
140 *value = (u32) tmp8;
141 break;
142
143 case 2:
144 if (where & 0x01) {
145 printk("pci_read_config_word: misaligned reg [%x]\n",
146 where);
147 return PCIBIOS_SUCCESSFUL;
148 }
149 pci_config_read16((u16 *)addr, &tmp16);
150 *value = (u32) tmp16;
151 break;
152
153 case 4:
154 if (where & 0x03) {
155 printk("pci_read_config_dword: misaligned reg [%x]\n",
156 where);
157 return PCIBIOS_SUCCESSFUL;
158 }
159 pci_config_read32(addr, value);
160 break;
161 }
162 return PCIBIOS_SUCCESSFUL;
163}
164
165static int sun4u_write_pci_cfg_host(struct pci_pbm_info *pbm,
166 unsigned char bus, unsigned int devfn,
167 int where, int size, u32 value)
168{
169 u32 *addr;
170
171 addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
172 if (!addr)
173 return PCIBIOS_SUCCESSFUL;
174
175 switch (size) {
176 case 1:
177 if (where < 8) {
178 unsigned long align = (unsigned long) addr;
179 u16 tmp16;
180
181 align &= ~1;
182 pci_config_read16((u16 *)align, &tmp16);
183 if (where & 1) {
184 tmp16 &= 0x00ff;
185 tmp16 |= value << 8;
186 } else {
187 tmp16 &= 0xff00;
188 tmp16 |= value;
189 }
190 pci_config_write16((u16 *)align, tmp16);
191 } else
192 pci_config_write8((u8 *)addr, value);
193 break;
194 case 2:
195 if (where < 8) {
196 pci_config_write16((u16 *)addr, value);
197 } else {
198 pci_config_write8((u8 *)addr, value & 0xff);
199 pci_config_write8(((u8 *)addr) + 1, value >> 8);
200 }
201 break;
202 case 4:
203 sun4u_write_pci_cfg_host(pbm, bus, devfn,
204 where, 2, value & 0xffff);
205 sun4u_write_pci_cfg_host(pbm, bus, devfn,
206 where + 2, 2, value >> 16);
207 break;
208 }
209 return PCIBIOS_SUCCESSFUL;
210}
211
212static int sun4u_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
213 int where, int size, u32 value)
214{
215 struct pci_pbm_info *pbm = bus_dev->sysdata;
216 unsigned char bus = bus_dev->number;
217 u32 *addr;
218
219 if (!bus_dev->number && !PCI_SLOT(devfn))
220 return sun4u_write_pci_cfg_host(pbm, bus, devfn, where,
221 size, value);
222
223 addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
224 if (!addr)
225 return PCIBIOS_SUCCESSFUL;
226
227 switch (size) {
228 case 1:
229 pci_config_write8((u8 *)addr, value);
230 break;
231
232 case 2:
233 if (where & 0x01) {
234 printk("pci_write_config_word: misaligned reg [%x]\n",
235 where);
236 return PCIBIOS_SUCCESSFUL;
237 }
238 pci_config_write16((u16 *)addr, value);
239 break;
240
241 case 4:
242 if (where & 0x03) {
243 printk("pci_write_config_dword: misaligned reg [%x]\n",
244 where);
245 return PCIBIOS_SUCCESSFUL;
246 }
247 pci_config_write32(addr, value);
248 }
249 return PCIBIOS_SUCCESSFUL;
250}
251
252struct pci_ops sun4u_pci_ops = {
253 .read = sun4u_read_pci_cfg,
254 .write = sun4u_write_pci_cfg,
255};
256
257static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
258 int where, int size, u32 *value)
259{
260 struct pci_pbm_info *pbm = bus_dev->sysdata;
261 u32 devhandle = pbm->devhandle;
262 unsigned int bus = bus_dev->number;
263 unsigned int device = PCI_SLOT(devfn);
264 unsigned int func = PCI_FUNC(devfn);
265 unsigned long ret;
266
267 if (config_out_of_range(pbm, bus, devfn, where)) {
268 ret = ~0UL;
269 } else {
270 ret = pci_sun4v_config_get(devhandle,
271 HV_PCI_DEVICE_BUILD(bus, device, func),
272 where, size);
273 }
274 switch (size) {
275 case 1:
276 *value = ret & 0xff;
277 break;
278 case 2:
279 *value = ret & 0xffff;
280 break;
281 case 4:
282 *value = ret & 0xffffffff;
283 break;
284 };
285
286
287 return PCIBIOS_SUCCESSFUL;
288}
289
290static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
291 int where, int size, u32 value)
292{
293 struct pci_pbm_info *pbm = bus_dev->sysdata;
294 u32 devhandle = pbm->devhandle;
295 unsigned int bus = bus_dev->number;
296 unsigned int device = PCI_SLOT(devfn);
297 unsigned int func = PCI_FUNC(devfn);
298 unsigned long ret;
299
300 if (config_out_of_range(pbm, bus, devfn, where)) {
301 /* Do nothing. */
302 } else {
303 ret = pci_sun4v_config_put(devhandle,
304 HV_PCI_DEVICE_BUILD(bus, device, func),
305 where, size, value);
306 }
307 return PCIBIOS_SUCCESSFUL;
308}
309
310struct pci_ops sun4v_pci_ops = {
311 .read = sun4v_read_pci_cfg,
312 .write = sun4v_write_pci_cfg,
313};
314
315void pci_get_pbm_props(struct pci_pbm_info *pbm)
316{
317 const u32 *val = of_get_property(pbm->op->node, "bus-range", NULL);
318
319 pbm->pci_first_busno = val[0];
320 pbm->pci_last_busno = val[1];
321
322 val = of_get_property(pbm->op->node, "ino-bitmap", NULL);
323 if (val) {
324 pbm->ino_bitmap = (((u64)val[1] << 32UL) |
325 ((u64)val[0] << 0UL));
326 }
327}
328
329static void pci_register_legacy_regions(struct resource *io_res,
330 struct resource *mem_res)
331{
332 struct resource *p;
333
334 /* VGA Video RAM. */
335 p = kzalloc(sizeof(*p), GFP_KERNEL);
336 if (!p)
337 return;
338
339 p->name = "Video RAM area";
340 p->start = mem_res->start + 0xa0000UL;
341 p->end = p->start + 0x1ffffUL;
342 p->flags = IORESOURCE_BUSY;
343 request_resource(mem_res, p);
344
345 p = kzalloc(sizeof(*p), GFP_KERNEL);
346 if (!p)
347 return;
348
349 p->name = "System ROM";
350 p->start = mem_res->start + 0xf0000UL;
351 p->end = p->start + 0xffffUL;
352 p->flags = IORESOURCE_BUSY;
353 request_resource(mem_res, p);
354
355 p = kzalloc(sizeof(*p), GFP_KERNEL);
356 if (!p)
357 return;
358
359 p->name = "Video ROM";
360 p->start = mem_res->start + 0xc0000UL;
361 p->end = p->start + 0x7fffUL;
362 p->flags = IORESOURCE_BUSY;
363 request_resource(mem_res, p);
364}
365
366static void pci_register_iommu_region(struct pci_pbm_info *pbm)
367{
368 const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL);
369
370 if (vdma) {
371 struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL);
372
373 if (!rp) {
374 prom_printf("Cannot allocate IOMMU resource.\n");
375 prom_halt();
376 }
377 rp->name = "IOMMU";
378 rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
379 rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
380 rp->flags = IORESOURCE_BUSY;
381 request_resource(&pbm->mem_space, rp);
382 }
383}
384
385void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
386{
387 const struct linux_prom_pci_ranges *pbm_ranges;
388 int i, saw_mem, saw_io;
389 int num_pbm_ranges;
390
391 saw_mem = saw_io = 0;
392 pbm_ranges = of_get_property(pbm->op->node, "ranges", &i);
393 if (!pbm_ranges) {
394 prom_printf("PCI: Fatal error, missing PBM ranges property "
395 " for %s\n",
396 pbm->name);
397 prom_halt();
398 }
399
400 num_pbm_ranges = i / sizeof(*pbm_ranges);
401
402 for (i = 0; i < num_pbm_ranges; i++) {
403 const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
404 unsigned long a, size;
405 u32 parent_phys_hi, parent_phys_lo;
406 u32 size_hi, size_lo;
407 int type;
408
409 parent_phys_hi = pr->parent_phys_hi;
410 parent_phys_lo = pr->parent_phys_lo;
411 if (tlb_type == hypervisor)
412 parent_phys_hi &= 0x0fffffff;
413
414 size_hi = pr->size_hi;
415 size_lo = pr->size_lo;
416
417 type = (pr->child_phys_hi >> 24) & 0x3;
418 a = (((unsigned long)parent_phys_hi << 32UL) |
419 ((unsigned long)parent_phys_lo << 0UL));
420 size = (((unsigned long)size_hi << 32UL) |
421 ((unsigned long)size_lo << 0UL));
422
423 switch (type) {
424 case 0:
425 /* PCI config space, 16MB */
426 pbm->config_space = a;
427 break;
428
429 case 1:
430 /* 16-bit IO space, 16MB */
431 pbm->io_space.start = a;
432 pbm->io_space.end = a + size - 1UL;
433 pbm->io_space.flags = IORESOURCE_IO;
434 saw_io = 1;
435 break;
436
437 case 2:
438 /* 32-bit MEM space, 2GB */
439 pbm->mem_space.start = a;
440 pbm->mem_space.end = a + size - 1UL;
441 pbm->mem_space.flags = IORESOURCE_MEM;
442 saw_mem = 1;
443 break;
444
445 case 3:
446 /* XXX 64-bit MEM handling XXX */
447
448 default:
449 break;
450 };
451 }
452
453 if (!saw_io || !saw_mem) {
454 prom_printf("%s: Fatal error, missing %s PBM range.\n",
455 pbm->name,
456 (!saw_io ? "IO" : "MEM"));
457 prom_halt();
458 }
459
460 printk("%s: PCI IO[%lx] MEM[%lx]\n",
461 pbm->name,
462 pbm->io_space.start,
463 pbm->mem_space.start);
464
465 pbm->io_space.name = pbm->mem_space.name = pbm->name;
466
467 request_resource(&ioport_resource, &pbm->io_space);
468 request_resource(&iomem_resource, &pbm->mem_space);
469
470 pci_register_legacy_regions(&pbm->io_space,
471 &pbm->mem_space);
472 pci_register_iommu_region(pbm);
473}
474
475/* Generic helper routines for PCI error reporting. */
476void pci_scan_for_target_abort(struct pci_pbm_info *pbm,
477 struct pci_bus *pbus)
478{
479 struct pci_dev *pdev;
480 struct pci_bus *bus;
481
482 list_for_each_entry(pdev, &pbus->devices, bus_list) {
483 u16 status, error_bits;
484
485 pci_read_config_word(pdev, PCI_STATUS, &status);
486 error_bits =
487 (status & (PCI_STATUS_SIG_TARGET_ABORT |
488 PCI_STATUS_REC_TARGET_ABORT));
489 if (error_bits) {
490 pci_write_config_word(pdev, PCI_STATUS, error_bits);
491 printk("%s: Device %s saw Target Abort [%016x]\n",
492 pbm->name, pci_name(pdev), status);
493 }
494 }
495
496 list_for_each_entry(bus, &pbus->children, node)
497 pci_scan_for_target_abort(pbm, bus);
498}
499
500void pci_scan_for_master_abort(struct pci_pbm_info *pbm,
501 struct pci_bus *pbus)
502{
503 struct pci_dev *pdev;
504 struct pci_bus *bus;
505
506 list_for_each_entry(pdev, &pbus->devices, bus_list) {
507 u16 status, error_bits;
508
509 pci_read_config_word(pdev, PCI_STATUS, &status);
510 error_bits =
511 (status & (PCI_STATUS_REC_MASTER_ABORT));
512 if (error_bits) {
513 pci_write_config_word(pdev, PCI_STATUS, error_bits);
514 printk("%s: Device %s received Master Abort [%016x]\n",
515 pbm->name, pci_name(pdev), status);
516 }
517 }
518
519 list_for_each_entry(bus, &pbus->children, node)
520 pci_scan_for_master_abort(pbm, bus);
521}
522
523void pci_scan_for_parity_error(struct pci_pbm_info *pbm,
524 struct pci_bus *pbus)
525{
526 struct pci_dev *pdev;
527 struct pci_bus *bus;
528
529 list_for_each_entry(pdev, &pbus->devices, bus_list) {
530 u16 status, error_bits;
531
532 pci_read_config_word(pdev, PCI_STATUS, &status);
533 error_bits =
534 (status & (PCI_STATUS_PARITY |
535 PCI_STATUS_DETECTED_PARITY));
536 if (error_bits) {
537 pci_write_config_word(pdev, PCI_STATUS, error_bits);
538 printk("%s: Device %s saw Parity Error [%016x]\n",
539 pbm->name, pci_name(pdev), status);
540 }
541 }
542
543 list_for_each_entry(bus, &pbus->children, node)
544 pci_scan_for_parity_error(pbm, bus);
545}