pci-common.c (d92a208d086063ecc785b4588f74ab42268cbc4b) | pci-common.c (654837e8fe8d1d302803458e3a100aa78e0d90de) |
---|---|
1/* 2 * Contains common pci routines for ALL ppc platform 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 --- 672 unchanged lines hidden (view full) --- 681 * it for 64 bits but I would expect problems on 32 bits. 682 * 683 * - Some 32 bits platforms such as 4xx can have physical space larger than 684 * 32 bits so we need to use 64 bits values for the parsing 685 */ 686void pci_process_bridge_OF_ranges(struct pci_controller *hose, 687 struct device_node *dev, int primary) 688{ | 1/* 2 * Contains common pci routines for ALL ppc platform 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 --- 672 unchanged lines hidden (view full) --- 681 * it for 64 bits but I would expect problems on 32 bits. 682 * 683 * - Some 32 bits platforms such as 4xx can have physical space larger than 684 * 32 bits so we need to use 64 bits values for the parsing 685 */ 686void pci_process_bridge_OF_ranges(struct pci_controller *hose, 687 struct device_node *dev, int primary) 688{ |
689 const __be32 *ranges; 690 int rlen; 691 int pna = of_n_addr_cells(dev); 692 int np = pna + 5; | |
693 int memno = 0; | 689 int memno = 0; |
694 u32 pci_space; 695 unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; | |
696 struct resource *res; | 690 struct resource *res; |
691 struct of_pci_range range; 692 struct of_pci_range_parser parser; |
|
697 698 printk(KERN_INFO "PCI host bridge %s %s ranges:\n", 699 dev->full_name, primary ? "(primary)" : ""); 700 | 693 694 printk(KERN_INFO "PCI host bridge %s %s ranges:\n", 695 dev->full_name, primary ? "(primary)" : ""); 696 |
701 /* Get ranges property */ 702 ranges = of_get_property(dev, "ranges", &rlen); 703 if (ranges == NULL) | 697 /* Check for ranges property */ 698 if (of_pci_range_parser_init(&parser, dev)) |
704 return; 705 706 /* Parse it */ | 699 return; 700 701 /* Parse it */ |
707 while ((rlen -= np * 4) >= 0) { 708 /* Read next ranges element */ 709 pci_space = of_read_number(ranges, 1); 710 pci_addr = of_read_number(ranges + 1, 2); 711 cpu_addr = of_translate_address(dev, ranges + 3); 712 size = of_read_number(ranges + pna + 3, 2); 713 ranges += np; 714 | 702 for_each_of_pci_range(&parser, &range) { |
715 /* If we failed translation or got a zero-sized region 716 * (some FW try to feed us with non sensical zero sized regions 717 * such as power3 which look like some kind of attempt at exposing 718 * the VGA memory hole) 719 */ | 703 /* If we failed translation or got a zero-sized region 704 * (some FW try to feed us with non sensical zero sized regions 705 * such as power3 which look like some kind of attempt at exposing 706 * the VGA memory hole) 707 */ |
720 if (cpu_addr == OF_BAD_ADDR || size == 0) | 708 if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) |
721 continue; 722 | 709 continue; 710 |
723 /* Now consume following elements while they are contiguous */ 724 for (; rlen >= np * sizeof(u32); 725 ranges += np, rlen -= np * 4) { 726 if (of_read_number(ranges, 1) != pci_space) 727 break; 728 pci_next = of_read_number(ranges + 1, 2); 729 cpu_next = of_translate_address(dev, ranges + 3); 730 if (pci_next != pci_addr + size || 731 cpu_next != cpu_addr + size) 732 break; 733 size += of_read_number(ranges + pna + 3, 2); 734 } 735 | |
736 /* Act based on address space type */ 737 res = NULL; | 711 /* Act based on address space type */ 712 res = NULL; |
738 switch ((pci_space >> 24) & 0x3) { 739 case 1: /* PCI IO space */ | 713 switch (range.flags & IORESOURCE_TYPE_BITS) { 714 case IORESOURCE_IO: |
740 printk(KERN_INFO 741 " IO 0x%016llx..0x%016llx -> 0x%016llx\n", | 715 printk(KERN_INFO 716 " IO 0x%016llx..0x%016llx -> 0x%016llx\n", |
742 cpu_addr, cpu_addr + size - 1, pci_addr); | 717 range.cpu_addr, range.cpu_addr + range.size - 1, 718 range.pci_addr); |
743 744 /* We support only one IO range */ 745 if (hose->pci_io_size) { 746 printk(KERN_INFO 747 " \\--> Skipped (too many) !\n"); 748 continue; 749 } 750#ifdef CONFIG_PPC32 751 /* On 32 bits, limit I/O space to 16MB */ | 719 720 /* We support only one IO range */ 721 if (hose->pci_io_size) { 722 printk(KERN_INFO 723 " \\--> Skipped (too many) !\n"); 724 continue; 725 } 726#ifdef CONFIG_PPC32 727 /* On 32 bits, limit I/O space to 16MB */ |
752 if (size > 0x01000000) 753 size = 0x01000000; | 728 if (range.size > 0x01000000) 729 range.size = 0x01000000; |
754 755 /* 32 bits needs to map IOs here */ | 730 731 /* 32 bits needs to map IOs here */ |
756 hose->io_base_virt = ioremap(cpu_addr, size); | 732 hose->io_base_virt = ioremap(range.cpu_addr, 733 range.size); |
757 758 /* Expect trouble if pci_addr is not 0 */ 759 if (primary) 760 isa_io_base = 761 (unsigned long)hose->io_base_virt; 762#endif /* CONFIG_PPC32 */ 763 /* pci_io_size and io_base_phys always represent IO 764 * space starting at 0 so we factor in pci_addr 765 */ | 734 735 /* Expect trouble if pci_addr is not 0 */ 736 if (primary) 737 isa_io_base = 738 (unsigned long)hose->io_base_virt; 739#endif /* CONFIG_PPC32 */ 740 /* pci_io_size and io_base_phys always represent IO 741 * space starting at 0 so we factor in pci_addr 742 */ |
766 hose->pci_io_size = pci_addr + size; 767 hose->io_base_phys = cpu_addr - pci_addr; | 743 hose->pci_io_size = range.pci_addr + range.size; 744 hose->io_base_phys = range.cpu_addr - range.pci_addr; |
768 769 /* Build resource */ 770 res = &hose->io_resource; | 745 746 /* Build resource */ 747 res = &hose->io_resource; |
771 res->flags = IORESOURCE_IO; 772 res->start = pci_addr; | 748 range.cpu_addr = range.pci_addr; |
773 break; | 749 break; |
774 case 2: /* PCI Memory space */ 775 case 3: /* PCI 64 bits Memory space */ | 750 case IORESOURCE_MEM: |
776 printk(KERN_INFO 777 " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", | 751 printk(KERN_INFO 752 " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", |
778 cpu_addr, cpu_addr + size - 1, pci_addr, 779 (pci_space & 0x40000000) ? "Prefetch" : ""); | 753 range.cpu_addr, range.cpu_addr + range.size - 1, 754 range.pci_addr, 755 (range.pci_space & 0x40000000) ? 756 "Prefetch" : ""); |
780 781 /* We support only 3 memory ranges */ 782 if (memno >= 3) { 783 printk(KERN_INFO 784 " \\--> Skipped (too many) !\n"); 785 continue; 786 } 787 /* Handles ISA memory hole space here */ | 757 758 /* We support only 3 memory ranges */ 759 if (memno >= 3) { 760 printk(KERN_INFO 761 " \\--> Skipped (too many) !\n"); 762 continue; 763 } 764 /* Handles ISA memory hole space here */ |
788 if (pci_addr == 0) { | 765 if (range.pci_addr == 0) { |
789 if (primary || isa_mem_base == 0) | 766 if (primary || isa_mem_base == 0) |
790 isa_mem_base = cpu_addr; 791 hose->isa_mem_phys = cpu_addr; 792 hose->isa_mem_size = size; | 767 isa_mem_base = range.cpu_addr; 768 hose->isa_mem_phys = range.cpu_addr; 769 hose->isa_mem_size = range.size; |
793 } 794 795 /* Build resource */ | 770 } 771 772 /* Build resource */ |
796 hose->mem_offset[memno] = cpu_addr - pci_addr; | 773 hose->mem_offset[memno] = range.cpu_addr - 774 range.pci_addr; |
797 res = &hose->mem_resources[memno++]; | 775 res = &hose->mem_resources[memno++]; |
798 res->flags = IORESOURCE_MEM; 799 if (pci_space & 0x40000000) 800 res->flags |= IORESOURCE_PREFETCH; 801 res->start = cpu_addr; | |
802 break; 803 } 804 if (res != NULL) { | 776 break; 777 } 778 if (res != NULL) { |
805 res->name = dev->full_name; 806 res->end = res->start + size - 1; 807 res->parent = NULL; 808 res->sibling = NULL; 809 res->child = NULL; | 779 of_pci_range_to_resource(&range, dev, res); |
810 } 811 } 812} 813 814/* Decide whether to display the domain number in /proc */ 815int pci_proc_domain(struct pci_bus *bus) 816{ 817 struct pci_controller *hose = pci_bus_to_host(bus); --- 914 unchanged lines hidden --- | 780 } 781 } 782} 783 784/* Decide whether to display the domain number in /proc */ 785int pci_proc_domain(struct pci_bus *bus) 786{ 787 struct pci_controller *hose = pci_bus_to_host(bus); --- 914 unchanged lines hidden --- |