diff options
Diffstat (limited to 'arch/sparc64/kernel/pci_psycho.c')
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index b6f073ed31d4..8ef808348993 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -98,13 +98,8 @@ static int psycho_out_of_range(struct pci_pbm_info *pbm, | |||
98 | unsigned char bus, | 98 | unsigned char bus, |
99 | unsigned char devfn) | 99 | unsigned char devfn) |
100 | { | 100 | { |
101 | return ((pbm->parent == 0) || | 101 | return ((bus == pbm->pci_first_busno) && |
102 | ((pbm == &pbm->parent->pbm_B) && | 102 | PCI_SLOT(devfn) > 8); |
103 | (bus == pbm->pci_first_busno) && | ||
104 | PCI_SLOT(devfn) > 8) || | ||
105 | ((pbm == &pbm->parent->pbm_A) && | ||
106 | (bus == pbm->pci_first_busno) && | ||
107 | PCI_SLOT(devfn) > 8)); | ||
108 | } | 103 | } |
109 | 104 | ||
110 | /* PSYCHO PCI configuration space accessors. */ | 105 | /* PSYCHO PCI configuration space accessors. */ |
@@ -918,33 +913,33 @@ static void psycho_scan_bus(struct pci_pbm_info *pbm) | |||
918 | psycho_register_error_handlers(pbm); | 913 | psycho_register_error_handlers(pbm); |
919 | } | 914 | } |
920 | 915 | ||
921 | static void psycho_iommu_init(struct pci_controller_info *p) | 916 | static void psycho_iommu_init(struct pci_pbm_info *pbm) |
922 | { | 917 | { |
923 | struct iommu *iommu = p->pbm_A.iommu; | 918 | struct iommu *iommu = pbm->iommu; |
924 | unsigned long i; | 919 | unsigned long i; |
925 | u64 control; | 920 | u64 control; |
926 | 921 | ||
927 | /* Register addresses. */ | 922 | /* Register addresses. */ |
928 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; | 923 | iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL; |
929 | iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE; | 924 | iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE; |
930 | iommu->iommu_flush = p->pbm_A.controller_regs + PSYCHO_IOMMU_FLUSH; | 925 | iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH; |
931 | /* PSYCHO's IOMMU lacks ctx flushing. */ | 926 | /* PSYCHO's IOMMU lacks ctx flushing. */ |
932 | iommu->iommu_ctxflush = 0; | 927 | iommu->iommu_ctxflush = 0; |
933 | 928 | ||
934 | /* We use the main control register of PSYCHO as the write | 929 | /* We use the main control register of PSYCHO as the write |
935 | * completion register. | 930 | * completion register. |
936 | */ | 931 | */ |
937 | iommu->write_complete_reg = p->pbm_A.controller_regs + PSYCHO_CONTROL; | 932 | iommu->write_complete_reg = pbm->controller_regs + PSYCHO_CONTROL; |
938 | 933 | ||
939 | /* | 934 | /* |
940 | * Invalidate TLB Entries. | 935 | * Invalidate TLB Entries. |
941 | */ | 936 | */ |
942 | control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); | 937 | control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL); |
943 | control |= PSYCHO_IOMMU_CTRL_DENAB; | 938 | control |= PSYCHO_IOMMU_CTRL_DENAB; |
944 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); | 939 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control); |
945 | for(i = 0; i < 16; i++) { | 940 | for(i = 0; i < 16; i++) { |
946 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); | 941 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); |
947 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); | 942 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); |
948 | } | 943 | } |
949 | 944 | ||
950 | /* Leave diag mode enabled for full-flushing done | 945 | /* Leave diag mode enabled for full-flushing done |
@@ -952,17 +947,17 @@ static void psycho_iommu_init(struct pci_controller_info *p) | |||
952 | */ | 947 | */ |
953 | pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff); | 948 | pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff); |
954 | 949 | ||
955 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, | 950 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE, |
956 | __pa(iommu->page_table)); | 951 | __pa(iommu->page_table)); |
957 | 952 | ||
958 | control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); | 953 | control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL); |
959 | control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); | 954 | control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); |
960 | control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB); | 955 | control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB); |
961 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); | 956 | psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control); |
962 | 957 | ||
963 | /* If necessary, hook us up for starfire IRQ translations. */ | 958 | /* If necessary, hook us up for starfire IRQ translations. */ |
964 | if (this_is_starfire) | 959 | if (this_is_starfire) |
965 | starfire_hookup(p->pbm_A.portid); | 960 | starfire_hookup(pbm->portid); |
966 | } | 961 | } |
967 | 962 | ||
968 | #define PSYCHO_IRQ_RETRY 0x1a00UL | 963 | #define PSYCHO_IRQ_RETRY 0x1a00UL |
@@ -977,36 +972,35 @@ static void psycho_iommu_init(struct pci_controller_info *p) | |||
977 | #define PSYCHO_PCIDIAG_IPAPAR 0x0000000000000002UL /* Invert PIO address parity */ | 972 | #define PSYCHO_PCIDIAG_IPAPAR 0x0000000000000002UL /* Invert PIO address parity */ |
978 | #define PSYCHO_PCIDIAG_LPBACK 0x0000000000000001UL /* Enable loopback mode */ | 973 | #define PSYCHO_PCIDIAG_LPBACK 0x0000000000000001UL /* Enable loopback mode */ |
979 | 974 | ||
980 | static void psycho_controller_hwinit(struct pci_controller_info *p) | 975 | static void psycho_controller_hwinit(struct pci_pbm_info *pbm) |
981 | { | 976 | { |
982 | u64 tmp; | 977 | u64 tmp; |
983 | 978 | ||
984 | psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5); | 979 | psycho_write(pbm->controller_regs + PSYCHO_IRQ_RETRY, 5); |
985 | 980 | ||
986 | /* Enable arbiter for all PCI slots. */ | 981 | /* Enable arbiter for all PCI slots. */ |
987 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); | 982 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIA_CTRL); |
988 | tmp |= PSYCHO_PCICTRL_AEN; | 983 | tmp |= PSYCHO_PCICTRL_AEN; |
989 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL, tmp); | 984 | psycho_write(pbm->controller_regs + PSYCHO_PCIA_CTRL, tmp); |
990 | 985 | ||
991 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL); | 986 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIB_CTRL); |
992 | tmp |= PSYCHO_PCICTRL_AEN; | 987 | tmp |= PSYCHO_PCICTRL_AEN; |
993 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL, tmp); | 988 | psycho_write(pbm->controller_regs + PSYCHO_PCIB_CTRL, tmp); |
994 | 989 | ||
995 | /* Disable DMA write / PIO read synchronization on | 990 | /* Disable DMA write / PIO read synchronization on |
996 | * both PCI bus segments. | 991 | * both PCI bus segments. |
997 | * [ U2P Erratum 1243770, STP2223BGA data sheet ] | 992 | * [ U2P Erratum 1243770, STP2223BGA data sheet ] |
998 | */ | 993 | */ |
999 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG); | 994 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIA_DIAG); |
1000 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; | 995 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; |
1001 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG, tmp); | 996 | psycho_write(pbm->controller_regs + PSYCHO_PCIA_DIAG, tmp); |
1002 | 997 | ||
1003 | tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG); | 998 | tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIB_DIAG); |
1004 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; | 999 | tmp |= PSYCHO_PCIDIAG_DDWSYNC; |
1005 | psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); | 1000 | psycho_write(pbm->controller_regs + PSYCHO_PCIB_DIAG, tmp); |
1006 | } | 1001 | } |
1007 | 1002 | ||
1008 | static void psycho_pbm_strbuf_init(struct pci_controller_info *p, | 1003 | static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, |
1009 | struct pci_pbm_info *pbm, | ||
1010 | int is_pbm_a) | 1004 | int is_pbm_a) |
1011 | { | 1005 | { |
1012 | unsigned long base = pbm->controller_regs; | 1006 | unsigned long base = pbm->controller_regs; |
@@ -1105,7 +1099,7 @@ static void psycho_pbm_init(struct pci_controller_info *p, | |||
1105 | 1099 | ||
1106 | pci_get_pbm_props(pbm); | 1100 | pci_get_pbm_props(pbm); |
1107 | 1101 | ||
1108 | psycho_pbm_strbuf_init(p, pbm, is_pbm_a); | 1102 | psycho_pbm_strbuf_init(pbm, is_pbm_a); |
1109 | } | 1103 | } |
1110 | 1104 | ||
1111 | #define PSYCHO_CONFIGSPACE 0x001000000UL | 1105 | #define PSYCHO_CONFIGSPACE 0x001000000UL |
@@ -1165,9 +1159,9 @@ void psycho_init(struct device_node *dp, char *model_name) | |||
1165 | */ | 1159 | */ |
1166 | pci_memspace_mask = 0x7fffffffUL; | 1160 | pci_memspace_mask = 0x7fffffffUL; |
1167 | 1161 | ||
1168 | psycho_controller_hwinit(p); | 1162 | psycho_controller_hwinit(&p->pbm_A); |
1169 | 1163 | ||
1170 | psycho_iommu_init(p); | 1164 | psycho_iommu_init(&p->pbm_A); |
1171 | 1165 | ||
1172 | is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); | 1166 | is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); |
1173 | psycho_pbm_init(p, dp, is_pbm_a); | 1167 | psycho_pbm_init(p, dp, is_pbm_a); |