1 |
1275 |
phoenix |
/* $Id: pci_sabre.c,v 1.1.1.1 2004-04-15 01:34:27 phoenix Exp $
|
2 |
|
|
* pci_sabre.c: Sabre specific PCI controller support.
|
3 |
|
|
*
|
4 |
|
|
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
|
5 |
|
|
* Copyright (C) 1998, 1999 Eddie C. Dost (ecd@skynet.be)
|
6 |
|
|
* Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
|
7 |
|
|
*/
|
8 |
|
|
|
9 |
|
|
#include <linux/kernel.h>
|
10 |
|
|
#include <linux/types.h>
|
11 |
|
|
#include <linux/pci.h>
|
12 |
|
|
#include <linux/init.h>
|
13 |
|
|
#include <linux/slab.h>
|
14 |
|
|
|
15 |
|
|
#include <asm/apb.h>
|
16 |
|
|
#include <asm/pbm.h>
|
17 |
|
|
#include <asm/iommu.h>
|
18 |
|
|
#include <asm/irq.h>
|
19 |
|
|
#include <asm/smp.h>
|
20 |
|
|
|
21 |
|
|
#include "pci_impl.h"
|
22 |
|
|
#include "iommu_common.h"
|
23 |
|
|
|
24 |
|
|
/* All SABRE registers are 64-bits. The following accessor
|
25 |
|
|
* routines are how they are accessed. The REG parameter
|
26 |
|
|
* is a physical address.
|
27 |
|
|
*/
|
28 |
|
|
#define sabre_read(__reg) \
|
29 |
|
|
({ u64 __ret; \
|
30 |
|
|
__asm__ __volatile__("ldxa [%1] %2, %0" \
|
31 |
|
|
: "=r" (__ret) \
|
32 |
|
|
: "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
|
33 |
|
|
: "memory"); \
|
34 |
|
|
__ret; \
|
35 |
|
|
})
|
36 |
|
|
#define sabre_write(__reg, __val) \
|
37 |
|
|
__asm__ __volatile__("stxa %0, [%1] %2" \
|
38 |
|
|
: /* no outputs */ \
|
39 |
|
|
: "r" (__val), "r" (__reg), \
|
40 |
|
|
"i" (ASI_PHYS_BYPASS_EC_E) \
|
41 |
|
|
: "memory")
|
42 |
|
|
|
43 |
|
|
/* SABRE PCI controller register offsets and definitions. */
|
44 |
|
|
#define SABRE_UE_AFSR 0x0030UL
|
45 |
|
|
#define SABRE_UEAFSR_PDRD 0x4000000000000000UL /* Primary PCI DMA Read */
|
46 |
|
|
#define SABRE_UEAFSR_PDWR 0x2000000000000000UL /* Primary PCI DMA Write */
|
47 |
|
|
#define SABRE_UEAFSR_SDRD 0x0800000000000000UL /* Secondary PCI DMA Read */
|
48 |
|
|
#define SABRE_UEAFSR_SDWR 0x0400000000000000UL /* Secondary PCI DMA Write */
|
49 |
|
|
#define SABRE_UEAFSR_SDTE 0x0200000000000000UL /* Secondary DMA Translation Error */
|
50 |
|
|
#define SABRE_UEAFSR_PDTE 0x0100000000000000UL /* Primary DMA Translation Error */
|
51 |
|
|
#define SABRE_UEAFSR_BMSK 0x0000ffff00000000UL /* Bytemask */
|
52 |
|
|
#define SABRE_UEAFSR_OFF 0x00000000e0000000UL /* Offset (AFAR bits [5:3] */
|
53 |
|
|
#define SABRE_UEAFSR_BLK 0x0000000000800000UL /* Was block operation */
|
54 |
|
|
#define SABRE_UECE_AFAR 0x0038UL
|
55 |
|
|
#define SABRE_CE_AFSR 0x0040UL
|
56 |
|
|
#define SABRE_CEAFSR_PDRD 0x4000000000000000UL /* Primary PCI DMA Read */
|
57 |
|
|
#define SABRE_CEAFSR_PDWR 0x2000000000000000UL /* Primary PCI DMA Write */
|
58 |
|
|
#define SABRE_CEAFSR_SDRD 0x0800000000000000UL /* Secondary PCI DMA Read */
|
59 |
|
|
#define SABRE_CEAFSR_SDWR 0x0400000000000000UL /* Secondary PCI DMA Write */
|
60 |
|
|
#define SABRE_CEAFSR_ESYND 0x00ff000000000000UL /* ECC Syndrome */
|
61 |
|
|
#define SABRE_CEAFSR_BMSK 0x0000ffff00000000UL /* Bytemask */
|
62 |
|
|
#define SABRE_CEAFSR_OFF 0x00000000e0000000UL /* Offset */
|
63 |
|
|
#define SABRE_CEAFSR_BLK 0x0000000000800000UL /* Was block operation */
|
64 |
|
|
#define SABRE_UECE_AFAR_ALIAS 0x0048UL /* Aliases to 0x0038 */
|
65 |
|
|
#define SABRE_IOMMU_CONTROL 0x0200UL
|
66 |
|
|
#define SABRE_IOMMUCTRL_ERRSTS 0x0000000006000000UL /* Error status bits */
|
67 |
|
|
#define SABRE_IOMMUCTRL_ERR 0x0000000001000000UL /* Error present in IOTLB */
|
68 |
|
|
#define SABRE_IOMMUCTRL_LCKEN 0x0000000000800000UL /* IOTLB lock enable */
|
69 |
|
|
#define SABRE_IOMMUCTRL_LCKPTR 0x0000000000780000UL /* IOTLB lock pointer */
|
70 |
|
|
#define SABRE_IOMMUCTRL_TSBSZ 0x0000000000070000UL /* TSB Size */
|
71 |
|
|
#define SABRE_IOMMU_TSBSZ_1K 0x0000000000000000
|
72 |
|
|
#define SABRE_IOMMU_TSBSZ_2K 0x0000000000010000
|
73 |
|
|
#define SABRE_IOMMU_TSBSZ_4K 0x0000000000020000
|
74 |
|
|
#define SABRE_IOMMU_TSBSZ_8K 0x0000000000030000
|
75 |
|
|
#define SABRE_IOMMU_TSBSZ_16K 0x0000000000040000
|
76 |
|
|
#define SABRE_IOMMU_TSBSZ_32K 0x0000000000050000
|
77 |
|
|
#define SABRE_IOMMU_TSBSZ_64K 0x0000000000060000
|
78 |
|
|
#define SABRE_IOMMU_TSBSZ_128K 0x0000000000070000
|
79 |
|
|
#define SABRE_IOMMUCTRL_TBWSZ 0x0000000000000004UL /* TSB assumed page size */
|
80 |
|
|
#define SABRE_IOMMUCTRL_DENAB 0x0000000000000002UL /* Diagnostic Mode Enable */
|
81 |
|
|
#define SABRE_IOMMUCTRL_ENAB 0x0000000000000001UL /* IOMMU Enable */
|
82 |
|
|
#define SABRE_IOMMU_TSBBASE 0x0208UL
|
83 |
|
|
#define SABRE_IOMMU_FLUSH 0x0210UL
|
84 |
|
|
#define SABRE_IMAP_A_SLOT0 0x0c00UL
|
85 |
|
|
#define SABRE_IMAP_B_SLOT0 0x0c20UL
|
86 |
|
|
#define SABRE_IMAP_SCSI 0x1000UL
|
87 |
|
|
#define SABRE_IMAP_ETH 0x1008UL
|
88 |
|
|
#define SABRE_IMAP_BPP 0x1010UL
|
89 |
|
|
#define SABRE_IMAP_AU_REC 0x1018UL
|
90 |
|
|
#define SABRE_IMAP_AU_PLAY 0x1020UL
|
91 |
|
|
#define SABRE_IMAP_PFAIL 0x1028UL
|
92 |
|
|
#define SABRE_IMAP_KMS 0x1030UL
|
93 |
|
|
#define SABRE_IMAP_FLPY 0x1038UL
|
94 |
|
|
#define SABRE_IMAP_SHW 0x1040UL
|
95 |
|
|
#define SABRE_IMAP_KBD 0x1048UL
|
96 |
|
|
#define SABRE_IMAP_MS 0x1050UL
|
97 |
|
|
#define SABRE_IMAP_SER 0x1058UL
|
98 |
|
|
#define SABRE_IMAP_UE 0x1070UL
|
99 |
|
|
#define SABRE_IMAP_CE 0x1078UL
|
100 |
|
|
#define SABRE_IMAP_PCIERR 0x1080UL
|
101 |
|
|
#define SABRE_IMAP_GFX 0x1098UL
|
102 |
|
|
#define SABRE_IMAP_EUPA 0x10a0UL
|
103 |
|
|
#define SABRE_ICLR_A_SLOT0 0x1400UL
|
104 |
|
|
#define SABRE_ICLR_B_SLOT0 0x1480UL
|
105 |
|
|
#define SABRE_ICLR_SCSI 0x1800UL
|
106 |
|
|
#define SABRE_ICLR_ETH 0x1808UL
|
107 |
|
|
#define SABRE_ICLR_BPP 0x1810UL
|
108 |
|
|
#define SABRE_ICLR_AU_REC 0x1818UL
|
109 |
|
|
#define SABRE_ICLR_AU_PLAY 0x1820UL
|
110 |
|
|
#define SABRE_ICLR_PFAIL 0x1828UL
|
111 |
|
|
#define SABRE_ICLR_KMS 0x1830UL
|
112 |
|
|
#define SABRE_ICLR_FLPY 0x1838UL
|
113 |
|
|
#define SABRE_ICLR_SHW 0x1840UL
|
114 |
|
|
#define SABRE_ICLR_KBD 0x1848UL
|
115 |
|
|
#define SABRE_ICLR_MS 0x1850UL
|
116 |
|
|
#define SABRE_ICLR_SER 0x1858UL
|
117 |
|
|
#define SABRE_ICLR_UE 0x1870UL
|
118 |
|
|
#define SABRE_ICLR_CE 0x1878UL
|
119 |
|
|
#define SABRE_ICLR_PCIERR 0x1880UL
|
120 |
|
|
#define SABRE_WRSYNC 0x1c20UL
|
121 |
|
|
#define SABRE_PCICTRL 0x2000UL
|
122 |
|
|
#define SABRE_PCICTRL_MRLEN 0x0000001000000000UL /* Use MemoryReadLine for block loads/stores */
|
123 |
|
|
#define SABRE_PCICTRL_SERR 0x0000000400000000UL /* Set when SERR asserted on PCI bus */
|
124 |
|
|
#define SABRE_PCICTRL_ARBPARK 0x0000000000200000UL /* Bus Parking 0=Ultra-IIi 1=prev-bus-owner */
|
125 |
|
|
#define SABRE_PCICTRL_CPUPRIO 0x0000000000100000UL /* Ultra-IIi granted every other bus cycle */
|
126 |
|
|
#define SABRE_PCICTRL_ARBPRIO 0x00000000000f0000UL /* Slot which is granted every other bus cycle */
|
127 |
|
|
#define SABRE_PCICTRL_ERREN 0x0000000000000100UL /* PCI Error Interrupt Enable */
|
128 |
|
|
#define SABRE_PCICTRL_RTRYWE 0x0000000000000080UL /* DMA Flow Control 0=wait-if-possible 1=retry */
|
129 |
|
|
#define SABRE_PCICTRL_AEN 0x000000000000000fUL /* Slot PCI arbitration enables */
|
130 |
|
|
#define SABRE_PIOAFSR 0x2010UL
|
131 |
|
|
#define SABRE_PIOAFSR_PMA 0x8000000000000000UL /* Primary Master Abort */
|
132 |
|
|
#define SABRE_PIOAFSR_PTA 0x4000000000000000UL /* Primary Target Abort */
|
133 |
|
|
#define SABRE_PIOAFSR_PRTRY 0x2000000000000000UL /* Primary Excessive Retries */
|
134 |
|
|
#define SABRE_PIOAFSR_PPERR 0x1000000000000000UL /* Primary Parity Error */
|
135 |
|
|
#define SABRE_PIOAFSR_SMA 0x0800000000000000UL /* Secondary Master Abort */
|
136 |
|
|
#define SABRE_PIOAFSR_STA 0x0400000000000000UL /* Secondary Target Abort */
|
137 |
|
|
#define SABRE_PIOAFSR_SRTRY 0x0200000000000000UL /* Secondary Excessive Retries */
|
138 |
|
|
#define SABRE_PIOAFSR_SPERR 0x0100000000000000UL /* Secondary Parity Error */
|
139 |
|
|
#define SABRE_PIOAFSR_BMSK 0x0000ffff00000000UL /* Byte Mask */
|
140 |
|
|
#define SABRE_PIOAFSR_BLK 0x0000000080000000UL /* Was Block Operation */
|
141 |
|
|
#define SABRE_PIOAFAR 0x2018UL
|
142 |
|
|
#define SABRE_PCIDIAG 0x2020UL
|
143 |
|
|
#define SABRE_PCIDIAG_DRTRY 0x0000000000000040UL /* Disable PIO Retry Limit */
|
144 |
|
|
#define SABRE_PCIDIAG_IPAPAR 0x0000000000000008UL /* Invert PIO Address Parity */
|
145 |
|
|
#define SABRE_PCIDIAG_IPDPAR 0x0000000000000004UL /* Invert PIO Data Parity */
|
146 |
|
|
#define SABRE_PCIDIAG_IDDPAR 0x0000000000000002UL /* Invert DMA Data Parity */
|
147 |
|
|
#define SABRE_PCIDIAG_ELPBK 0x0000000000000001UL /* Loopback Enable - not supported */
|
148 |
|
|
#define SABRE_PCITASR 0x2028UL
|
149 |
|
|
#define SABRE_PCITASR_EF 0x0000000000000080UL /* Respond to 0xe0000000-0xffffffff */
|
150 |
|
|
#define SABRE_PCITASR_CD 0x0000000000000040UL /* Respond to 0xc0000000-0xdfffffff */
|
151 |
|
|
#define SABRE_PCITASR_AB 0x0000000000000020UL /* Respond to 0xa0000000-0xbfffffff */
|
152 |
|
|
#define SABRE_PCITASR_89 0x0000000000000010UL /* Respond to 0x80000000-0x9fffffff */
|
153 |
|
|
#define SABRE_PCITASR_67 0x0000000000000008UL /* Respond to 0x60000000-0x7fffffff */
|
154 |
|
|
#define SABRE_PCITASR_45 0x0000000000000004UL /* Respond to 0x40000000-0x5fffffff */
|
155 |
|
|
#define SABRE_PCITASR_23 0x0000000000000002UL /* Respond to 0x20000000-0x3fffffff */
|
156 |
|
|
#define SABRE_PCITASR_01 0x0000000000000001UL /* Respond to 0x00000000-0x1fffffff */
|
157 |
|
|
#define SABRE_PIOBUF_DIAG 0x5000UL
|
158 |
|
|
#define SABRE_DMABUF_DIAGLO 0x5100UL
|
159 |
|
|
#define SABRE_DMABUF_DIAGHI 0x51c0UL
|
160 |
|
|
#define SABRE_IMAP_GFX_ALIAS 0x6000UL /* Aliases to 0x1098 */
|
161 |
|
|
#define SABRE_IMAP_EUPA_ALIAS 0x8000UL /* Aliases to 0x10a0 */
|
162 |
|
|
#define SABRE_IOMMU_VADIAG 0xa400UL
|
163 |
|
|
#define SABRE_IOMMU_TCDIAG 0xa408UL
|
164 |
|
|
#define SABRE_IOMMU_TAG 0xa580UL
|
165 |
|
|
#define SABRE_IOMMUTAG_ERRSTS 0x0000000001800000UL /* Error status bits */
|
166 |
|
|
#define SABRE_IOMMUTAG_ERR 0x0000000000400000UL /* Error present */
|
167 |
|
|
#define SABRE_IOMMUTAG_WRITE 0x0000000000200000UL /* Page is writable */
|
168 |
|
|
#define SABRE_IOMMUTAG_STREAM 0x0000000000100000UL /* Streamable bit - unused */
|
169 |
|
|
#define SABRE_IOMMUTAG_SIZE 0x0000000000080000UL /* 0=8k 1=16k */
|
170 |
|
|
#define SABRE_IOMMUTAG_VPN 0x000000000007ffffUL /* Virtual Page Number [31:13] */
|
171 |
|
|
#define SABRE_IOMMU_DATA 0xa600UL
|
172 |
|
|
#define SABRE_IOMMUDATA_VALID 0x0000000040000000UL /* Valid */
|
173 |
|
|
#define SABRE_IOMMUDATA_USED 0x0000000020000000UL /* Used (for LRU algorithm) */
|
174 |
|
|
#define SABRE_IOMMUDATA_CACHE 0x0000000010000000UL /* Cacheable */
|
175 |
|
|
#define SABRE_IOMMUDATA_PPN 0x00000000001fffffUL /* Physical Page Number [33:13] */
|
176 |
|
|
#define SABRE_PCI_IRQSTATE 0xa800UL
|
177 |
|
|
#define SABRE_OBIO_IRQSTATE 0xa808UL
|
178 |
|
|
#define SABRE_FFBCFG 0xf000UL
|
179 |
|
|
#define SABRE_FFBCFG_SPRQS 0x000000000f000000 /* Slave P_RQST queue size */
|
180 |
|
|
#define SABRE_FFBCFG_ONEREAD 0x0000000000004000 /* Slave supports one outstanding read */
|
181 |
|
|
#define SABRE_MCCTRL0 0xf010UL
|
182 |
|
|
#define SABRE_MCCTRL0_RENAB 0x0000000080000000 /* Refresh Enable */
|
183 |
|
|
#define SABRE_MCCTRL0_EENAB 0x0000000010000000 /* Enable all ECC functions */
|
184 |
|
|
#define SABRE_MCCTRL0_11BIT 0x0000000000001000 /* Enable 11-bit column addressing */
|
185 |
|
|
#define SABRE_MCCTRL0_DPP 0x0000000000000f00 /* DIMM Pair Present Bits */
|
186 |
|
|
#define SABRE_MCCTRL0_RINTVL 0x00000000000000ff /* Refresh Interval */
|
187 |
|
|
#define SABRE_MCCTRL1 0xf018UL
|
188 |
|
|
#define SABRE_MCCTRL1_AMDC 0x0000000038000000 /* Advance Memdata Clock */
|
189 |
|
|
#define SABRE_MCCTRL1_ARDC 0x0000000007000000 /* Advance DRAM Read Data Clock */
|
190 |
|
|
#define SABRE_MCCTRL1_CSR 0x0000000000e00000 /* CAS to RAS delay for CBR refresh */
|
191 |
|
|
#define SABRE_MCCTRL1_CASRW 0x00000000001c0000 /* CAS length for read/write */
|
192 |
|
|
#define SABRE_MCCTRL1_RCD 0x0000000000038000 /* RAS to CAS delay */
|
193 |
|
|
#define SABRE_MCCTRL1_CP 0x0000000000007000 /* CAS Precharge */
|
194 |
|
|
#define SABRE_MCCTRL1_RP 0x0000000000000e00 /* RAS Precharge */
|
195 |
|
|
#define SABRE_MCCTRL1_RAS 0x00000000000001c0 /* Length of RAS for refresh */
|
196 |
|
|
#define SABRE_MCCTRL1_CASRW2 0x0000000000000038 /* Must be same as CASRW */
|
197 |
|
|
#define SABRE_MCCTRL1_RSC 0x0000000000000007 /* RAS after CAS hold time */
|
198 |
|
|
#define SABRE_RESETCTRL 0xf020UL
|
199 |
|
|
|
200 |
|
|
#define SABRE_CONFIGSPACE 0x001000000UL
|
201 |
|
|
#define SABRE_IOSPACE 0x002000000UL
|
202 |
|
|
#define SABRE_IOSPACE_SIZE 0x000ffffffUL
|
203 |
|
|
#define SABRE_MEMSPACE 0x100000000UL
|
204 |
|
|
#define SABRE_MEMSPACE_SIZE 0x07fffffffUL
|
205 |
|
|
|
206 |
|
|
/* UltraSparc-IIi Programmer's Manual, page 325, PCI
|
207 |
|
|
* configuration space address format:
|
208 |
|
|
*
|
209 |
|
|
* 32 24 23 16 15 11 10 8 7 2 1 0
|
210 |
|
|
* ---------------------------------------------------------
|
211 |
|
|
* |0 0 0 0 0 0 0 0 1| bus | device | function | reg | 0 0 |
|
212 |
|
|
* ---------------------------------------------------------
|
213 |
|
|
*/
|
214 |
|
|
#define SABRE_CONFIG_BASE(PBM) \
|
215 |
|
|
((PBM)->config_space | (1UL << 24))
|
216 |
|
|
#define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \
|
217 |
|
|
(((unsigned long)(BUS) << 16) | \
|
218 |
|
|
((unsigned long)(DEVFN) << 8) | \
|
219 |
|
|
((unsigned long)(REG)))
|
220 |
|
|
|
221 |
|
|
static int hummingbird_p;
|
222 |
|
|
static struct pci_bus *sabre_root_bus;
|
223 |
|
|
|
224 |
|
|
static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,
|
225 |
|
|
unsigned char bus,
|
226 |
|
|
unsigned int devfn,
|
227 |
|
|
int where)
|
228 |
|
|
{
|
229 |
|
|
if (!pbm)
|
230 |
|
|
return NULL;
|
231 |
|
|
return (void *)
|
232 |
|
|
(SABRE_CONFIG_BASE(pbm) |
|
233 |
|
|
SABRE_CONFIG_ENCODE(bus, devfn, where));
|
234 |
|
|
}
|
235 |
|
|
|
236 |
|
|
static int sabre_out_of_range(unsigned char devfn)
|
237 |
|
|
{
|
238 |
|
|
if (hummingbird_p)
|
239 |
|
|
return 0;
|
240 |
|
|
|
241 |
|
|
return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) ||
|
242 |
|
|
((PCI_SLOT(devfn) == 1) && (PCI_FUNC(devfn) > 1)) ||
|
243 |
|
|
(PCI_SLOT(devfn) > 1));
|
244 |
|
|
}
|
245 |
|
|
|
246 |
|
|
static int __sabre_out_of_range(struct pci_pbm_info *pbm,
|
247 |
|
|
unsigned char bus,
|
248 |
|
|
unsigned char devfn)
|
249 |
|
|
{
|
250 |
|
|
if (hummingbird_p)
|
251 |
|
|
return 0;
|
252 |
|
|
|
253 |
|
|
return ((pbm->parent == 0) ||
|
254 |
|
|
((pbm == &pbm->parent->pbm_B) &&
|
255 |
|
|
(bus == pbm->pci_first_busno) &&
|
256 |
|
|
PCI_SLOT(devfn) > 8) ||
|
257 |
|
|
((pbm == &pbm->parent->pbm_A) &&
|
258 |
|
|
(bus == pbm->pci_first_busno) &&
|
259 |
|
|
PCI_SLOT(devfn) > 8));
|
260 |
|
|
}
|
261 |
|
|
|
262 |
|
|
static int __sabre_read_byte(struct pci_dev *dev, int where, u8 *value)
|
263 |
|
|
{
|
264 |
|
|
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
|
265 |
|
|
unsigned char bus = dev->bus->number;
|
266 |
|
|
unsigned int devfn = dev->devfn;
|
267 |
|
|
u8 *addr;
|
268 |
|
|
|
269 |
|
|
*value = 0xff;
|
270 |
|
|
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
|
271 |
|
|
if (!addr)
|
272 |
|
|
return PCIBIOS_SUCCESSFUL;
|
273 |
|
|
|
274 |
|
|
if (__sabre_out_of_range(pbm, bus, devfn))
|
275 |
|
|
return PCIBIOS_SUCCESSFUL;
|
276 |
|
|
pci_config_read8(addr, value);
|
277 |
|
|
return PCIBIOS_SUCCESSFUL;
|
278 |
|
|
}
|
279 |
|
|
|
280 |
|
|
static int __sabre_read_word(struct pci_dev *dev, int where, u16 *value)
|
281 |
|
|
{
|
282 |
|
|
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
|
283 |
|
|
unsigned char bus = dev->bus->number;
|
284 |
|
|
unsigned int devfn = dev->devfn;
|
285 |
|
|
u16 *addr;
|
286 |
|
|
|
287 |
|
|
*value = 0xffff;
|
288 |
|
|
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
|
289 |
|
|
if (!addr)
|
290 |
|
|
return PCIBIOS_SUCCESSFUL;
|
291 |
|
|
|
292 |
|
|
if (__sabre_out_of_range(pbm, bus, devfn))
|
293 |
|
|
return PCIBIOS_SUCCESSFUL;
|
294 |
|
|
|
295 |
|
|
if (where & 0x01) {
|
296 |
|
|
printk("pcibios_read_config_word: misaligned reg [%x]\n",
|
297 |
|
|
where);
|
298 |
|
|
return PCIBIOS_SUCCESSFUL;
|
299 |
|
|
}
|
300 |
|
|
pci_config_read16(addr, value);
|
301 |
|
|
return PCIBIOS_SUCCESSFUL;
|
302 |
|
|
}
|
303 |
|
|
|
304 |
|
|
static int __sabre_read_dword(struct pci_dev *dev, int where, u32 *value)
|
305 |
|
|
{
|
306 |
|
|
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
|
307 |
|
|
unsigned char bus = dev->bus->number;
|
308 |
|
|
unsigned int devfn = dev->devfn;
|
309 |
|
|
u32 *addr;
|
310 |
|
|
|
311 |
|
|
*value = 0xffffffff;
|
312 |
|
|
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
|
313 |
|
|
if (!addr)
|
314 |
|
|
return PCIBIOS_SUCCESSFUL;
|
315 |
|
|
|
316 |
|
|
if (__sabre_out_of_range(pbm, bus, devfn))
|
317 |
|
|
return PCIBIOS_SUCCESSFUL;
|
318 |
|
|
|
319 |
|
|
if (where & 0x03) {
|
320 |
|
|
printk("pcibios_read_config_dword: misaligned reg [%x]\n",
|
321 |
|
|
where);
|
322 |
|
|
return PCIBIOS_SUCCESSFUL;
|
323 |
|
|
}
|
324 |
|
|
pci_config_read32(addr, value);
|
325 |
|
|
return PCIBIOS_SUCCESSFUL;
|
326 |
|
|
}
|
327 |
|
|
|
328 |
|
|
/* When accessing PCI config space of the PCI controller itself (bus
|
329 |
|
|
* 0, device slot 0, function 0) there are restrictions. Each
|
330 |
|
|
* register must be accessed as it's natural size. Thus, for example
|
331 |
|
|
* the Vendor ID must be accessed as a 16-bit quantity.
|
332 |
|
|
*/
|
333 |
|
|
|
334 |
|
|
static int sabre_read_byte(struct pci_dev *dev, int where, u8 *value)
|
335 |
|
|
{
|
336 |
|
|
if (!dev->bus->number && sabre_out_of_range(dev->devfn)) {
|
337 |
|
|
*value = 0xff;
|
338 |
|
|
return PCIBIOS_SUCCESSFUL;
|
339 |
|
|
}
|
340 |
|
|
|
341 |
|
|
if (dev->bus->number || PCI_SLOT(dev->devfn))
|
342 |
|
|
return __sabre_read_byte(dev, where, value);
|
343 |
|
|
|
344 |
|
|
if (where < 8) {
|
345 |
|
|
u16 tmp;
|
346 |
|
|
|
347 |
|
|
__sabre_read_word(dev, where & ~1, &tmp);
|
348 |
|
|
if (where & 1)
|
349 |
|
|
*value = tmp >> 8;
|
350 |
|
|
else
|
351 |
|
|
*value = tmp & 0xff;
|
352 |
|
|
return PCIBIOS_SUCCESSFUL;
|
353 |
|
|
} else
|
354 |
|
|
return __sabre_read_byte(dev, where, value);
|
355 |
|
|
}
|
356 |
|
|
|
357 |
|
|
static int sabre_read_word(struct pci_dev *dev, int where, u16 *value)
|
358 |
|
|
{
|
359 |
|
|
if (!dev->bus->number && sabre_out_of_range(dev->devfn)) {
|
360 |
|
|
*value = 0xffff;
|
361 |
|
|
return PCIBIOS_SUCCESSFUL;
|
362 |
|
|
}
|
363 |
|
|
|
364 |
|
|
if (dev->bus->number || PCI_SLOT(dev->devfn))
|
365 |
|
|
return __sabre_read_word(dev, where, value);
|
366 |
|
|
|
367 |
|
|
if (where < 8)
|
368 |
|
|
return __sabre_read_word(dev, where, value);
|
369 |
|
|
else {
|
370 |
|
|
u8 tmp;
|
371 |
|
|
|
372 |
|
|
__sabre_read_byte(dev, where, &tmp);
|
373 |
|
|
*value = tmp;
|
374 |
|
|
__sabre_read_byte(dev, where + 1, &tmp);
|
375 |
|
|
*value |= tmp << 8;
|
376 |
|
|
return PCIBIOS_SUCCESSFUL;
|
377 |
|
|
}
|
378 |
|
|
}
|
379 |
|
|
|
380 |
|
|
static int sabre_read_dword(struct pci_dev *dev, int where, u32 *value)
|
381 |
|
|
{
|
382 |
|
|
u16 tmp;
|
383 |
|
|
|
384 |
|
|
if (!dev->bus->number && sabre_out_of_range(dev->devfn)) {
|
385 |
|
|
*value = 0xffffffff;
|
386 |
|
|
return PCIBIOS_SUCCESSFUL;
|
387 |
|
|
}
|
388 |
|
|
|
389 |
|
|
if (dev->bus->number || PCI_SLOT(dev->devfn))
|
390 |
|
|
return __sabre_read_dword(dev, where, value);
|
391 |
|
|
|
392 |
|
|
sabre_read_word(dev, where, &tmp);
|
393 |
|
|
*value = tmp;
|
394 |
|
|
sabre_read_word(dev, where + 2, &tmp);
|
395 |
|
|
*value |= tmp << 16;
|
396 |
|
|
return PCIBIOS_SUCCESSFUL;
|
397 |
|
|
}
|
398 |
|
|
|
399 |
|
|
static int __sabre_write_byte(struct pci_dev *dev, int where, u8 value)
|
400 |
|
|
{
|
401 |
|
|
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
|
402 |
|
|
unsigned char bus = dev->bus->number;
|
403 |
|
|
unsigned int devfn = dev->devfn;
|
404 |
|
|
u8 *addr;
|
405 |
|
|
|
406 |
|
|
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
|
407 |
|
|
if (!addr)
|
408 |
|
|
return PCIBIOS_SUCCESSFUL;
|
409 |
|
|
|
410 |
|
|
if (__sabre_out_of_range(pbm, bus, devfn))
|
411 |
|
|
return PCIBIOS_SUCCESSFUL;
|
412 |
|
|
pci_config_write8(addr, value);
|
413 |
|
|
return PCIBIOS_SUCCESSFUL;
|
414 |
|
|
}
|
415 |
|
|
|
416 |
|
|
static int __sabre_write_word(struct pci_dev *dev, int where, u16 value)
|
417 |
|
|
{
|
418 |
|
|
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
|
419 |
|
|
unsigned char bus = dev->bus->number;
|
420 |
|
|
unsigned int devfn = dev->devfn;
|
421 |
|
|
u16 *addr;
|
422 |
|
|
|
423 |
|
|
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
|
424 |
|
|
if (!addr)
|
425 |
|
|
return PCIBIOS_SUCCESSFUL;
|
426 |
|
|
|
427 |
|
|
if (__sabre_out_of_range(pbm, bus, devfn))
|
428 |
|
|
return PCIBIOS_SUCCESSFUL;
|
429 |
|
|
|
430 |
|
|
if (where & 0x01) {
|
431 |
|
|
printk("pcibios_write_config_word: misaligned reg [%x]\n",
|
432 |
|
|
where);
|
433 |
|
|
return PCIBIOS_SUCCESSFUL;
|
434 |
|
|
}
|
435 |
|
|
pci_config_write16(addr, value);
|
436 |
|
|
return PCIBIOS_SUCCESSFUL;
|
437 |
|
|
}
|
438 |
|
|
|
439 |
|
|
static int __sabre_write_dword(struct pci_dev *dev, int where, u32 value)
|
440 |
|
|
{
|
441 |
|
|
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
|
442 |
|
|
unsigned char bus = dev->bus->number;
|
443 |
|
|
unsigned int devfn = dev->devfn;
|
444 |
|
|
u32 *addr;
|
445 |
|
|
|
446 |
|
|
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
|
447 |
|
|
if (!addr)
|
448 |
|
|
return PCIBIOS_SUCCESSFUL;
|
449 |
|
|
|
450 |
|
|
if (__sabre_out_of_range(pbm, bus, devfn))
|
451 |
|
|
return PCIBIOS_SUCCESSFUL;
|
452 |
|
|
|
453 |
|
|
if (where & 0x03) {
|
454 |
|
|
printk("pcibios_write_config_dword: misaligned reg [%x]\n",
|
455 |
|
|
where);
|
456 |
|
|
return PCIBIOS_SUCCESSFUL;
|
457 |
|
|
}
|
458 |
|
|
pci_config_write32(addr, value);
|
459 |
|
|
return PCIBIOS_SUCCESSFUL;
|
460 |
|
|
}
|
461 |
|
|
|
462 |
|
|
static int sabre_write_byte(struct pci_dev *dev, int where, u8 value)
|
463 |
|
|
{
|
464 |
|
|
if (dev->bus->number)
|
465 |
|
|
return __sabre_write_byte(dev, where, value);
|
466 |
|
|
|
467 |
|
|
if (sabre_out_of_range(dev->devfn))
|
468 |
|
|
return PCIBIOS_SUCCESSFUL;
|
469 |
|
|
|
470 |
|
|
if (where < 8) {
|
471 |
|
|
u16 tmp;
|
472 |
|
|
|
473 |
|
|
__sabre_read_word(dev, where & ~1, &tmp);
|
474 |
|
|
if (where & 1) {
|
475 |
|
|
value &= 0x00ff;
|
476 |
|
|
value |= tmp << 8;
|
477 |
|
|
} else {
|
478 |
|
|
value &= 0xff00;
|
479 |
|
|
value |= tmp;
|
480 |
|
|
}
|
481 |
|
|
return __sabre_write_word(dev, where & ~1, tmp);
|
482 |
|
|
} else
|
483 |
|
|
return __sabre_write_byte(dev, where, value);
|
484 |
|
|
}
|
485 |
|
|
|
486 |
|
|
static int sabre_write_word(struct pci_dev *dev, int where, u16 value)
|
487 |
|
|
{
|
488 |
|
|
if (dev->bus->number)
|
489 |
|
|
return __sabre_write_word(dev, where, value);
|
490 |
|
|
|
491 |
|
|
if (sabre_out_of_range(dev->devfn))
|
492 |
|
|
return PCIBIOS_SUCCESSFUL;
|
493 |
|
|
|
494 |
|
|
if (where < 8)
|
495 |
|
|
return __sabre_write_word(dev, where, value);
|
496 |
|
|
else {
|
497 |
|
|
__sabre_write_byte(dev, where, value & 0xff);
|
498 |
|
|
__sabre_write_byte(dev, where + 1, value >> 8);
|
499 |
|
|
return PCIBIOS_SUCCESSFUL;
|
500 |
|
|
}
|
501 |
|
|
}
|
502 |
|
|
|
503 |
|
|
static int sabre_write_dword(struct pci_dev *dev, int where, u32 value)
|
504 |
|
|
{
|
505 |
|
|
if (dev->bus->number)
|
506 |
|
|
return __sabre_write_dword(dev, where, value);
|
507 |
|
|
|
508 |
|
|
if (sabre_out_of_range(dev->devfn))
|
509 |
|
|
return PCIBIOS_SUCCESSFUL;
|
510 |
|
|
|
511 |
|
|
sabre_write_word(dev, where, value & 0xffff);
|
512 |
|
|
sabre_write_word(dev, where + 2, value >> 16);
|
513 |
|
|
return PCIBIOS_SUCCESSFUL;
|
514 |
|
|
}
|
515 |
|
|
|
516 |
|
|
static struct pci_ops sabre_ops = {
|
517 |
|
|
sabre_read_byte,
|
518 |
|
|
sabre_read_word,
|
519 |
|
|
sabre_read_dword,
|
520 |
|
|
sabre_write_byte,
|
521 |
|
|
sabre_write_word,
|
522 |
|
|
sabre_write_dword
|
523 |
|
|
};
|
524 |
|
|
|
525 |
|
|
static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
|
526 |
|
|
{
|
527 |
|
|
unsigned int bus = (ino & 0x10) >> 4;
|
528 |
|
|
unsigned int slot = (ino & 0x0c) >> 2;
|
529 |
|
|
|
530 |
|
|
if (bus == 0)
|
531 |
|
|
return SABRE_IMAP_A_SLOT0 + (slot * 8);
|
532 |
|
|
else
|
533 |
|
|
return SABRE_IMAP_B_SLOT0 + (slot * 8);
|
534 |
|
|
}
|
535 |
|
|
|
536 |
|
|
static unsigned long __onboard_imap_off[] = {
|
537 |
|
|
/*0x20*/ SABRE_IMAP_SCSI,
|
538 |
|
|
/*0x21*/ SABRE_IMAP_ETH,
|
539 |
|
|
/*0x22*/ SABRE_IMAP_BPP,
|
540 |
|
|
/*0x23*/ SABRE_IMAP_AU_REC,
|
541 |
|
|
/*0x24*/ SABRE_IMAP_AU_PLAY,
|
542 |
|
|
/*0x25*/ SABRE_IMAP_PFAIL,
|
543 |
|
|
/*0x26*/ SABRE_IMAP_KMS,
|
544 |
|
|
/*0x27*/ SABRE_IMAP_FLPY,
|
545 |
|
|
/*0x28*/ SABRE_IMAP_SHW,
|
546 |
|
|
/*0x29*/ SABRE_IMAP_KBD,
|
547 |
|
|
/*0x2a*/ SABRE_IMAP_MS,
|
548 |
|
|
/*0x2b*/ SABRE_IMAP_SER,
|
549 |
|
|
/*0x2c*/ 0 /* reserved */,
|
550 |
|
|
/*0x2d*/ 0 /* reserved */,
|
551 |
|
|
/*0x2e*/ SABRE_IMAP_UE,
|
552 |
|
|
/*0x2f*/ SABRE_IMAP_CE,
|
553 |
|
|
/*0x30*/ SABRE_IMAP_PCIERR,
|
554 |
|
|
};
|
555 |
|
|
#define SABRE_ONBOARD_IRQ_BASE 0x20
|
556 |
|
|
#define SABRE_ONBOARD_IRQ_LAST 0x30
|
557 |
|
|
#define sabre_onboard_imap_offset(__ino) \
|
558 |
|
|
__onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
|
559 |
|
|
|
560 |
|
|
#define sabre_iclr_offset(ino) \
|
561 |
|
|
((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \
|
562 |
|
|
(SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3)))
|
563 |
|
|
|
564 |
|
|
/* PCI SABRE INO number to Sparc PIL level. */
|
565 |
|
|
static unsigned char sabre_pil_table[] = {
|
566 |
|
|
/*0x00*/0, 0, 0, 0, /* PCI A slot 0 Int A, B, C, D */
|
567 |
|
|
/*0x04*/0, 0, 0, 0, /* PCI A slot 1 Int A, B, C, D */
|
568 |
|
|
/*0x08*/0, 0, 0, 0, /* PCI A slot 2 Int A, B, C, D */
|
569 |
|
|
/*0x0c*/0, 0, 0, 0, /* PCI A slot 3 Int A, B, C, D */
|
570 |
|
|
/*0x10*/0, 0, 0, 0, /* PCI B slot 0 Int A, B, C, D */
|
571 |
|
|
/*0x14*/0, 0, 0, 0, /* PCI B slot 1 Int A, B, C, D */
|
572 |
|
|
/*0x18*/0, 0, 0, 0, /* PCI B slot 2 Int A, B, C, D */
|
573 |
|
|
/*0x1c*/0, 0, 0, 0, /* PCI B slot 3 Int A, B, C, D */
|
574 |
|
|
/*0x20*/4, /* SCSI */
|
575 |
|
|
/*0x21*/5, /* Ethernet */
|
576 |
|
|
/*0x22*/8, /* Parallel Port */
|
577 |
|
|
/*0x23*/13, /* Audio Record */
|
578 |
|
|
/*0x24*/14, /* Audio Playback */
|
579 |
|
|
/*0x25*/15, /* PowerFail */
|
580 |
|
|
/*0x26*/4, /* second SCSI */
|
581 |
|
|
/*0x27*/11, /* Floppy */
|
582 |
|
|
/*0x28*/4, /* Spare Hardware */
|
583 |
|
|
/*0x29*/9, /* Keyboard */
|
584 |
|
|
/*0x2a*/4, /* Mouse */
|
585 |
|
|
/*0x2b*/12, /* Serial */
|
586 |
|
|
/*0x2c*/10, /* Timer 0 */
|
587 |
|
|
/*0x2d*/11, /* Timer 1 */
|
588 |
|
|
/*0x2e*/15, /* Uncorrectable ECC */
|
589 |
|
|
/*0x2f*/15, /* Correctable ECC */
|
590 |
|
|
/*0x30*/15, /* PCI Bus A Error */
|
591 |
|
|
/*0x31*/15, /* PCI Bus B Error */
|
592 |
|
|
/*0x32*/15, /* Power Management */
|
593 |
|
|
};
|
594 |
|
|
|
595 |
|
|
static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
|
596 |
|
|
{
|
597 |
|
|
int ret;
|
598 |
|
|
|
599 |
|
|
if (pdev &&
|
600 |
|
|
pdev->vendor == PCI_VENDOR_ID_SUN &&
|
601 |
|
|
pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
|
602 |
|
|
return 9;
|
603 |
|
|
|
604 |
|
|
ret = sabre_pil_table[ino];
|
605 |
|
|
if (ret == 0 && pdev == NULL) {
|
606 |
|
|
ret = 4;
|
607 |
|
|
} else if (ret == 0) {
|
608 |
|
|
switch ((pdev->class >> 16) & 0xff) {
|
609 |
|
|
case PCI_BASE_CLASS_STORAGE:
|
610 |
|
|
ret = 4;
|
611 |
|
|
break;
|
612 |
|
|
|
613 |
|
|
case PCI_BASE_CLASS_NETWORK:
|
614 |
|
|
ret = 6;
|
615 |
|
|
break;
|
616 |
|
|
|
617 |
|
|
case PCI_BASE_CLASS_DISPLAY:
|
618 |
|
|
ret = 9;
|
619 |
|
|
break;
|
620 |
|
|
|
621 |
|
|
case PCI_BASE_CLASS_MULTIMEDIA:
|
622 |
|
|
case PCI_BASE_CLASS_MEMORY:
|
623 |
|
|
case PCI_BASE_CLASS_BRIDGE:
|
624 |
|
|
case PCI_BASE_CLASS_SERIAL:
|
625 |
|
|
ret = 10;
|
626 |
|
|
break;
|
627 |
|
|
|
628 |
|
|
default:
|
629 |
|
|
ret = 4;
|
630 |
|
|
break;
|
631 |
|
|
};
|
632 |
|
|
}
|
633 |
|
|
return ret;
|
634 |
|
|
}
|
635 |
|
|
|
636 |
|
|
static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
|
637 |
|
|
struct pci_dev *pdev,
|
638 |
|
|
unsigned int ino)
|
639 |
|
|
{
|
640 |
|
|
struct ino_bucket *bucket;
|
641 |
|
|
unsigned long imap, iclr;
|
642 |
|
|
unsigned long imap_off, iclr_off;
|
643 |
|
|
int pil, inofixup = 0;
|
644 |
|
|
|
645 |
|
|
ino &= PCI_IRQ_INO;
|
646 |
|
|
if (ino < SABRE_ONBOARD_IRQ_BASE) {
|
647 |
|
|
/* PCI slot */
|
648 |
|
|
imap_off = sabre_pcislot_imap_offset(ino);
|
649 |
|
|
} else {
|
650 |
|
|
/* onboard device */
|
651 |
|
|
if (ino > SABRE_ONBOARD_IRQ_LAST) {
|
652 |
|
|
prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
|
653 |
|
|
prom_halt();
|
654 |
|
|
}
|
655 |
|
|
imap_off = sabre_onboard_imap_offset(ino);
|
656 |
|
|
}
|
657 |
|
|
|
658 |
|
|
/* Now build the IRQ bucket. */
|
659 |
|
|
pil = sabre_ino_to_pil(pdev, ino);
|
660 |
|
|
|
661 |
|
|
if (PIL_RESERVED(pil))
|
662 |
|
|
BUG();
|
663 |
|
|
|
664 |
|
|
imap = pbm->controller_regs + imap_off;
|
665 |
|
|
imap += 4;
|
666 |
|
|
|
667 |
|
|
iclr_off = sabre_iclr_offset(ino);
|
668 |
|
|
iclr = pbm->controller_regs + iclr_off;
|
669 |
|
|
iclr += 4;
|
670 |
|
|
|
671 |
|
|
if ((ino & 0x20) == 0)
|
672 |
|
|
inofixup = ino & 0x03;
|
673 |
|
|
|
674 |
|
|
bucket = __bucket(build_irq(pil, inofixup, iclr, imap));
|
675 |
|
|
bucket->flags |= IBF_PCI;
|
676 |
|
|
|
677 |
|
|
if (pdev) {
|
678 |
|
|
struct pcidev_cookie *pcp = pdev->sysdata;
|
679 |
|
|
|
680 |
|
|
/* When a device lives behind a bridge deeper in the
|
681 |
|
|
* PCI bus topology than APB, a special sequence must
|
682 |
|
|
* run to make sure all pending DMA transfers at the
|
683 |
|
|
* time of IRQ delivery are visible in the coherency
|
684 |
|
|
* domain by the cpu. This sequence is to perform
|
685 |
|
|
* a read on the far side of the non-APB bridge, then
|
686 |
|
|
* perform a read of Sabre's DMA write-sync register.
|
687 |
|
|
*
|
688 |
|
|
* Currently, the PCI_CONFIG register for the device
|
689 |
|
|
* is used for this read from the far side of the bridge.
|
690 |
|
|
*/
|
691 |
|
|
if (pdev->bus->number != pcp->pbm->pci_first_busno) {
|
692 |
|
|
bucket->flags |= IBF_DMA_SYNC;
|
693 |
|
|
bucket->synctab_ent = dma_sync_reg_table_entry++;
|
694 |
|
|
dma_sync_reg_table[bucket->synctab_ent] =
|
695 |
|
|
(unsigned long) sabre_pci_config_mkaddr(
|
696 |
|
|
pcp->pbm,
|
697 |
|
|
pdev->bus->number, pdev->devfn, PCI_COMMAND);
|
698 |
|
|
}
|
699 |
|
|
}
|
700 |
|
|
return __irq(bucket);
|
701 |
|
|
}
|
702 |
|
|
|
703 |
|
|
/* SABRE error handling support. */
|
704 |
|
|
static void sabre_check_iommu_error(struct pci_controller_info *p,
|
705 |
|
|
unsigned long afsr,
|
706 |
|
|
unsigned long afar)
|
707 |
|
|
{
|
708 |
|
|
struct pci_iommu *iommu = p->pbm_A.iommu;
|
709 |
|
|
unsigned long iommu_tag[16];
|
710 |
|
|
unsigned long iommu_data[16];
|
711 |
|
|
unsigned long flags;
|
712 |
|
|
u64 control;
|
713 |
|
|
int i;
|
714 |
|
|
|
715 |
|
|
spin_lock_irqsave(&iommu->lock, flags);
|
716 |
|
|
control = sabre_read(iommu->iommu_control);
|
717 |
|
|
if (control & SABRE_IOMMUCTRL_ERR) {
|
718 |
|
|
char *type_string;
|
719 |
|
|
|
720 |
|
|
/* Clear the error encountered bit.
|
721 |
|
|
* NOTE: On Sabre this is write 1 to clear,
|
722 |
|
|
* which is different from Psycho.
|
723 |
|
|
*/
|
724 |
|
|
sabre_write(iommu->iommu_control, control);
|
725 |
|
|
switch((control & SABRE_IOMMUCTRL_ERRSTS) >> 25UL) {
|
726 |
|
|
case 1:
|
727 |
|
|
type_string = "Invalid Error";
|
728 |
|
|
break;
|
729 |
|
|
case 3:
|
730 |
|
|
type_string = "ECC Error";
|
731 |
|
|
break;
|
732 |
|
|
default:
|
733 |
|
|
type_string = "Unknown";
|
734 |
|
|
break;
|
735 |
|
|
};
|
736 |
|
|
printk("SABRE%d: IOMMU Error, type[%s]\n",
|
737 |
|
|
p->index, type_string);
|
738 |
|
|
|
739 |
|
|
/* Enter diagnostic mode and probe for error'd
|
740 |
|
|
* entries in the IOTLB.
|
741 |
|
|
*/
|
742 |
|
|
control &= ~(SABRE_IOMMUCTRL_ERRSTS | SABRE_IOMMUCTRL_ERR);
|
743 |
|
|
sabre_write(iommu->iommu_control,
|
744 |
|
|
(control | SABRE_IOMMUCTRL_DENAB));
|
745 |
|
|
for (i = 0; i < 16; i++) {
|
746 |
|
|
unsigned long base = p->pbm_A.controller_regs;
|
747 |
|
|
|
748 |
|
|
iommu_tag[i] =
|
749 |
|
|
sabre_read(base + SABRE_IOMMU_TAG + (i * 8UL));
|
750 |
|
|
iommu_data[i] =
|
751 |
|
|
sabre_read(base + SABRE_IOMMU_DATA + (i * 8UL));
|
752 |
|
|
sabre_write(base + SABRE_IOMMU_TAG + (i * 8UL), 0);
|
753 |
|
|
sabre_write(base + SABRE_IOMMU_DATA + (i * 8UL), 0);
|
754 |
|
|
}
|
755 |
|
|
sabre_write(iommu->iommu_control, control);
|
756 |
|
|
|
757 |
|
|
for (i = 0; i < 16; i++) {
|
758 |
|
|
unsigned long tag, data;
|
759 |
|
|
|
760 |
|
|
tag = iommu_tag[i];
|
761 |
|
|
if (!(tag & SABRE_IOMMUTAG_ERR))
|
762 |
|
|
continue;
|
763 |
|
|
|
764 |
|
|
data = iommu_data[i];
|
765 |
|
|
switch((tag & SABRE_IOMMUTAG_ERRSTS) >> 23UL) {
|
766 |
|
|
case 1:
|
767 |
|
|
type_string = "Invalid Error";
|
768 |
|
|
break;
|
769 |
|
|
case 3:
|
770 |
|
|
type_string = "ECC Error";
|
771 |
|
|
break;
|
772 |
|
|
default:
|
773 |
|
|
type_string = "Unknown";
|
774 |
|
|
break;
|
775 |
|
|
};
|
776 |
|
|
printk("SABRE%d: IOMMU TAG(%d)[RAW(%016lx)error(%s)wr(%d)sz(%dK)vpg(%08lx)]\n",
|
777 |
|
|
p->index, i, tag, type_string,
|
778 |
|
|
((tag & SABRE_IOMMUTAG_WRITE) ? 1 : 0),
|
779 |
|
|
((tag & SABRE_IOMMUTAG_SIZE) ? 64 : 8),
|
780 |
|
|
((tag & SABRE_IOMMUTAG_VPN) << IOMMU_PAGE_SHIFT));
|
781 |
|
|
printk("SABRE%d: IOMMU DATA(%d)[RAW(%016lx)valid(%d)used(%d)cache(%d)ppg(%016lx)\n",
|
782 |
|
|
p->index, i, data,
|
783 |
|
|
((data & SABRE_IOMMUDATA_VALID) ? 1 : 0),
|
784 |
|
|
((data & SABRE_IOMMUDATA_USED) ? 1 : 0),
|
785 |
|
|
((data & SABRE_IOMMUDATA_CACHE) ? 1 : 0),
|
786 |
|
|
((data & SABRE_IOMMUDATA_PPN) << IOMMU_PAGE_SHIFT));
|
787 |
|
|
}
|
788 |
|
|
}
|
789 |
|
|
spin_unlock_irqrestore(&iommu->lock, flags);
|
790 |
|
|
}
|
791 |
|
|
|
792 |
|
|
static void sabre_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
|
793 |
|
|
{
|
794 |
|
|
struct pci_controller_info *p = dev_id;
|
795 |
|
|
unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_UE_AFSR;
|
796 |
|
|
unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR;
|
797 |
|
|
unsigned long afsr, afar, error_bits;
|
798 |
|
|
int reported;
|
799 |
|
|
|
800 |
|
|
/* Latch uncorrectable error status. */
|
801 |
|
|
afar = sabre_read(afar_reg);
|
802 |
|
|
afsr = sabre_read(afsr_reg);
|
803 |
|
|
|
804 |
|
|
/* Clear the primary/secondary error status bits. */
|
805 |
|
|
error_bits = afsr &
|
806 |
|
|
(SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
|
807 |
|
|
SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
|
808 |
|
|
SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE);
|
809 |
|
|
if (!error_bits)
|
810 |
|
|
return;
|
811 |
|
|
sabre_write(afsr_reg, error_bits);
|
812 |
|
|
|
813 |
|
|
/* Log the error. */
|
814 |
|
|
printk("SABRE%d: Uncorrectable Error, primary error type[%s%s]\n",
|
815 |
|
|
p->index,
|
816 |
|
|
((error_bits & SABRE_UEAFSR_PDRD) ?
|
817 |
|
|
"DMA Read" :
|
818 |
|
|
((error_bits & SABRE_UEAFSR_PDWR) ?
|
819 |
|
|
"DMA Write" : "???")),
|
820 |
|
|
((error_bits & SABRE_UEAFSR_PDTE) ?
|
821 |
|
|
":Translation Error" : ""));
|
822 |
|
|
printk("SABRE%d: bytemask[%04lx] dword_offset[%lx] was_block(%d)\n",
|
823 |
|
|
p->index,
|
824 |
|
|
(afsr & SABRE_UEAFSR_BMSK) >> 32UL,
|
825 |
|
|
(afsr & SABRE_UEAFSR_OFF) >> 29UL,
|
826 |
|
|
((afsr & SABRE_UEAFSR_BLK) ? 1 : 0));
|
827 |
|
|
printk("SABRE%d: UE AFAR [%016lx]\n", p->index, afar);
|
828 |
|
|
printk("SABRE%d: UE Secondary errors [", p->index);
|
829 |
|
|
reported = 0;
|
830 |
|
|
if (afsr & SABRE_UEAFSR_SDRD) {
|
831 |
|
|
reported++;
|
832 |
|
|
printk("(DMA Read)");
|
833 |
|
|
}
|
834 |
|
|
if (afsr & SABRE_UEAFSR_SDWR) {
|
835 |
|
|
reported++;
|
836 |
|
|
printk("(DMA Write)");
|
837 |
|
|
}
|
838 |
|
|
if (afsr & SABRE_UEAFSR_SDTE) {
|
839 |
|
|
reported++;
|
840 |
|
|
printk("(Translation Error)");
|
841 |
|
|
}
|
842 |
|
|
if (!reported)
|
843 |
|
|
printk("(none)");
|
844 |
|
|
printk("]\n");
|
845 |
|
|
|
846 |
|
|
/* Interrogate IOMMU for error status. */
|
847 |
|
|
sabre_check_iommu_error(p, afsr, afar);
|
848 |
|
|
}
|
849 |
|
|
|
850 |
|
|
static void sabre_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
|
851 |
|
|
{
|
852 |
|
|
struct pci_controller_info *p = dev_id;
|
853 |
|
|
unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_CE_AFSR;
|
854 |
|
|
unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR;
|
855 |
|
|
unsigned long afsr, afar, error_bits;
|
856 |
|
|
int reported;
|
857 |
|
|
|
858 |
|
|
/* Latch error status. */
|
859 |
|
|
afar = sabre_read(afar_reg);
|
860 |
|
|
afsr = sabre_read(afsr_reg);
|
861 |
|
|
|
862 |
|
|
/* Clear primary/secondary error status bits. */
|
863 |
|
|
error_bits = afsr &
|
864 |
|
|
(SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
|
865 |
|
|
SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR);
|
866 |
|
|
if (!error_bits)
|
867 |
|
|
return;
|
868 |
|
|
sabre_write(afsr_reg, error_bits);
|
869 |
|
|
|
870 |
|
|
/* Log the error. */
|
871 |
|
|
printk("SABRE%d: Correctable Error, primary error type[%s]\n",
|
872 |
|
|
p->index,
|
873 |
|
|
((error_bits & SABRE_CEAFSR_PDRD) ?
|
874 |
|
|
"DMA Read" :
|
875 |
|
|
((error_bits & SABRE_CEAFSR_PDWR) ?
|
876 |
|
|
"DMA Write" : "???")));
|
877 |
|
|
|
878 |
|
|
/* XXX Use syndrome and afar to print out module string just like
|
879 |
|
|
* XXX UDB CE trap handler does... -DaveM
|
880 |
|
|
*/
|
881 |
|
|
printk("SABRE%d: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] "
|
882 |
|
|
"was_block(%d)\n",
|
883 |
|
|
p->index,
|
884 |
|
|
(afsr & SABRE_CEAFSR_ESYND) >> 48UL,
|
885 |
|
|
(afsr & SABRE_CEAFSR_BMSK) >> 32UL,
|
886 |
|
|
(afsr & SABRE_CEAFSR_OFF) >> 29UL,
|
887 |
|
|
((afsr & SABRE_CEAFSR_BLK) ? 1 : 0));
|
888 |
|
|
printk("SABRE%d: CE AFAR [%016lx]\n", p->index, afar);
|
889 |
|
|
printk("SABRE%d: CE Secondary errors [", p->index);
|
890 |
|
|
reported = 0;
|
891 |
|
|
if (afsr & SABRE_CEAFSR_SDRD) {
|
892 |
|
|
reported++;
|
893 |
|
|
printk("(DMA Read)");
|
894 |
|
|
}
|
895 |
|
|
if (afsr & SABRE_CEAFSR_SDWR) {
|
896 |
|
|
reported++;
|
897 |
|
|
printk("(DMA Write)");
|
898 |
|
|
}
|
899 |
|
|
if (!reported)
|
900 |
|
|
printk("(none)");
|
901 |
|
|
printk("]\n");
|
902 |
|
|
}
|
903 |
|
|
|
904 |
|
|
static void sabre_pcierr_intr_other(struct pci_controller_info *p)
|
905 |
|
|
{
|
906 |
|
|
unsigned long csr_reg, csr, csr_error_bits;
|
907 |
|
|
u16 stat;
|
908 |
|
|
|
909 |
|
|
csr_reg = p->pbm_A.controller_regs + SABRE_PCICTRL;
|
910 |
|
|
csr = sabre_read(csr_reg);
|
911 |
|
|
csr_error_bits =
|
912 |
|
|
csr & SABRE_PCICTRL_SERR;
|
913 |
|
|
if (csr_error_bits) {
|
914 |
|
|
/* Clear the errors. */
|
915 |
|
|
sabre_write(csr_reg, csr);
|
916 |
|
|
|
917 |
|
|
/* Log 'em. */
|
918 |
|
|
if (csr_error_bits & SABRE_PCICTRL_SERR)
|
919 |
|
|
printk("SABRE%d: PCI SERR signal asserted.\n",
|
920 |
|
|
p->index);
|
921 |
|
|
}
|
922 |
|
|
pci_read_config_word(sabre_root_bus->self,
|
923 |
|
|
PCI_STATUS, &stat);
|
924 |
|
|
if (stat & (PCI_STATUS_PARITY |
|
925 |
|
|
PCI_STATUS_SIG_TARGET_ABORT |
|
926 |
|
|
PCI_STATUS_REC_TARGET_ABORT |
|
927 |
|
|
PCI_STATUS_REC_MASTER_ABORT |
|
928 |
|
|
PCI_STATUS_SIG_SYSTEM_ERROR)) {
|
929 |
|
|
printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n",
|
930 |
|
|
p->index, stat);
|
931 |
|
|
pci_write_config_word(sabre_root_bus->self,
|
932 |
|
|
PCI_STATUS, 0xffff);
|
933 |
|
|
}
|
934 |
|
|
}
|
935 |
|
|
|
936 |
|
|
static void sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
|
937 |
|
|
{
|
938 |
|
|
struct pci_controller_info *p = dev_id;
|
939 |
|
|
unsigned long afsr_reg, afar_reg;
|
940 |
|
|
unsigned long afsr, afar, error_bits;
|
941 |
|
|
int reported;
|
942 |
|
|
|
943 |
|
|
afsr_reg = p->pbm_A.controller_regs + SABRE_PIOAFSR;
|
944 |
|
|
afar_reg = p->pbm_A.controller_regs + SABRE_PIOAFAR;
|
945 |
|
|
|
946 |
|
|
/* Latch error status. */
|
947 |
|
|
afar = sabre_read(afar_reg);
|
948 |
|
|
afsr = sabre_read(afsr_reg);
|
949 |
|
|
|
950 |
|
|
/* Clear primary/secondary error status bits. */
|
951 |
|
|
error_bits = afsr &
|
952 |
|
|
(SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_PTA |
|
953 |
|
|
SABRE_PIOAFSR_PRTRY | SABRE_PIOAFSR_PPERR |
|
954 |
|
|
SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA |
|
955 |
|
|
SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR);
|
956 |
|
|
if (!error_bits)
|
957 |
|
|
return sabre_pcierr_intr_other(p);
|
958 |
|
|
sabre_write(afsr_reg, error_bits);
|
959 |
|
|
|
960 |
|
|
/* Log the error. */
|
961 |
|
|
printk("SABRE%d: PCI Error, primary error type[%s]\n",
|
962 |
|
|
p->index,
|
963 |
|
|
(((error_bits & SABRE_PIOAFSR_PMA) ?
|
964 |
|
|
"Master Abort" :
|
965 |
|
|
((error_bits & SABRE_PIOAFSR_PTA) ?
|
966 |
|
|
"Target Abort" :
|
967 |
|
|
((error_bits & SABRE_PIOAFSR_PRTRY) ?
|
968 |
|
|
"Excessive Retries" :
|
969 |
|
|
((error_bits & SABRE_PIOAFSR_PPERR) ?
|
970 |
|
|
"Parity Error" : "???"))))));
|
971 |
|
|
printk("SABRE%d: bytemask[%04lx] was_block(%d)\n",
|
972 |
|
|
p->index,
|
973 |
|
|
(afsr & SABRE_PIOAFSR_BMSK) >> 32UL,
|
974 |
|
|
(afsr & SABRE_PIOAFSR_BLK) ? 1 : 0);
|
975 |
|
|
printk("SABRE%d: PCI AFAR [%016lx]\n", p->index, afar);
|
976 |
|
|
printk("SABRE%d: PCI Secondary errors [", p->index);
|
977 |
|
|
reported = 0;
|
978 |
|
|
if (afsr & SABRE_PIOAFSR_SMA) {
|
979 |
|
|
reported++;
|
980 |
|
|
printk("(Master Abort)");
|
981 |
|
|
}
|
982 |
|
|
if (afsr & SABRE_PIOAFSR_STA) {
|
983 |
|
|
reported++;
|
984 |
|
|
printk("(Target Abort)");
|
985 |
|
|
}
|
986 |
|
|
if (afsr & SABRE_PIOAFSR_SRTRY) {
|
987 |
|
|
reported++;
|
988 |
|
|
printk("(Excessive Retries)");
|
989 |
|
|
}
|
990 |
|
|
if (afsr & SABRE_PIOAFSR_SPERR) {
|
991 |
|
|
reported++;
|
992 |
|
|
printk("(Parity Error)");
|
993 |
|
|
}
|
994 |
|
|
if (!reported)
|
995 |
|
|
printk("(none)");
|
996 |
|
|
printk("]\n");
|
997 |
|
|
|
998 |
|
|
/* For the error types shown, scan both PCI buses for devices
|
999 |
|
|
* which have logged that error type.
|
1000 |
|
|
*/
|
1001 |
|
|
|
1002 |
|
|
/* If we see a Target Abort, this could be the result of an
|
1003 |
|
|
* IOMMU translation error of some sort. It is extremely
|
1004 |
|
|
* useful to log this information as usually it indicates
|
1005 |
|
|
* a bug in the IOMMU support code or a PCI device driver.
|
1006 |
|
|
*/
|
1007 |
|
|
if (error_bits & (SABRE_PIOAFSR_PTA | SABRE_PIOAFSR_STA)) {
|
1008 |
|
|
sabre_check_iommu_error(p, afsr, afar);
|
1009 |
|
|
pci_scan_for_target_abort(p, &p->pbm_A, p->pbm_A.pci_bus);
|
1010 |
|
|
pci_scan_for_target_abort(p, &p->pbm_B, p->pbm_B.pci_bus);
|
1011 |
|
|
}
|
1012 |
|
|
if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) {
|
1013 |
|
|
pci_scan_for_master_abort(p, &p->pbm_A, p->pbm_A.pci_bus);
|
1014 |
|
|
pci_scan_for_master_abort(p, &p->pbm_B, p->pbm_B.pci_bus);
|
1015 |
|
|
}
|
1016 |
|
|
/* For excessive retries, SABRE/PBM will abort the device
|
1017 |
|
|
* and there is no way to specifically check for excessive
|
1018 |
|
|
* retries in the config space status registers. So what
|
1019 |
|
|
* we hope is that we'll catch it via the master/target
|
1020 |
|
|
* abort events.
|
1021 |
|
|
*/
|
1022 |
|
|
|
1023 |
|
|
if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) {
|
1024 |
|
|
pci_scan_for_parity_error(p, &p->pbm_A, p->pbm_A.pci_bus);
|
1025 |
|
|
pci_scan_for_parity_error(p, &p->pbm_B, p->pbm_B.pci_bus);
|
1026 |
|
|
}
|
1027 |
|
|
}
|
1028 |
|
|
|
1029 |
|
|
/* XXX What about PowerFail/PowerManagement??? -DaveM */
|
1030 |
|
|
#define SABRE_UE_INO 0x2e
|
1031 |
|
|
#define SABRE_CE_INO 0x2f
|
1032 |
|
|
#define SABRE_PCIERR_INO 0x30
|
1033 |
|
|
static void __init sabre_register_error_handlers(struct pci_controller_info *p)
|
1034 |
|
|
{
|
1035 |
|
|
struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */
|
1036 |
|
|
unsigned long base = pbm->controller_regs;
|
1037 |
|
|
unsigned long irq, portid = pbm->portid;
|
1038 |
|
|
u64 tmp;
|
1039 |
|
|
|
1040 |
|
|
/* We clear the error bits in the appropriate AFSR before
|
1041 |
|
|
* registering the handler so that we don't get spurious
|
1042 |
|
|
* interrupts.
|
1043 |
|
|
*/
|
1044 |
|
|
sabre_write(base + SABRE_UE_AFSR,
|
1045 |
|
|
(SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR |
|
1046 |
|
|
SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR |
|
1047 |
|
|
SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE));
|
1048 |
|
|
irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_UE_INO);
|
1049 |
|
|
if (request_irq(irq, sabre_ue_intr,
|
1050 |
|
|
SA_SHIRQ, "SABRE UE", p) < 0) {
|
1051 |
|
|
prom_printf("SABRE%d: Cannot register UE interrupt.\n",
|
1052 |
|
|
p->index);
|
1053 |
|
|
prom_halt();
|
1054 |
|
|
}
|
1055 |
|
|
|
1056 |
|
|
sabre_write(base + SABRE_CE_AFSR,
|
1057 |
|
|
(SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR |
|
1058 |
|
|
SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR));
|
1059 |
|
|
irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_CE_INO);
|
1060 |
|
|
if (request_irq(irq, sabre_ce_intr,
|
1061 |
|
|
SA_SHIRQ, "SABRE CE", p) < 0) {
|
1062 |
|
|
prom_printf("SABRE%d: Cannot register CE interrupt.\n",
|
1063 |
|
|
p->index);
|
1064 |
|
|
prom_halt();
|
1065 |
|
|
}
|
1066 |
|
|
|
1067 |
|
|
irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_PCIERR_INO);
|
1068 |
|
|
if (request_irq(irq, sabre_pcierr_intr,
|
1069 |
|
|
SA_SHIRQ, "SABRE PCIERR", p) < 0) {
|
1070 |
|
|
prom_printf("SABRE%d: Cannot register PciERR interrupt.\n",
|
1071 |
|
|
p->index);
|
1072 |
|
|
prom_halt();
|
1073 |
|
|
}
|
1074 |
|
|
|
1075 |
|
|
tmp = sabre_read(base + SABRE_PCICTRL);
|
1076 |
|
|
tmp |= SABRE_PCICTRL_ERREN;
|
1077 |
|
|
sabre_write(base + SABRE_PCICTRL, tmp);
|
1078 |
|
|
}
|
1079 |
|
|
|
1080 |
|
|
static void __init sabre_resource_adjust(struct pci_dev *pdev,
|
1081 |
|
|
struct resource *res,
|
1082 |
|
|
struct resource *root)
|
1083 |
|
|
{
|
1084 |
|
|
struct pci_pbm_info *pbm = pci_bus2pbm[pdev->bus->number];
|
1085 |
|
|
unsigned long base;
|
1086 |
|
|
|
1087 |
|
|
if (res->flags & IORESOURCE_IO)
|
1088 |
|
|
base = pbm->controller_regs + SABRE_IOSPACE;
|
1089 |
|
|
else
|
1090 |
|
|
base = pbm->controller_regs + SABRE_MEMSPACE;
|
1091 |
|
|
|
1092 |
|
|
res->start += base;
|
1093 |
|
|
res->end += base;
|
1094 |
|
|
}
|
1095 |
|
|
|
1096 |
|
|
static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
|
1097 |
|
|
{
|
1098 |
|
|
struct pcidev_cookie *pcp = pdev->sysdata;
|
1099 |
|
|
struct pci_pbm_info *pbm = pcp->pbm;
|
1100 |
|
|
struct resource *res;
|
1101 |
|
|
unsigned long base;
|
1102 |
|
|
u32 reg;
|
1103 |
|
|
int where, size, is_64bit;
|
1104 |
|
|
|
1105 |
|
|
res = &pdev->resource[resource];
|
1106 |
|
|
if (resource < 6) {
|
1107 |
|
|
where = PCI_BASE_ADDRESS_0 + (resource * 4);
|
1108 |
|
|
} else if (resource == PCI_ROM_RESOURCE) {
|
1109 |
|
|
where = pdev->rom_base_reg;
|
1110 |
|
|
} else {
|
1111 |
|
|
/* Somebody might have asked allocation of a non-standard resource */
|
1112 |
|
|
return;
|
1113 |
|
|
}
|
1114 |
|
|
|
1115 |
|
|
is_64bit = 0;
|
1116 |
|
|
if (res->flags & IORESOURCE_IO)
|
1117 |
|
|
base = pbm->controller_regs + SABRE_IOSPACE;
|
1118 |
|
|
else {
|
1119 |
|
|
base = pbm->controller_regs + SABRE_MEMSPACE;
|
1120 |
|
|
if ((res->flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
|
1121 |
|
|
== PCI_BASE_ADDRESS_MEM_TYPE_64)
|
1122 |
|
|
is_64bit = 1;
|
1123 |
|
|
}
|
1124 |
|
|
|
1125 |
|
|
size = res->end - res->start;
|
1126 |
|
|
pci_read_config_dword(pdev, where, ®);
|
1127 |
|
|
reg = ((reg & size) |
|
1128 |
|
|
(((u32)(res->start - base)) & ~size));
|
1129 |
|
|
if (resource == PCI_ROM_RESOURCE) {
|
1130 |
|
|
reg |= PCI_ROM_ADDRESS_ENABLE;
|
1131 |
|
|
res->flags |= PCI_ROM_ADDRESS_ENABLE;
|
1132 |
|
|
}
|
1133 |
|
|
pci_write_config_dword(pdev, where, reg);
|
1134 |
|
|
|
1135 |
|
|
/* This knows that the upper 32-bits of the address
|
1136 |
|
|
* must be zero. Our PCI common layer enforces this.
|
1137 |
|
|
*/
|
1138 |
|
|
if (is_64bit)
|
1139 |
|
|
pci_write_config_dword(pdev, where + 4, 0);
|
1140 |
|
|
}
|
1141 |
|
|
|
1142 |
|
|
static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
|
1143 |
|
|
{
|
1144 |
|
|
struct list_head *walk = &sabre_bus->devices;
|
1145 |
|
|
|
1146 |
|
|
for (walk = walk->next; walk != &sabre_bus->devices; walk = walk->next) {
|
1147 |
|
|
struct pci_dev *pdev = pci_dev_b(walk);
|
1148 |
|
|
|
1149 |
|
|
if (pdev->vendor == PCI_VENDOR_ID_SUN &&
|
1150 |
|
|
pdev->device == PCI_DEVICE_ID_SUN_SIMBA) {
|
1151 |
|
|
u16 word;
|
1152 |
|
|
|
1153 |
|
|
sabre_read_word(pdev, PCI_COMMAND, &word);
|
1154 |
|
|
word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
|
1155 |
|
|
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
|
1156 |
|
|
PCI_COMMAND_IO;
|
1157 |
|
|
sabre_write_word(pdev, PCI_COMMAND, word);
|
1158 |
|
|
|
1159 |
|
|
/* Status register bits are "write 1 to clear". */
|
1160 |
|
|
sabre_write_word(pdev, PCI_STATUS, 0xffff);
|
1161 |
|
|
sabre_write_word(pdev, PCI_SEC_STATUS, 0xffff);
|
1162 |
|
|
|
1163 |
|
|
/* Use a primary/seconday latency timer value
|
1164 |
|
|
* of 64.
|
1165 |
|
|
*/
|
1166 |
|
|
sabre_write_byte(pdev, PCI_LATENCY_TIMER, 64);
|
1167 |
|
|
sabre_write_byte(pdev, PCI_SEC_LATENCY_TIMER, 64);
|
1168 |
|
|
|
1169 |
|
|
/* Enable reporting/forwarding of master aborts,
|
1170 |
|
|
* parity, and SERR.
|
1171 |
|
|
*/
|
1172 |
|
|
sabre_write_byte(pdev, PCI_BRIDGE_CONTROL,
|
1173 |
|
|
(PCI_BRIDGE_CTL_PARITY |
|
1174 |
|
|
PCI_BRIDGE_CTL_SERR |
|
1175 |
|
|
PCI_BRIDGE_CTL_MASTER_ABORT));
|
1176 |
|
|
}
|
1177 |
|
|
}
|
1178 |
|
|
}
|
1179 |
|
|
|
1180 |
|
|
static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
|
1181 |
|
|
{
|
1182 |
|
|
struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
|
1183 |
|
|
|
1184 |
|
|
if (!cookie) {
|
1185 |
|
|
prom_printf("SABRE: Critical allocation failure.\n");
|
1186 |
|
|
prom_halt();
|
1187 |
|
|
}
|
1188 |
|
|
|
1189 |
|
|
/* All we care about is the PBM. */
|
1190 |
|
|
memset(cookie, 0, sizeof(*cookie));
|
1191 |
|
|
cookie->pbm = pbm;
|
1192 |
|
|
|
1193 |
|
|
return cookie;
|
1194 |
|
|
}
|
1195 |
|
|
|
1196 |
|
|
static void __init sabre_scan_bus(struct pci_controller_info *p)
|
1197 |
|
|
{
|
1198 |
|
|
static int once;
|
1199 |
|
|
struct pci_bus *sabre_bus;
|
1200 |
|
|
struct pci_pbm_info *pbm;
|
1201 |
|
|
struct pcidev_cookie *cookie;
|
1202 |
|
|
struct list_head *walk;
|
1203 |
|
|
int sabres_scanned;
|
1204 |
|
|
|
1205 |
|
|
/* The APB bridge speaks to the Sabre host PCI bridge
|
1206 |
|
|
* at 66Mhz, but the front side of APB runs at 33Mhz
|
1207 |
|
|
* for both segments.
|
1208 |
|
|
*/
|
1209 |
|
|
p->pbm_A.is_66mhz_capable = 0;
|
1210 |
|
|
p->pbm_B.is_66mhz_capable = 0;
|
1211 |
|
|
|
1212 |
|
|
/* Unlike for PSYCHO, we can only have one SABRE
|
1213 |
|
|
* in a system. Having multiple SABREs is thus
|
1214 |
|
|
* and error, and as a consequence we do not need
|
1215 |
|
|
* to do any bus renumbering but we do have to have
|
1216 |
|
|
* the pci_bus2pbm array setup properly.
|
1217 |
|
|
*
|
1218 |
|
|
* Also note that the SABRE host bridge is hardwired
|
1219 |
|
|
* to live at bus 0.
|
1220 |
|
|
*/
|
1221 |
|
|
if (once != 0) {
|
1222 |
|
|
prom_printf("SABRE: Multiple controllers unsupported.\n");
|
1223 |
|
|
prom_halt();
|
1224 |
|
|
}
|
1225 |
|
|
once++;
|
1226 |
|
|
|
1227 |
|
|
cookie = alloc_bridge_cookie(&p->pbm_A);
|
1228 |
|
|
|
1229 |
|
|
/* The pci_bus2pbm table has already been setup in sabre_init. */
|
1230 |
|
|
sabre_bus = pci_scan_bus(p->pci_first_busno,
|
1231 |
|
|
p->pci_ops,
|
1232 |
|
|
&p->pbm_A);
|
1233 |
|
|
pci_fixup_host_bridge_self(sabre_bus);
|
1234 |
|
|
sabre_bus->self->sysdata = cookie;
|
1235 |
|
|
|
1236 |
|
|
sabre_root_bus = sabre_bus;
|
1237 |
|
|
|
1238 |
|
|
apb_init(p, sabre_bus);
|
1239 |
|
|
|
1240 |
|
|
sabres_scanned = 0;
|
1241 |
|
|
|
1242 |
|
|
walk = &sabre_bus->children;
|
1243 |
|
|
for (walk = walk->next; walk != &sabre_bus->children; walk = walk->next) {
|
1244 |
|
|
struct pci_bus *pbus = pci_bus_b(walk);
|
1245 |
|
|
|
1246 |
|
|
if (pbus->number == p->pbm_A.pci_first_busno) {
|
1247 |
|
|
pbm = &p->pbm_A;
|
1248 |
|
|
} else if (pbus->number == p->pbm_B.pci_first_busno) {
|
1249 |
|
|
pbm = &p->pbm_B;
|
1250 |
|
|
} else
|
1251 |
|
|
continue;
|
1252 |
|
|
|
1253 |
|
|
cookie = alloc_bridge_cookie(pbm);
|
1254 |
|
|
pbus->self->sysdata = cookie;
|
1255 |
|
|
|
1256 |
|
|
sabres_scanned++;
|
1257 |
|
|
|
1258 |
|
|
pbus->sysdata = pbm;
|
1259 |
|
|
pbm->pci_bus = pbus;
|
1260 |
|
|
pci_fill_in_pbm_cookies(pbus, pbm, pbm->prom_node);
|
1261 |
|
|
pci_record_assignments(pbm, pbus);
|
1262 |
|
|
pci_assign_unassigned(pbm, pbus);
|
1263 |
|
|
pci_fixup_irq(pbm, pbus);
|
1264 |
|
|
pci_determine_66mhz_disposition(pbm, pbus);
|
1265 |
|
|
pci_setup_busmastering(pbm, pbus);
|
1266 |
|
|
}
|
1267 |
|
|
|
1268 |
|
|
if (!sabres_scanned) {
|
1269 |
|
|
/* Hummingbird, no APBs. */
|
1270 |
|
|
pbm = &p->pbm_A;
|
1271 |
|
|
sabre_bus->sysdata = pbm;
|
1272 |
|
|
pbm->pci_bus = sabre_bus;
|
1273 |
|
|
pci_fill_in_pbm_cookies(sabre_bus, pbm, pbm->prom_node);
|
1274 |
|
|
pci_record_assignments(pbm, sabre_bus);
|
1275 |
|
|
pci_assign_unassigned(pbm, sabre_bus);
|
1276 |
|
|
pci_fixup_irq(pbm, sabre_bus);
|
1277 |
|
|
pci_determine_66mhz_disposition(pbm, sabre_bus);
|
1278 |
|
|
pci_setup_busmastering(pbm, sabre_bus);
|
1279 |
|
|
}
|
1280 |
|
|
|
1281 |
|
|
sabre_register_error_handlers(p);
|
1282 |
|
|
}
|
1283 |
|
|
|
1284 |
|
|
static void __init sabre_iommu_init(struct pci_controller_info *p,
|
1285 |
|
|
int tsbsize, unsigned long dvma_offset,
|
1286 |
|
|
u32 dma_mask)
|
1287 |
|
|
{
|
1288 |
|
|
struct pci_iommu *iommu = p->pbm_A.iommu;
|
1289 |
|
|
unsigned long tsbbase, i, order;
|
1290 |
|
|
u64 control;
|
1291 |
|
|
|
1292 |
|
|
/* Setup initial software IOMMU state. */
|
1293 |
|
|
spin_lock_init(&iommu->lock);
|
1294 |
|
|
iommu->iommu_cur_ctx = 0;
|
1295 |
|
|
|
1296 |
|
|
/* Register addresses. */
|
1297 |
|
|
iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
|
1298 |
|
|
iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE;
|
1299 |
|
|
iommu->iommu_flush = p->pbm_A.controller_regs + SABRE_IOMMU_FLUSH;
|
1300 |
|
|
iommu->write_complete_reg = p->pbm_A.controller_regs + SABRE_WRSYNC;
|
1301 |
|
|
/* Sabre's IOMMU lacks ctx flushing. */
|
1302 |
|
|
iommu->iommu_ctxflush = 0;
|
1303 |
|
|
|
1304 |
|
|
/* Invalidate TLB Entries. */
|
1305 |
|
|
control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
|
1306 |
|
|
control |= SABRE_IOMMUCTRL_DENAB;
|
1307 |
|
|
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
|
1308 |
|
|
|
1309 |
|
|
for(i = 0; i < 16; i++) {
|
1310 |
|
|
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0);
|
1311 |
|
|
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0);
|
1312 |
|
|
}
|
1313 |
|
|
|
1314 |
|
|
/* Leave diag mode enabled for full-flushing done
|
1315 |
|
|
* in pci_iommu.c
|
1316 |
|
|
*/
|
1317 |
|
|
|
1318 |
|
|
tsbbase = __get_free_pages(GFP_KERNEL, order = get_order(tsbsize * 1024 * 8));
|
1319 |
|
|
if (!tsbbase) {
|
1320 |
|
|
prom_printf("SABRE_IOMMU: Error, gfp(tsb) failed.\n");
|
1321 |
|
|
prom_halt();
|
1322 |
|
|
}
|
1323 |
|
|
iommu->page_table = (iopte_t *)tsbbase;
|
1324 |
|
|
iommu->page_table_map_base = dvma_offset;
|
1325 |
|
|
iommu->dma_addr_mask = dma_mask;
|
1326 |
|
|
memset((char *)tsbbase, 0, PAGE_SIZE << order);
|
1327 |
|
|
|
1328 |
|
|
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
|
1329 |
|
|
|
1330 |
|
|
control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
|
1331 |
|
|
control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
|
1332 |
|
|
control |= SABRE_IOMMUCTRL_ENAB;
|
1333 |
|
|
switch(tsbsize) {
|
1334 |
|
|
case 64:
|
1335 |
|
|
control |= SABRE_IOMMU_TSBSZ_64K;
|
1336 |
|
|
iommu->page_table_sz_bits = 16;
|
1337 |
|
|
break;
|
1338 |
|
|
case 128:
|
1339 |
|
|
control |= SABRE_IOMMU_TSBSZ_128K;
|
1340 |
|
|
iommu->page_table_sz_bits = 17;
|
1341 |
|
|
break;
|
1342 |
|
|
default:
|
1343 |
|
|
prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
|
1344 |
|
|
prom_halt();
|
1345 |
|
|
break;
|
1346 |
|
|
}
|
1347 |
|
|
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
|
1348 |
|
|
|
1349 |
|
|
/* We start with no consistent mappings. */
|
1350 |
|
|
iommu->lowest_consistent_map =
|
1351 |
|
|
1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
|
1352 |
|
|
|
1353 |
|
|
for (i = 0; i < PBM_NCLUSTERS; i++) {
|
1354 |
|
|
iommu->alloc_info[i].flush = 0;
|
1355 |
|
|
iommu->alloc_info[i].next = 0;
|
1356 |
|
|
}
|
1357 |
|
|
}
|
1358 |
|
|
|
1359 |
|
|
static void __init pbm_register_toplevel_resources(struct pci_controller_info *p,
|
1360 |
|
|
struct pci_pbm_info *pbm)
|
1361 |
|
|
{
|
1362 |
|
|
char *name = pbm->name;
|
1363 |
|
|
unsigned long ibase = p->pbm_A.controller_regs + SABRE_IOSPACE;
|
1364 |
|
|
unsigned long mbase = p->pbm_A.controller_regs + SABRE_MEMSPACE;
|
1365 |
|
|
unsigned int devfn;
|
1366 |
|
|
unsigned long first, last, i;
|
1367 |
|
|
u8 *addr, map;
|
1368 |
|
|
|
1369 |
|
|
sprintf(name, "SABRE%d PBM%c",
|
1370 |
|
|
p->index,
|
1371 |
|
|
(pbm == &p->pbm_A ? 'A' : 'B'));
|
1372 |
|
|
pbm->io_space.name = pbm->mem_space.name = name;
|
1373 |
|
|
|
1374 |
|
|
devfn = PCI_DEVFN(1, (pbm == &p->pbm_A) ? 0 : 1);
|
1375 |
|
|
addr = sabre_pci_config_mkaddr(pbm, 0, devfn, APB_IO_ADDRESS_MAP);
|
1376 |
|
|
map = 0;
|
1377 |
|
|
pci_config_read8(addr, &map);
|
1378 |
|
|
|
1379 |
|
|
first = 8;
|
1380 |
|
|
last = 0;
|
1381 |
|
|
for (i = 0; i < 8; i++) {
|
1382 |
|
|
if ((map & (1 << i)) != 0) {
|
1383 |
|
|
if (first > i)
|
1384 |
|
|
first = i;
|
1385 |
|
|
if (last < i)
|
1386 |
|
|
last = i;
|
1387 |
|
|
}
|
1388 |
|
|
}
|
1389 |
|
|
pbm->io_space.start = ibase + (first << 21UL);
|
1390 |
|
|
pbm->io_space.end = ibase + (last << 21UL) + ((1 << 21UL) - 1);
|
1391 |
|
|
pbm->io_space.flags = IORESOURCE_IO;
|
1392 |
|
|
|
1393 |
|
|
addr = sabre_pci_config_mkaddr(pbm, 0, devfn, APB_MEM_ADDRESS_MAP);
|
1394 |
|
|
map = 0;
|
1395 |
|
|
pci_config_read8(addr, &map);
|
1396 |
|
|
|
1397 |
|
|
first = 8;
|
1398 |
|
|
last = 0;
|
1399 |
|
|
for (i = 0; i < 8; i++) {
|
1400 |
|
|
if ((map & (1 << i)) != 0) {
|
1401 |
|
|
if (first > i)
|
1402 |
|
|
first = i;
|
1403 |
|
|
if (last < i)
|
1404 |
|
|
last = i;
|
1405 |
|
|
}
|
1406 |
|
|
}
|
1407 |
|
|
pbm->mem_space.start = mbase + (first << 29UL);
|
1408 |
|
|
pbm->mem_space.end = mbase + (last << 29UL) + ((1 << 29UL) - 1);
|
1409 |
|
|
pbm->mem_space.flags = IORESOURCE_MEM;
|
1410 |
|
|
|
1411 |
|
|
if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
|
1412 |
|
|
prom_printf("Cannot register PBM-%c's IO space.\n",
|
1413 |
|
|
(pbm == &p->pbm_A ? 'A' : 'B'));
|
1414 |
|
|
prom_halt();
|
1415 |
|
|
}
|
1416 |
|
|
if (request_resource(&iomem_resource, &pbm->mem_space) < 0) {
|
1417 |
|
|
prom_printf("Cannot register PBM-%c's MEM space.\n",
|
1418 |
|
|
(pbm == &p->pbm_A ? 'A' : 'B'));
|
1419 |
|
|
prom_halt();
|
1420 |
|
|
}
|
1421 |
|
|
|
1422 |
|
|
/* Register legacy regions if this PBM covers that area. */
|
1423 |
|
|
if (pbm->io_space.start == ibase &&
|
1424 |
|
|
pbm->mem_space.start == mbase)
|
1425 |
|
|
pci_register_legacy_regions(&pbm->io_space,
|
1426 |
|
|
&pbm->mem_space);
|
1427 |
|
|
}
|
1428 |
|
|
|
1429 |
|
|
static void __init sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin)
|
1430 |
|
|
{
|
1431 |
|
|
struct pci_pbm_info *pbm;
|
1432 |
|
|
char namebuf[128];
|
1433 |
|
|
u32 busrange[2];
|
1434 |
|
|
int node, simbas_found;
|
1435 |
|
|
|
1436 |
|
|
simbas_found = 0;
|
1437 |
|
|
node = prom_getchild(sabre_node);
|
1438 |
|
|
while ((node = prom_searchsiblings(node, "pci")) != 0) {
|
1439 |
|
|
int err;
|
1440 |
|
|
|
1441 |
|
|
err = prom_getproperty(node, "model", namebuf, sizeof(namebuf));
|
1442 |
|
|
if ((err <= 0) || strncmp(namebuf, "SUNW,simba", err))
|
1443 |
|
|
goto next_pci;
|
1444 |
|
|
|
1445 |
|
|
err = prom_getproperty(node, "bus-range",
|
1446 |
|
|
(char *)&busrange[0], sizeof(busrange));
|
1447 |
|
|
if (err == 0 || err == -1) {
|
1448 |
|
|
prom_printf("APB: Error, cannot get PCI bus-range.\n");
|
1449 |
|
|
prom_halt();
|
1450 |
|
|
}
|
1451 |
|
|
|
1452 |
|
|
simbas_found++;
|
1453 |
|
|
if (busrange[0] == 1)
|
1454 |
|
|
pbm = &p->pbm_B;
|
1455 |
|
|
else
|
1456 |
|
|
pbm = &p->pbm_A;
|
1457 |
|
|
pbm->chip_type = PBM_CHIP_TYPE_SABRE;
|
1458 |
|
|
pbm->parent = p;
|
1459 |
|
|
pbm->prom_node = node;
|
1460 |
|
|
pbm->pci_first_slot = 1;
|
1461 |
|
|
pbm->pci_first_busno = busrange[0];
|
1462 |
|
|
pbm->pci_last_busno = busrange[1];
|
1463 |
|
|
for (err = pbm->pci_first_busno;
|
1464 |
|
|
err <= pbm->pci_last_busno;
|
1465 |
|
|
err++)
|
1466 |
|
|
pci_bus2pbm[err] = pbm;
|
1467 |
|
|
|
1468 |
|
|
|
1469 |
|
|
prom_getstring(node, "name", pbm->prom_name, sizeof(pbm->prom_name));
|
1470 |
|
|
err = prom_getproperty(node, "ranges",
|
1471 |
|
|
(char *)pbm->pbm_ranges,
|
1472 |
|
|
sizeof(pbm->pbm_ranges));
|
1473 |
|
|
if (err != -1)
|
1474 |
|
|
pbm->num_pbm_ranges =
|
1475 |
|
|
(err / sizeof(struct linux_prom_pci_ranges));
|
1476 |
|
|
else
|
1477 |
|
|
pbm->num_pbm_ranges = 0;
|
1478 |
|
|
|
1479 |
|
|
err = prom_getproperty(node, "interrupt-map",
|
1480 |
|
|
(char *)pbm->pbm_intmap,
|
1481 |
|
|
sizeof(pbm->pbm_intmap));
|
1482 |
|
|
if (err != -1) {
|
1483 |
|
|
pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap));
|
1484 |
|
|
err = prom_getproperty(node, "interrupt-map-mask",
|
1485 |
|
|
(char *)&pbm->pbm_intmask,
|
1486 |
|
|
sizeof(pbm->pbm_intmask));
|
1487 |
|
|
if (err == -1) {
|
1488 |
|
|
prom_printf("APB: Fatal error, no interrupt-map-mask.\n");
|
1489 |
|
|
prom_halt();
|
1490 |
|
|
}
|
1491 |
|
|
} else {
|
1492 |
|
|
pbm->num_pbm_intmap = 0;
|
1493 |
|
|
memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
|
1494 |
|
|
}
|
1495 |
|
|
|
1496 |
|
|
pbm_register_toplevel_resources(p, pbm);
|
1497 |
|
|
|
1498 |
|
|
next_pci:
|
1499 |
|
|
node = prom_getsibling(node);
|
1500 |
|
|
if (!node)
|
1501 |
|
|
break;
|
1502 |
|
|
}
|
1503 |
|
|
if (simbas_found == 0) {
|
1504 |
|
|
int err;
|
1505 |
|
|
|
1506 |
|
|
/* No APBs underneath, probably this is a hummingbird
|
1507 |
|
|
* system.
|
1508 |
|
|
*/
|
1509 |
|
|
pbm = &p->pbm_A;
|
1510 |
|
|
pbm->parent = p;
|
1511 |
|
|
pbm->prom_node = sabre_node;
|
1512 |
|
|
pbm->pci_first_busno = p->pci_first_busno;
|
1513 |
|
|
pbm->pci_last_busno = p->pci_last_busno;
|
1514 |
|
|
for (err = pbm->pci_first_busno;
|
1515 |
|
|
err <= pbm->pci_last_busno;
|
1516 |
|
|
err++)
|
1517 |
|
|
pci_bus2pbm[err] = pbm;
|
1518 |
|
|
|
1519 |
|
|
prom_getstring(sabre_node, "name", pbm->prom_name, sizeof(pbm->prom_name));
|
1520 |
|
|
err = prom_getproperty(sabre_node, "ranges",
|
1521 |
|
|
(char *) pbm->pbm_ranges,
|
1522 |
|
|
sizeof(pbm->pbm_ranges));
|
1523 |
|
|
if (err != -1)
|
1524 |
|
|
pbm->num_pbm_ranges =
|
1525 |
|
|
(err / sizeof(struct linux_prom_pci_ranges));
|
1526 |
|
|
else
|
1527 |
|
|
pbm->num_pbm_ranges = 0;
|
1528 |
|
|
|
1529 |
|
|
err = prom_getproperty(sabre_node, "interrupt-map",
|
1530 |
|
|
(char *) pbm->pbm_intmap,
|
1531 |
|
|
sizeof(pbm->pbm_intmap));
|
1532 |
|
|
|
1533 |
|
|
if (err != -1) {
|
1534 |
|
|
pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap));
|
1535 |
|
|
err = prom_getproperty(sabre_node, "interrupt-map-mask",
|
1536 |
|
|
(char *)&pbm->pbm_intmask,
|
1537 |
|
|
sizeof(pbm->pbm_intmask));
|
1538 |
|
|
if (err == -1) {
|
1539 |
|
|
prom_printf("Hummingbird: Fatal error, no interrupt-map-mask.\n");
|
1540 |
|
|
prom_halt();
|
1541 |
|
|
}
|
1542 |
|
|
} else {
|
1543 |
|
|
pbm->num_pbm_intmap = 0;
|
1544 |
|
|
memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
|
1545 |
|
|
}
|
1546 |
|
|
|
1547 |
|
|
|
1548 |
|
|
sprintf(pbm->name, "SABRE%d PBM%c", p->index,
|
1549 |
|
|
(pbm == &p->pbm_A ? 'A' : 'B'));
|
1550 |
|
|
pbm->io_space.name = pbm->mem_space.name = pbm->name;
|
1551 |
|
|
|
1552 |
|
|
/* Hack up top-level resources. */
|
1553 |
|
|
pbm->io_space.start = p->pbm_A.controller_regs + SABRE_IOSPACE;
|
1554 |
|
|
pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL;
|
1555 |
|
|
pbm->io_space.flags = IORESOURCE_IO;
|
1556 |
|
|
|
1557 |
|
|
pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE;
|
1558 |
|
|
pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL;
|
1559 |
|
|
pbm->mem_space.flags = IORESOURCE_MEM;
|
1560 |
|
|
|
1561 |
|
|
if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
|
1562 |
|
|
prom_printf("Cannot register Hummingbird's IO space.\n");
|
1563 |
|
|
prom_halt();
|
1564 |
|
|
}
|
1565 |
|
|
if (request_resource(&iomem_resource, &pbm->mem_space) < 0) {
|
1566 |
|
|
prom_printf("Cannot register Hummingbird's MEM space.\n");
|
1567 |
|
|
prom_halt();
|
1568 |
|
|
}
|
1569 |
|
|
|
1570 |
|
|
pci_register_legacy_regions(&pbm->io_space,
|
1571 |
|
|
&pbm->mem_space);
|
1572 |
|
|
}
|
1573 |
|
|
}
|
1574 |
|
|
|
1575 |
|
|
void __init sabre_init(int pnode, char *model_name)
|
1576 |
|
|
{
|
1577 |
|
|
struct linux_prom64_registers pr_regs[2];
|
1578 |
|
|
struct pci_controller_info *p;
|
1579 |
|
|
struct pci_iommu *iommu;
|
1580 |
|
|
unsigned long flags;
|
1581 |
|
|
int tsbsize, err;
|
1582 |
|
|
u32 busrange[2];
|
1583 |
|
|
u32 vdma[2];
|
1584 |
|
|
u32 upa_portid, dma_mask;
|
1585 |
|
|
u64 clear_irq;
|
1586 |
|
|
int bus;
|
1587 |
|
|
|
1588 |
|
|
hummingbird_p = 0;
|
1589 |
|
|
if (!strcmp(model_name, "pci108e,a001"))
|
1590 |
|
|
hummingbird_p = 1;
|
1591 |
|
|
else if (!strcmp(model_name, "SUNW,sabre")) {
|
1592 |
|
|
char compat[64];
|
1593 |
|
|
|
1594 |
|
|
if (prom_getproperty(pnode, "compatible",
|
1595 |
|
|
compat, sizeof(compat)) > 0 &&
|
1596 |
|
|
!strcmp(compat, "pci108e,a001")) {
|
1597 |
|
|
hummingbird_p = 1;
|
1598 |
|
|
} else {
|
1599 |
|
|
int cpu_node = linux_cpus[0].prom_node;
|
1600 |
|
|
|
1601 |
|
|
/* Of course, Sun has to encode things a thousand
|
1602 |
|
|
* different ways, inconsistently.
|
1603 |
|
|
*/
|
1604 |
|
|
if (prom_getproperty(cpu_node, "name",
|
1605 |
|
|
compat, sizeof(compat)) > 0 &&
|
1606 |
|
|
!strcmp(compat, "SUNW,UltraSPARC-IIe"))
|
1607 |
|
|
hummingbird_p = 1;
|
1608 |
|
|
}
|
1609 |
|
|
}
|
1610 |
|
|
|
1611 |
|
|
p = kmalloc(sizeof(*p), GFP_ATOMIC);
|
1612 |
|
|
if (!p) {
|
1613 |
|
|
prom_printf("SABRE: Error, kmalloc(pci_controller_info) failed.\n");
|
1614 |
|
|
prom_halt();
|
1615 |
|
|
}
|
1616 |
|
|
memset(p, 0, sizeof(*p));
|
1617 |
|
|
|
1618 |
|
|
iommu = kmalloc(sizeof(*iommu), GFP_ATOMIC);
|
1619 |
|
|
if (!iommu) {
|
1620 |
|
|
prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n");
|
1621 |
|
|
prom_halt();
|
1622 |
|
|
}
|
1623 |
|
|
memset(iommu, 0, sizeof(*iommu));
|
1624 |
|
|
p->pbm_A.iommu = p->pbm_B.iommu = iommu;
|
1625 |
|
|
|
1626 |
|
|
upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff);
|
1627 |
|
|
|
1628 |
|
|
spin_lock_irqsave(&pci_controller_lock, flags);
|
1629 |
|
|
p->next = pci_controller_root;
|
1630 |
|
|
pci_controller_root = p;
|
1631 |
|
|
spin_unlock_irqrestore(&pci_controller_lock, flags);
|
1632 |
|
|
|
1633 |
|
|
p->pbm_A.portid = upa_portid;
|
1634 |
|
|
p->pbm_B.portid = upa_portid;
|
1635 |
|
|
p->index = pci_num_controllers++;
|
1636 |
|
|
p->pbms_same_domain = 1;
|
1637 |
|
|
p->scan_bus = sabre_scan_bus;
|
1638 |
|
|
p->irq_build = sabre_irq_build;
|
1639 |
|
|
p->base_address_update = sabre_base_address_update;
|
1640 |
|
|
p->resource_adjust = sabre_resource_adjust;
|
1641 |
|
|
p->pci_ops = &sabre_ops;
|
1642 |
|
|
|
1643 |
|
|
/*
|
1644 |
|
|
* Map in SABRE register set and report the presence of this SABRE.
|
1645 |
|
|
*/
|
1646 |
|
|
err = prom_getproperty(pnode, "reg",
|
1647 |
|
|
(char *)&pr_regs[0], sizeof(pr_regs));
|
1648 |
|
|
if(err == 0 || err == -1) {
|
1649 |
|
|
prom_printf("SABRE: Error, cannot get U2P registers "
|
1650 |
|
|
"from PROM.\n");
|
1651 |
|
|
prom_halt();
|
1652 |
|
|
}
|
1653 |
|
|
|
1654 |
|
|
/*
|
1655 |
|
|
* First REG in property is base of entire SABRE register space.
|
1656 |
|
|
*/
|
1657 |
|
|
p->pbm_A.controller_regs = pr_regs[0].phys_addr;
|
1658 |
|
|
p->pbm_B.controller_regs = pr_regs[0].phys_addr;
|
1659 |
|
|
pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC;
|
1660 |
|
|
|
1661 |
|
|
printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n",
|
1662 |
|
|
p->pbm_A.controller_regs, pci_dma_wsync);
|
1663 |
|
|
|
1664 |
|
|
/* Clear interrupts */
|
1665 |
|
|
|
1666 |
|
|
/* PCI first */
|
1667 |
|
|
for (clear_irq = SABRE_ICLR_A_SLOT0; clear_irq < SABRE_ICLR_B_SLOT0 + 0x80; clear_irq += 8)
|
1668 |
|
|
sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL);
|
1669 |
|
|
|
1670 |
|
|
/* Then OBIO */
|
1671 |
|
|
for (clear_irq = SABRE_ICLR_SCSI; clear_irq < SABRE_ICLR_SCSI + 0x80; clear_irq += 8)
|
1672 |
|
|
sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL);
|
1673 |
|
|
|
1674 |
|
|
/* Error interrupts are enabled later after the bus scan. */
|
1675 |
|
|
sabre_write(p->pbm_A.controller_regs + SABRE_PCICTRL,
|
1676 |
|
|
(SABRE_PCICTRL_MRLEN | SABRE_PCICTRL_SERR |
|
1677 |
|
|
SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN));
|
1678 |
|
|
|
1679 |
|
|
/* Now map in PCI config space for entire SABRE. */
|
1680 |
|
|
p->pbm_A.config_space = p->pbm_B.config_space =
|
1681 |
|
|
(p->pbm_A.controller_regs + SABRE_CONFIGSPACE);
|
1682 |
|
|
printk("SABRE: Shared PCI config space at %016lx\n",
|
1683 |
|
|
p->pbm_A.config_space);
|
1684 |
|
|
|
1685 |
|
|
err = prom_getproperty(pnode, "virtual-dma",
|
1686 |
|
|
(char *)&vdma[0], sizeof(vdma));
|
1687 |
|
|
if(err == 0 || err == -1) {
|
1688 |
|
|
prom_printf("SABRE: Error, cannot get virtual-dma property "
|
1689 |
|
|
"from PROM.\n");
|
1690 |
|
|
prom_halt();
|
1691 |
|
|
}
|
1692 |
|
|
|
1693 |
|
|
dma_mask = vdma[0];
|
1694 |
|
|
switch(vdma[1]) {
|
1695 |
|
|
case 0x20000000:
|
1696 |
|
|
dma_mask |= 0x1fffffff;
|
1697 |
|
|
tsbsize = 64;
|
1698 |
|
|
break;
|
1699 |
|
|
case 0x40000000:
|
1700 |
|
|
dma_mask |= 0x3fffffff;
|
1701 |
|
|
tsbsize = 128;
|
1702 |
|
|
break;
|
1703 |
|
|
|
1704 |
|
|
case 0x80000000:
|
1705 |
|
|
dma_mask |= 0x7fffffff;
|
1706 |
|
|
tsbsize = 128;
|
1707 |
|
|
break;
|
1708 |
|
|
default:
|
1709 |
|
|
prom_printf("SABRE: strange virtual-dma size.\n");
|
1710 |
|
|
prom_halt();
|
1711 |
|
|
}
|
1712 |
|
|
|
1713 |
|
|
sabre_iommu_init(p, tsbsize, vdma[0], dma_mask);
|
1714 |
|
|
|
1715 |
|
|
printk("SABRE: DVMA at %08x [%08x]\n", vdma[0], vdma[1]);
|
1716 |
|
|
|
1717 |
|
|
err = prom_getproperty(pnode, "bus-range",
|
1718 |
|
|
(char *)&busrange[0], sizeof(busrange));
|
1719 |
|
|
if(err == 0 || err == -1) {
|
1720 |
|
|
prom_printf("SABRE: Error, cannot get PCI bus-range "
|
1721 |
|
|
" from PROM.\n");
|
1722 |
|
|
prom_halt();
|
1723 |
|
|
}
|
1724 |
|
|
|
1725 |
|
|
p->pci_first_busno = busrange[0];
|
1726 |
|
|
p->pci_last_busno = busrange[1];
|
1727 |
|
|
|
1728 |
|
|
/*
|
1729 |
|
|
* Handle config space reads through any Simba on APB.
|
1730 |
|
|
*/
|
1731 |
|
|
for (bus = p->pci_first_busno; bus <= p->pci_last_busno; bus++)
|
1732 |
|
|
pci_bus2pbm[bus] = &p->pbm_A;
|
1733 |
|
|
|
1734 |
|
|
/*
|
1735 |
|
|
* Look for APB underneath.
|
1736 |
|
|
*/
|
1737 |
|
|
sabre_pbm_init(p, pnode, vdma[0]);
|
1738 |
|
|
}
|