2 * linux/arch/sh/kernel/io_hs7751rvoip.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 HS7751RVoIP
9 * Initial version only to support LAN access; some
10 * placeholder code from io_hs7751rvoip.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
14 #include <linux/config.h>
15 #include <linux/kernel.h>
16 #include <linux/types.h>
18 #include <asm/hs7751rvoip/hs7751rvoip.h>
19 #include <asm/addrspace.h>
21 #include <linux/module.h>
22 #include <linux/pci.h>
23 #include "../../../drivers/pci/pci-sh7751.h"
25 extern void *area5_io8_base
; /* Area 5 8bit I/O Base address */
26 extern void *area6_io8_base
; /* Area 6 8bit I/O Base address */
27 extern void *area5_io16_base
; /* Area 5 16bit I/O Base address */
28 extern void *area6_io16_base
; /* Area 6 16bit I/O Base address */
31 * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC)
32 * of the 7751R processor, and has a SuperIO accessible via the PCI.
33 * The board also includes a PCMCIA controller on its memory bus,
34 * like the other Solution Engine boards.
37 #define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
38 #define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
39 #define PCI_IO_AREA SH7751_PCI_IO_BASE
40 #define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
42 #define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
44 #if defined(CONFIG_HS7751RVOIP_CODEC)
45 #define CODEC_IO_BASE 0x1000
48 #define maybebadio(name,port) \
49 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
50 #name, (port), (__u32) __builtin_return_address(0))
52 static inline void delay(void)
57 static inline unsigned long port2adr(unsigned int port
)
59 if ((0x1f0 <= port
&& port
< 0x1f8) || port
== 0x3f6)
61 return ((unsigned long)area5_io16_base
+ 0x0c);
63 return ((unsigned long)area5_io16_base
+ 0x800 + ((port
-0x1f0) << 1));
65 maybebadio(port2adr
, (unsigned long)port
);
69 /* The 7751R HS7751RVoIP seems to have everything hooked */
70 /* up pretty normally (nothing on high-bytes only...) so this */
71 /* shouldn't be needed */
72 static inline int shifted_port(unsigned long port
)
74 /* For IDE registers, value is not shifted */
75 if ((0x1f0 <= port
&& port
< 0x1f8) || port
== 0x3f6)
81 #if defined(CONFIG_HS7751RVOIP_CODEC)
83 codec_port(unsigned long port
)
85 if (CODEC_IO_BASE
<= port
&& port
< (CODEC_IO_BASE
+0x20))
92 /* In case someone configures the kernel w/o PCI support: in that */
93 /* scenario, don't ever bother to check for PCI-window addresses */
95 /* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
96 #if defined(CONFIG_PCI)
97 #define CHECK_SH7751_PCIIO(port) \
98 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
100 #define CHECK_SH7751_PCIIO(port) (0)
104 * General outline: remap really low stuff [eventually] to SuperIO,
105 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
106 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
107 * should be way beyond the window, and is used w/o translation for
110 unsigned char hs7751rvoip_inb(unsigned long port
)
113 return *(volatile unsigned char *)port
;
114 #if defined(CONFIG_HS7751RVOIP_CODEC)
115 else if (codec_port(port
))
116 return *(volatile unsigned char *)((unsigned long)area6_io8_base
+(port
-CODEC_IO_BASE
));
118 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
119 return *(volatile unsigned char *)PCI_IOMAP(port
);
121 return (*(volatile unsigned short *)port2adr(port
) & 0xff);
124 unsigned char hs7751rvoip_inb_p(unsigned long port
)
129 v
= *(volatile unsigned char *)port
;
130 #if defined(CONFIG_HS7751RVOIP_CODEC)
131 else if (codec_port(port
))
132 v
= *(volatile unsigned char *)((unsigned long)area6_io8_base
+(port
-CODEC_IO_BASE
));
134 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
135 v
= *(volatile unsigned char *)PCI_IOMAP(port
);
137 v
= (*(volatile unsigned short *)port2adr(port
) & 0xff);
142 unsigned short hs7751rvoip_inw(unsigned long port
)
145 return *(volatile unsigned short *)port
;
146 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
147 return *(volatile unsigned short *)PCI_IOMAP(port
);
149 maybebadio(inw
, port
);
153 unsigned int hs7751rvoip_inl(unsigned long port
)
156 return *(volatile unsigned long *)port
;
157 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
158 return *(volatile unsigned long *)PCI_IOMAP(port
);
160 maybebadio(inl
, port
);
164 void hs7751rvoip_outb(unsigned char value
, unsigned long port
)
168 *(volatile unsigned char *)port
= value
;
169 #if defined(CONFIG_HS7751RVOIP_CODEC)
170 else if (codec_port(port
))
171 *(volatile unsigned cjar
*)((unsigned long)area6_io8_base
+(port
-CODEC_IO_BASE
)) = value
;
173 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
174 *(unsigned char *)PCI_IOMAP(port
) = value
;
176 *(volatile unsigned short *)port2adr(port
) = value
;
179 void hs7751rvoip_outb_p(unsigned char value
, unsigned long port
)
182 *(volatile unsigned char *)port
= value
;
183 #if defined(CONFIG_HS7751RVOIP_CODEC)
184 else if (codec_port(port
))
185 *(volatile unsigned cjar
*)((unsigned long)area6_io8_base
+(port
-CODEC_IO_BASE
)) = value
;
187 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
188 *(unsigned char *)PCI_IOMAP(port
) = value
;
190 *(volatile unsigned short *)port2adr(port
) = value
;
194 void hs7751rvoip_outw(unsigned short value
, unsigned long port
)
197 *(volatile unsigned short *)port
= value
;
198 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
199 *(unsigned short *)PCI_IOMAP(port
) = value
;
201 maybebadio(outw
, port
);
204 void hs7751rvoip_outl(unsigned int value
, unsigned long port
)
207 *(volatile unsigned long *)port
= value
;
208 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
209 *((unsigned long *)PCI_IOMAP(port
)) = value
;
211 maybebadio(outl
, port
);
214 void hs7751rvoip_insb(unsigned long port
, void *addr
, unsigned long count
)
217 while (count
--) *((unsigned char *) addr
)++ = *(volatile unsigned char *)port
;
218 #if defined(CONFIG_HS7751RVOIP_CODEC)
219 else if (codec_port(port
))
220 while (count
--) *((unsigned char *) addr
)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base
+(port
-CODEC_IO_BASE
));
222 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
223 volatile __u8
*bp
= (__u8
*)PCI_IOMAP(port
);
225 while (count
--) *((volatile unsigned char *) addr
)++ = *bp
;
227 volatile __u16
*p
= (volatile unsigned short *)port2adr(port
);
229 while (count
--) *((unsigned char *) addr
)++ = *p
& 0xff;
233 void hs7751rvoip_insw(unsigned long port
, void *addr
, unsigned long count
)
238 p
= (volatile unsigned short *)port
;
239 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
240 p
= (volatile unsigned short *)PCI_IOMAP(port
);
242 p
= (volatile unsigned short *)port2adr(port
);
243 while (count
--) *((__u16
*) addr
)++ = *p
;
246 void hs7751rvoip_insl(unsigned long port
, void *addr
, unsigned long count
)
248 if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
249 volatile __u32
*p
= (__u32
*)PCI_IOMAP(port
);
251 while (count
--) *((__u32
*) addr
)++ = *p
;
253 maybebadio(insl
, port
);
256 void hs7751rvoip_outsb(unsigned long port
, const void *addr
, unsigned long count
)
259 while (count
--) *(volatile unsigned char *)port
= *((unsigned char *) addr
)++;
260 #if defined(CONFIG_HS7751RVOIP_CODEC)
261 else if (codec_port(port
))
262 while (count
--) *(volatile unsigned char *)((unsigned long)area6_io8_base
+(port
-CODEC_IO_BASE
)) = *((unsigned char *) addr
)++;
264 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
265 volatile __u8
*bp
= (__u8
*)PCI_IOMAP(port
);
267 while (count
--) *bp
= *((volatile unsigned char *) addr
)++;
269 volatile __u16
*p
= (volatile unsigned short *)port2adr(port
);
271 while (count
--) *p
= *((unsigned char *) addr
)++;
275 void hs7751rvoip_outsw(unsigned long port
, const void *addr
, unsigned long count
)
280 p
= (volatile unsigned short *)port
;
281 else if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
))
282 p
= (volatile unsigned short *)PCI_IOMAP(port
);
284 p
= (volatile unsigned short *)port2adr(port
);
285 while (count
--) *p
= *((__u16
*) addr
)++;
288 void hs7751rvoip_outsl(unsigned long port
, const void *addr
, unsigned long count
)
290 if (CHECK_SH7751_PCIIO(port
) || shifted_port(port
)) {
291 volatile __u32
*p
= (__u32
*)PCI_IOMAP(port
);
293 while (count
--) *p
= *((__u32
*) addr
)++;
295 maybebadio(outsl
, port
);
298 void *hs7751rvoip_ioremap(unsigned long offset
, unsigned long size
)
300 if (offset
>= 0xfd000000)
301 return (void *)offset
;
303 return (void *)P2SEGADDR(offset
);
305 EXPORT_SYMBOL(hs7751rvoip_ioremap
);
307 unsigned long hs7751rvoip_isa_port2addr(unsigned long offset
)
309 return port2adr(offset
);