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)
219 unsigned char *s = addr;
221 if (CHECK_AX88796L_PORT(port)) {
222 p = (volatile unsigned short *)port88796l(port, 0);
223 while (count--) *s++ = *p & 0xff;
224 } else if (PXSEG(port))
225 while (count--) *s++ = *(volatile unsigned char *)port;
226 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
227 bp = (__u8 *)PCI_IOMAP(port);
228 while (count--) *s++ = *bp;
230 p = (volatile unsigned short *)port2adr(port);
231 while (count--) *s++ = *p & 0xff;
235 void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
240 if (CHECK_AX88796L_PORT(port))
241 p = (volatile unsigned short *)port88796l(port, 1);
242 else if (PXSEG(port))
243 p = (volatile unsigned short *)port;
244 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
245 p = (volatile unsigned short *)PCI_IOMAP(port);
247 p = (volatile unsigned short *)port2adr(port);
248 while (count--) *s++ = *p;
251 void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
253 if (CHECK_AX88796L_PORT(port))
254 maybebadio(insl, port);
255 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
256 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
259 while (count--) *s++ = *p;
261 maybebadio(insl, port);
264 void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
268 const __u8 *s = addr;
270 if (CHECK_AX88796L_PORT(port)) {
271 p = (volatile unsigned short *)port88796l(port, 0);
272 while (count--) *p = *s++;
273 } else if (PXSEG(port))
274 while (count--) *(volatile unsigned char *)port = *s++;
275 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
276 bp = (__u8 *)PCI_IOMAP(port);
277 while (count--) *bp = *s++;
279 p = (volatile unsigned short *)port2adr(port);
280 while (count--) *p = *s++;
284 void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
287 const __u16 *s = addr;
289 if (CHECK_AX88796L_PORT(port))
290 p = (volatile unsigned short *)port88796l(port, 1);
291 else if (PXSEG(port))
292 p = (volatile unsigned short *)port;
293 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port))
294 p = (volatile unsigned short *)PCI_IOMAP(port);
296 p = (volatile unsigned short *)port2adr(port);
297 while (count--) *p = *s++;
300 void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
302 if (CHECK_AX88796L_PORT(port))
303 maybebadio(outsl, port);
304 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
305 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
306 const __u32 *s = addr;
308 while (count--) *p = *s++;
310 maybebadio(outsl, port);
313 void *rts7751r2d_ioremap(unsigned long offset, unsigned long size)
315 if (offset >= 0xfd000000)
316 return (void *)offset;
318 return (void *)P2SEGADDR(offset);
320 EXPORT_SYMBOL(rts7751r2d_ioremap);
322 unsigned long rts7751r2d_isa_port2addr(unsigned long offset)
324 return port2adr(offset);