2 * linux/arch/sh/kernel/io_7751se.c
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
7 * I/O routine for Hitachi 7751 SolutionEngine.
9 * Initial version only to support LAN access; some
10 * placeholder code from io_se.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/se7751.h>
18 #include <asm/addrspace.h>
20 #include <linux/pci.h>
21 #include "../../../drivers/pci/pci-sh7751.h"
24 /******************************************************************
25 * Variables from io_se.c, related to PCMCIA (not PCI); we're not
26 * compiling them in, and have removed references from functions
27 * which follow. [Many checked for IO ports in the range bounded
28 * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset.
29 * As start/stop are uninitialized, only port 0x0 would match?]
30 * When used, remember to adjust names to avoid clash with io_se?
31 *****************************************************************/
32 /* SH pcmcia io window base, start and end. */
33 int sh_pcic_io_wbase = 0xb8400000;
38 /*************************************************************/
42 * The 7751 Solution Engine uses the built-in PCI controller (PCIC)
43 * of the 7751 processor, and has a SuperIO accessible via the PCI.
44 * The board also includes a PCMCIA controller on its memory bus,
45 * like the other Solution Engine boards.
48 #define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
49 #define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
50 #define PCI_IO_AREA SH7751_PCI_IO_BASE
51 #define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
53 #define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
55 static inline void delay(void)
60 static inline volatile __u16 *
61 port2adr(unsigned int port)
64 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
65 maybebadio((unsigned long)port);
66 return (volatile __u16*)port;
70 /* The 7751 Solution Engine seems to have everything hooked */
71 /* up pretty normally (nothing on high-bytes only...) so this */
72 /* shouldn't be needed */
74 shifted_port(unsigned long port)
76 /* For IDE registers, value is not shifted */
77 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)
96 * General outline: remap really low stuff [eventually] to SuperIO,
97 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
98 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
99 * should be way beyond the window, and is used w/o translation for
102 unsigned char sh7751se_inb(unsigned long port)
105 return *(volatile unsigned char *)port;
106 else if (CHECK_SH7751_PCIIO(port))
107 return *(volatile unsigned char *)PCI_IOMAP(port);
109 return (*port2adr(port))&0xff;
112 unsigned char sh7751se_inb_p(unsigned long port)
117 v = *(volatile unsigned char *)port;
118 else if (CHECK_SH7751_PCIIO(port))
119 v = *(volatile unsigned char *)PCI_IOMAP(port);
121 v = (*port2adr(port))&0xff;
126 unsigned short sh7751se_inw(unsigned long port)
129 return *(volatile unsigned short *)port;
130 else if (CHECK_SH7751_PCIIO(port))
131 return *(volatile unsigned short *)PCI_IOMAP(port);
132 else if (port >= 0x2000)
133 return *port2adr(port);
139 unsigned int sh7751se_inl(unsigned long port)
142 return *(volatile unsigned long *)port;
143 else if (CHECK_SH7751_PCIIO(port))
144 return *(volatile unsigned int *)PCI_IOMAP(port);
145 else if (port >= 0x2000)
146 return *port2adr(port);
152 void sh7751se_outb(unsigned char value, unsigned long port)
156 *(volatile unsigned char *)port = value;
157 else if (CHECK_SH7751_PCIIO(port))
158 *((unsigned char*)PCI_IOMAP(port)) = value;
160 *(port2adr(port)) = value;
163 void sh7751se_outb_p(unsigned char value, unsigned long port)
166 *(volatile unsigned char *)port = value;
167 else if (CHECK_SH7751_PCIIO(port))
168 *((unsigned char*)PCI_IOMAP(port)) = value;
170 *(port2adr(port)) = value;
174 void sh7751se_outw(unsigned short value, unsigned long port)
177 *(volatile unsigned short *)port = value;
178 else if (CHECK_SH7751_PCIIO(port))
179 *((unsigned short *)PCI_IOMAP(port)) = value;
180 else if (port >= 0x2000)
181 *port2adr(port) = value;
186 void sh7751se_outl(unsigned int value, unsigned long port)
189 *(volatile unsigned long *)port = value;
190 else if (CHECK_SH7751_PCIIO(port))
191 *((unsigned long*)PCI_IOMAP(port)) = value;
196 void sh7751se_insl(unsigned long port, void *addr, unsigned long count)
201 void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count)
206 /* Map ISA bus address to the real address. Only for PCMCIA. */
208 /* ISA page descriptor. */
209 static __u32 sh_isa_memmap[256];
213 sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
217 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
221 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
222 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
223 start, length, offset, idx, sh_isa_memmap[idx]);
229 sh7751se_isa_port2addr(unsigned long offset)
233 idx = (offset >> 12) & 0xff;
235 return sh_isa_memmap[idx] + offset;