aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/pci-common.c177
-rw-r--r--arch/powerpc/kernel/pci_32.c114
-rw-r--r--arch/powerpc/kernel/pci_64.c93
-rw-r--r--include/asm-powerpc/pci-bridge.h3
4 files changed, 180 insertions, 207 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index bea11df0a79b..9979c43cc8c7 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -462,3 +462,180 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
462 *start = rsrc->start - offset; 462 *start = rsrc->start - offset;
463 *end = rsrc->end - offset; 463 *end = rsrc->end - offset;
464} 464}
465
466/**
467 * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
468 * @hose: newly allocated pci_controller to be setup
469 * @dev: device node of the host bridge
470 * @primary: set if primary bus (32 bits only, soon to be deprecated)
471 *
472 * This function will parse the "ranges" property of a PCI host bridge device
473 * node and setup the resource mapping of a pci controller based on its
474 * content.
475 *
476 * Life would be boring if it wasn't for a few issues that we have to deal
477 * with here:
478 *
479 * - We can only cope with one IO space range and up to 3 Memory space
480 * ranges. However, some machines (thanks Apple !) tend to split their
481 * space into lots of small contiguous ranges. So we have to coalesce.
482 *
483 * - We can only cope with all memory ranges having the same offset
484 * between CPU addresses and PCI addresses. Unfortunately, some bridges
485 * are setup for a large 1:1 mapping along with a small "window" which
486 * maps PCI address 0 to some arbitrary high address of the CPU space in
487 * order to give access to the ISA memory hole.
488 * The way out of here that I've chosen for now is to always set the
489 * offset based on the first resource found, then override it if we
490 * have a different offset and the previous was set by an ISA hole.
491 *
492 * - Some busses have IO space not starting at 0, which causes trouble with
493 * the way we do our IO resource renumbering. The code somewhat deals with
494 * it for 64 bits but I would expect problems on 32 bits.
495 *
496 * - Some 32 bits platforms such as 4xx can have physical space larger than
497 * 32 bits so we need to use 64 bits values for the parsing
498 */
499void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
500 struct device_node *dev,
501 int primary)
502{
503 const u32 *ranges;
504 int rlen;
505 int pna = of_n_addr_cells(dev);
506 int np = pna + 5;
507 int memno = 0, isa_hole = -1;
508 u32 pci_space;
509 unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
510 unsigned long long isa_mb = 0;
511 struct resource *res;
512
513 printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
514 dev->full_name, primary ? "(primary)" : "");
515
516 /* Get ranges property */
517 ranges = of_get_property(dev, "ranges", &rlen);
518 if (ranges == NULL)
519 return;
520
521 /* Parse it */
522 while ((rlen -= np * 4) >= 0) {
523 /* Read next ranges element */
524 pci_space = ranges[0];
525 pci_addr = of_read_number(ranges + 1, 2);
526 cpu_addr = of_translate_address(dev, ranges + 3);
527 size = of_read_number(ranges + pna + 3, 2);
528 ranges += np;
529 if (cpu_addr == OF_BAD_ADDR || size == 0)
530 continue;
531
532 /* Now consume following elements while they are contiguous */
533 for (; rlen >= np * sizeof(u32);
534 ranges += np, rlen -= np * 4) {
535 if (ranges[0] != pci_space)
536 break;
537 pci_next = of_read_number(ranges + 1, 2);
538 cpu_next = of_translate_address(dev, ranges + 3);
539 if (pci_next != pci_addr + size ||
540 cpu_next != cpu_addr + size)
541 break;
542 size += of_read_number(ranges + pna + 3, 2);
543 }
544
545 /* Act based on address space type */
546 res = NULL;
547 switch ((pci_space >> 24) & 0x3) {
548 case 1: /* PCI IO space */
549 printk(KERN_INFO
550 " IO 0x%016llx..0x%016llx -> 0x%016llx\n",
551 cpu_addr, cpu_addr + size - 1, pci_addr);
552
553 /* We support only one IO range */
554 if (hose->pci_io_size) {
555 printk(KERN_INFO
556 " \\--> Skipped (too many) !\n");
557 continue;
558 }
559#ifdef CONFIG_PPC32
560 /* On 32 bits, limit I/O space to 16MB */
561 if (size > 0x01000000)
562 size = 0x01000000;
563
564 /* 32 bits needs to map IOs here */
565 hose->io_base_virt = ioremap(cpu_addr, size);
566
567 /* Expect trouble if pci_addr is not 0 */
568 if (primary)
569 isa_io_base =
570 (unsigned long)hose->io_base_virt;
571#endif /* CONFIG_PPC32 */
572 /* pci_io_size and io_base_phys always represent IO
573 * space starting at 0 so we factor in pci_addr
574 */
575 hose->pci_io_size = pci_addr + size;
576 hose->io_base_phys = cpu_addr - pci_addr;
577
578 /* Build resource */
579 res = &hose->io_resource;
580 res->flags = IORESOURCE_IO;
581 res->start = pci_addr;
582 break;
583 case 2: /* PCI Memory space */
584 printk(KERN_INFO
585 " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
586 cpu_addr, cpu_addr + size - 1, pci_addr,
587 (pci_space & 0x40000000) ? "Prefetch" : "");
588
589 /* We support only 3 memory ranges */
590 if (memno >= 3) {
591 printk(KERN_INFO
592 " \\--> Skipped (too many) !\n");
593 continue;
594 }
595 /* Handles ISA memory hole space here */
596 if (pci_addr == 0) {
597 isa_mb = cpu_addr;
598 isa_hole = memno;
599 if (primary || isa_mem_base == 0)
600 isa_mem_base = cpu_addr;
601 }
602
603 /* We get the PCI/Mem offset from the first range or
604 * the, current one if the offset came from an ISA
605 * hole. If they don't match, bugger.
606 */
607 if (memno == 0 ||
608 (isa_hole >= 0 && pci_addr != 0 &&
609 hose->pci_mem_offset == isa_mb))
610 hose->pci_mem_offset = cpu_addr - pci_addr;
611 else if (pci_addr != 0 &&
612 hose->pci_mem_offset != cpu_addr - pci_addr) {
613 printk(KERN_INFO
614 " \\--> Skipped (offset mismatch) !\n");
615 continue;
616 }
617
618 /* Build resource */
619 res = &hose->mem_resources[memno++];
620 res->flags = IORESOURCE_MEM;
621 if (pci_space & 0x40000000)
622 res->flags |= IORESOURCE_PREFETCH;
623 res->start = cpu_addr;
624 break;
625 }
626 if (res != NULL) {
627 res->name = dev->full_name;
628 res->end = res->start + size - 1;
629 res->parent = NULL;
630 res->sibling = NULL;
631 res->child = NULL;
632 }
633 }
634
635 /* Out of paranoia, let's put the ISA hole last if any */
636 if (isa_hole >= 0 && memno > 0 && isa_hole != (memno-1)) {
637 struct resource tmp = hose->mem_resources[isa_hole];
638 hose->mem_resources[isa_hole] = hose->mem_resources[memno-1];
639 hose->mem_resources[memno-1] = tmp;
640 }
641}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index a33c2820c200..20a1192de1a2 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -842,120 +842,6 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
842} 842}
843EXPORT_SYMBOL(pci_device_from_OF_node); 843EXPORT_SYMBOL(pci_device_from_OF_node);
844 844
845void __init
846pci_process_bridge_OF_ranges(struct pci_controller *hose,
847 struct device_node *dev, int primary)
848{
849 static unsigned int static_lc_ranges[256] __initdata;
850 const unsigned int *dt_ranges;
851 unsigned int *lc_ranges, *ranges, *prev, size;
852 int rlen = 0, orig_rlen;
853 int memno = 0;
854 struct resource *res;
855 int np, na = of_n_addr_cells(dev);
856 np = na + 5;
857
858 /* First we try to merge ranges to fix a problem with some pmacs
859 * that can have more than 3 ranges, fortunately using contiguous
860 * addresses -- BenH
861 */
862 dt_ranges = of_get_property(dev, "ranges", &rlen);
863 if (!dt_ranges)
864 return;
865 /* Sanity check, though hopefully that never happens */
866 if (rlen > sizeof(static_lc_ranges)) {
867 printk(KERN_WARNING "OF ranges property too large !\n");
868 rlen = sizeof(static_lc_ranges);
869 }
870 lc_ranges = static_lc_ranges;
871 memcpy(lc_ranges, dt_ranges, rlen);
872 orig_rlen = rlen;
873
874 /* Let's work on a copy of the "ranges" property instead of damaging
875 * the device-tree image in memory
876 */
877 ranges = lc_ranges;
878 prev = NULL;
879 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
880 if (prev) {
881 if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
882 (prev[2] + prev[na+4]) == ranges[2] &&
883 (prev[na+2] + prev[na+4]) == ranges[na+2]) {
884 prev[na+4] += ranges[na+4];
885 ranges[0] = 0;
886 ranges += np;
887 continue;
888 }
889 }
890 prev = ranges;
891 ranges += np;
892 }
893
894 /*
895 * The ranges property is laid out as an array of elements,
896 * each of which comprises:
897 * cells 0 - 2: a PCI address
898 * cells 3 or 3+4: a CPU physical address
899 * (size depending on dev->n_addr_cells)
900 * cells 4+5 or 5+6: the size of the range
901 */
902 ranges = lc_ranges;
903 rlen = orig_rlen;
904 while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
905 res = NULL;
906 size = ranges[na+4];
907 switch ((ranges[0] >> 24) & 0x3) {
908 case 1: /* I/O space */
909 if (ranges[2] != 0)
910 break;
911 hose->io_base_phys = ranges[na+2];
912 /* limit I/O space to 16MB */
913 if (size > 0x01000000)
914 size = 0x01000000;
915 hose->io_base_virt = ioremap(ranges[na+2], size);
916 if (primary)
917 isa_io_base = (unsigned long) hose->io_base_virt;
918 res = &hose->io_resource;
919 res->flags = IORESOURCE_IO;
920 res->start = ranges[2];
921 DBG("PCI: IO 0x%llx -> 0x%llx\n",
922 (u64)res->start, (u64)res->start + size - 1);
923 break;
924 case 2: /* memory space */
925 memno = 0;
926 if (ranges[1] == 0 && ranges[2] == 0
927 && ranges[na+4] <= (16 << 20)) {
928 /* 1st 16MB, i.e. ISA memory area */
929 if (primary)
930 isa_mem_base = ranges[na+2];
931 memno = 1;
932 }
933 while (memno < 3 && hose->mem_resources[memno].flags)
934 ++memno;
935 if (memno == 0)
936 hose->pci_mem_offset = ranges[na+2] - ranges[2];
937 if (memno < 3) {
938 res = &hose->mem_resources[memno];
939 res->flags = IORESOURCE_MEM;
940 if(ranges[0] & 0x40000000)
941 res->flags |= IORESOURCE_PREFETCH;
942 res->start = ranges[na+2];
943 DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
944 (u64)res->start, (u64)res->start + size - 1);
945 }
946 break;
947 }
948 if (res != NULL) {
949 res->name = dev->full_name;
950 res->end = res->start + size - 1;
951 res->parent = NULL;
952 res->sibling = NULL;
953 res->child = NULL;
954 }
955 ranges += np;
956 }
957}
958
959/* We create the "pci-OF-bus-map" property now so it appears in the 845/* We create the "pci-OF-bus-map" property now so it appears in the
960 * /proc device tree 846 * /proc device tree
961 */ 847 */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 6b9a8564e735..bf06926f677d 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -578,99 +578,6 @@ int pci_proc_domain(struct pci_bus *bus)
578 return hose->buid != 0; 578 return hose->buid != 0;
579} 579}
580 580
581void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
582 struct device_node *dev, int prim)
583{
584 const unsigned int *ranges;
585 unsigned int pci_space;
586 unsigned long size;
587 int rlen = 0;
588 int memno = 0;
589 struct resource *res;
590 int np, na = of_n_addr_cells(dev);
591 unsigned long pci_addr, cpu_phys_addr;
592
593 np = na + 5;
594
595 /* From "PCI Binding to 1275"
596 * The ranges property is laid out as an array of elements,
597 * each of which comprises:
598 * cells 0 - 2: a PCI address
599 * cells 3 or 3+4: a CPU physical address
600 * (size depending on dev->n_addr_cells)
601 * cells 4+5 or 5+6: the size of the range
602 */
603 ranges = of_get_property(dev, "ranges", &rlen);
604 if (ranges == NULL)
605 return;
606 hose->io_base_phys = 0;
607 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
608 res = NULL;
609 pci_space = ranges[0];
610 pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
611 cpu_phys_addr = of_translate_address(dev, &ranges[3]);
612 size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
613 ranges += np;
614 if (size == 0)
615 continue;
616
617 /* Now consume following elements while they are contiguous */
618 while (rlen >= np * sizeof(unsigned int)) {
619 unsigned long addr, phys;
620
621 if (ranges[0] != pci_space)
622 break;
623 addr = ((unsigned long)ranges[1] << 32) | ranges[2];
624 phys = ranges[3];
625 if (na >= 2)
626 phys = (phys << 32) | ranges[4];
627 if (addr != pci_addr + size ||
628 phys != cpu_phys_addr + size)
629 break;
630
631 size += ((unsigned long)ranges[na+3] << 32)
632 | ranges[na+4];
633 ranges += np;
634 rlen -= np * sizeof(unsigned int);
635 }
636
637 switch ((pci_space >> 24) & 0x3) {
638 case 1: /* I/O space */
639 hose->io_base_phys = cpu_phys_addr - pci_addr;
640 /* handle from 0 to top of I/O window */
641 hose->pci_io_size = pci_addr + size;
642
643 res = &hose->io_resource;
644 res->flags = IORESOURCE_IO;
645 res->start = pci_addr;
646 DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
647 res->start, res->start + size - 1);
648 break;
649 case 2: /* memory space */
650 memno = 0;
651 while (memno < 3 && hose->mem_resources[memno].flags)
652 ++memno;
653
654 if (memno == 0)
655 hose->pci_mem_offset = cpu_phys_addr - pci_addr;
656 if (memno < 3) {
657 res = &hose->mem_resources[memno];
658 res->flags = IORESOURCE_MEM;
659 res->start = cpu_phys_addr;
660 DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
661 res->start, res->start + size - 1);
662 }
663 break;
664 }
665 if (res != NULL) {
666 res->name = dev->full_name;
667 res->end = res->start + size - 1;
668 res->parent = NULL;
669 res->sibling = NULL;
670 res->child = NULL;
671 }
672 }
673}
674 581
675#ifdef CONFIG_HOTPLUG 582#ifdef CONFIG_HOTPLUG
676 583
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index f139f2a44b19..8245e84836c9 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -37,6 +37,9 @@ struct pci_controller {
37 void *io_base_alloc; 37 void *io_base_alloc;
38#endif 38#endif
39 resource_size_t io_base_phys; 39 resource_size_t io_base_phys;
40#ifndef CONFIG_PPC64
41 resource_size_t pci_io_size;
42#endif
40 43
41 /* Some machines (PReP) have a non 1:1 mapping of 44 /* Some machines (PReP) have a non 1:1 mapping of
42 * the PCI memory space in the CPU bus space 45 * the PCI memory space in the CPU bus space