Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Marvel systems use the IO7 I/O chip provides PCI/PCIX/AGP access | |
3 | * | |
4 | * This file is based on: | |
5 | * | |
6 | * Marvel / EV7 System Programmer's Manual | |
7 | * Revision 1.00 | |
8 | * 14 May 2001 | |
9 | */ | |
10 | ||
11 | #ifndef __ALPHA_MARVEL__H__ | |
12 | #define __ALPHA_MARVEL__H__ | |
13 | ||
14 | #include <linux/types.h> | |
15 | #include <linux/pci.h> | |
16 | #include <linux/spinlock.h> | |
17 | ||
18 | #include <asm/compiler.h> | |
19 | ||
20 | #define MARVEL_MAX_PIDS 32 /* as long as we rely on 43-bit superpage */ | |
21 | #define MARVEL_IRQ_VEC_PE_SHIFT (10) | |
22 | #define MARVEL_IRQ_VEC_IRQ_MASK ((1 << MARVEL_IRQ_VEC_PE_SHIFT) - 1) | |
23 | #define MARVEL_NR_IRQS \ | |
24 | (16 + (MARVEL_MAX_PIDS * (1 << MARVEL_IRQ_VEC_PE_SHIFT))) | |
25 | ||
26 | /* | |
27 | * EV7 RBOX Registers | |
28 | */ | |
29 | typedef struct { | |
30 | volatile unsigned long csr __attribute__((aligned(16))); | |
31 | } ev7_csr; | |
32 | ||
33 | typedef struct { | |
34 | ev7_csr RBOX_CFG; /* 0x0000 */ | |
35 | ev7_csr RBOX_NSVC; | |
36 | ev7_csr RBOX_EWVC; | |
37 | ev7_csr RBOX_WHAMI; | |
38 | ev7_csr RBOX_TCTL; /* 0x0040 */ | |
39 | ev7_csr RBOX_INT; | |
40 | ev7_csr RBOX_IMASK; | |
41 | ev7_csr RBOX_IREQ; | |
42 | ev7_csr RBOX_INTQ; /* 0x0080 */ | |
43 | ev7_csr RBOX_INTA; | |
44 | ev7_csr RBOX_IT; | |
45 | ev7_csr RBOX_SCRATCH1; | |
46 | ev7_csr RBOX_SCRATCH2; /* 0x00c0 */ | |
47 | ev7_csr RBOX_L_ERR; | |
48 | } ev7_csrs; | |
49 | ||
50 | /* | |
51 | * EV7 CSR addressing macros | |
52 | */ | |
53 | #define EV7_MASK40(addr) ((addr) & ((1UL << 41) - 1)) | |
54 | #define EV7_KERN_ADDR(addr) ((void *)(IDENT_ADDR | EV7_MASK40(addr))) | |
55 | ||
56 | #define EV7_PE_MASK 0x1ffUL /* 9 bits ( 256 + mem/io ) */ | |
57 | #define EV7_IPE(pe) ((~((long)(pe)) & EV7_PE_MASK) << 35) | |
58 | ||
59 | #define EV7_CSR_PHYS(pe, off) (EV7_IPE(pe) | (0x7FFCUL << 20) | (off)) | |
60 | #define EV7_CSRS_PHYS(pe) (EV7_CSR_PHYS(pe, 0UL)) | |
61 | ||
62 | #define EV7_CSR_KERN(pe, off) (EV7_KERN_ADDR(EV7_CSR_PHYS(pe, off))) | |
63 | #define EV7_CSRS_KERN(pe) (EV7_KERN_ADDR(EV7_CSRS_PHYS(pe))) | |
64 | ||
65 | #define EV7_CSR_OFFSET(name) ((unsigned long)&((ev7_csrs *)NULL)->name.csr) | |
66 | ||
67 | /* | |
68 | * IO7 registers | |
69 | */ | |
70 | typedef struct { | |
71 | volatile unsigned long csr __attribute__((aligned(64))); | |
72 | } io7_csr; | |
73 | ||
74 | typedef struct { | |
75 | /* I/O Port Control Registers */ | |
76 | io7_csr POx_CTRL; /* 0x0000 */ | |
77 | io7_csr POx_CACHE_CTL; | |
78 | io7_csr POx_TIMER; | |
79 | io7_csr POx_IO_ADR_EXT; | |
80 | io7_csr POx_MEM_ADR_EXT; /* 0x0100 */ | |
81 | io7_csr POx_XCAL_CTRL; | |
82 | io7_csr rsvd1[2]; /* ?? spec doesn't show 0x180 */ | |
83 | io7_csr POx_DM_SOURCE; /* 0x0200 */ | |
84 | io7_csr POx_DM_DEST; | |
85 | io7_csr POx_DM_SIZE; | |
86 | io7_csr POx_DM_CTRL; | |
87 | io7_csr rsvd2[4]; /* 0x0300 */ | |
88 | ||
89 | /* AGP Control Registers -- port 3 only */ | |
90 | io7_csr AGP_CAP_ID; /* 0x0400 */ | |
91 | io7_csr AGP_STAT; | |
92 | io7_csr AGP_CMD; | |
93 | io7_csr rsvd3; | |
94 | ||
95 | /* I/O Port Monitor Registers */ | |
96 | io7_csr POx_MONCTL; /* 0x0500 */ | |
97 | io7_csr POx_CTRA; | |
98 | io7_csr POx_CTRB; | |
99 | io7_csr POx_CTR56; | |
100 | io7_csr POx_SCRATCH; /* 0x0600 */ | |
101 | io7_csr POx_XTRA_A; | |
102 | io7_csr POx_XTRA_TS; | |
103 | io7_csr POx_XTRA_Z; | |
104 | io7_csr rsvd4; /* 0x0700 */ | |
105 | io7_csr POx_THRESHA; | |
106 | io7_csr POx_THRESHB; | |
107 | io7_csr rsvd5[33]; | |
108 | ||
109 | /* System Address Space Window Control Registers */ | |
110 | ||
111 | io7_csr POx_WBASE[4]; /* 0x1000 */ | |
112 | io7_csr POx_WMASK[4]; | |
113 | io7_csr POx_TBASE[4]; | |
114 | io7_csr POx_SG_TBIA; | |
115 | io7_csr POx_MSI_WBASE; | |
116 | io7_csr rsvd6[50]; | |
117 | ||
118 | /* I/O Port Error Registers */ | |
119 | io7_csr POx_ERR_SUM; | |
120 | io7_csr POx_FIRST_ERR; | |
121 | io7_csr POx_MSK_HEI; | |
122 | io7_csr POx_TLB_ERR; | |
123 | io7_csr POx_SPL_COMPLT; | |
124 | io7_csr POx_TRANS_SUM; | |
125 | io7_csr POx_FRC_PCI_ERR; | |
126 | io7_csr POx_MULT_ERR; | |
127 | io7_csr rsvd7[8]; | |
128 | ||
129 | /* I/O Port End of Interrupt Registers */ | |
130 | io7_csr EOI_DAT; | |
131 | io7_csr rsvd8[7]; | |
132 | io7_csr POx_IACK_SPECIAL; | |
133 | io7_csr rsvd9[103]; | |
134 | } io7_ioport_csrs; | |
135 | ||
136 | typedef struct { | |
137 | io7_csr IO_ASIC_REV; /* 0x30.0000 */ | |
138 | io7_csr IO_SYS_REV; | |
139 | io7_csr SER_CHAIN3; | |
140 | io7_csr PO7_RST1; | |
141 | io7_csr PO7_RST2; /* 0x30.0100 */ | |
142 | io7_csr POx_RST[4]; | |
143 | io7_csr IO7_DWNH; | |
144 | io7_csr IO7_MAF; | |
145 | io7_csr IO7_MAF_TO; | |
146 | io7_csr IO7_ACC_CLUMP; /* 0x30.0300 */ | |
147 | io7_csr IO7_PMASK; | |
148 | io7_csr IO7_IOMASK; | |
149 | io7_csr IO7_UPH; | |
150 | io7_csr IO7_UPH_TO; /* 0x30.0400 */ | |
151 | io7_csr RBX_IREQ_OFF; | |
152 | io7_csr RBX_INTA_OFF; | |
153 | io7_csr INT_RTY; | |
154 | io7_csr PO7_MONCTL; /* 0x30.0500 */ | |
155 | io7_csr PO7_CTRA; | |
156 | io7_csr PO7_CTRB; | |
157 | io7_csr PO7_CTR56; | |
158 | io7_csr PO7_SCRATCH; /* 0x30.0600 */ | |
159 | io7_csr PO7_XTRA_A; | |
160 | io7_csr PO7_XTRA_TS; | |
161 | io7_csr PO7_XTRA_Z; | |
162 | io7_csr PO7_PMASK; /* 0x30.0700 */ | |
163 | io7_csr PO7_THRESHA; | |
164 | io7_csr PO7_THRESHB; | |
165 | io7_csr rsvd1[97]; | |
166 | io7_csr PO7_ERROR_SUM; /* 0x30.2000 */ | |
167 | io7_csr PO7_BHOLE_MASK; | |
168 | io7_csr PO7_HEI_MSK; | |
169 | io7_csr PO7_CRD_MSK; | |
170 | io7_csr PO7_UNCRR_SYM; /* 0x30.2100 */ | |
171 | io7_csr PO7_CRRCT_SYM; | |
172 | io7_csr PO7_ERR_PKT[2]; | |
173 | io7_csr PO7_UGBGE_SYM; /* 0x30.2200 */ | |
174 | io7_csr rsbv2[887]; | |
175 | io7_csr PO7_LSI_CTL[128]; /* 0x31.0000 */ | |
176 | io7_csr rsvd3[123]; | |
177 | io7_csr HLT_CTL; /* 0x31.3ec0 */ | |
178 | io7_csr HPI_CTL; /* 0x31.3f00 */ | |
179 | io7_csr CRD_CTL; | |
180 | io7_csr STV_CTL; | |
181 | io7_csr HEI_CTL; | |
182 | io7_csr PO7_MSI_CTL[16]; /* 0x31.4000 */ | |
183 | io7_csr rsvd4[240]; | |
184 | ||
185 | /* | |
186 | * Interrupt Diagnostic / Test | |
187 | */ | |
188 | struct { | |
189 | io7_csr INT_PND; | |
190 | io7_csr INT_CLR; | |
191 | io7_csr INT_EOI; | |
192 | io7_csr rsvd[29]; | |
193 | } INT_DIAG[4]; | |
194 | io7_csr rsvd5[125]; /* 0x31.a000 */ | |
195 | io7_csr MISC_PND; /* 0x31.b800 */ | |
196 | io7_csr rsvd6[31]; | |
197 | io7_csr MSI_PND[16]; /* 0x31.c000 */ | |
198 | io7_csr rsvd7[16]; | |
199 | io7_csr MSI_CLR[16]; /* 0x31.c800 */ | |
200 | } io7_port7_csrs; | |
201 | ||
202 | /* | |
203 | * IO7 DMA Window Base register (POx_WBASEx) | |
204 | */ | |
205 | #define wbase_m_ena 0x1 | |
206 | #define wbase_m_sg 0x2 | |
207 | #define wbase_m_dac 0x4 | |
208 | #define wbase_m_addr 0xFFF00000 | |
209 | union IO7_POx_WBASE { | |
210 | struct { | |
211 | unsigned ena : 1; /* <0> */ | |
212 | unsigned sg : 1; /* <1> */ | |
213 | unsigned dac : 1; /* <2> -- window 3 only */ | |
214 | unsigned rsvd1 : 17; | |
215 | unsigned addr : 12; /* <31:20> */ | |
216 | unsigned rsvd2 : 32; | |
217 | } bits; | |
218 | unsigned as_long[2]; | |
219 | unsigned as_quad; | |
220 | }; | |
221 | ||
222 | /* | |
223 | * IO7 IID (Interrupt IDentifier) format | |
224 | * | |
225 | * For level-sensative interrupts, int_num is encoded as: | |
226 | * | |
227 | * bus/port slot/device INTx | |
228 | * <7:5> <4:2> <1:0> | |
229 | */ | |
230 | union IO7_IID { | |
231 | struct { | |
232 | unsigned int_num : 9; /* <8:0> */ | |
233 | unsigned tpu_mask : 4; /* <12:9> rsvd */ | |
234 | unsigned msi : 1; /* 13 */ | |
235 | unsigned ipe : 10; /* <23:14> */ | |
236 | unsigned long rsvd : 40; | |
237 | } bits; | |
238 | unsigned int as_long[2]; | |
239 | unsigned long as_quad; | |
240 | }; | |
241 | ||
242 | /* | |
243 | * IO7 addressing macros | |
244 | */ | |
245 | #define IO7_KERN_ADDR(addr) (EV7_KERN_ADDR(addr)) | |
246 | ||
247 | #define IO7_PORT_MASK 0x07UL /* 3 bits of port */ | |
248 | ||
249 | #define IO7_IPE(pe) (EV7_IPE(pe)) | |
250 | #define IO7_IPORT(port) ((~((long)(port)) & IO7_PORT_MASK) << 32) | |
251 | ||
252 | #define IO7_HOSE(pe, port) (IO7_IPE(pe) | IO7_IPORT(port)) | |
253 | ||
254 | #define IO7_MEM_PHYS(pe, port) (IO7_HOSE(pe, port) | 0x00000000UL) | |
255 | #define IO7_CONF_PHYS(pe, port) (IO7_HOSE(pe, port) | 0xFE000000UL) | |
256 | #define IO7_IO_PHYS(pe, port) (IO7_HOSE(pe, port) | 0xFF000000UL) | |
257 | #define IO7_CSR_PHYS(pe, port, off) \ | |
258 | (IO7_HOSE(pe, port) | 0xFF800000UL | (off)) | |
259 | #define IO7_CSRS_PHYS(pe, port) (IO7_CSR_PHYS(pe, port, 0UL)) | |
260 | #define IO7_PORT7_CSRS_PHYS(pe) (IO7_CSR_PHYS(pe, 7, 0x300000UL)) | |
261 | ||
262 | #define IO7_MEM_KERN(pe, port) (IO7_KERN_ADDR(IO7_MEM_PHYS(pe, port))) | |
263 | #define IO7_CONF_KERN(pe, port) (IO7_KERN_ADDR(IO7_CONF_PHYS(pe, port))) | |
264 | #define IO7_IO_KERN(pe, port) (IO7_KERN_ADDR(IO7_IO_PHYS(pe, port))) | |
265 | #define IO7_CSR_KERN(pe, port, off) (IO7_KERN_ADDR(IO7_CSR_PHYS(pe,port,off))) | |
266 | #define IO7_CSRS_KERN(pe, port) (IO7_KERN_ADDR(IO7_CSRS_PHYS(pe, port))) | |
267 | #define IO7_PORT7_CSRS_KERN(pe) (IO7_KERN_ADDR(IO7_PORT7_CSRS_PHYS(pe))) | |
268 | ||
269 | #define IO7_PLL_RNGA(pll) (((pll) >> 3) & 0x7) | |
270 | #define IO7_PLL_RNGB(pll) (((pll) >> 6) & 0x7) | |
271 | ||
272 | #define IO7_MEM_SPACE (2UL * 1024 * 1024 * 1024) /* 2GB MEM */ | |
273 | #define IO7_IO_SPACE (8UL * 1024 * 1024) /* 8MB I/O */ | |
274 | ||
275 | ||
276 | /* | |
277 | * Offset between ram physical addresses and pci64 DAC addresses | |
278 | */ | |
279 | #define IO7_DAC_OFFSET (1UL << 49) | |
280 | ||
281 | /* | |
282 | * This is needed to satisify the IO() macro used in initializing the machvec | |
283 | */ | |
284 | #define MARVEL_IACK_SC \ | |
285 | ((unsigned long) \ | |
286 | (&(((io7_ioport_csrs *)IO7_CSRS_KERN(0, 0))->POx_IACK_SPECIAL))) | |
287 | ||
288 | #ifdef __KERNEL__ | |
289 | ||
290 | /* | |
291 | * IO7 structs | |
292 | */ | |
293 | #define IO7_NUM_PORTS 4 | |
294 | #define IO7_AGP_PORT 3 | |
295 | ||
296 | struct io7_port { | |
297 | struct io7 *io7; | |
298 | struct pci_controller *hose; | |
299 | ||
300 | int enabled; | |
301 | unsigned int port; | |
302 | io7_ioport_csrs *csrs; | |
303 | ||
304 | unsigned long saved_wbase[4]; | |
305 | unsigned long saved_wmask[4]; | |
306 | unsigned long saved_tbase[4]; | |
307 | }; | |
308 | ||
309 | struct io7 { | |
310 | struct io7 *next; | |
311 | ||
312 | unsigned int pe; | |
313 | io7_port7_csrs *csrs; | |
314 | struct io7_port ports[IO7_NUM_PORTS]; | |
315 | ||
316 | spinlock_t irq_lock; | |
317 | }; | |
318 | ||
319 | #ifndef __EXTERN_INLINE | |
320 | # define __EXTERN_INLINE extern inline | |
321 | # define __IO_EXTERN_INLINE | |
322 | #endif | |
323 | ||
324 | /* | |
325 | * I/O functions. All access through linear space. | |
326 | */ | |
327 | ||
328 | /* | |
329 | * Memory functions. All accesses through linear space. | |
330 | */ | |
331 | ||
332 | #define vucp volatile unsigned char __force * | |
333 | #define vusp volatile unsigned short __force * | |
334 | ||
335 | extern unsigned int marvel_ioread8(void __iomem *); | |
336 | extern void marvel_iowrite8(u8 b, void __iomem *); | |
337 | ||
338 | __EXTERN_INLINE unsigned int marvel_ioread16(void __iomem *addr) | |
339 | { | |
340 | return __kernel_ldwu(*(vusp)addr); | |
341 | } | |
342 | ||
343 | __EXTERN_INLINE void marvel_iowrite16(u16 b, void __iomem *addr) | |
344 | { | |
345 | __kernel_stw(b, *(vusp)addr); | |
346 | } | |
347 | ||
348 | extern void __iomem *marvel_ioremap(unsigned long addr, unsigned long size); | |
349 | extern void marvel_iounmap(volatile void __iomem *addr); | |
350 | extern void __iomem *marvel_ioportmap (unsigned long addr); | |
351 | ||
352 | __EXTERN_INLINE int marvel_is_ioaddr(unsigned long addr) | |
353 | { | |
354 | return (addr >> 40) & 1; | |
355 | } | |
356 | ||
357 | extern int marvel_is_mmio(const volatile void __iomem *); | |
358 | ||
359 | #undef vucp | |
360 | #undef vusp | |
361 | ||
362 | #undef __IO_PREFIX | |
363 | #define __IO_PREFIX marvel | |
364 | #define marvel_trivial_rw_bw 1 | |
365 | #define marvel_trivial_rw_lq 1 | |
366 | #define marvel_trivial_io_bw 0 | |
367 | #define marvel_trivial_io_lq 1 | |
368 | #define marvel_trivial_iounmap 0 | |
369 | #include <asm/io_trivial.h> | |
370 | ||
371 | #ifdef __IO_EXTERN_INLINE | |
372 | # undef __EXTERN_INLINE | |
373 | # undef __IO_EXTERN_INLINE | |
374 | #endif | |
375 | ||
376 | #endif /* __KERNEL__ */ | |
377 | ||
378 | #endif /* __ALPHA_MARVEL__H__ */ |