io.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * arch/sh/boards/landisk/io.c
  3. *
  4. * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
  5. * Based largely on io_se.c.
  6. *
  7. * I/O routine for I-O Data Device, Inc. LANDISK.
  8. *
  9. * Initial version only to support LAN access; some
  10. * placeholder code from io_landisk.c left in with the
  11. * expectation of later SuperIO and PCMCIA access.
  12. */
  13. /*
  14. * modifed by kogiidena
  15. * 2005.03.03
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/types.h>
  19. #include <asm/io.h>
  20. #include <asm/landisk/iodata_landisk.h>
  21. #include <asm/addrspace.h>
  22. #include <linux/module.h>
  23. #include <linux/pci.h>
  24. #include "../../drivers/pci/pci-sh7751.h"
  25. extern void *area5_io_base; /* Area 5 I/O Base address */
  26. extern void *area6_io_base; /* Area 6 I/O Base address */
  27. /*
  28. * The 7751R LANDISK uses the built-in PCI controller (PCIC)
  29. * of the 7751R processor, and has a SuperIO accessible via the PCI.
  30. * The board also includes a PCMCIA controller on its memory bus,
  31. * like the other Solution Engine boards.
  32. */
  33. #define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
  34. #define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
  35. #define PCI_IO_AREA SH7751_PCI_IO_BASE
  36. #define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
  37. #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))
  41. static inline void delay(void)
  42. {
  43. ctrl_inw(0xa0000000);
  44. }
  45. static inline unsigned long port2adr(unsigned int port)
  46. {
  47. if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
  48. if (port == 0x3f6)
  49. return ((unsigned long)area5_io_base + 0x2c);
  50. else
  51. return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
  52. ((port - 0x1f0) << 1));
  53. else if ((0x170 <= port && port < 0x178) || port == 0x376)
  54. if (port == 0x376)
  55. return ((unsigned long)area6_io_base + 0x2c);
  56. else
  57. return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
  58. ((port - 0x170) << 1));
  59. else
  60. maybebadio(port2adr, (unsigned long)port);
  61. return port;
  62. }
  63. /* In case someone configures the kernel w/o PCI support: in that */
  64. /* scenario, don't ever bother to check for PCI-window addresses */
  65. /* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
  66. #if defined(CONFIG_PCI)
  67. #define CHECK_SH7751_PCIIO(port) \
  68. ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
  69. #else
  70. #define CHECK_SH_7751_PCIIO(port) (0)
  71. #endif
  72. /*
  73. * General outline: remap really low stuff [eventually] to SuperIO,
  74. * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
  75. * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
  76. * should be way beyond the window, and is used w/o translation for
  77. * compatibility.
  78. */
  79. unsigned char landisk_inb(unsigned long port)
  80. {
  81. if (PXSEG(port))
  82. return *(volatile unsigned char *)port;
  83. else if (CHECK_SH7751_PCIIO(port))
  84. return *(volatile unsigned char *)PCI_IOMAP(port);
  85. else
  86. return (*(volatile unsigned short *)port2adr(port) & 0xff);
  87. }
  88. unsigned char landisk_inb_p(unsigned long port)
  89. {
  90. unsigned char v;
  91. if (PXSEG(port))
  92. v = *(volatile unsigned char *)port;
  93. else if (CHECK_SH7751_PCIIO(port))
  94. v = *(volatile unsigned char *)PCI_IOMAP(port);
  95. else
  96. v = (*(volatile unsigned short *)port2adr(port) & 0xff);
  97. delay();
  98. return v;
  99. }
  100. unsigned short landisk_inw(unsigned long port)
  101. {
  102. if (PXSEG(port))
  103. return *(volatile unsigned short *)port;
  104. else if (CHECK_SH7751_PCIIO(port))
  105. return *(volatile unsigned short *)PCI_IOMAP(port);
  106. else
  107. maybebadio(inw, port);
  108. return 0;
  109. }
  110. unsigned int landisk_inl(unsigned long port)
  111. {
  112. if (PXSEG(port))
  113. return *(volatile unsigned long *)port;
  114. else if (CHECK_SH7751_PCIIO(port))
  115. return *(volatile unsigned long *)PCI_IOMAP(port);
  116. else
  117. maybebadio(inl, port);
  118. return 0;
  119. }
  120. void landisk_outb(unsigned char value, unsigned long port)
  121. {
  122. if (PXSEG(port))
  123. *(volatile unsigned char *)port = value;
  124. else if (CHECK_SH7751_PCIIO(port))
  125. *(volatile unsigned char *)PCI_IOMAP(port) = value;
  126. else
  127. *(volatile unsigned short *)port2adr(port) = value;
  128. }
  129. void landisk_outb_p(unsigned char value, unsigned long port)
  130. {
  131. if (PXSEG(port))
  132. *(volatile unsigned char *)port = value;
  133. else if (CHECK_SH7751_PCIIO(port))
  134. *(volatile unsigned char *)PCI_IOMAP(port) = value;
  135. else
  136. *(volatile unsigned short *)port2adr(port) = value;
  137. delay();
  138. }
  139. void landisk_outw(unsigned short value, unsigned long port)
  140. {
  141. if (PXSEG(port))
  142. *(volatile unsigned short *)port = value;
  143. else if (CHECK_SH7751_PCIIO(port))
  144. *(volatile unsigned short *)PCI_IOMAP(port) = value;
  145. else
  146. maybebadio(outw, port);
  147. }
  148. void landisk_outl(unsigned int value, unsigned long port)
  149. {
  150. if (PXSEG(port))
  151. *(volatile unsigned long *)port = value;
  152. else if (CHECK_SH7751_PCIIO(port))
  153. *(volatile unsigned long *)PCI_IOMAP(port) = value;
  154. else
  155. maybebadio(outl, port);
  156. }
  157. void landisk_insb(unsigned long port, void *addr, unsigned long count)
  158. {
  159. if (PXSEG(port))
  160. while (count--)
  161. *((unsigned char *)addr)++ =
  162. *(volatile unsigned char *)port;
  163. else if (CHECK_SH7751_PCIIO(port)) {
  164. volatile __u8 *bp = (__u8 *) PCI_IOMAP(port);
  165. while (count--)
  166. *((volatile unsigned char *)addr)++ = *bp;
  167. } else {
  168. volatile __u16 *p = (volatile unsigned short *)port2adr(port);
  169. while (count--)
  170. *((unsigned char *)addr)++ = *p;
  171. }
  172. }
  173. void landisk_insw(unsigned long port, void *addr, unsigned long count)
  174. {
  175. volatile __u16 *p;
  176. if (PXSEG(port))
  177. p = (volatile unsigned short *)port;
  178. else if (CHECK_SH7751_PCIIO(port))
  179. p = (volatile unsigned short *)PCI_IOMAP(port);
  180. else
  181. p = (volatile unsigned short *)port2adr(port);
  182. while (count--)
  183. *((__u16 *) addr)++ = *p;
  184. }
  185. void landisk_insl(unsigned long port, void *addr, unsigned long count)
  186. {
  187. if (CHECK_SH7751_PCIIO(port)) {
  188. volatile __u32 *p = (__u32 *) PCI_IOMAP(port);
  189. while (count--)
  190. *((__u32 *) addr)++ = *p;
  191. } else
  192. maybebadio(insl, port);
  193. }
  194. void landisk_outsb(unsigned long port, const void *addr, unsigned long count)
  195. {
  196. if (PXSEG(port))
  197. while (count--)
  198. *(volatile unsigned char *)port =
  199. *((unsigned char *)addr)++;
  200. else if (CHECK_SH7751_PCIIO(port)) {
  201. volatile __u8 *bp = (__u8 *) PCI_IOMAP(port);
  202. while (count--)
  203. *bp = *((volatile unsigned char *)addr)++;
  204. } else {
  205. volatile __u16 *p = (volatile unsigned short *)port2adr(port);
  206. while (count--)
  207. *p = *((unsigned char *)addr)++;
  208. }
  209. }
  210. void landisk_outsw(unsigned long port, const void *addr, unsigned long count)
  211. {
  212. volatile __u16 *p;
  213. if (PXSEG(port))
  214. p = (volatile unsigned short *)port;
  215. else if (CHECK_SH7751_PCIIO(port))
  216. p = (volatile unsigned short *)PCI_IOMAP(port);
  217. else
  218. p = (volatile unsigned short *)port2adr(port);
  219. while (count--)
  220. *p = *((__u16 *) addr)++;
  221. }
  222. void landisk_outsl(unsigned long port, const void *addr, unsigned long count)
  223. {
  224. if (CHECK_SH7751_PCIIO(port)) {
  225. volatile __u32 *p = (__u32 *) PCI_IOMAP(port);
  226. while (count--)
  227. *p = *((__u32 *) addr)++;
  228. } else
  229. maybebadio(outsl, port);
  230. }
  231. /* For read/write calls, just copy generic (pass-thru); PCIMBR is */
  232. /* already set up. For a larger memory space, these would need to */
  233. /* reset PCIMBR as needed on a per-call basis... */
  234. unsigned char landisk_readb(unsigned long addr)
  235. {
  236. return *(volatile unsigned char *)addr;
  237. }
  238. unsigned short landisk_readw(unsigned long addr)
  239. {
  240. return *(volatile unsigned short *)addr;
  241. }
  242. unsigned int landisk_readl(unsigned long addr)
  243. {
  244. return *(volatile unsigned long *)addr;
  245. }
  246. void landisk_writeb(unsigned char b, unsigned long addr)
  247. {
  248. *(volatile unsigned char *)addr = b;
  249. }
  250. void landisk_writew(unsigned short b, unsigned long addr)
  251. {
  252. *(volatile unsigned short *)addr = b;
  253. }
  254. void landisk_writel(unsigned int b, unsigned long addr)
  255. {
  256. *(volatile unsigned long *)addr = b;
  257. }
  258. void *landisk_ioremap(unsigned long offset, unsigned long size)
  259. {
  260. if (offset >= 0xfd000000)
  261. return (void *)offset;
  262. else
  263. return (void *)P2SEGADDR(offset);
  264. }
  265. void landisk_iounmap(void *addr)
  266. {
  267. }
  268. /* Map ISA bus address to the real address. Only for PCMCIA. */
  269. unsigned long landisk_isa_port2addr(unsigned long offset)
  270. {
  271. return port2adr(offset);
  272. }