Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef __ALPHA_APECS__H__ |
2 | #define __ALPHA_APECS__H__ | |
3 | ||
4 | #include <linux/types.h> | |
5 | #include <asm/compiler.h> | |
6 | ||
7 | /* | |
8 | * APECS is the internal name for the 2107x chipset which provides | |
9 | * memory controller and PCI access for the 21064 chip based systems. | |
10 | * | |
11 | * This file is based on: | |
12 | * | |
13 | * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets | |
14 | * Data Sheet | |
15 | * | |
16 | * EC-N0648-72 | |
17 | * | |
18 | * | |
19 | * david.rusling@reo.mts.dec.com Initial Version. | |
20 | * | |
21 | */ | |
22 | ||
23 | /* | |
24 | An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address | |
25 | that get passed through the PCI<->ISA bridge chip. So we've gotta use | |
26 | both windows to max out the physical memory we can DMA to. Sigh... | |
27 | ||
28 | If we try a window at 0 for 1GB as a work-around, we run into conflicts | |
29 | with ISA/PCI bus memory which can't be relocated, like VGA aperture and | |
30 | BIOS ROMs. So we must put the windows high enough to avoid these areas. | |
31 | ||
32 | We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1, | |
33 | and window 2 at BUS 1Gb for 1Gb, mapping physical 0 to 1Gb-1. | |
34 | Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually | |
35 | be used for that range (via virt_to_bus()). | |
36 | ||
37 | Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb, | |
38 | to keep virt_to_bus() from returning an address in the first window, for | |
39 | a data area that goes beyond the 64Mb first DMA window. Sigh... | |
40 | The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but | |
41 | we can't just use that here, because of header file looping... :-( | |
42 | ||
43 | Window 1 will be used for all DMA from the ISA bus; yes, that does | |
44 | limit what memory an ISA floppy or sound card or Ethernet can touch, but | |
45 | it's also a known limitation on other platforms as well. We use the | |
46 | same technique that is used on INTEL platforms with similar limitation: | |
47 | set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init(). | |
48 | We trust that any ISA bus device drivers will *always* ask for DMAable | |
49 | memory explicitly via kmalloc()/get_free_pages() flags arguments. | |
50 | ||
51 | Note that most PCI bus devices' drivers do *not* explicitly ask for | |
52 | DMAable memory; they count on being able to DMA to any memory they | |
53 | get from kmalloc()/get_free_pages(). They will also use window 1 for | |
54 | any physical memory accesses below 64Mb; the rest will be handled by | |
55 | window 2, maxing out at 1Gb of memory. I trust this is enough... :-) | |
56 | ||
57 | We hope that the area before the first window is large enough so that | |
58 | there will be no overlap at the top end (64Mb). We *must* locate the | |
59 | PCI cards' memory just below window 1, so that there's still the | |
60 | possibility of being able to access it via SPARSE space. This is | |
61 | important for cards such as the Matrox Millennium, whose Xserver | |
62 | wants to access memory-mapped registers in byte and short lengths. | |
63 | ||
64 | Note that the XL is treated differently from the AVANTI, even though | |
65 | for most other things they are identical. It didn't seem reasonable to | |
66 | make the AVANTI support pay for the limitations of the XL. It is true, | |
67 | however, that an XL kernel will run on an AVANTI without problems. | |
68 | ||
69 | %%% All of this should be obviated by the ability to route | |
70 | everything through the iommu. | |
71 | */ | |
72 | ||
73 | /* | |
74 | * 21071-DA Control and Status registers. | |
75 | * These are used for PCI memory access. | |
76 | */ | |
77 | #define APECS_IOC_DCSR (IDENT_ADDR + 0x1A0000000UL) | |
78 | #define APECS_IOC_PEAR (IDENT_ADDR + 0x1A0000020UL) | |
79 | #define APECS_IOC_SEAR (IDENT_ADDR + 0x1A0000040UL) | |
80 | #define APECS_IOC_DR1 (IDENT_ADDR + 0x1A0000060UL) | |
81 | #define APECS_IOC_DR2 (IDENT_ADDR + 0x1A0000080UL) | |
82 | #define APECS_IOC_DR3 (IDENT_ADDR + 0x1A00000A0UL) | |
83 | ||
84 | #define APECS_IOC_TB1R (IDENT_ADDR + 0x1A00000C0UL) | |
85 | #define APECS_IOC_TB2R (IDENT_ADDR + 0x1A00000E0UL) | |
86 | ||
87 | #define APECS_IOC_PB1R (IDENT_ADDR + 0x1A0000100UL) | |
88 | #define APECS_IOC_PB2R (IDENT_ADDR + 0x1A0000120UL) | |
89 | ||
90 | #define APECS_IOC_PM1R (IDENT_ADDR + 0x1A0000140UL) | |
91 | #define APECS_IOC_PM2R (IDENT_ADDR + 0x1A0000160UL) | |
92 | ||
93 | #define APECS_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL) | |
94 | #define APECS_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL) | |
95 | #define APECS_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL) | |
96 | ||
97 | #define APECS_IOC_PMLT (IDENT_ADDR + 0x1A00001E0UL) | |
98 | ||
99 | #define APECS_IOC_TLBTAG0 (IDENT_ADDR + 0x1A0000200UL) | |
100 | #define APECS_IOC_TLBTAG1 (IDENT_ADDR + 0x1A0000220UL) | |
101 | #define APECS_IOC_TLBTAG2 (IDENT_ADDR + 0x1A0000240UL) | |
102 | #define APECS_IOC_TLBTAG3 (IDENT_ADDR + 0x1A0000260UL) | |
103 | #define APECS_IOC_TLBTAG4 (IDENT_ADDR + 0x1A0000280UL) | |
104 | #define APECS_IOC_TLBTAG5 (IDENT_ADDR + 0x1A00002A0UL) | |
105 | #define APECS_IOC_TLBTAG6 (IDENT_ADDR + 0x1A00002C0UL) | |
106 | #define APECS_IOC_TLBTAG7 (IDENT_ADDR + 0x1A00002E0UL) | |
107 | ||
108 | #define APECS_IOC_TLBDATA0 (IDENT_ADDR + 0x1A0000300UL) | |
109 | #define APECS_IOC_TLBDATA1 (IDENT_ADDR + 0x1A0000320UL) | |
110 | #define APECS_IOC_TLBDATA2 (IDENT_ADDR + 0x1A0000340UL) | |
111 | #define APECS_IOC_TLBDATA3 (IDENT_ADDR + 0x1A0000360UL) | |
112 | #define APECS_IOC_TLBDATA4 (IDENT_ADDR + 0x1A0000380UL) | |
113 | #define APECS_IOC_TLBDATA5 (IDENT_ADDR + 0x1A00003A0UL) | |
114 | #define APECS_IOC_TLBDATA6 (IDENT_ADDR + 0x1A00003C0UL) | |
115 | #define APECS_IOC_TLBDATA7 (IDENT_ADDR + 0x1A00003E0UL) | |
116 | ||
117 | #define APECS_IOC_TBIA (IDENT_ADDR + 0x1A0000400UL) | |
118 | ||
119 | ||
120 | /* | |
121 | * 21071-CA Control and Status registers. | |
122 | * These are used to program memory timing, | |
123 | * configure memory and initialise the B-Cache. | |
124 | */ | |
125 | #define APECS_MEM_GCR (IDENT_ADDR + 0x180000000UL) | |
126 | #define APECS_MEM_EDSR (IDENT_ADDR + 0x180000040UL) | |
127 | #define APECS_MEM_TAR (IDENT_ADDR + 0x180000060UL) | |
128 | #define APECS_MEM_ELAR (IDENT_ADDR + 0x180000080UL) | |
129 | #define APECS_MEM_EHAR (IDENT_ADDR + 0x1800000a0UL) | |
130 | #define APECS_MEM_SFT_RST (IDENT_ADDR + 0x1800000c0UL) | |
131 | #define APECS_MEM_LDxLAR (IDENT_ADDR + 0x1800000e0UL) | |
132 | #define APECS_MEM_LDxHAR (IDENT_ADDR + 0x180000100UL) | |
133 | #define APECS_MEM_GTR (IDENT_ADDR + 0x180000200UL) | |
134 | #define APECS_MEM_RTR (IDENT_ADDR + 0x180000220UL) | |
135 | #define APECS_MEM_VFPR (IDENT_ADDR + 0x180000240UL) | |
136 | #define APECS_MEM_PDLDR (IDENT_ADDR + 0x180000260UL) | |
137 | #define APECS_MEM_PDhDR (IDENT_ADDR + 0x180000280UL) | |
138 | ||
139 | /* Bank x Base Address Register */ | |
140 | #define APECS_MEM_B0BAR (IDENT_ADDR + 0x180000800UL) | |
141 | #define APECS_MEM_B1BAR (IDENT_ADDR + 0x180000820UL) | |
142 | #define APECS_MEM_B2BAR (IDENT_ADDR + 0x180000840UL) | |
143 | #define APECS_MEM_B3BAR (IDENT_ADDR + 0x180000860UL) | |
144 | #define APECS_MEM_B4BAR (IDENT_ADDR + 0x180000880UL) | |
145 | #define APECS_MEM_B5BAR (IDENT_ADDR + 0x1800008A0UL) | |
146 | #define APECS_MEM_B6BAR (IDENT_ADDR + 0x1800008C0UL) | |
147 | #define APECS_MEM_B7BAR (IDENT_ADDR + 0x1800008E0UL) | |
148 | #define APECS_MEM_B8BAR (IDENT_ADDR + 0x180000900UL) | |
149 | ||
150 | /* Bank x Configuration Register */ | |
151 | #define APECS_MEM_B0BCR (IDENT_ADDR + 0x180000A00UL) | |
152 | #define APECS_MEM_B1BCR (IDENT_ADDR + 0x180000A20UL) | |
153 | #define APECS_MEM_B2BCR (IDENT_ADDR + 0x180000A40UL) | |
154 | #define APECS_MEM_B3BCR (IDENT_ADDR + 0x180000A60UL) | |
155 | #define APECS_MEM_B4BCR (IDENT_ADDR + 0x180000A80UL) | |
156 | #define APECS_MEM_B5BCR (IDENT_ADDR + 0x180000AA0UL) | |
157 | #define APECS_MEM_B6BCR (IDENT_ADDR + 0x180000AC0UL) | |
158 | #define APECS_MEM_B7BCR (IDENT_ADDR + 0x180000AE0UL) | |
159 | #define APECS_MEM_B8BCR (IDENT_ADDR + 0x180000B00UL) | |
160 | ||
161 | /* Bank x Timing Register A */ | |
162 | #define APECS_MEM_B0TRA (IDENT_ADDR + 0x180000C00UL) | |
163 | #define APECS_MEM_B1TRA (IDENT_ADDR + 0x180000C20UL) | |
164 | #define APECS_MEM_B2TRA (IDENT_ADDR + 0x180000C40UL) | |
165 | #define APECS_MEM_B3TRA (IDENT_ADDR + 0x180000C60UL) | |
166 | #define APECS_MEM_B4TRA (IDENT_ADDR + 0x180000C80UL) | |
167 | #define APECS_MEM_B5TRA (IDENT_ADDR + 0x180000CA0UL) | |
168 | #define APECS_MEM_B6TRA (IDENT_ADDR + 0x180000CC0UL) | |
169 | #define APECS_MEM_B7TRA (IDENT_ADDR + 0x180000CE0UL) | |
170 | #define APECS_MEM_B8TRA (IDENT_ADDR + 0x180000D00UL) | |
171 | ||
172 | /* Bank x Timing Register B */ | |
173 | #define APECS_MEM_B0TRB (IDENT_ADDR + 0x180000E00UL) | |
174 | #define APECS_MEM_B1TRB (IDENT_ADDR + 0x180000E20UL) | |
175 | #define APECS_MEM_B2TRB (IDENT_ADDR + 0x180000E40UL) | |
176 | #define APECS_MEM_B3TRB (IDENT_ADDR + 0x180000E60UL) | |
177 | #define APECS_MEM_B4TRB (IDENT_ADDR + 0x180000E80UL) | |
178 | #define APECS_MEM_B5TRB (IDENT_ADDR + 0x180000EA0UL) | |
179 | #define APECS_MEM_B6TRB (IDENT_ADDR + 0x180000EC0UL) | |
180 | #define APECS_MEM_B7TRB (IDENT_ADDR + 0x180000EE0UL) | |
181 | #define APECS_MEM_B8TRB (IDENT_ADDR + 0x180000F00UL) | |
182 | ||
183 | ||
184 | /* | |
185 | * Memory spaces: | |
186 | */ | |
187 | #define APECS_IACK_SC (IDENT_ADDR + 0x1b0000000UL) | |
188 | #define APECS_CONF (IDENT_ADDR + 0x1e0000000UL) | |
189 | #define APECS_IO (IDENT_ADDR + 0x1c0000000UL) | |
190 | #define APECS_SPARSE_MEM (IDENT_ADDR + 0x200000000UL) | |
191 | #define APECS_DENSE_MEM (IDENT_ADDR + 0x300000000UL) | |
192 | ||
193 | ||
194 | /* | |
195 | * Bit definitions for I/O Controller status register 0: | |
196 | */ | |
197 | #define APECS_IOC_STAT0_CMD 0xf | |
198 | #define APECS_IOC_STAT0_ERR (1<<4) | |
199 | #define APECS_IOC_STAT0_LOST (1<<5) | |
200 | #define APECS_IOC_STAT0_THIT (1<<6) | |
201 | #define APECS_IOC_STAT0_TREF (1<<7) | |
202 | #define APECS_IOC_STAT0_CODE_SHIFT 8 | |
203 | #define APECS_IOC_STAT0_CODE_MASK 0x7 | |
204 | #define APECS_IOC_STAT0_P_NBR_SHIFT 13 | |
205 | #define APECS_IOC_STAT0_P_NBR_MASK 0x7ffff | |
206 | ||
207 | #define APECS_HAE_ADDRESS APECS_IOC_HAXR1 | |
208 | ||
209 | ||
210 | /* | |
211 | * Data structure for handling APECS machine checks: | |
212 | */ | |
213 | ||
214 | struct el_apecs_mikasa_sysdata_mcheck | |
215 | { | |
216 | unsigned long coma_gcr; | |
217 | unsigned long coma_edsr; | |
218 | unsigned long coma_ter; | |
219 | unsigned long coma_elar; | |
220 | unsigned long coma_ehar; | |
221 | unsigned long coma_ldlr; | |
222 | unsigned long coma_ldhr; | |
223 | unsigned long coma_base0; | |
224 | unsigned long coma_base1; | |
225 | unsigned long coma_base2; | |
226 | unsigned long coma_base3; | |
227 | unsigned long coma_cnfg0; | |
228 | unsigned long coma_cnfg1; | |
229 | unsigned long coma_cnfg2; | |
230 | unsigned long coma_cnfg3; | |
231 | unsigned long epic_dcsr; | |
232 | unsigned long epic_pear; | |
233 | unsigned long epic_sear; | |
234 | unsigned long epic_tbr1; | |
235 | unsigned long epic_tbr2; | |
236 | unsigned long epic_pbr1; | |
237 | unsigned long epic_pbr2; | |
238 | unsigned long epic_pmr1; | |
239 | unsigned long epic_pmr2; | |
240 | unsigned long epic_harx1; | |
241 | unsigned long epic_harx2; | |
242 | unsigned long epic_pmlt; | |
243 | unsigned long epic_tag0; | |
244 | unsigned long epic_tag1; | |
245 | unsigned long epic_tag2; | |
246 | unsigned long epic_tag3; | |
247 | unsigned long epic_tag4; | |
248 | unsigned long epic_tag5; | |
249 | unsigned long epic_tag6; | |
250 | unsigned long epic_tag7; | |
251 | unsigned long epic_data0; | |
252 | unsigned long epic_data1; | |
253 | unsigned long epic_data2; | |
254 | unsigned long epic_data3; | |
255 | unsigned long epic_data4; | |
256 | unsigned long epic_data5; | |
257 | unsigned long epic_data6; | |
258 | unsigned long epic_data7; | |
259 | ||
260 | unsigned long pceb_vid; | |
261 | unsigned long pceb_did; | |
262 | unsigned long pceb_revision; | |
263 | unsigned long pceb_command; | |
264 | unsigned long pceb_status; | |
265 | unsigned long pceb_latency; | |
266 | unsigned long pceb_control; | |
267 | unsigned long pceb_arbcon; | |
268 | unsigned long pceb_arbpri; | |
269 | ||
270 | unsigned long esc_id; | |
271 | unsigned long esc_revision; | |
272 | unsigned long esc_int0; | |
273 | unsigned long esc_int1; | |
274 | unsigned long esc_elcr0; | |
275 | unsigned long esc_elcr1; | |
276 | unsigned long esc_last_eisa; | |
277 | unsigned long esc_nmi_stat; | |
278 | ||
279 | unsigned long pci_ir; | |
280 | unsigned long pci_imr; | |
281 | unsigned long svr_mgr; | |
282 | }; | |
283 | ||
284 | /* This for the normal APECS machines. */ | |
285 | struct el_apecs_sysdata_mcheck | |
286 | { | |
287 | unsigned long coma_gcr; | |
288 | unsigned long coma_edsr; | |
289 | unsigned long coma_ter; | |
290 | unsigned long coma_elar; | |
291 | unsigned long coma_ehar; | |
292 | unsigned long coma_ldlr; | |
293 | unsigned long coma_ldhr; | |
294 | unsigned long coma_base0; | |
295 | unsigned long coma_base1; | |
296 | unsigned long coma_base2; | |
297 | unsigned long coma_cnfg0; | |
298 | unsigned long coma_cnfg1; | |
299 | unsigned long coma_cnfg2; | |
300 | unsigned long epic_dcsr; | |
301 | unsigned long epic_pear; | |
302 | unsigned long epic_sear; | |
303 | unsigned long epic_tbr1; | |
304 | unsigned long epic_tbr2; | |
305 | unsigned long epic_pbr1; | |
306 | unsigned long epic_pbr2; | |
307 | unsigned long epic_pmr1; | |
308 | unsigned long epic_pmr2; | |
309 | unsigned long epic_harx1; | |
310 | unsigned long epic_harx2; | |
311 | unsigned long epic_pmlt; | |
312 | unsigned long epic_tag0; | |
313 | unsigned long epic_tag1; | |
314 | unsigned long epic_tag2; | |
315 | unsigned long epic_tag3; | |
316 | unsigned long epic_tag4; | |
317 | unsigned long epic_tag5; | |
318 | unsigned long epic_tag6; | |
319 | unsigned long epic_tag7; | |
320 | unsigned long epic_data0; | |
321 | unsigned long epic_data1; | |
322 | unsigned long epic_data2; | |
323 | unsigned long epic_data3; | |
324 | unsigned long epic_data4; | |
325 | unsigned long epic_data5; | |
326 | unsigned long epic_data6; | |
327 | unsigned long epic_data7; | |
328 | }; | |
329 | ||
330 | struct el_apecs_procdata | |
331 | { | |
332 | unsigned long paltemp[32]; /* PAL TEMP REGS. */ | |
333 | /* EV4-specific fields */ | |
334 | unsigned long exc_addr; /* Address of excepting instruction. */ | |
335 | unsigned long exc_sum; /* Summary of arithmetic traps. */ | |
336 | unsigned long exc_mask; /* Exception mask (from exc_sum). */ | |
337 | unsigned long iccsr; /* IBox hardware enables. */ | |
338 | unsigned long pal_base; /* Base address for PALcode. */ | |
339 | unsigned long hier; /* Hardware Interrupt Enable. */ | |
340 | unsigned long hirr; /* Hardware Interrupt Request. */ | |
341 | unsigned long csr; /* D-stream fault info. */ | |
342 | unsigned long dc_stat; /* D-cache status (ECC/Parity Err). */ | |
343 | unsigned long dc_addr; /* EV3 Phys Addr for ECC/DPERR. */ | |
344 | unsigned long abox_ctl; /* ABox Control Register. */ | |
345 | unsigned long biu_stat; /* BIU Status. */ | |
346 | unsigned long biu_addr; /* BUI Address. */ | |
347 | unsigned long biu_ctl; /* BIU Control. */ | |
348 | unsigned long fill_syndrome;/* For correcting ECC errors. */ | |
349 | unsigned long fill_addr; /* Cache block which was being read */ | |
350 | unsigned long va; /* Effective VA of fault or miss. */ | |
351 | unsigned long bc_tag; /* Backup Cache Tag Probe Results.*/ | |
352 | }; | |
353 | ||
354 | ||
355 | #ifdef __KERNEL__ | |
356 | ||
357 | #ifndef __EXTERN_INLINE | |
358 | #define __EXTERN_INLINE extern inline | |
359 | #define __IO_EXTERN_INLINE | |
360 | #endif | |
361 | ||
362 | /* | |
363 | * I/O functions: | |
364 | * | |
365 | * Unlike Jensen, the APECS machines have no concept of local | |
366 | * I/O---everything goes over the PCI bus. | |
367 | * | |
368 | * There is plenty room for optimization here. In particular, | |
369 | * the Alpha's insb/insw/extb/extw should be useful in moving | |
370 | * data to/from the right byte-lanes. | |
371 | */ | |
372 | ||
373 | #define vip volatile int __force * | |
374 | #define vuip volatile unsigned int __force * | |
375 | #define vulp volatile unsigned long __force * | |
376 | ||
377 | #define APECS_SET_HAE \ | |
378 | do { \ | |
379 | if (addr >= (1UL << 24)) { \ | |
380 | unsigned long msb = addr & 0xf8000000; \ | |
381 | addr -= msb; \ | |
382 | set_hae(msb); \ | |
383 | } \ | |
384 | } while (0) | |
385 | ||
386 | __EXTERN_INLINE unsigned int apecs_ioread8(void __iomem *xaddr) | |
387 | { | |
388 | unsigned long addr = (unsigned long) xaddr; | |
389 | unsigned long result, base_and_type; | |
390 | ||
391 | if (addr >= APECS_DENSE_MEM) { | |
392 | addr -= APECS_DENSE_MEM; | |
393 | APECS_SET_HAE; | |
394 | base_and_type = APECS_SPARSE_MEM + 0x00; | |
395 | } else { | |
396 | addr -= APECS_IO; | |
397 | base_and_type = APECS_IO + 0x00; | |
398 | } | |
399 | ||
400 | result = *(vip) ((addr << 5) + base_and_type); | |
401 | return __kernel_extbl(result, addr & 3); | |
402 | } | |
403 | ||
404 | __EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr) | |
405 | { | |
406 | unsigned long addr = (unsigned long) xaddr; | |
407 | unsigned long w, base_and_type; | |
408 | ||
409 | if (addr >= APECS_DENSE_MEM) { | |
410 | addr -= APECS_DENSE_MEM; | |
411 | APECS_SET_HAE; | |
412 | base_and_type = APECS_SPARSE_MEM + 0x00; | |
413 | } else { | |
414 | addr -= APECS_IO; | |
415 | base_and_type = APECS_IO + 0x00; | |
416 | } | |
417 | ||
418 | w = __kernel_insbl(b, addr & 3); | |
419 | *(vuip) ((addr << 5) + base_and_type) = w; | |
420 | } | |
421 | ||
422 | __EXTERN_INLINE unsigned int apecs_ioread16(void __iomem *xaddr) | |
423 | { | |
424 | unsigned long addr = (unsigned long) xaddr; | |
425 | unsigned long result, base_and_type; | |
426 | ||
427 | if (addr >= APECS_DENSE_MEM) { | |
428 | addr -= APECS_DENSE_MEM; | |
429 | APECS_SET_HAE; | |
430 | base_and_type = APECS_SPARSE_MEM + 0x08; | |
431 | } else { | |
432 | addr -= APECS_IO; | |
433 | base_and_type = APECS_IO + 0x08; | |
434 | } | |
435 | ||
436 | result = *(vip) ((addr << 5) + base_and_type); | |
437 | return __kernel_extwl(result, addr & 3); | |
438 | } | |
439 | ||
440 | __EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr) | |
441 | { | |
442 | unsigned long addr = (unsigned long) xaddr; | |
443 | unsigned long w, base_and_type; | |
444 | ||
445 | if (addr >= APECS_DENSE_MEM) { | |
446 | addr -= APECS_DENSE_MEM; | |
447 | APECS_SET_HAE; | |
448 | base_and_type = APECS_SPARSE_MEM + 0x08; | |
449 | } else { | |
450 | addr -= APECS_IO; | |
451 | base_and_type = APECS_IO + 0x08; | |
452 | } | |
453 | ||
454 | w = __kernel_inswl(b, addr & 3); | |
455 | *(vuip) ((addr << 5) + base_and_type) = w; | |
456 | } | |
457 | ||
458 | __EXTERN_INLINE unsigned int apecs_ioread32(void __iomem *xaddr) | |
459 | { | |
460 | unsigned long addr = (unsigned long) xaddr; | |
461 | if (addr < APECS_DENSE_MEM) | |
462 | addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18; | |
463 | return *(vuip)addr; | |
464 | } | |
465 | ||
466 | __EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr) | |
467 | { | |
468 | unsigned long addr = (unsigned long) xaddr; | |
469 | if (addr < APECS_DENSE_MEM) | |
470 | addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18; | |
471 | *(vuip)addr = b; | |
472 | } | |
473 | ||
474 | __EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr) | |
475 | { | |
476 | return (void __iomem *)(addr + APECS_IO); | |
477 | } | |
478 | ||
479 | __EXTERN_INLINE void __iomem *apecs_ioremap(unsigned long addr, | |
480 | unsigned long size) | |
481 | { | |
482 | return (void __iomem *)(addr + APECS_DENSE_MEM); | |
483 | } | |
484 | ||
485 | __EXTERN_INLINE int apecs_is_ioaddr(unsigned long addr) | |
486 | { | |
487 | return addr >= IDENT_ADDR + 0x180000000UL; | |
488 | } | |
489 | ||
490 | __EXTERN_INLINE int apecs_is_mmio(const volatile void __iomem *addr) | |
491 | { | |
492 | return (unsigned long)addr >= APECS_DENSE_MEM; | |
493 | } | |
494 | ||
495 | #undef APECS_SET_HAE | |
496 | ||
497 | #undef vip | |
498 | #undef vuip | |
499 | #undef vulp | |
500 | ||
501 | #undef __IO_PREFIX | |
502 | #define __IO_PREFIX apecs | |
503 | #define apecs_trivial_io_bw 0 | |
504 | #define apecs_trivial_io_lq 0 | |
505 | #define apecs_trivial_rw_bw 2 | |
506 | #define apecs_trivial_rw_lq 1 | |
507 | #define apecs_trivial_iounmap 1 | |
508 | #include <asm/io_trivial.h> | |
509 | ||
510 | #ifdef __IO_EXTERN_INLINE | |
511 | #undef __EXTERN_INLINE | |
512 | #undef __IO_EXTERN_INLINE | |
513 | #endif | |
514 | ||
515 | #endif /* __KERNEL__ */ | |
516 | ||
517 | #endif /* __ALPHA_APECS__H__ */ |