diff options
Diffstat (limited to 'arch/sparc64/kernel/pci_sabre.c')
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 465 |
1 files changed, 63 insertions, 402 deletions
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 94bb681f2323..397862fbd9e1 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* $Id: pci_sabre.c,v 1.42 2002/01/23 11:27:32 davem Exp $ | 1 | /* pci_sabre.c: Sabre specific PCI controller support. |
2 | * pci_sabre.c: Sabre specific PCI controller support. | ||
3 | * | 2 | * |
4 | * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) | 3 | * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net) |
5 | * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) | 4 | * Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be) |
6 | * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) | 5 | * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) |
7 | */ | 6 | */ |
@@ -254,9 +253,6 @@ static int __sabre_out_of_range(struct pci_pbm_info *pbm, | |||
254 | return 0; | 253 | return 0; |
255 | 254 | ||
256 | return ((pbm->parent == 0) || | 255 | return ((pbm->parent == 0) || |
257 | ((pbm == &pbm->parent->pbm_B) && | ||
258 | (bus == pbm->pci_first_busno) && | ||
259 | PCI_SLOT(devfn) > 8) || | ||
260 | ((pbm == &pbm->parent->pbm_A) && | 256 | ((pbm == &pbm->parent->pbm_A) && |
261 | (bus == pbm->pci_first_busno) && | 257 | (bus == pbm->pci_first_busno) && |
262 | PCI_SLOT(devfn) > 8)); | 258 | PCI_SLOT(devfn) > 8)); |
@@ -322,6 +318,12 @@ static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | |||
322 | static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, | 318 | static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn, |
323 | int where, int size, u32 *value) | 319 | int where, int size, u32 *value) |
324 | { | 320 | { |
321 | struct pci_pbm_info *pbm = bus->sysdata; | ||
322 | |||
323 | if (bus == pbm->pci_bus && devfn == 0x00) | ||
324 | return pci_host_bridge_read_pci_cfg(bus, devfn, where, | ||
325 | size, value); | ||
326 | |||
325 | if (!bus->number && sabre_out_of_range(devfn)) { | 327 | if (!bus->number && sabre_out_of_range(devfn)) { |
326 | switch (size) { | 328 | switch (size) { |
327 | case 1: | 329 | case 1: |
@@ -438,6 +440,12 @@ static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, | |||
438 | static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, | 440 | static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn, |
439 | int where, int size, u32 value) | 441 | int where, int size, u32 value) |
440 | { | 442 | { |
443 | struct pci_pbm_info *pbm = bus->sysdata; | ||
444 | |||
445 | if (bus == pbm->pci_bus && devfn == 0x00) | ||
446 | return pci_host_bridge_write_pci_cfg(bus, devfn, where, | ||
447 | size, value); | ||
448 | |||
441 | if (bus->number) | 449 | if (bus->number) |
442 | return __sabre_write_pci_cfg(bus, devfn, where, size, value); | 450 | return __sabre_write_pci_cfg(bus, devfn, where, size, value); |
443 | 451 | ||
@@ -490,7 +498,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, | |||
490 | unsigned long afsr, | 498 | unsigned long afsr, |
491 | unsigned long afar) | 499 | unsigned long afar) |
492 | { | 500 | { |
493 | struct pci_iommu *iommu = p->pbm_A.iommu; | 501 | struct iommu *iommu = p->pbm_A.iommu; |
494 | unsigned long iommu_tag[16]; | 502 | unsigned long iommu_tag[16]; |
495 | unsigned long iommu_data[16]; | 503 | unsigned long iommu_data[16]; |
496 | unsigned long flags; | 504 | unsigned long flags; |
@@ -710,8 +718,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) | |||
710 | p->index); | 718 | p->index); |
711 | ret = IRQ_HANDLED; | 719 | ret = IRQ_HANDLED; |
712 | } | 720 | } |
713 | pci_read_config_word(sabre_root_bus->self, | 721 | pci_bus_read_config_word(sabre_root_bus, 0, |
714 | PCI_STATUS, &stat); | 722 | PCI_STATUS, &stat); |
715 | if (stat & (PCI_STATUS_PARITY | | 723 | if (stat & (PCI_STATUS_PARITY | |
716 | PCI_STATUS_SIG_TARGET_ABORT | | 724 | PCI_STATUS_SIG_TARGET_ABORT | |
717 | PCI_STATUS_REC_TARGET_ABORT | | 725 | PCI_STATUS_REC_TARGET_ABORT | |
@@ -719,8 +727,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) | |||
719 | PCI_STATUS_SIG_SYSTEM_ERROR)) { | 727 | PCI_STATUS_SIG_SYSTEM_ERROR)) { |
720 | printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n", | 728 | printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n", |
721 | p->index, stat); | 729 | p->index, stat); |
722 | pci_write_config_word(sabre_root_bus->self, | 730 | pci_bus_write_config_word(sabre_root_bus, 0, |
723 | PCI_STATUS, 0xffff); | 731 | PCI_STATUS, 0xffff); |
724 | ret = IRQ_HANDLED; | 732 | ret = IRQ_HANDLED; |
725 | } | 733 | } |
726 | return ret; | 734 | return ret; |
@@ -800,12 +808,10 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | |||
800 | if (error_bits & (SABRE_PIOAFSR_PTA | SABRE_PIOAFSR_STA)) { | 808 | if (error_bits & (SABRE_PIOAFSR_PTA | SABRE_PIOAFSR_STA)) { |
801 | sabre_check_iommu_error(p, afsr, afar); | 809 | sabre_check_iommu_error(p, afsr, afar); |
802 | pci_scan_for_target_abort(p, &p->pbm_A, p->pbm_A.pci_bus); | 810 | pci_scan_for_target_abort(p, &p->pbm_A, p->pbm_A.pci_bus); |
803 | pci_scan_for_target_abort(p, &p->pbm_B, p->pbm_B.pci_bus); | ||
804 | } | 811 | } |
805 | if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) { | 812 | if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) |
806 | pci_scan_for_master_abort(p, &p->pbm_A, p->pbm_A.pci_bus); | 813 | pci_scan_for_master_abort(p, &p->pbm_A, p->pbm_A.pci_bus); |
807 | pci_scan_for_master_abort(p, &p->pbm_B, p->pbm_B.pci_bus); | 814 | |
808 | } | ||
809 | /* For excessive retries, SABRE/PBM will abort the device | 815 | /* For excessive retries, SABRE/PBM will abort the device |
810 | * and there is no way to specifically check for excessive | 816 | * and there is no way to specifically check for excessive |
811 | * retries in the config space status registers. So what | 817 | * retries in the config space status registers. So what |
@@ -813,10 +819,8 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) | |||
813 | * abort events. | 819 | * abort events. |
814 | */ | 820 | */ |
815 | 821 | ||
816 | if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) { | 822 | if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) |
817 | pci_scan_for_parity_error(p, &p->pbm_A, p->pbm_A.pci_bus); | 823 | pci_scan_for_parity_error(p, &p->pbm_A, p->pbm_A.pci_bus); |
818 | pci_scan_for_parity_error(p, &p->pbm_B, p->pbm_B.pci_bus); | ||
819 | } | ||
820 | 824 | ||
821 | return IRQ_HANDLED; | 825 | return IRQ_HANDLED; |
822 | } | 826 | } |
@@ -869,144 +873,52 @@ static void sabre_register_error_handlers(struct pci_controller_info *p) | |||
869 | sabre_write(base + SABRE_PCICTRL, tmp); | 873 | sabre_write(base + SABRE_PCICTRL, tmp); |
870 | } | 874 | } |
871 | 875 | ||
872 | static void sabre_resource_adjust(struct pci_dev *pdev, | ||
873 | struct resource *res, | ||
874 | struct resource *root) | ||
875 | { | ||
876 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | ||
877 | unsigned long base; | ||
878 | |||
879 | if (res->flags & IORESOURCE_IO) | ||
880 | base = pbm->controller_regs + SABRE_IOSPACE; | ||
881 | else | ||
882 | base = pbm->controller_regs + SABRE_MEMSPACE; | ||
883 | |||
884 | res->start += base; | ||
885 | res->end += base; | ||
886 | } | ||
887 | |||
888 | static void sabre_base_address_update(struct pci_dev *pdev, int resource) | ||
889 | { | ||
890 | struct pcidev_cookie *pcp = pdev->sysdata; | ||
891 | struct pci_pbm_info *pbm = pcp->pbm; | ||
892 | struct resource *res; | ||
893 | unsigned long base; | ||
894 | u32 reg; | ||
895 | int where, size, is_64bit; | ||
896 | |||
897 | res = &pdev->resource[resource]; | ||
898 | if (resource < 6) { | ||
899 | where = PCI_BASE_ADDRESS_0 + (resource * 4); | ||
900 | } else if (resource == PCI_ROM_RESOURCE) { | ||
901 | where = pdev->rom_base_reg; | ||
902 | } else { | ||
903 | /* Somebody might have asked allocation of a non-standard resource */ | ||
904 | return; | ||
905 | } | ||
906 | |||
907 | is_64bit = 0; | ||
908 | if (res->flags & IORESOURCE_IO) | ||
909 | base = pbm->controller_regs + SABRE_IOSPACE; | ||
910 | else { | ||
911 | base = pbm->controller_regs + SABRE_MEMSPACE; | ||
912 | if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) | ||
913 | == PCI_BASE_ADDRESS_MEM_TYPE_64) | ||
914 | is_64bit = 1; | ||
915 | } | ||
916 | |||
917 | size = res->end - res->start; | ||
918 | pci_read_config_dword(pdev, where, ®); | ||
919 | reg = ((reg & size) | | ||
920 | (((u32)(res->start - base)) & ~size)); | ||
921 | if (resource == PCI_ROM_RESOURCE) { | ||
922 | reg |= PCI_ROM_ADDRESS_ENABLE; | ||
923 | res->flags |= IORESOURCE_ROM_ENABLE; | ||
924 | } | ||
925 | pci_write_config_dword(pdev, where, reg); | ||
926 | |||
927 | /* This knows that the upper 32-bits of the address | ||
928 | * must be zero. Our PCI common layer enforces this. | ||
929 | */ | ||
930 | if (is_64bit) | ||
931 | pci_write_config_dword(pdev, where + 4, 0); | ||
932 | } | ||
933 | |||
934 | static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) | 876 | static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) |
935 | { | 877 | { |
936 | struct pci_dev *pdev; | 878 | struct pci_dev *pdev; |
937 | 879 | ||
938 | list_for_each_entry(pdev, &sabre_bus->devices, bus_list) { | 880 | list_for_each_entry(pdev, &sabre_bus->devices, bus_list) { |
939 | |||
940 | if (pdev->vendor == PCI_VENDOR_ID_SUN && | 881 | if (pdev->vendor == PCI_VENDOR_ID_SUN && |
941 | pdev->device == PCI_DEVICE_ID_SUN_SIMBA) { | 882 | pdev->device == PCI_DEVICE_ID_SUN_SIMBA) { |
942 | u32 word32; | ||
943 | u16 word16; | 883 | u16 word16; |
944 | 884 | ||
945 | sabre_read_pci_cfg(pdev->bus, pdev->devfn, | 885 | pci_read_config_word(pdev, PCI_COMMAND, &word16); |
946 | PCI_COMMAND, 2, &word32); | ||
947 | word16 = (u16) word32; | ||
948 | word16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | | 886 | word16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | |
949 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | | 887 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | |
950 | PCI_COMMAND_IO; | 888 | PCI_COMMAND_IO; |
951 | word32 = (u32) word16; | 889 | pci_write_config_word(pdev, PCI_COMMAND, word16); |
952 | sabre_write_pci_cfg(pdev->bus, pdev->devfn, | ||
953 | PCI_COMMAND, 2, word32); | ||
954 | 890 | ||
955 | /* Status register bits are "write 1 to clear". */ | 891 | /* Status register bits are "write 1 to clear". */ |
956 | sabre_write_pci_cfg(pdev->bus, pdev->devfn, | 892 | pci_write_config_word(pdev, PCI_STATUS, 0xffff); |
957 | PCI_STATUS, 2, 0xffff); | 893 | pci_write_config_word(pdev, PCI_SEC_STATUS, 0xffff); |
958 | sabre_write_pci_cfg(pdev->bus, pdev->devfn, | ||
959 | PCI_SEC_STATUS, 2, 0xffff); | ||
960 | 894 | ||
961 | /* Use a primary/seconday latency timer value | 895 | /* Use a primary/seconday latency timer value |
962 | * of 64. | 896 | * of 64. |
963 | */ | 897 | */ |
964 | sabre_write_pci_cfg(pdev->bus, pdev->devfn, | 898 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64); |
965 | PCI_LATENCY_TIMER, 1, 64); | 899 | pci_write_config_byte(pdev, PCI_SEC_LATENCY_TIMER, 64); |
966 | sabre_write_pci_cfg(pdev->bus, pdev->devfn, | ||
967 | PCI_SEC_LATENCY_TIMER, 1, 64); | ||
968 | 900 | ||
969 | /* Enable reporting/forwarding of master aborts, | 901 | /* Enable reporting/forwarding of master aborts, |
970 | * parity, and SERR. | 902 | * parity, and SERR. |
971 | */ | 903 | */ |
972 | sabre_write_pci_cfg(pdev->bus, pdev->devfn, | 904 | pci_write_config_byte(pdev, PCI_BRIDGE_CONTROL, |
973 | PCI_BRIDGE_CONTROL, 1, | 905 | (PCI_BRIDGE_CTL_PARITY | |
974 | (PCI_BRIDGE_CTL_PARITY | | 906 | PCI_BRIDGE_CTL_SERR | |
975 | PCI_BRIDGE_CTL_SERR | | 907 | PCI_BRIDGE_CTL_MASTER_ABORT)); |
976 | PCI_BRIDGE_CTL_MASTER_ABORT)); | ||
977 | } | 908 | } |
978 | } | 909 | } |
979 | } | 910 | } |
980 | 911 | ||
981 | static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm) | ||
982 | { | ||
983 | struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); | ||
984 | |||
985 | if (!cookie) { | ||
986 | prom_printf("SABRE: Critical allocation failure.\n"); | ||
987 | prom_halt(); | ||
988 | } | ||
989 | |||
990 | /* All we care about is the PBM. */ | ||
991 | cookie->pbm = pbm; | ||
992 | |||
993 | return cookie; | ||
994 | } | ||
995 | |||
996 | static void sabre_scan_bus(struct pci_controller_info *p) | 912 | static void sabre_scan_bus(struct pci_controller_info *p) |
997 | { | 913 | { |
998 | static int once; | 914 | static int once; |
999 | struct pci_bus *sabre_bus, *pbus; | 915 | struct pci_bus *pbus; |
1000 | struct pci_pbm_info *pbm; | ||
1001 | struct pcidev_cookie *cookie; | ||
1002 | int sabres_scanned; | ||
1003 | 916 | ||
1004 | /* The APB bridge speaks to the Sabre host PCI bridge | 917 | /* The APB bridge speaks to the Sabre host PCI bridge |
1005 | * at 66Mhz, but the front side of APB runs at 33Mhz | 918 | * at 66Mhz, but the front side of APB runs at 33Mhz |
1006 | * for both segments. | 919 | * for both segments. |
1007 | */ | 920 | */ |
1008 | p->pbm_A.is_66mhz_capable = 0; | 921 | p->pbm_A.is_66mhz_capable = 0; |
1009 | p->pbm_B.is_66mhz_capable = 0; | ||
1010 | 922 | ||
1011 | /* This driver has not been verified to handle | 923 | /* This driver has not been verified to handle |
1012 | * multiple SABREs yet, so trap this. | 924 | * multiple SABREs yet, so trap this. |
@@ -1020,56 +932,13 @@ static void sabre_scan_bus(struct pci_controller_info *p) | |||
1020 | } | 932 | } |
1021 | once++; | 933 | once++; |
1022 | 934 | ||
1023 | cookie = alloc_bridge_cookie(&p->pbm_A); | 935 | pbus = pci_scan_one_pbm(&p->pbm_A); |
1024 | 936 | if (!pbus) | |
1025 | sabre_bus = pci_scan_bus(p->pci_first_busno, | 937 | return; |
1026 | p->pci_ops, | ||
1027 | &p->pbm_A); | ||
1028 | pci_fixup_host_bridge_self(sabre_bus); | ||
1029 | sabre_bus->self->sysdata = cookie; | ||
1030 | |||
1031 | sabre_root_bus = sabre_bus; | ||
1032 | |||
1033 | apb_init(p, sabre_bus); | ||
1034 | |||
1035 | sabres_scanned = 0; | ||
1036 | |||
1037 | list_for_each_entry(pbus, &sabre_bus->children, node) { | ||
1038 | |||
1039 | if (pbus->number == p->pbm_A.pci_first_busno) { | ||
1040 | pbm = &p->pbm_A; | ||
1041 | } else if (pbus->number == p->pbm_B.pci_first_busno) { | ||
1042 | pbm = &p->pbm_B; | ||
1043 | } else | ||
1044 | continue; | ||
1045 | |||
1046 | cookie = alloc_bridge_cookie(pbm); | ||
1047 | pbus->self->sysdata = cookie; | ||
1048 | |||
1049 | sabres_scanned++; | ||
1050 | 938 | ||
1051 | pbus->sysdata = pbm; | 939 | sabre_root_bus = pbus; |
1052 | pbm->pci_bus = pbus; | ||
1053 | pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node); | ||
1054 | pci_record_assignments(pbm, pbus); | ||
1055 | pci_assign_unassigned(pbm, pbus); | ||
1056 | pci_fixup_irq(pbm, pbus); | ||
1057 | pci_determine_66mhz_disposition(pbm, pbus); | ||
1058 | pci_setup_busmastering(pbm, pbus); | ||
1059 | } | ||
1060 | 940 | ||
1061 | if (!sabres_scanned) { | 941 | apb_init(p, pbus); |
1062 | /* Hummingbird, no APBs. */ | ||
1063 | pbm = &p->pbm_A; | ||
1064 | sabre_bus->sysdata = pbm; | ||
1065 | pbm->pci_bus = sabre_bus; | ||
1066 | pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node); | ||
1067 | pci_record_assignments(pbm, sabre_bus); | ||
1068 | pci_assign_unassigned(pbm, sabre_bus); | ||
1069 | pci_fixup_irq(pbm, sabre_bus); | ||
1070 | pci_determine_66mhz_disposition(pbm, sabre_bus); | ||
1071 | pci_setup_busmastering(pbm, sabre_bus); | ||
1072 | } | ||
1073 | 942 | ||
1074 | sabre_register_error_handlers(p); | 943 | sabre_register_error_handlers(p); |
1075 | } | 944 | } |
@@ -1078,7 +947,7 @@ static void sabre_iommu_init(struct pci_controller_info *p, | |||
1078 | int tsbsize, unsigned long dvma_offset, | 947 | int tsbsize, unsigned long dvma_offset, |
1079 | u32 dma_mask) | 948 | u32 dma_mask) |
1080 | { | 949 | { |
1081 | struct pci_iommu *iommu = p->pbm_A.iommu; | 950 | struct iommu *iommu = p->pbm_A.iommu; |
1082 | unsigned long i; | 951 | unsigned long i; |
1083 | u64 control; | 952 | u64 control; |
1084 | 953 | ||
@@ -1126,224 +995,31 @@ static void sabre_iommu_init(struct pci_controller_info *p, | |||
1126 | sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); | 995 | sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); |
1127 | } | 996 | } |
1128 | 997 | ||
1129 | static void pbm_register_toplevel_resources(struct pci_controller_info *p, | 998 | static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp) |
1130 | struct pci_pbm_info *pbm) | ||
1131 | { | ||
1132 | char *name = pbm->name; | ||
1133 | unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE; | ||
1134 | unsigned long mbase = p->pbm_A.controller_regs + SABRE_MEMSPACE; | ||
1135 | unsigned int devfn; | ||
1136 | unsigned long first, last, i; | ||
1137 | u8 *addr, map; | ||
1138 | |||
1139 | sprintf(name, "SABRE%d PBM%c", | ||
1140 | p->index, | ||
1141 | (pbm == &p->pbm_A ? 'A' : 'B')); | ||
1142 | pbm->io_space.name = pbm->mem_space.name = name; | ||
1143 | |||
1144 | devfn = PCI_DEVFN(1, (pbm == &p->pbm_A) ? 0 : 1); | ||
1145 | addr = sabre_pci_config_mkaddr(pbm, 0, devfn, APB_IO_ADDRESS_MAP); | ||
1146 | map = 0; | ||
1147 | pci_config_read8(addr, &map); | ||
1148 | |||
1149 | first = 8; | ||
1150 | last = 0; | ||
1151 | for (i = 0; i < 8; i++) { | ||
1152 | if ((map & (1 << i)) != 0) { | ||
1153 | if (first > i) | ||
1154 | first = i; | ||
1155 | if (last < i) | ||
1156 | last = i; | ||
1157 | } | ||
1158 | } | ||
1159 | pbm->io_space.start = ibase + (first << 21UL); | ||
1160 | pbm->io_space.end = ibase + (last << 21UL) + ((1 << 21UL) - 1); | ||
1161 | pbm->io_space.flags = IORESOURCE_IO; | ||
1162 | |||
1163 | addr = sabre_pci_config_mkaddr(pbm, 0, devfn, APB_MEM_ADDRESS_MAP); | ||
1164 | map = 0; | ||
1165 | pci_config_read8(addr, &map); | ||
1166 | |||
1167 | first = 8; | ||
1168 | last = 0; | ||
1169 | for (i = 0; i < 8; i++) { | ||
1170 | if ((map & (1 << i)) != 0) { | ||
1171 | if (first > i) | ||
1172 | first = i; | ||
1173 | if (last < i) | ||
1174 | last = i; | ||
1175 | } | ||
1176 | } | ||
1177 | pbm->mem_space.start = mbase + (first << 29UL); | ||
1178 | pbm->mem_space.end = mbase + (last << 29UL) + ((1 << 29UL) - 1); | ||
1179 | pbm->mem_space.flags = IORESOURCE_MEM; | ||
1180 | |||
1181 | if (request_resource(&ioport_resource, &pbm->io_space) < 0) { | ||
1182 | prom_printf("Cannot register PBM-%c's IO space.\n", | ||
1183 | (pbm == &p->pbm_A ? 'A' : 'B')); | ||
1184 | prom_halt(); | ||
1185 | } | ||
1186 | if (request_resource(&iomem_resource, &pbm->mem_space) < 0) { | ||
1187 | prom_printf("Cannot register PBM-%c's MEM space.\n", | ||
1188 | (pbm == &p->pbm_A ? 'A' : 'B')); | ||
1189 | prom_halt(); | ||
1190 | } | ||
1191 | |||
1192 | /* Register legacy regions if this PBM covers that area. */ | ||
1193 | if (pbm->io_space.start == ibase && | ||
1194 | pbm->mem_space.start == mbase) | ||
1195 | pci_register_legacy_regions(&pbm->io_space, | ||
1196 | &pbm->mem_space); | ||
1197 | } | ||
1198 | |||
1199 | static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end) | ||
1200 | { | 999 | { |
1201 | struct pci_pbm_info *pbm; | 1000 | struct pci_pbm_info *pbm; |
1202 | struct device_node *node; | ||
1203 | struct property *prop; | ||
1204 | u32 *busrange; | ||
1205 | int len, simbas_found; | ||
1206 | |||
1207 | simbas_found = 0; | ||
1208 | node = dp->child; | ||
1209 | while (node != NULL) { | ||
1210 | if (strcmp(node->name, "pci")) | ||
1211 | goto next_pci; | ||
1212 | |||
1213 | prop = of_find_property(node, "model", NULL); | ||
1214 | if (!prop || strncmp(prop->value, "SUNW,simba", prop->length)) | ||
1215 | goto next_pci; | ||
1216 | |||
1217 | simbas_found++; | ||
1218 | |||
1219 | prop = of_find_property(node, "bus-range", NULL); | ||
1220 | busrange = prop->value; | ||
1221 | if (busrange[0] == 1) | ||
1222 | pbm = &p->pbm_B; | ||
1223 | else | ||
1224 | pbm = &p->pbm_A; | ||
1225 | |||
1226 | pbm->name = node->full_name; | ||
1227 | printk("%s: SABRE PCI Bus Module\n", pbm->name); | ||
1228 | |||
1229 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; | ||
1230 | pbm->parent = p; | ||
1231 | pbm->prom_node = node; | ||
1232 | pbm->pci_first_slot = 1; | ||
1233 | pbm->pci_first_busno = busrange[0]; | ||
1234 | pbm->pci_last_busno = busrange[1]; | ||
1235 | |||
1236 | prop = of_find_property(node, "ranges", &len); | ||
1237 | if (prop) { | ||
1238 | pbm->pbm_ranges = prop->value; | ||
1239 | pbm->num_pbm_ranges = | ||
1240 | (len / sizeof(struct linux_prom_pci_ranges)); | ||
1241 | } else { | ||
1242 | pbm->num_pbm_ranges = 0; | ||
1243 | } | ||
1244 | 1001 | ||
1245 | prop = of_find_property(node, "interrupt-map", &len); | 1002 | pbm = &p->pbm_A; |
1246 | if (prop) { | 1003 | pbm->name = dp->full_name; |
1247 | pbm->pbm_intmap = prop->value; | 1004 | printk("%s: SABRE PCI Bus Module\n", pbm->name); |
1248 | pbm->num_pbm_intmap = | ||
1249 | (len / sizeof(struct linux_prom_pci_intmap)); | ||
1250 | |||
1251 | prop = of_find_property(node, "interrupt-map-mask", | ||
1252 | NULL); | ||
1253 | pbm->pbm_intmask = prop->value; | ||
1254 | } else { | ||
1255 | pbm->num_pbm_intmap = 0; | ||
1256 | } | ||
1257 | 1005 | ||
1258 | pbm_register_toplevel_resources(p, pbm); | 1006 | pbm->chip_type = PBM_CHIP_TYPE_SABRE; |
1259 | 1007 | pbm->parent = p; | |
1260 | next_pci: | 1008 | pbm->prom_node = dp; |
1261 | node = node->sibling; | 1009 | pbm->pci_first_busno = p->pci_first_busno; |
1262 | } | 1010 | pbm->pci_last_busno = p->pci_last_busno; |
1263 | if (simbas_found == 0) { | ||
1264 | struct resource *rp; | ||
1265 | 1011 | ||
1266 | /* No APBs underneath, probably this is a hummingbird | 1012 | pci_determine_mem_io_space(pbm); |
1267 | * system. | ||
1268 | */ | ||
1269 | pbm = &p->pbm_A; | ||
1270 | pbm->parent = p; | ||
1271 | pbm->prom_node = dp; | ||
1272 | pbm->pci_first_busno = p->pci_first_busno; | ||
1273 | pbm->pci_last_busno = p->pci_last_busno; | ||
1274 | |||
1275 | prop = of_find_property(dp, "ranges", &len); | ||
1276 | if (prop) { | ||
1277 | pbm->pbm_ranges = prop->value; | ||
1278 | pbm->num_pbm_ranges = | ||
1279 | (len / sizeof(struct linux_prom_pci_ranges)); | ||
1280 | } else { | ||
1281 | pbm->num_pbm_ranges = 0; | ||
1282 | } | ||
1283 | |||
1284 | prop = of_find_property(dp, "interrupt-map", &len); | ||
1285 | if (prop) { | ||
1286 | pbm->pbm_intmap = prop->value; | ||
1287 | pbm->num_pbm_intmap = | ||
1288 | (len / sizeof(struct linux_prom_pci_intmap)); | ||
1289 | |||
1290 | prop = of_find_property(dp, "interrupt-map-mask", | ||
1291 | NULL); | ||
1292 | pbm->pbm_intmask = prop->value; | ||
1293 | } else { | ||
1294 | pbm->num_pbm_intmap = 0; | ||
1295 | } | ||
1296 | |||
1297 | pbm->name = dp->full_name; | ||
1298 | printk("%s: SABRE PCI Bus Module\n", pbm->name); | ||
1299 | |||
1300 | pbm->io_space.name = pbm->mem_space.name = pbm->name; | ||
1301 | |||
1302 | /* Hack up top-level resources. */ | ||
1303 | pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE; | ||
1304 | pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; | ||
1305 | pbm->io_space.flags = IORESOURCE_IO; | ||
1306 | |||
1307 | pbm->mem_space.start = | ||
1308 | (p->pbm_A.controller_regs + SABRE_MEMSPACE); | ||
1309 | pbm->mem_space.end = | ||
1310 | (pbm->mem_space.start + ((1UL << 32UL) - 1UL)); | ||
1311 | pbm->mem_space.flags = IORESOURCE_MEM; | ||
1312 | |||
1313 | if (request_resource(&ioport_resource, &pbm->io_space) < 0) { | ||
1314 | prom_printf("Cannot register Hummingbird's IO space.\n"); | ||
1315 | prom_halt(); | ||
1316 | } | ||
1317 | if (request_resource(&iomem_resource, &pbm->mem_space) < 0) { | ||
1318 | prom_printf("Cannot register Hummingbird's MEM space.\n"); | ||
1319 | prom_halt(); | ||
1320 | } | ||
1321 | |||
1322 | rp = kmalloc(sizeof(*rp), GFP_KERNEL); | ||
1323 | if (!rp) { | ||
1324 | prom_printf("Cannot allocate IOMMU resource.\n"); | ||
1325 | prom_halt(); | ||
1326 | } | ||
1327 | rp->name = "IOMMU"; | ||
1328 | rp->start = pbm->mem_space.start + (unsigned long) dma_start; | ||
1329 | rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL; | ||
1330 | rp->flags = IORESOURCE_BUSY; | ||
1331 | request_resource(&pbm->mem_space, rp); | ||
1332 | |||
1333 | pci_register_legacy_regions(&pbm->io_space, | ||
1334 | &pbm->mem_space); | ||
1335 | } | ||
1336 | } | 1013 | } |
1337 | 1014 | ||
1338 | void sabre_init(struct device_node *dp, char *model_name) | 1015 | void sabre_init(struct device_node *dp, char *model_name) |
1339 | { | 1016 | { |
1340 | struct linux_prom64_registers *pr_regs; | 1017 | const struct linux_prom64_registers *pr_regs; |
1341 | struct pci_controller_info *p; | 1018 | struct pci_controller_info *p; |
1342 | struct pci_iommu *iommu; | 1019 | struct iommu *iommu; |
1343 | struct property *prop; | ||
1344 | int tsbsize; | 1020 | int tsbsize; |
1345 | u32 *busrange; | 1021 | const u32 *busrange; |
1346 | u32 *vdma; | 1022 | const u32 *vdma; |
1347 | u32 upa_portid, dma_mask; | 1023 | u32 upa_portid, dma_mask; |
1348 | u64 clear_irq; | 1024 | u64 clear_irq; |
1349 | 1025 | ||
@@ -1351,13 +1027,9 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1351 | if (!strcmp(model_name, "pci108e,a001")) | 1027 | if (!strcmp(model_name, "pci108e,a001")) |
1352 | hummingbird_p = 1; | 1028 | hummingbird_p = 1; |
1353 | else if (!strcmp(model_name, "SUNW,sabre")) { | 1029 | else if (!strcmp(model_name, "SUNW,sabre")) { |
1354 | prop = of_find_property(dp, "compatible", NULL); | 1030 | const char *compat = of_get_property(dp, "compatible", NULL); |
1355 | if (prop) { | 1031 | if (compat && !strcmp(compat, "pci108e,a001")) |
1356 | const char *compat = prop->value; | 1032 | hummingbird_p = 1; |
1357 | |||
1358 | if (!strcmp(compat, "pci108e,a001")) | ||
1359 | hummingbird_p = 1; | ||
1360 | } | ||
1361 | if (!hummingbird_p) { | 1033 | if (!hummingbird_p) { |
1362 | struct device_node *dp; | 1034 | struct device_node *dp; |
1363 | 1035 | ||
@@ -1381,37 +1053,28 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1381 | prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n"); | 1053 | prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n"); |
1382 | prom_halt(); | 1054 | prom_halt(); |
1383 | } | 1055 | } |
1384 | p->pbm_A.iommu = p->pbm_B.iommu = iommu; | 1056 | p->pbm_A.iommu = iommu; |
1385 | 1057 | ||
1386 | upa_portid = 0xff; | 1058 | upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); |
1387 | prop = of_find_property(dp, "upa-portid", NULL); | ||
1388 | if (prop) | ||
1389 | upa_portid = *(u32 *) prop->value; | ||
1390 | 1059 | ||
1391 | p->next = pci_controller_root; | 1060 | p->next = pci_controller_root; |
1392 | pci_controller_root = p; | 1061 | pci_controller_root = p; |
1393 | 1062 | ||
1394 | p->pbm_A.portid = upa_portid; | 1063 | p->pbm_A.portid = upa_portid; |
1395 | p->pbm_B.portid = upa_portid; | ||
1396 | p->index = pci_num_controllers++; | 1064 | p->index = pci_num_controllers++; |
1397 | p->pbms_same_domain = 1; | ||
1398 | p->scan_bus = sabre_scan_bus; | 1065 | p->scan_bus = sabre_scan_bus; |
1399 | p->base_address_update = sabre_base_address_update; | ||
1400 | p->resource_adjust = sabre_resource_adjust; | ||
1401 | p->pci_ops = &sabre_ops; | 1066 | p->pci_ops = &sabre_ops; |
1402 | 1067 | ||
1403 | /* | 1068 | /* |
1404 | * Map in SABRE register set and report the presence of this SABRE. | 1069 | * Map in SABRE register set and report the presence of this SABRE. |
1405 | */ | 1070 | */ |
1406 | 1071 | ||
1407 | prop = of_find_property(dp, "reg", NULL); | 1072 | pr_regs = of_get_property(dp, "reg", NULL); |
1408 | pr_regs = prop->value; | ||
1409 | 1073 | ||
1410 | /* | 1074 | /* |
1411 | * First REG in property is base of entire SABRE register space. | 1075 | * First REG in property is base of entire SABRE register space. |
1412 | */ | 1076 | */ |
1413 | p->pbm_A.controller_regs = pr_regs[0].phys_addr; | 1077 | p->pbm_A.controller_regs = pr_regs[0].phys_addr; |
1414 | p->pbm_B.controller_regs = pr_regs[0].phys_addr; | ||
1415 | 1078 | ||
1416 | /* Clear interrupts */ | 1079 | /* Clear interrupts */ |
1417 | 1080 | ||
@@ -1429,11 +1092,10 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1429 | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); | 1092 | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); |
1430 | 1093 | ||
1431 | /* Now map in PCI config space for entire SABRE. */ | 1094 | /* Now map in PCI config space for entire SABRE. */ |
1432 | p->pbm_A.config_space = p->pbm_B.config_space = | 1095 | p->pbm_A.config_space = |
1433 | (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); | 1096 | (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); |
1434 | 1097 | ||
1435 | prop = of_find_property(dp, "virtual-dma", NULL); | 1098 | vdma = of_get_property(dp, "virtual-dma", NULL); |
1436 | vdma = prop->value; | ||
1437 | 1099 | ||
1438 | dma_mask = vdma[0]; | 1100 | dma_mask = vdma[0]; |
1439 | switch(vdma[1]) { | 1101 | switch(vdma[1]) { |
@@ -1457,13 +1119,12 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
1457 | 1119 | ||
1458 | sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); | 1120 | sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); |
1459 | 1121 | ||
1460 | prop = of_find_property(dp, "bus-range", NULL); | 1122 | busrange = of_get_property(dp, "bus-range", NULL); |
1461 | busrange = prop->value; | ||
1462 | p->pci_first_busno = busrange[0]; | 1123 | p->pci_first_busno = busrange[0]; |
1463 | p->pci_last_busno = busrange[1]; | 1124 | p->pci_last_busno = busrange[1]; |
1464 | 1125 | ||
1465 | /* | 1126 | /* |
1466 | * Look for APB underneath. | 1127 | * Look for APB underneath. |
1467 | */ | 1128 | */ |
1468 | sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]); | 1129 | sabre_pbm_init(p, dp); |
1469 | } | 1130 | } |