1 /* pci_common.c: PCI controller common support.
3 * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
6 #include <linux/string.h>
7 #include <linux/slab.h>
8 #include <linux/init.h>
10 #include <linux/device.h>
14 #include <asm/of_device.h>
18 static void pci_register_legacy_regions(struct resource
*io_res
,
19 struct resource
*mem_res
)
24 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
28 p
->name
= "Video RAM area";
29 p
->start
= mem_res
->start
+ 0xa0000UL
;
30 p
->end
= p
->start
+ 0x1ffffUL
;
31 p
->flags
= IORESOURCE_BUSY
;
32 request_resource(mem_res
, p
);
34 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
38 p
->name
= "System ROM";
39 p
->start
= mem_res
->start
+ 0xf0000UL
;
40 p
->end
= p
->start
+ 0xffffUL
;
41 p
->flags
= IORESOURCE_BUSY
;
42 request_resource(mem_res
, p
);
44 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
48 p
->name
= "Video ROM";
49 p
->start
= mem_res
->start
+ 0xc0000UL
;
50 p
->end
= p
->start
+ 0x7fffUL
;
51 p
->flags
= IORESOURCE_BUSY
;
52 request_resource(mem_res
, p
);
55 static void pci_register_iommu_region(struct pci_pbm_info
*pbm
)
57 u32
*vdma
= of_get_property(pbm
->prom_node
, "virtual-dma", NULL
);
60 struct resource
*rp
= kmalloc(sizeof(*rp
), GFP_KERNEL
);
63 prom_printf("Cannot allocate IOMMU resource.\n");
67 rp
->start
= pbm
->mem_space
.start
+ (unsigned long) vdma
[0];
68 rp
->end
= rp
->start
+ (unsigned long) vdma
[1] - 1UL;
69 rp
->flags
= IORESOURCE_BUSY
;
70 request_resource(&pbm
->mem_space
, rp
);
74 void pci_determine_mem_io_space(struct pci_pbm_info
*pbm
)
76 struct linux_prom_pci_ranges
*pbm_ranges
;
77 int i
, saw_mem
, saw_io
;
81 pbm_ranges
= of_get_property(pbm
->prom_node
, "ranges", &i
);
82 num_pbm_ranges
= i
/ sizeof(*pbm_ranges
);
84 for (i
= 0; i
< num_pbm_ranges
; i
++) {
85 struct linux_prom_pci_ranges
*pr
= &pbm_ranges
[i
];
87 u32 parent_phys_hi
, parent_phys_lo
;
90 parent_phys_hi
= pr
->parent_phys_hi
;
91 parent_phys_lo
= pr
->parent_phys_lo
;
92 if (tlb_type
== hypervisor
)
93 parent_phys_hi
&= 0x0fffffff;
95 type
= (pr
->child_phys_hi
>> 24) & 0x3;
96 a
= (((unsigned long)parent_phys_hi
<< 32UL) |
97 ((unsigned long)parent_phys_lo
<< 0UL));
101 /* PCI config space, 16MB */
102 pbm
->config_space
= a
;
106 /* 16-bit IO space, 16MB */
107 pbm
->io_space
.start
= a
;
108 pbm
->io_space
.end
= a
+ ((16UL*1024UL*1024UL) - 1UL);
109 pbm
->io_space
.flags
= IORESOURCE_IO
;
114 /* 32-bit MEM space, 2GB */
115 pbm
->mem_space
.start
= a
;
116 pbm
->mem_space
.end
= a
+ (0x80000000UL
- 1UL);
117 pbm
->mem_space
.flags
= IORESOURCE_MEM
;
122 /* XXX 64-bit MEM handling XXX */
129 if (!saw_io
|| !saw_mem
) {
130 prom_printf("%s: Fatal error, missing %s PBM range.\n",
132 (!saw_io
? "IO" : "MEM"));
136 printk("%s: PCI IO[%lx] MEM[%lx]\n",
139 pbm
->mem_space
.start
);
141 pbm
->io_space
.name
= pbm
->mem_space
.name
= pbm
->name
;
143 request_resource(&ioport_resource
, &pbm
->io_space
);
144 request_resource(&iomem_resource
, &pbm
->mem_space
);
146 pci_register_legacy_regions(&pbm
->io_space
,
148 pci_register_iommu_region(pbm
);
151 /* Generic helper routines for PCI error reporting. */
152 void pci_scan_for_target_abort(struct pci_controller_info
*p
,
153 struct pci_pbm_info
*pbm
,
154 struct pci_bus
*pbus
)
156 struct pci_dev
*pdev
;
159 list_for_each_entry(pdev
, &pbus
->devices
, bus_list
) {
160 u16 status
, error_bits
;
162 pci_read_config_word(pdev
, PCI_STATUS
, &status
);
164 (status
& (PCI_STATUS_SIG_TARGET_ABORT
|
165 PCI_STATUS_REC_TARGET_ABORT
));
167 pci_write_config_word(pdev
, PCI_STATUS
, error_bits
);
168 printk("PCI%d(PBM%c): Device [%s] saw Target Abort [%016x]\n",
169 p
->index
, ((pbm
== &p
->pbm_A
) ? 'A' : 'B'),
170 pci_name(pdev
), status
);
174 list_for_each_entry(bus
, &pbus
->children
, node
)
175 pci_scan_for_target_abort(p
, pbm
, bus
);
178 void pci_scan_for_master_abort(struct pci_controller_info
*p
,
179 struct pci_pbm_info
*pbm
,
180 struct pci_bus
*pbus
)
182 struct pci_dev
*pdev
;
185 list_for_each_entry(pdev
, &pbus
->devices
, bus_list
) {
186 u16 status
, error_bits
;
188 pci_read_config_word(pdev
, PCI_STATUS
, &status
);
190 (status
& (PCI_STATUS_REC_MASTER_ABORT
));
192 pci_write_config_word(pdev
, PCI_STATUS
, error_bits
);
193 printk("PCI%d(PBM%c): Device [%s] received Master Abort [%016x]\n",
194 p
->index
, ((pbm
== &p
->pbm_A
) ? 'A' : 'B'),
195 pci_name(pdev
), status
);
199 list_for_each_entry(bus
, &pbus
->children
, node
)
200 pci_scan_for_master_abort(p
, pbm
, bus
);
203 void pci_scan_for_parity_error(struct pci_controller_info
*p
,
204 struct pci_pbm_info
*pbm
,
205 struct pci_bus
*pbus
)
207 struct pci_dev
*pdev
;
210 list_for_each_entry(pdev
, &pbus
->devices
, bus_list
) {
211 u16 status
, error_bits
;
213 pci_read_config_word(pdev
, PCI_STATUS
, &status
);
215 (status
& (PCI_STATUS_PARITY
|
216 PCI_STATUS_DETECTED_PARITY
));
218 pci_write_config_word(pdev
, PCI_STATUS
, error_bits
);
219 printk("PCI%d(PBM%c): Device [%s] saw Parity Error [%016x]\n",
220 p
->index
, ((pbm
== &p
->pbm_A
) ? 'A' : 'B'),
221 pci_name(pdev
), status
);
225 list_for_each_entry(bus
, &pbus
->children
, node
)
226 pci_scan_for_parity_error(p
, pbm
, bus
);