blob: dec3db0ee933ba61a11d0438f64c81201d3edd0b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Uwe Zeisbergerf30c2262006-10-03 23:01:26 +02002 * linux/arch/sh/boards/renesas/systemh/io.c
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for Hitachi 7751 Systemh.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07009#include <linux/kernel.h>
10#include <linux/types.h>
Paul Mundt373e68b2006-09-27 15:41:24 +090011#include <linux/pci.h>
Paul Mundt7639a452008-10-20 13:02:48 +090012#include <mach/systemh7751.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <asm/addrspace.h>
14#include <asm/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area
17 of smc lan chip*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070018static inline volatile __u16 *
19port2adr(unsigned int port)
20{
21 if (port >= 0x2000)
22 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
Paul Mundt373e68b2006-09-27 15:41:24 +090023 maybebadio((unsigned long)port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 return (volatile __u16*)port;
25}
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027/*
28 * General outline: remap really low stuff [eventually] to SuperIO,
29 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
30 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
31 * should be way beyond the window, and is used w/o translation for
32 * compatibility.
33 */
34unsigned char sh7751systemh_inb(unsigned long port)
35{
36 if (PXSEG(port))
37 return *(volatile unsigned char *)port;
Paul Mundt959f85f2006-09-27 16:43:28 +090038 else if (is_pci_ioaddr(port))
39 return *(volatile unsigned char *)pci_ioaddr(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 else if (port <= 0x3F1)
41 return *(volatile unsigned char *)ETHER_IOMAP(port);
42 else
43 return (*port2adr(port))&0xff;
44}
45
46unsigned char sh7751systemh_inb_p(unsigned long port)
47{
48 unsigned char v;
49
50 if (PXSEG(port))
51 v = *(volatile unsigned char *)port;
Paul Mundt959f85f2006-09-27 16:43:28 +090052 else if (is_pci_ioaddr(port))
53 v = *(volatile unsigned char *)pci_ioaddr(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 else if (port <= 0x3F1)
55 v = *(volatile unsigned char *)ETHER_IOMAP(port);
56 else
57 v = (*port2adr(port))&0xff;
Paul Mundt959f85f2006-09-27 16:43:28 +090058 ctrl_delay();
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 return v;
60}
61
62unsigned short sh7751systemh_inw(unsigned long port)
63{
64 if (PXSEG(port))
65 return *(volatile unsigned short *)port;
Paul Mundt959f85f2006-09-27 16:43:28 +090066 else if (is_pci_ioaddr(port))
67 return *(volatile unsigned short *)pci_ioaddr(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 else if (port >= 0x2000)
69 return *port2adr(port);
70 else if (port <= 0x3F1)
71 return *(volatile unsigned int *)ETHER_IOMAP(port);
72 else
Paul Mundt373e68b2006-09-27 15:41:24 +090073 maybebadio(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 return 0;
75}
76
77unsigned int sh7751systemh_inl(unsigned long port)
78{
79 if (PXSEG(port))
80 return *(volatile unsigned long *)port;
Paul Mundt959f85f2006-09-27 16:43:28 +090081 else if (is_pci_ioaddr(port))
82 return *(volatile unsigned int *)pci_ioaddr(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 else if (port >= 0x2000)
84 return *port2adr(port);
85 else if (port <= 0x3F1)
86 return *(volatile unsigned int *)ETHER_IOMAP(port);
87 else
Paul Mundt373e68b2006-09-27 15:41:24 +090088 maybebadio(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 return 0;
90}
91
92void sh7751systemh_outb(unsigned char value, unsigned long port)
93{
94
95 if (PXSEG(port))
96 *(volatile unsigned char *)port = value;
Paul Mundt959f85f2006-09-27 16:43:28 +090097 else if (is_pci_ioaddr(port))
98 *((unsigned char*)pci_ioaddr(port)) = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 else if (port <= 0x3F1)
100 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
101 else
102 *(port2adr(port)) = value;
103}
104
105void sh7751systemh_outb_p(unsigned char value, unsigned long port)
106{
107 if (PXSEG(port))
108 *(volatile unsigned char *)port = value;
Paul Mundt959f85f2006-09-27 16:43:28 +0900109 else if (is_pci_ioaddr(port))
110 *((unsigned char*)pci_ioaddr(port)) = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 else if (port <= 0x3F1)
112 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
113 else
114 *(port2adr(port)) = value;
Paul Mundt959f85f2006-09-27 16:43:28 +0900115 ctrl_delay();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116}
117
118void sh7751systemh_outw(unsigned short value, unsigned long port)
119{
120 if (PXSEG(port))
121 *(volatile unsigned short *)port = value;
Paul Mundt959f85f2006-09-27 16:43:28 +0900122 else if (is_pci_ioaddr(port))
123 *((unsigned short *)pci_ioaddr(port)) = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 else if (port >= 0x2000)
125 *port2adr(port) = value;
126 else if (port <= 0x3F1)
127 *(volatile unsigned short *)ETHER_IOMAP(port) = value;
128 else
Paul Mundt373e68b2006-09-27 15:41:24 +0900129 maybebadio(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130}
131
132void sh7751systemh_outl(unsigned int value, unsigned long port)
133{
134 if (PXSEG(port))
135 *(volatile unsigned long *)port = value;
Paul Mundt959f85f2006-09-27 16:43:28 +0900136 else if (is_pci_ioaddr(port))
137 *((unsigned long*)pci_ioaddr(port)) = value;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 else
Paul Mundt373e68b2006-09-27 15:41:24 +0900139 maybebadio(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140}
141
142void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count)
143{
144 unsigned char *p = addr;
145 while (count--) *p++ = sh7751systemh_inb(port);
146}
147
148void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count)
149{
150 unsigned short *p = addr;
151 while (count--) *p++ = sh7751systemh_inw(port);
152}
153
154void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count)
155{
Paul Mundt373e68b2006-09-27 15:41:24 +0900156 maybebadio(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157}
158
159void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count)
160{
161 unsigned char *p = (unsigned char*)addr;
162 while (count--) sh7751systemh_outb(*p++, port);
163}
164
165void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count)
166{
167 unsigned short *p = (unsigned short*)addr;
168 while (count--) sh7751systemh_outw(*p++, port);
169}
170
171void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count)
172{
Paul Mundt373e68b2006-09-27 15:41:24 +0900173 maybebadio(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174}