aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci_32.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-19 22:54:44 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-20 00:18:06 -0500
commitb9baa20b0a50947f2e86d7775c9dba87c0d946ef (patch)
tree21659df63935450730be4c2a61c1f54e40693aba /arch/powerpc/kernel/pci_32.c
parent0ec6b5c1028f29aed07bc7c32945990c5cd48c14 (diff)
[POWERPC] pci32: Remove PowerMac P2P bridge IO hack
The 32 bits PowerPC PCI code has a hack for use by some PowerMacs to try to re-open PCI<->PCI bridge IO resources that were closed by the firmware. This is no longer necessary as the generic code will now do that for us. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r--arch/powerpc/kernel/pci_32.c215
1 files changed, 1 insertions, 214 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 1020d04b0a5a..dfb165802529 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -711,217 +711,6 @@ void pcibios_make_OF_bus_map(void)
711} 711}
712#endif /* CONFIG_PPC_OF */ 712#endif /* CONFIG_PPC_OF */
713 713
714#ifdef CONFIG_PPC_PMAC
715/*
716 * This set of routines checks for PCI<->PCI bridges that have closed
717 * IO resources and have child devices. It tries to re-open an IO
718 * window on them.
719 *
720 * This is a _temporary_ fix to workaround a problem with Apple's OF
721 * closing IO windows on P2P bridges when the OF drivers of cards
722 * below this bridge don't claim any IO range (typically ATI or
723 * Adaptec).
724 *
725 * A more complete fix would be to use drivers/pci/setup-bus.c, which
726 * involves a working pcibios_fixup_pbus_ranges(), some more care about
727 * ordering when creating the host bus resources, and maybe a few more
728 * minor tweaks
729 */
730
731/* Initialize bridges with base/limit values we have collected */
732static void __init
733do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
734{
735 struct pci_dev *bridge = bus->self;
736 struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
737 u32 l;
738 u16 w;
739 struct resource res;
740
741 if (bus->resource[0] == NULL)
742 return;
743 res = *(bus->resource[0]);
744
745 DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
746 res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
747 res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
748 DBG(" IO window: %016llx-%016llx\n", res.start, res.end);
749
750 /* Set up the top and bottom of the PCI I/O segment for this bus. */
751 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
752 l &= 0xffff000f;
753 l |= (res.start >> 8) & 0x00f0;
754 l |= res.end & 0xf000;
755 pci_write_config_dword(bridge, PCI_IO_BASE, l);
756
757 if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
758 l = (res.start >> 16) | (res.end & 0xffff0000);
759 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
760 }
761
762 pci_read_config_word(bridge, PCI_COMMAND, &w);
763 w |= PCI_COMMAND_IO;
764 pci_write_config_word(bridge, PCI_COMMAND, w);
765
766#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
767 if (enable_vga) {
768 pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
769 w |= PCI_BRIDGE_CTL_VGA;
770 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
771 }
772#endif
773}
774
775/* This function is pretty basic and actually quite broken for the
776 * general case, it's enough for us right now though. It's supposed
777 * to tell us if we need to open an IO range at all or not and what
778 * size.
779 */
780static int __init
781check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
782{
783 struct pci_dev *dev;
784 int i;
785 int rc = 0;
786
787#define push_end(res, mask) do { \
788 BUG_ON((mask+1) & mask); \
789 res->end = (res->end + mask) | mask; \
790} while (0)
791
792 list_for_each_entry(dev, &bus->devices, bus_list) {
793 u16 class = dev->class >> 8;
794
795 if (class == PCI_CLASS_DISPLAY_VGA ||
796 class == PCI_CLASS_NOT_DEFINED_VGA)
797 *found_vga = 1;
798 if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
799 rc |= check_for_io_childs(dev->subordinate, res, found_vga);
800 if (class == PCI_CLASS_BRIDGE_CARDBUS)
801 push_end(res, 0xfff);
802
803 for (i=0; i<PCI_NUM_RESOURCES; i++) {
804 struct resource *r;
805 unsigned long r_size;
806
807 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
808 && i >= PCI_BRIDGE_RESOURCES)
809 continue;
810 r = &dev->resource[i];
811 r_size = r->end - r->start;
812 if (r_size < 0xfff)
813 r_size = 0xfff;
814 if (r->flags & IORESOURCE_IO && (r_size) != 0) {
815 rc = 1;
816 push_end(res, r_size);
817 }
818 }
819 }
820
821 return rc;
822}
823
824/* Here we scan all P2P bridges of a given level that have a closed
825 * IO window. Note that the test for the presence of a VGA card should
826 * be improved to take into account already configured P2P bridges,
827 * currently, we don't see them and might end up configuring 2 bridges
828 * with VGA pass through enabled
829 */
830static void __init
831do_fixup_p2p_level(struct pci_bus *bus)
832{
833 struct pci_bus *b;
834 int i, parent_io;
835 int has_vga = 0;
836
837 for (parent_io=0; parent_io<4; parent_io++)
838 if (bus->resource[parent_io]
839 && bus->resource[parent_io]->flags & IORESOURCE_IO)
840 break;
841 if (parent_io >= 4)
842 return;
843
844 list_for_each_entry(b, &bus->children, node) {
845 struct pci_dev *d = b->self;
846 struct pci_controller* hose = (struct pci_controller *)d->sysdata;
847 struct resource *res = b->resource[0];
848 struct resource tmp_res;
849 unsigned long max;
850 int found_vga = 0;
851
852 memset(&tmp_res, 0, sizeof(tmp_res));
853 tmp_res.start = bus->resource[parent_io]->start;
854
855 /* We don't let low addresses go through that closed P2P bridge, well,
856 * that may not be necessary but I feel safer that way
857 */
858 if (tmp_res.start == 0)
859 tmp_res.start = 0x1000;
860
861 if (!list_empty(&b->devices) && res && res->flags == 0 &&
862 res != bus->resource[parent_io] &&
863 (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
864 check_for_io_childs(b, &tmp_res, &found_vga)) {
865 u8 io_base_lo;
866
867 printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
868
869 if (found_vga) {
870 if (has_vga) {
871 printk(KERN_WARNING "Skipping VGA, already active"
872 " on bus segment\n");
873 found_vga = 0;
874 } else
875 has_vga = 1;
876 }
877 pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
878
879 if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
880 max = ((unsigned long) hose->io_base_virt
881 - isa_io_base) + 0xffffffff;
882 else
883 max = ((unsigned long) hose->io_base_virt
884 - isa_io_base) + 0xffff;
885
886 *res = tmp_res;
887 res->flags = IORESOURCE_IO;
888 res->name = b->name;
889
890 /* Find a resource in the parent where we can allocate */
891 for (i = 0 ; i < 4; i++) {
892 struct resource *r = bus->resource[i];
893 if (!r)
894 continue;
895 if ((r->flags & IORESOURCE_IO) == 0)
896 continue;
897 DBG("Trying to allocate from %016llx, size %016llx from parent"
898 " res %d: %016llx -> %016llx\n",
899 res->start, res->end, i, r->start, r->end);
900
901 if (allocate_resource(r, res, res->end + 1, res->start, max,
902 res->end + 1, NULL, NULL) < 0) {
903 DBG("Failed !\n");
904 continue;
905 }
906 do_update_p2p_io_resource(b, found_vga);
907 break;
908 }
909 }
910 do_fixup_p2p_level(b);
911 }
912}
913
914static void
915pcibios_fixup_p2p_bridges(void)
916{
917 struct pci_bus *b;
918
919 list_for_each_entry(b, &pci_root_buses, node)
920 do_fixup_p2p_level(b);
921}
922
923#endif /* CONFIG_PPC_PMAC */
924
925static int __init 714static int __init
926pcibios_init(void) 715pcibios_init(void)
927{ 716{
@@ -961,9 +750,7 @@ pcibios_init(void)
961 pcibios_allocate_bus_resources(&pci_root_buses); 750 pcibios_allocate_bus_resources(&pci_root_buses);
962 pcibios_allocate_resources(0); 751 pcibios_allocate_resources(0);
963 pcibios_allocate_resources(1); 752 pcibios_allocate_resources(1);
964#ifdef CONFIG_PPC_PMAC 753
965 pcibios_fixup_p2p_bridges();
966#endif /* CONFIG_PPC_PMAC */
967 DBG("PCI: Assigning unassigned resouces...\n"); 754 DBG("PCI: Assigning unassigned resouces...\n");
968 pci_assign_unassigned_resources(); 755 pci_assign_unassigned_resources();
969 756