2 * linux/arch/sh/kernel/io_rts7751r2d.c
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
7 * I/O routine for Renesas Technology sales RTS7751R2D.
9 * Initial version only to support LAN access; some
10 * placeholder code from io_rts7751r2d.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
14 #include <linux/kernel.h>
15 #include <linux/types.h>
17 #include <asm/rts7751r2d/rts7751r2d.h>
18 #include <asm/addrspace.h>
20 #include <linux/module.h>
21 #include <linux/pci.h>
22 #include "../../../drivers/pci/pci-sh7751.h"
25 * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC)
26 * of the 7751R processor, and has a SuperIO accessible via the PCI.
27 * The board also includes a PCMCIA controller on its memory bus,
28 * like the other Solution Engine boards.
31 #define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
32 #define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
33 #define PCI_IO_AREA SH7751_PCI_IO_BASE
34 #define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
36 #define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
38 #define maybebadio(name,port) \
39 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
40 #name, (port), (__u32) __builtin_return_address(0))
42 static inline void delay(void)
47 static inline unsigned long port2adr(unsigned int port
)
49 if ((0x1f0 <= port
&& port
< 0x1f8) || port
== 0x3f6)
51 return (PA_AREA5_IO
+ 0x80c);
53 return (PA_AREA5_IO
+ 0x1000 + ((port
-0x1f0) << 1));
55 maybebadio(port2adr
, (unsigned long)port
);
60 static inline unsigned long port88796l(unsigned int port
, int flag
)
65 addr
= PA_AX88796L
+ ((port
- AX88796L_IO_BASE
) << 1);
67 addr
= PA_AX88796L
+ ((port
- AX88796L_IO_BASE
) << 1) + 0x1000;
72 /* The 7751R RTS7751R2D seems to have everything hooked */
73 /* up pretty normally (nothing on high-bytes only...) so this */
74 /* shouldn't be needed */
75 static inline int shifted_port(unsigned long port
)
77 /* For IDE registers, value is not shifted */
78 if ((0x1f0 <= port
&& port
< 0x1f8) || port
== 0x3f6)
84 /* In case someone configures the kernel w/o PCI support: in that */
85 /* scenario, don't ever bother to check for PCI-window addresses */
87 /* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
88 #if defined(CONFIG_PCI)
89 #define CHECK_SH7751_PCIIO(port) \
90 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
92 #define CHECK_SH7751_PCIIO(port) (0)
95 #if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
96 #define CHECK_AX88796L_PORT(port) \
97 ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
99 #define CHECK_AX88796L_PORT(port) (0)
103 * General outline: remap really low stuff [eventually] to SuperIO,
104 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
105 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
106 * should be way beyond the window, and is used w/o translation for
109 unsigned char rts7751r2d_inb(unsigned long port
)
111 if (CHECK_AX88796L_PORT(port
))
112 return (*(volatile unsigned short *)port88796l(port
, 0)) & 0xff;
113 else if (PXSEG(port
))
114 return *(volatile unsigned char *)port
;
115 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
116 return *(volatile unsigned char *)PCI_IOMAP(port
);
118 return (*(volatile unsigned short *)port2adr(port
) & 0xff);
121 unsigned char rts7751r2d_inb_p(unsigned long port
)
125 if (CHECK_AX88796L_PORT(port
))
126 v
= (*(volatile unsigned short *)port88796l(port
, 0)) & 0xff;
127 else if (PXSEG(port
))
128 v
= *(volatile unsigned char *)port
;
129 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
130 v
= *(volatile unsigned char *)PCI_IOMAP(port
);
132 v
= (*(volatile unsigned short *)port2adr(port
) & 0xff);
138 unsigned short rts7751r2d_inw(unsigned long port
)
140 if (CHECK_AX88796L_PORT(port
))
141 maybebadio(inw
, port
);
142 else if (PXSEG(port
))
143 return *(volatile unsigned short *)port
;
144 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
145 return *(volatile unsigned short *)PCI_IOMAP(port
);
147 maybebadio(inw
, port
);
152 unsigned int rts7751r2d_inl(unsigned long port
)
154 if (CHECK_AX88796L_PORT(port
))
155 maybebadio(inl
, port
);
156 else if (PXSEG(port
))
157 return *(volatile unsigned long *)port
;
158 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
159 return *(volatile unsigned long *)PCI_IOMAP(port
);
161 maybebadio(inl
, port
);
166 void rts7751r2d_outb(unsigned char value
, unsigned long port
)
168 if (CHECK_AX88796L_PORT(port
))
169 *((volatile unsigned short *)port88796l(port
, 0)) = value
;
170 else if (PXSEG(port
))
171 *(volatile unsigned char *)port
= value
;
172 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
173 *(volatile unsigned char *)PCI_IOMAP(port
) = value
;
175 *(volatile unsigned short *)port2adr(port
) = value
;
178 void rts7751r2d_outb_p(unsigned char value
, unsigned long port
)
180 if (CHECK_AX88796L_PORT(port
))
181 *((volatile unsigned short *)port88796l(port
, 0)) = value
;
182 else if (PXSEG(port
))
183 *(volatile unsigned char *)port
= value
;
184 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
185 *(volatile unsigned char *)PCI_IOMAP(port
) = value
;
187 *(volatile unsigned short *)port2adr(port
) = value
;
191 void rts7751r2d_outw(unsigned short value
, unsigned long port
)
193 if (CHECK_AX88796L_PORT(port
))
194 maybebadio(outw
, port
);
195 else if (PXSEG(port
))
196 *(volatile unsigned short *)port
= value
;
197 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
198 *(volatile unsigned short *)PCI_IOMAP(port
) = value
;
200 maybebadio(outw
, port
);
203 void rts7751r2d_outl(unsigned int value
, unsigned long port
)
205 if (CHECK_AX88796L_PORT(port
))
206 maybebadio(outl
, port
);
207 else if (PXSEG(port
))
208 *(volatile unsigned long *)port
= value
;
209 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
210 *(volatile unsigned long *)PCI_IOMAP(port
) = value
;
212 maybebadio(outl
, port
);
215 void rts7751r2d_insb(unsigned long port
, void *addr
, unsigned long count
)
220 if (CHECK_AX88796L_PORT(port
)) {
221 p
= (volatile unsigned short *)port88796l(port
, 0);
222 while (count
--) *((unsigned char *) addr
)++ = *p
& 0xff;
223 } else if (PXSEG(port
))
224 while (count
--) *((unsigned char *) addr
)++ = *(volatile unsigned char *)port
;
225 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
226 bp
= (__u8
*)PCI_IOMAP(port
);
227 while (count
--) *((volatile unsigned char *) addr
)++ = *bp
;
229 p
= (volatile unsigned short *)port2adr(port
);
230 while (count
--) *((unsigned char *) addr
)++ = *p
& 0xff;
234 void rts7751r2d_insw(unsigned long port
, void *addr
, unsigned long count
)
238 if (CHECK_AX88796L_PORT(port
))
239 p
= (volatile unsigned short *)port88796l(port
, 1);
240 else if (PXSEG(port
))
241 p
= (volatile unsigned short *)port
;
242 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
243 p
= (volatile unsigned short *)PCI_IOMAP(port
);
245 p
= (volatile unsigned short *)port2adr(port
);
246 while (count
--) *((__u16
*) addr
)++ = *p
;
249 void rts7751r2d_insl(unsigned long port
, void *addr
, unsigned long count
)
251 if (CHECK_AX88796L_PORT(port
))
252 maybebadio(insl
, port
);
253 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
254 volatile __u32
*p
= (__u32
*)PCI_IOMAP(port
);
256 while (count
--) *((__u32
*) addr
)++ = *p
;
258 maybebadio(insl
, port
);
261 void rts7751r2d_outsb(unsigned long port
, const void *addr
, unsigned long count
)
266 if (CHECK_AX88796L_PORT(port
)) {
267 p
= (volatile unsigned short *)port88796l(port
, 0);
268 while (count
--) *p
= *((unsigned char *) addr
)++;
269 } else if (PXSEG(port
))
270 while (count
--) *(volatile unsigned char *)port
= *((unsigned char *) addr
)++;
271 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
272 bp
= (__u8
*)PCI_IOMAP(port
);
273 while (count
--) *bp
= *((volatile unsigned char *) addr
)++;
275 p
= (volatile unsigned short *)port2adr(port
);
276 while (count
--) *p
= *((unsigned char *) addr
)++;
280 void rts7751r2d_outsw(unsigned long port
, const void *addr
, unsigned long count
)
284 if (CHECK_AX88796L_PORT(port
))
285 p
= (volatile unsigned short *)port88796l(port
, 1);
286 else if (PXSEG(port
))
287 p
= (volatile unsigned short *)port
;
288 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
289 p
= (volatile unsigned short *)PCI_IOMAP(port
);
291 p
= (volatile unsigned short *)port2adr(port
);
292 while (count
--) *p
= *((__u16
*) addr
)++;
295 void rts7751r2d_outsl(unsigned long port
, const void *addr
, unsigned long count
)
297 if (CHECK_AX88796L_PORT(port
))
298 maybebadio(outsl
, port
);
299 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
300 volatile __u32
*p
= (__u32
*)PCI_IOMAP(port
);
302 while (count
--) *p
= *((__u32
*) addr
)++;
304 maybebadio(outsl
, port
);
307 void *rts7751r2d_ioremap(unsigned long offset
, unsigned long size
)
309 if (offset
>= 0xfd000000)
310 return (void *)offset
;
312 return (void *)P2SEGADDR(offset
);
314 EXPORT_SYMBOL(rts7751r2d_ioremap
);
316 unsigned long rts7751r2d_isa_port2addr(unsigned long offset
)
318 return port2adr(offset
);