Commit | Line | Data |
---|---|---|
5516b540 KG |
1 | /* |
2 | * Contains common pci routines for ALL ppc platform | |
cf1d8a8a KG |
3 | * (based on pci_32.c and pci_64.c) |
4 | * | |
5 | * Port for PPC64 David Engebretsen, IBM Corp. | |
6 | * Contains common pci routines for ppc64 platform, pSeries and iSeries brands. | |
7 | * | |
8 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM | |
9 | * Rework, based on alpha PCI code. | |
10 | * | |
11 | * Common pmac/prep/chrp pci routines. -- Cort | |
5516b540 KG |
12 | * |
13 | * This program is free software; you can redistribute it and/or | |
14 | * modify it under the terms of the GNU General Public License | |
15 | * as published by the Free Software Foundation; either version | |
16 | * 2 of the License, or (at your option) any later version. | |
17 | */ | |
18 | ||
19 | #undef DEBUG | |
20 | ||
21 | #include <linux/kernel.h> | |
22 | #include <linux/pci.h> | |
23 | #include <linux/string.h> | |
24 | #include <linux/init.h> | |
25 | #include <linux/bootmem.h> | |
26 | #include <linux/mm.h> | |
27 | #include <linux/list.h> | |
28 | #include <linux/syscalls.h> | |
29 | #include <linux/irq.h> | |
30 | #include <linux/vmalloc.h> | |
31 | ||
32 | #include <asm/processor.h> | |
33 | #include <asm/io.h> | |
34 | #include <asm/prom.h> | |
35 | #include <asm/pci-bridge.h> | |
36 | #include <asm/byteorder.h> | |
37 | #include <asm/machdep.h> | |
38 | #include <asm/ppc-pci.h> | |
39 | #include <asm/firmware.h> | |
40 | ||
41 | #ifdef DEBUG | |
42 | #include <asm/udbg.h> | |
43 | #define DBG(fmt...) printk(fmt) | |
44 | #else | |
45 | #define DBG(fmt...) | |
46 | #endif | |
47 | ||
a4c9e328 KG |
48 | static DEFINE_SPINLOCK(hose_spinlock); |
49 | ||
50 | /* XXX kill that some day ... */ | |
51 | int global_phb_number; /* Global phb counter */ | |
52 | ||
53 | extern struct list_head hose_list; | |
54 | ||
55 | /* | |
56 | * pci_controller(phb) initialized common variables. | |
57 | */ | |
58 | static void __devinit pci_setup_pci_controller(struct pci_controller *hose) | |
59 | { | |
60 | memset(hose, 0, sizeof(struct pci_controller)); | |
61 | ||
62 | spin_lock(&hose_spinlock); | |
63 | hose->global_number = global_phb_number++; | |
64 | list_add_tail(&hose->list_node, &hose_list); | |
65 | spin_unlock(&hose_spinlock); | |
66 | } | |
67 | ||
68 | struct pci_controller * pcibios_alloc_controller(struct device_node *dev) | |
69 | { | |
70 | struct pci_controller *phb; | |
71 | ||
72 | if (mem_init_done) | |
73 | phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL); | |
74 | else | |
75 | phb = alloc_bootmem(sizeof (struct pci_controller)); | |
76 | if (phb == NULL) | |
77 | return NULL; | |
78 | pci_setup_pci_controller(phb); | |
79 | phb->arch_data = dev; | |
80 | phb->is_dynamic = mem_init_done; | |
81 | #ifdef CONFIG_PPC64 | |
82 | if (dev) { | |
83 | int nid = of_node_to_nid(dev); | |
84 | ||
85 | if (nid < 0 || !node_online(nid)) | |
86 | nid = -1; | |
87 | ||
88 | PHB_SET_NODE(phb, nid); | |
89 | } | |
90 | #endif | |
91 | return phb; | |
92 | } | |
93 | ||
94 | void pcibios_free_controller(struct pci_controller *phb) | |
95 | { | |
96 | spin_lock(&hose_spinlock); | |
97 | list_del(&phb->list_node); | |
98 | spin_unlock(&hose_spinlock); | |
99 | ||
100 | if (phb->is_dynamic) | |
101 | kfree(phb); | |
102 | } | |
103 | ||
5516b540 KG |
104 | /* |
105 | * Return the domain number for this bus. | |
106 | */ | |
107 | int pci_domain_nr(struct pci_bus *bus) | |
108 | { | |
109 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | |
110 | return 0; | |
111 | else { | |
112 | struct pci_controller *hose = pci_bus_to_host(bus); | |
113 | ||
114 | return hose->global_number; | |
115 | } | |
116 | } | |
117 | ||
118 | EXPORT_SYMBOL(pci_domain_nr); | |
58083dad KG |
119 | |
120 | #ifdef CONFIG_PPC_OF | |
a4c9e328 KG |
121 | |
122 | /* This routine is meant to be used early during boot, when the | |
123 | * PCI bus numbers have not yet been assigned, and you need to | |
124 | * issue PCI config cycles to an OF device. | |
125 | * It could also be used to "fix" RTAS config cycles if you want | |
126 | * to set pci_assign_all_buses to 1 and still use RTAS for PCI | |
127 | * config cycles. | |
128 | */ | |
129 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) | |
130 | { | |
131 | if (!have_of) | |
132 | return NULL; | |
133 | while(node) { | |
134 | struct pci_controller *hose, *tmp; | |
135 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | |
136 | if (hose->arch_data == node) | |
137 | return hose; | |
138 | node = node->parent; | |
139 | } | |
140 | return NULL; | |
141 | } | |
142 | ||
58083dad KG |
143 | static ssize_t pci_show_devspec(struct device *dev, |
144 | struct device_attribute *attr, char *buf) | |
145 | { | |
146 | struct pci_dev *pdev; | |
147 | struct device_node *np; | |
148 | ||
149 | pdev = to_pci_dev (dev); | |
150 | np = pci_device_to_OF_node(pdev); | |
151 | if (np == NULL || np->full_name == NULL) | |
152 | return 0; | |
153 | return sprintf(buf, "%s", np->full_name); | |
154 | } | |
155 | static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); | |
156 | #endif /* CONFIG_PPC_OF */ | |
157 | ||
158 | /* Add sysfs properties */ | |
4f3731da | 159 | int pcibios_add_platform_entries(struct pci_dev *pdev) |
58083dad KG |
160 | { |
161 | #ifdef CONFIG_PPC_OF | |
4f3731da TB |
162 | return device_create_file(&pdev->dev, &dev_attr_devspec); |
163 | #else | |
164 | return 0; | |
58083dad | 165 | #endif /* CONFIG_PPC_OF */ |
4f3731da | 166 | |
58083dad KG |
167 | } |
168 | ||
169 | char __init *pcibios_setup(char *str) | |
170 | { | |
171 | return str; | |
172 | } | |
173 | ||
174 | /* | |
175 | * Reads the interrupt pin to determine if interrupt is use by card. | |
176 | * If the interrupt is used, then gets the interrupt line from the | |
177 | * openfirmware and sets it in the pci_dev and pci_config line. | |
178 | */ | |
179 | int pci_read_irq_line(struct pci_dev *pci_dev) | |
180 | { | |
181 | struct of_irq oirq; | |
182 | unsigned int virq; | |
183 | ||
184 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | |
185 | ||
186 | #ifdef DEBUG | |
187 | memset(&oirq, 0xff, sizeof(oirq)); | |
188 | #endif | |
189 | /* Try to get a mapping from the device-tree */ | |
190 | if (of_irq_map_pci(pci_dev, &oirq)) { | |
191 | u8 line, pin; | |
192 | ||
193 | /* If that fails, lets fallback to what is in the config | |
194 | * space and map that through the default controller. We | |
195 | * also set the type to level low since that's what PCI | |
196 | * interrupts are. If your platform does differently, then | |
197 | * either provide a proper interrupt tree or don't use this | |
198 | * function. | |
199 | */ | |
200 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) | |
201 | return -1; | |
202 | if (pin == 0) | |
203 | return -1; | |
204 | if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || | |
205 | line == 0xff) { | |
206 | return -1; | |
207 | } | |
208 | DBG(" -> no map ! Using irq line %d from PCI config\n", line); | |
209 | ||
210 | virq = irq_create_mapping(NULL, line); | |
211 | if (virq != NO_IRQ) | |
212 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | |
213 | } else { | |
214 | DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", | |
215 | oirq.size, oirq.specifier[0], oirq.specifier[1], | |
216 | oirq.controller->full_name); | |
217 | ||
218 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | |
219 | oirq.size); | |
220 | } | |
221 | if(virq == NO_IRQ) { | |
222 | DBG(" -> failed to map !\n"); | |
223 | return -1; | |
224 | } | |
225 | ||
226 | DBG(" -> mapped to linux irq %d\n", virq); | |
227 | ||
228 | pci_dev->irq = virq; | |
229 | ||
230 | return 0; | |
231 | } | |
232 | EXPORT_SYMBOL(pci_read_irq_line); | |
233 | ||
234 | /* | |
235 | * Platform support for /proc/bus/pci/X/Y mmap()s, | |
236 | * modelled on the sparc64 implementation by Dave Miller. | |
237 | * -- paulus. | |
238 | */ | |
239 | ||
240 | /* | |
241 | * Adjust vm_pgoff of VMA such that it is the physical page offset | |
242 | * corresponding to the 32-bit pci bus offset for DEV requested by the user. | |
243 | * | |
244 | * Basically, the user finds the base address for his device which he wishes | |
245 | * to mmap. They read the 32-bit value from the config space base register, | |
246 | * add whatever PAGE_SIZE multiple offset they wish, and feed this into the | |
247 | * offset parameter of mmap on /proc/bus/pci/XXX for that device. | |
248 | * | |
249 | * Returns negative error code on failure, zero on success. | |
250 | */ | |
251 | static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |
252 | resource_size_t *offset, | |
253 | enum pci_mmap_state mmap_state) | |
254 | { | |
255 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | |
256 | unsigned long io_offset = 0; | |
257 | int i, res_bit; | |
258 | ||
259 | if (hose == 0) | |
260 | return NULL; /* should never happen */ | |
261 | ||
262 | /* If memory, add on the PCI bridge address offset */ | |
263 | if (mmap_state == pci_mmap_mem) { | |
264 | #if 0 /* See comment in pci_resource_to_user() for why this is disabled */ | |
265 | *offset += hose->pci_mem_offset; | |
266 | #endif | |
267 | res_bit = IORESOURCE_MEM; | |
268 | } else { | |
269 | io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; | |
270 | *offset += io_offset; | |
271 | res_bit = IORESOURCE_IO; | |
272 | } | |
273 | ||
274 | /* | |
275 | * Check that the offset requested corresponds to one of the | |
276 | * resources of the device. | |
277 | */ | |
278 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | |
279 | struct resource *rp = &dev->resource[i]; | |
280 | int flags = rp->flags; | |
281 | ||
282 | /* treat ROM as memory (should be already) */ | |
283 | if (i == PCI_ROM_RESOURCE) | |
284 | flags |= IORESOURCE_MEM; | |
285 | ||
286 | /* Active and same type? */ | |
287 | if ((flags & res_bit) == 0) | |
288 | continue; | |
289 | ||
290 | /* In the range of this resource? */ | |
291 | if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) | |
292 | continue; | |
293 | ||
294 | /* found it! construct the final physical address */ | |
295 | if (mmap_state == pci_mmap_io) | |
296 | *offset += hose->io_base_phys - io_offset; | |
297 | return rp; | |
298 | } | |
299 | ||
300 | return NULL; | |
301 | } | |
302 | ||
303 | /* | |
304 | * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci | |
305 | * device mapping. | |
306 | */ | |
307 | static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |
308 | pgprot_t protection, | |
309 | enum pci_mmap_state mmap_state, | |
310 | int write_combine) | |
311 | { | |
312 | unsigned long prot = pgprot_val(protection); | |
313 | ||
314 | /* Write combine is always 0 on non-memory space mappings. On | |
315 | * memory space, if the user didn't pass 1, we check for a | |
316 | * "prefetchable" resource. This is a bit hackish, but we use | |
317 | * this to workaround the inability of /sysfs to provide a write | |
318 | * combine bit | |
319 | */ | |
320 | if (mmap_state != pci_mmap_mem) | |
321 | write_combine = 0; | |
322 | else if (write_combine == 0) { | |
323 | if (rp->flags & IORESOURCE_PREFETCH) | |
324 | write_combine = 1; | |
325 | } | |
326 | ||
327 | /* XXX would be nice to have a way to ask for write-through */ | |
328 | prot |= _PAGE_NO_CACHE; | |
329 | if (write_combine) | |
330 | prot &= ~_PAGE_GUARDED; | |
331 | else | |
332 | prot |= _PAGE_GUARDED; | |
333 | ||
334 | return __pgprot(prot); | |
335 | } | |
336 | ||
337 | /* | |
338 | * This one is used by /dev/mem and fbdev who have no clue about the | |
339 | * PCI device, it tries to find the PCI device first and calls the | |
340 | * above routine | |
341 | */ | |
342 | pgprot_t pci_phys_mem_access_prot(struct file *file, | |
343 | unsigned long pfn, | |
344 | unsigned long size, | |
345 | pgprot_t protection) | |
346 | { | |
347 | struct pci_dev *pdev = NULL; | |
348 | struct resource *found = NULL; | |
349 | unsigned long prot = pgprot_val(protection); | |
350 | unsigned long offset = pfn << PAGE_SHIFT; | |
351 | int i; | |
352 | ||
353 | if (page_is_ram(pfn)) | |
354 | return __pgprot(prot); | |
355 | ||
356 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | |
357 | ||
358 | for_each_pci_dev(pdev) { | |
359 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | |
360 | struct resource *rp = &pdev->resource[i]; | |
361 | int flags = rp->flags; | |
362 | ||
363 | /* Active and same type? */ | |
364 | if ((flags & IORESOURCE_MEM) == 0) | |
365 | continue; | |
366 | /* In the range of this resource? */ | |
367 | if (offset < (rp->start & PAGE_MASK) || | |
368 | offset > rp->end) | |
369 | continue; | |
370 | found = rp; | |
371 | break; | |
372 | } | |
373 | if (found) | |
374 | break; | |
375 | } | |
376 | if (found) { | |
377 | if (found->flags & IORESOURCE_PREFETCH) | |
378 | prot &= ~_PAGE_GUARDED; | |
379 | pci_dev_put(pdev); | |
380 | } | |
381 | ||
382 | DBG("non-PCI map for %lx, prot: %lx\n", offset, prot); | |
383 | ||
384 | return __pgprot(prot); | |
385 | } | |
386 | ||
387 | ||
388 | /* | |
389 | * Perform the actual remap of the pages for a PCI device mapping, as | |
390 | * appropriate for this architecture. The region in the process to map | |
391 | * is described by vm_start and vm_end members of VMA, the base physical | |
392 | * address is found in vm_pgoff. | |
393 | * The pci device structure is provided so that architectures may make mapping | |
394 | * decisions on a per-device or per-bus basis. | |
395 | * | |
396 | * Returns a negative error code on failure, zero on success. | |
397 | */ | |
398 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |
399 | enum pci_mmap_state mmap_state, int write_combine) | |
400 | { | |
401 | resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; | |
402 | struct resource *rp; | |
403 | int ret; | |
404 | ||
405 | rp = __pci_mmap_make_offset(dev, &offset, mmap_state); | |
406 | if (rp == NULL) | |
407 | return -EINVAL; | |
408 | ||
409 | vma->vm_pgoff = offset >> PAGE_SHIFT; | |
410 | vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, | |
411 | vma->vm_page_prot, | |
412 | mmap_state, write_combine); | |
413 | ||
414 | ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | |
415 | vma->vm_end - vma->vm_start, vma->vm_page_prot); | |
416 | ||
417 | return ret; | |
418 | } | |
419 | ||
420 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | |
421 | const struct resource *rsrc, | |
422 | resource_size_t *start, resource_size_t *end) | |
423 | { | |
424 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | |
425 | resource_size_t offset = 0; | |
426 | ||
427 | if (hose == NULL) | |
428 | return; | |
429 | ||
430 | if (rsrc->flags & IORESOURCE_IO) | |
431 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | |
432 | ||
433 | /* We pass a fully fixed up address to userland for MMIO instead of | |
434 | * a BAR value because X is lame and expects to be able to use that | |
435 | * to pass to /dev/mem ! | |
436 | * | |
437 | * That means that we'll have potentially 64 bits values where some | |
438 | * userland apps only expect 32 (like X itself since it thinks only | |
439 | * Sparc has 64 bits MMIO) but if we don't do that, we break it on | |
440 | * 32 bits CHRPs :-( | |
441 | * | |
442 | * Hopefully, the sysfs insterface is immune to that gunk. Once X | |
443 | * has been fixed (and the fix spread enough), we can re-enable the | |
444 | * 2 lines below and pass down a BAR value to userland. In that case | |
445 | * we'll also have to re-enable the matching code in | |
446 | * __pci_mmap_make_offset(). | |
447 | * | |
448 | * BenH. | |
449 | */ | |
450 | #if 0 | |
451 | else if (rsrc->flags & IORESOURCE_MEM) | |
452 | offset = hose->pci_mem_offset; | |
453 | #endif | |
454 | ||
455 | *start = rsrc->start - offset; | |
456 | *end = rsrc->end - offset; | |
457 | } |