io.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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/landisk/iodata_landisk.h>
  20. #include <asm/addrspace.h>
  21. #include <asm/io.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. static inline void delay(void)
  39. {
  40. ctrl_inw(0xa0000000);
  41. }
  42. static inline unsigned long port2adr(unsigned int port)
  43. {
  44. if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
  45. if (port == 0x3f6)
  46. return ((unsigned long)area5_io_base + 0x2c);
  47. else
  48. return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
  49. ((port - 0x1f0) << 1));
  50. else if ((0x170 <= port && port < 0x178) || port == 0x376)
  51. if (port == 0x376)
  52. return ((unsigned long)area6_io_base + 0x2c);
  53. else
  54. return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
  55. ((port - 0x170) << 1));
  56. else
  57. maybebadio((unsigned long)port);
  58. return port;
  59. }
  60. /* In case someone configures the kernel w/o PCI support: in that */
  61. /* scenario, don't ever bother to check for PCI-window addresses */
  62. /* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
  63. #if defined(CONFIG_PCI)
  64. #define CHECK_SH7751_PCIIO(port) \
  65. ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
  66. #else
  67. #define CHECK_SH_7751_PCIIO(port) (0)
  68. #endif
  69. /*
  70. * General outline: remap really low stuff [eventually] to SuperIO,
  71. * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
  72. * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
  73. * should be way beyond the window, and is used w/o translation for
  74. * compatibility.
  75. */
  76. u8 landisk_inb(unsigned long port)
  77. {
  78. if (PXSEG(port))
  79. return ctrl_inb(port);
  80. else if (CHECK_SH7751_PCIIO(port))
  81. return ctrl_inb(PCI_IOMAP(port));
  82. return ctrl_inw(port2adr(port)) & 0xff;
  83. }
  84. u8 landisk_inb_p(unsigned long port)
  85. {
  86. u8 v;
  87. if (PXSEG(port))
  88. v = ctrl_inb(port);
  89. else if (CHECK_SH7751_PCIIO(port))
  90. v = ctrl_inb(PCI_IOMAP(port));
  91. else
  92. v = ctrl_inw(port2adr(port)) & 0xff;
  93. delay();
  94. return v;
  95. }
  96. u16 landisk_inw(unsigned long port)
  97. {
  98. if (PXSEG(port))
  99. return ctrl_inw(port);
  100. else if (CHECK_SH7751_PCIIO(port))
  101. return ctrl_inw(PCI_IOMAP(port));
  102. else
  103. maybebadio(port);
  104. return 0;
  105. }
  106. u32 landisk_inl(unsigned long port)
  107. {
  108. if (PXSEG(port))
  109. return ctrl_inl(port);
  110. else if (CHECK_SH7751_PCIIO(port))
  111. return ctrl_inl(PCI_IOMAP(port));
  112. else
  113. maybebadio(port);
  114. return 0;
  115. }
  116. void landisk_outb(u8 value, unsigned long port)
  117. {
  118. if (PXSEG(port))
  119. ctrl_outb(value, port);
  120. else if (CHECK_SH7751_PCIIO(port))
  121. ctrl_outb(value, PCI_IOMAP(port));
  122. else
  123. ctrl_outw(value, port2adr(port));
  124. }
  125. void landisk_outb_p(u8 value, unsigned long port)
  126. {
  127. if (PXSEG(port))
  128. ctrl_outb(value, port);
  129. else if (CHECK_SH7751_PCIIO(port))
  130. ctrl_outb(value, PCI_IOMAP(port));
  131. else
  132. ctrl_outw(value, port2adr(port));
  133. delay();
  134. }
  135. void landisk_outw(u16 value, unsigned long port)
  136. {
  137. if (PXSEG(port))
  138. ctrl_outw(value, port);
  139. else if (CHECK_SH7751_PCIIO(port))
  140. ctrl_outw(value, PCI_IOMAP(port));
  141. else
  142. maybebadio(port);
  143. }
  144. void landisk_outl(u32 value, unsigned long port)
  145. {
  146. if (PXSEG(port))
  147. ctrl_outl(value, port);
  148. else if (CHECK_SH7751_PCIIO(port))
  149. ctrl_outl(value, PCI_IOMAP(port));
  150. else
  151. maybebadio(port);
  152. }
  153. void landisk_insb(unsigned long port, void *dst, unsigned long count)
  154. {
  155. volatile u16 *p;
  156. u8 *buf = dst;
  157. if (PXSEG(port)) {
  158. while (count--)
  159. *buf++ = *(volatile u8 *)port;
  160. } else if (CHECK_SH7751_PCIIO(port)) {
  161. volatile u8 *bp = (volatile u8 *)PCI_IOMAP(port);
  162. while (count--)
  163. *buf++ = *bp;
  164. } else {
  165. p = (volatile u16 *)port2adr(port);
  166. while (count--)
  167. *buf++ = *p & 0xff;
  168. }
  169. }
  170. void landisk_insw(unsigned long port, void *dst, unsigned long count)
  171. {
  172. volatile u16 *p;
  173. u16 *buf = dst;
  174. if (PXSEG(port))
  175. p = (volatile u16 *)port;
  176. else if (CHECK_SH7751_PCIIO(port))
  177. p = (volatile u16 *)PCI_IOMAP(port);
  178. else
  179. p = (volatile u16 *)port2adr(port);
  180. while (count--)
  181. *buf++ = *p;
  182. }
  183. void landisk_insl(unsigned long port, void *dst, unsigned long count)
  184. {
  185. u32 *buf = dst;
  186. if (CHECK_SH7751_PCIIO(port)) {
  187. volatile u32 *p = (volatile u32 *)PCI_IOMAP(port);
  188. while (count--)
  189. *buf++ = *p;
  190. } else
  191. maybebadio(port);
  192. }
  193. void landisk_outsb(unsigned long port, const void *src, unsigned long count)
  194. {
  195. volatile u16 *p;
  196. const u8 *buf = src;
  197. if (PXSEG(port))
  198. while (count--)
  199. ctrl_outb(*buf++, port);
  200. else if (CHECK_SH7751_PCIIO(port)) {
  201. volatile u8 *bp = (volatile u8 *)PCI_IOMAP(port);
  202. while (count--)
  203. *bp = *buf++;
  204. } else {
  205. p = (volatile u16 *)port2adr(port);
  206. while (count--)
  207. *p = *buf++;
  208. }
  209. }
  210. void landisk_outsw(unsigned long port, const void *src, unsigned long count)
  211. {
  212. volatile u16 *p;
  213. const u16 *buf = src;
  214. if (PXSEG(port))
  215. p = (volatile u16 *)port;
  216. else if (CHECK_SH7751_PCIIO(port))
  217. p = (volatile u16 *)PCI_IOMAP(port);
  218. else
  219. p = (volatile u16 *)port2adr(port);
  220. while (count--)
  221. *p = *buf++;
  222. }
  223. void landisk_outsl(unsigned long port, const void *src, unsigned long count)
  224. {
  225. const u32 *buf = src;
  226. if (CHECK_SH7751_PCIIO(port)) {
  227. volatile u32 *p = (volatile u32 *)PCI_IOMAP(port);
  228. while (count--)
  229. *p = *buf++;
  230. } else
  231. maybebadio(port);
  232. }
  233. void __iomem *landisk_ioport_map(unsigned long port, unsigned int size)
  234. {
  235. if (PXSEG(port))
  236. return (void __iomem *)port;
  237. else if (CHECK_SH7751_PCIIO(port))
  238. return (void __iomem *)PCI_IOMAP(port);
  239. return (void __iomem *)port2adr(port);
  240. }