Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * This program is free software; you can redistribute it and/or modify it | |
3 | * under the terms of the GNU General Public License as published by the | |
4 | * Free Software Foundation; either version 2 of the License, or (at your | |
5 | * option) any later version. | |
6 | * | |
c539ef7d RB |
7 | * Copyright (C) 2003, 04, 11 Ralf Baechle (ralf@linux-mips.org) |
8 | * Copyright (C) 2011 Wind River Systems, | |
9 | * written by Ralf Baechle (ralf@linux-mips.org) | |
1da177e4 | 10 | */ |
c539ef7d | 11 | #include <linux/bug.h> |
1da177e4 LT |
12 | #include <linux/kernel.h> |
13 | #include <linux/mm.h> | |
14 | #include <linux/bootmem.h> | |
cae39d13 | 15 | #include <linux/export.h> |
1da177e4 LT |
16 | #include <linux/init.h> |
17 | #include <linux/types.h> | |
18 | #include <linux/pci.h> | |
19 | ||
c539ef7d RB |
20 | #include <asm/cpu-info.h> |
21 | ||
1da177e4 | 22 | /* |
29090606 BH |
23 | * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource |
24 | * assignments. | |
1da177e4 | 25 | */ |
1da177e4 LT |
26 | |
27 | #define PCI_ASSIGN_ALL_BUSSES 1 | |
28 | ||
29 | unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES; | |
30 | ||
31 | /* | |
32 | * The PCI controller list. | |
33 | */ | |
34 | ||
d58eaab5 | 35 | static struct pci_controller *hose_head, **hose_tail = &hose_head; |
1da177e4 | 36 | |
982f6ffe RB |
37 | unsigned long PCIBIOS_MIN_IO; |
38 | unsigned long PCIBIOS_MIN_MEM; | |
1da177e4 | 39 | |
540799e3 AJ |
40 | static int pci_initialized; |
41 | ||
1da177e4 LT |
42 | /* |
43 | * We need to avoid collisions with `mirrored' VGA ports | |
44 | * and other strange ISA hardware, so we always want the | |
45 | * addresses to be allocated in the 0x000-0x0ff region | |
46 | * modulo 0x400. | |
47 | * | |
48 | * Why? Because some silly external IO cards only decode | |
49 | * the low 10 bits of the IO address. The 0x00-0xff region | |
50 | * is reserved for motherboard devices that decode all 16 | |
51 | * bits, so it's ok to allocate at, say, 0x2800-0x28ff, | |
52 | * but we want to try to avoid allocating at 0x2900-0x2bff | |
53 | * which might have be mirrored at 0x0100-0x03ff.. | |
54 | */ | |
b26b2d49 | 55 | resource_size_t |
3b7a17fc | 56 | pcibios_align_resource(void *data, const struct resource *res, |
e31dd6e4 | 57 | resource_size_t size, resource_size_t align) |
1da177e4 LT |
58 | { |
59 | struct pci_dev *dev = data; | |
60 | struct pci_controller *hose = dev->sysdata; | |
e31dd6e4 | 61 | resource_size_t start = res->start; |
1da177e4 LT |
62 | |
63 | if (res->flags & IORESOURCE_IO) { | |
64 | /* Make sure we start at our min on all hoses */ | |
65 | if (start < PCIBIOS_MIN_IO + hose->io_resource->start) | |
66 | start = PCIBIOS_MIN_IO + hose->io_resource->start; | |
67 | ||
68 | /* | |
69 | * Put everything into 0x00-0xff region modulo 0x400 | |
70 | */ | |
71 | if (start & 0x300) | |
72 | start = (start + 0x3ff) & ~0x3ff; | |
73 | } else if (res->flags & IORESOURCE_MEM) { | |
74 | /* Make sure we start at our min on all hoses */ | |
75 | if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start) | |
76 | start = PCIBIOS_MIN_MEM + hose->mem_resource->start; | |
77 | } | |
78 | ||
b26b2d49 | 79 | return start; |
1da177e4 LT |
80 | } |
81 | ||
540799e3 AJ |
82 | static void __devinit pcibios_scanbus(struct pci_controller *hose) |
83 | { | |
84 | static int next_busno; | |
85 | static int need_domain_info; | |
7c090e5b | 86 | LIST_HEAD(resources); |
540799e3 AJ |
87 | struct pci_bus *bus; |
88 | ||
89 | if (!hose->iommu) | |
90 | PCI_DMA_BUS_IS_PHYS = 1; | |
91 | ||
29090606 | 92 | if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) |
540799e3 AJ |
93 | next_busno = (*hose->get_busno)(); |
94 | ||
7c090e5b BH |
95 | pci_add_resource(&resources, hose->mem_resource); |
96 | pci_add_resource(&resources, hose->io_resource); | |
97 | bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, | |
98 | &resources); | |
99 | if (!bus) | |
100 | pci_free_resource_list(&resources); | |
101 | ||
540799e3 AJ |
102 | hose->bus = bus; |
103 | ||
104 | need_domain_info = need_domain_info || hose->index; | |
105 | hose->need_domain_info = need_domain_info; | |
106 | if (bus) { | |
107 | next_busno = bus->subordinate + 1; | |
108 | /* Don't allow 8-bit bus number overflow inside the hose - | |
109 | reserve some space for bridges. */ | |
110 | if (next_busno > 224) { | |
111 | next_busno = 0; | |
112 | need_domain_info = 1; | |
113 | } | |
114 | ||
29090606 | 115 | if (!pci_has_flag(PCI_PROBE_ONLY)) { |
540799e3 AJ |
116 | pci_bus_size_bridges(bus); |
117 | pci_bus_assign_resources(bus); | |
118 | pci_enable_bridges(bus); | |
119 | } | |
120 | } | |
121 | } | |
122 | ||
123 | static DEFINE_MUTEX(pci_scan_mutex); | |
124 | ||
606bf782 | 125 | void __devinit register_pci_controller(struct pci_controller *hose) |
1da177e4 | 126 | { |
639702bd TB |
127 | if (request_resource(&iomem_resource, hose->mem_resource) < 0) |
128 | goto out; | |
129 | if (request_resource(&ioport_resource, hose->io_resource) < 0) { | |
130 | release_resource(hose->mem_resource); | |
131 | goto out; | |
132 | } | |
133 | ||
1da177e4 LT |
134 | *hose_tail = hose; |
135 | hose_tail = &hose->next; | |
140c1729 RB |
136 | |
137 | /* | |
25985edc | 138 | * Do not panic here but later - this might happen before console init. |
140c1729 RB |
139 | */ |
140 | if (!hose->io_map_base) { | |
141 | printk(KERN_WARNING | |
142 | "registering PCI controller with io_map_base unset\n"); | |
143 | } | |
540799e3 AJ |
144 | |
145 | /* | |
146 | * Scan the bus if it is register after the PCI subsystem | |
147 | * initialization. | |
148 | */ | |
149 | if (pci_initialized) { | |
150 | mutex_lock(&pci_scan_mutex); | |
151 | pcibios_scanbus(hose); | |
152 | mutex_unlock(&pci_scan_mutex); | |
153 | } | |
154 | ||
639702bd TB |
155 | return; |
156 | ||
157 | out: | |
158 | printk(KERN_WARNING | |
159 | "Skipping PCI bus scan due to resource conflict\n"); | |
1da177e4 LT |
160 | } |
161 | ||
c539ef7d RB |
162 | static void __init pcibios_set_cache_line_size(void) |
163 | { | |
164 | struct cpuinfo_mips *c = ¤t_cpu_data; | |
165 | unsigned int lsize; | |
166 | ||
167 | /* | |
168 | * Set PCI cacheline size to that of the highest level in the | |
169 | * cache hierarchy. | |
170 | */ | |
171 | lsize = c->dcache.linesz; | |
172 | lsize = c->scache.linesz ? : lsize; | |
173 | lsize = c->tcache.linesz ? : lsize; | |
174 | ||
175 | BUG_ON(!lsize); | |
176 | ||
177 | pci_dfl_cache_line_size = lsize >> 2; | |
178 | ||
179 | pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize); | |
180 | } | |
181 | ||
1da177e4 LT |
182 | static int __init pcibios_init(void) |
183 | { | |
184 | struct pci_controller *hose; | |
1da177e4 | 185 | |
c539ef7d RB |
186 | pcibios_set_cache_line_size(); |
187 | ||
1da177e4 | 188 | /* Scan all of the recorded PCI controllers. */ |
540799e3 AJ |
189 | for (hose = hose_head; hose; hose = hose->next) |
190 | pcibios_scanbus(hose); | |
1da177e4 | 191 | |
67eed580 | 192 | pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); |
1da177e4 | 193 | |
540799e3 AJ |
194 | pci_initialized = 1; |
195 | ||
1da177e4 LT |
196 | return 0; |
197 | } | |
198 | ||
199 | subsys_initcall(pcibios_init); | |
200 | ||
201 | static int pcibios_enable_resources(struct pci_dev *dev, int mask) | |
202 | { | |
203 | u16 cmd, old_cmd; | |
204 | int idx; | |
205 | struct resource *r; | |
206 | ||
207 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | |
208 | old_cmd = cmd; | |
e5de3b46 | 209 | for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { |
1da177e4 LT |
210 | /* Only set up the requested stuff */ |
211 | if (!(mask & (1<<idx))) | |
212 | continue; | |
213 | ||
214 | r = &dev->resource[idx]; | |
986c9485 RB |
215 | if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) |
216 | continue; | |
217 | if ((idx == PCI_ROM_RESOURCE) && | |
218 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | |
219 | continue; | |
1da177e4 | 220 | if (!r->start && r->end) { |
40d7c1aa RB |
221 | printk(KERN_ERR "PCI: Device %s not available " |
222 | "because of resource collisions\n", | |
223 | pci_name(dev)); | |
1da177e4 LT |
224 | return -EINVAL; |
225 | } | |
226 | if (r->flags & IORESOURCE_IO) | |
227 | cmd |= PCI_COMMAND_IO; | |
228 | if (r->flags & IORESOURCE_MEM) | |
229 | cmd |= PCI_COMMAND_MEMORY; | |
230 | } | |
1da177e4 | 231 | if (cmd != old_cmd) { |
40d7c1aa RB |
232 | printk("PCI: Enabling device %s (%04x -> %04x)\n", |
233 | pci_name(dev), old_cmd, cmd); | |
1da177e4 LT |
234 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
235 | } | |
236 | return 0; | |
237 | } | |
238 | ||
1da177e4 LT |
239 | unsigned int pcibios_assign_all_busses(void) |
240 | { | |
241 | return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; | |
242 | } | |
243 | ||
244 | int pcibios_enable_device(struct pci_dev *dev, int mask) | |
245 | { | |
246 | int err; | |
247 | ||
248 | if ((err = pcibios_enable_resources(dev, mask)) < 0) | |
249 | return err; | |
250 | ||
251 | return pcibios_plat_dev_init(dev); | |
252 | } | |
253 | ||
c4aa2563 | 254 | static void pcibios_fixup_device_resources(struct pci_dev *dev, |
1da177e4 LT |
255 | struct pci_bus *bus) |
256 | { | |
257 | /* Update device resources. */ | |
258 | struct pci_controller *hose = (struct pci_controller *)bus->sysdata; | |
259 | unsigned long offset = 0; | |
260 | int i; | |
261 | ||
262 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | |
263 | if (!dev->resource[i].start) | |
264 | continue; | |
265 | if (dev->resource[i].flags & IORESOURCE_IO) | |
266 | offset = hose->io_offset; | |
267 | else if (dev->resource[i].flags & IORESOURCE_MEM) | |
268 | offset = hose->mem_offset; | |
269 | ||
270 | dev->resource[i].start += offset; | |
271 | dev->resource[i].end += offset; | |
272 | } | |
273 | } | |
274 | ||
234fcd14 | 275 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
1da177e4 LT |
276 | { |
277 | /* Propagate hose info into the subordinate devices. */ | |
278 | ||
1da177e4 LT |
279 | struct list_head *ln; |
280 | struct pci_dev *dev = bus->self; | |
281 | ||
29090606 | 282 | if (pci_has_flag(PCI_PROBE_ONLY) && dev && |
7c090e5b | 283 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { |
1da177e4 LT |
284 | pci_read_bridge_bases(bus); |
285 | pcibios_fixup_device_resources(dev, bus); | |
42a3b4f2 | 286 | } |
1da177e4 LT |
287 | |
288 | for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { | |
8ed07a1c | 289 | dev = pci_dev_b(ln); |
1da177e4 LT |
290 | |
291 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | |
292 | pcibios_fixup_device_resources(dev, bus); | |
293 | } | |
294 | } | |
295 | ||
296 | void __init | |
297 | pcibios_update_irq(struct pci_dev *dev, int irq) | |
298 | { | |
299 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | |
300 | } | |
301 | ||
c4aa2563 | 302 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
1da177e4 LT |
303 | struct resource *res) |
304 | { | |
305 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | |
306 | unsigned long offset = 0; | |
307 | ||
308 | if (res->flags & IORESOURCE_IO) | |
309 | offset = hose->io_offset; | |
310 | else if (res->flags & IORESOURCE_MEM) | |
311 | offset = hose->mem_offset; | |
312 | ||
313 | region->start = res->start - offset; | |
314 | region->end = res->end - offset; | |
315 | } | |
316 | ||
e63ea56f YY |
317 | void __devinit |
318 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | |
319 | struct pci_bus_region *region) | |
320 | { | |
321 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | |
322 | unsigned long offset = 0; | |
323 | ||
324 | if (res->flags & IORESOURCE_IO) | |
325 | offset = hose->io_offset; | |
326 | else if (res->flags & IORESOURCE_MEM) | |
327 | offset = hose->mem_offset; | |
328 | ||
329 | res->start = region->start + offset; | |
330 | res->end = region->end + offset; | |
331 | } | |
332 | ||
1da177e4 LT |
333 | #ifdef CONFIG_HOTPLUG |
334 | EXPORT_SYMBOL(pcibios_resource_to_bus); | |
e63ea56f | 335 | EXPORT_SYMBOL(pcibios_bus_to_resource); |
1da177e4 LT |
336 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); |
337 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); | |
338 | #endif | |
339 | ||
98873f53 RB |
340 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
341 | enum pci_mmap_state mmap_state, int write_combine) | |
342 | { | |
343 | unsigned long prot; | |
344 | ||
345 | /* | |
346 | * I/O space can be accessed via normal processor loads and stores on | |
347 | * this platform but for now we elect not to do this and portable | |
348 | * drivers should not do this anyway. | |
349 | */ | |
350 | if (mmap_state == pci_mmap_io) | |
351 | return -EINVAL; | |
352 | ||
353 | /* | |
354 | * Ignore write-combine; for now only return uncached mappings. | |
355 | */ | |
356 | prot = pgprot_val(vma->vm_page_prot); | |
357 | prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED; | |
358 | vma->vm_page_prot = __pgprot(prot); | |
359 | ||
360 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | |
361 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | |
362 | } | |
363 | ||
47a5c976 AN |
364 | char * (*pcibios_plat_setup)(char *str) __devinitdata; |
365 | ||
366 | char *__devinit pcibios_setup(char *str) | |
1da177e4 | 367 | { |
47a5c976 AN |
368 | if (pcibios_plat_setup) |
369 | return pcibios_plat_setup(str); | |
1da177e4 LT |
370 | return str; |
371 | } |