io.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * linux/arch/arm/mach-ebsa110/isamem.c
  3. *
  4. * Copyright (C) 2001 Russell King
  5. *
  6. * Perform "ISA" memory and IO accesses. The EBSA110 has some "peculiarities"
  7. * in the way it handles accesses to odd IO ports on 16-bit devices. These
  8. * devices have their D0-D15 lines connected to the processors D0-D15 lines.
  9. * Since they expect all byte IO operations to be performed on D0-D7, and the
  10. * StrongARM expects to transfer the byte to these odd addresses on D8-D15,
  11. * we must use a trick to get the required behaviour.
  12. *
  13. * The trick employed here is to use long word stores to odd address -1. The
  14. * glue logic picks this up as a "trick" access, and asserts the LSB of the
  15. * peripherals address bus, thereby accessing the odd IO port. Meanwhile, the
  16. * StrongARM transfers its data on D0-D7 as expected.
  17. *
  18. * Things get more interesting on the pass-1 EBSA110 - the PCMCIA controller
  19. * wiring was screwed in such a way that it had limited memory space access.
  20. * Luckily, the work-around for this is not too horrible. See
  21. * __isamem_convert_addr for the details.
  22. */
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/types.h>
  26. #include <asm/io.h>
  27. #include <asm/page.h>
  28. static void __iomem *__isamem_convert_addr(void __iomem *addr)
  29. {
  30. u32 ret, a = (u32 __force) addr;
  31. /*
  32. * The PCMCIA controller is wired up as follows:
  33. * +---------+---------+---------+---------+---------+---------+
  34. * PCMCIA | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1 | | |
  35. * | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 |
  36. * +---------+---------+---------+---------+---------+---------+
  37. * CPU | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1 | | |
  38. * | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x |
  39. * +---------+---------+---------+---------+---------+---------+
  40. *
  41. * This means that we can access PCMCIA regions as follows:
  42. * 0x*10000 -> 0x*1ffff
  43. * 0x*70000 -> 0x*7ffff
  44. * 0x*90000 -> 0x*9ffff
  45. * 0x*f0000 -> 0x*fffff
  46. */
  47. ret = (a & 0xf803fe) << 1;
  48. ret |= (a & 0x03fc00) << 2;
  49. ret += 0xe8000000;
  50. if ((a & 0x20000) == (a & 0x40000) >> 1)
  51. return (void __iomem *)ret;
  52. BUG();
  53. return NULL;
  54. }
  55. /*
  56. * read[bwl] and write[bwl]
  57. */
  58. u8 __readb(void __iomem *addr)
  59. {
  60. void __iomem *a = __isamem_convert_addr(addr);
  61. u32 ret;
  62. if ((unsigned long)addr & 1)
  63. ret = __raw_readl(a);
  64. else
  65. ret = __raw_readb(a);
  66. return ret;
  67. }
  68. u16 __readw(void __iomem *addr)
  69. {
  70. void __iomem *a = __isamem_convert_addr(addr);
  71. if ((unsigned long)addr & 1)
  72. BUG();
  73. return __raw_readw(a);
  74. }
  75. u32 __readl(void __iomem *addr)
  76. {
  77. void __iomem *a = __isamem_convert_addr(addr);
  78. u32 ret;
  79. if ((unsigned long)addr & 3)
  80. BUG();
  81. ret = __raw_readw(a);
  82. ret |= __raw_readw(a + 4) << 16;
  83. return ret;
  84. }
  85. EXPORT_SYMBOL(__readb);
  86. EXPORT_SYMBOL(__readw);
  87. EXPORT_SYMBOL(__readl);
  88. void __writeb(u8 val, void __iomem *addr)
  89. {
  90. void __iomem *a = __isamem_convert_addr(addr);
  91. if ((unsigned long)addr & 1)
  92. __raw_writel(val, a);
  93. else
  94. __raw_writeb(val, a);
  95. }
  96. void __writew(u16 val, void __iomem *addr)
  97. {
  98. void __iomem *a = __isamem_convert_addr(addr);
  99. if ((unsigned long)addr & 1)
  100. BUG();
  101. __raw_writew(val, a);
  102. }
  103. void __writel(u32 val, void __iomem *addr)
  104. {
  105. void __iomem *a = __isamem_convert_addr(addr);
  106. if ((unsigned long)addr & 3)
  107. BUG();
  108. __raw_writew(val, a);
  109. __raw_writew(val >> 16, a + 4);
  110. }
  111. EXPORT_SYMBOL(__writeb);
  112. EXPORT_SYMBOL(__writew);
  113. EXPORT_SYMBOL(__writel);
  114. #define SUPERIO_PORT(p) \
  115. (((p) >> 3) == (0x3f8 >> 3) || \
  116. ((p) >> 3) == (0x2f8 >> 3) || \
  117. ((p) >> 3) == (0x378 >> 3))
  118. /*
  119. * We're addressing an 8 or 16-bit peripheral which tranfers
  120. * odd addresses on the low ISA byte lane.
  121. */
  122. u8 __inb8(unsigned int port)
  123. {
  124. u32 ret;
  125. /*
  126. * The SuperIO registers use sane addressing techniques...
  127. */
  128. if (SUPERIO_PORT(port))
  129. ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2));
  130. else {
  131. void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
  132. /*
  133. * Shame nothing else does
  134. */
  135. if (port & 1)
  136. ret = __raw_readl(a);
  137. else
  138. ret = __raw_readb(a);
  139. }
  140. return ret;
  141. }
  142. /*
  143. * We're addressing a 16-bit peripheral which transfers odd
  144. * addresses on the high ISA byte lane.
  145. */
  146. u8 __inb16(unsigned int port)
  147. {
  148. unsigned int offset;
  149. /*
  150. * The SuperIO registers use sane addressing techniques...
  151. */
  152. if (SUPERIO_PORT(port))
  153. offset = port << 2;
  154. else
  155. offset = (port & ~1) << 1 | (port & 1);
  156. return __raw_readb((void __iomem *)ISAIO_BASE + offset);
  157. }
  158. u16 __inw(unsigned int port)
  159. {
  160. unsigned int offset;
  161. /*
  162. * The SuperIO registers use sane addressing techniques...
  163. */
  164. if (SUPERIO_PORT(port))
  165. offset = port << 2;
  166. else {
  167. offset = port << 1;
  168. BUG_ON(port & 1);
  169. }
  170. return __raw_readw((void __iomem *)ISAIO_BASE + offset);
  171. }
  172. /*
  173. * Fake a 32-bit read with two 16-bit reads. Needed for 3c589.
  174. */
  175. u32 __inl(unsigned int port)
  176. {
  177. void __iomem *a;
  178. if (SUPERIO_PORT(port) || port & 3)
  179. BUG();
  180. a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
  181. return __raw_readw(a) | __raw_readw(a + 4) << 16;
  182. }
  183. EXPORT_SYMBOL(__inb8);
  184. EXPORT_SYMBOL(__inb16);
  185. EXPORT_SYMBOL(__inw);
  186. EXPORT_SYMBOL(__inl);
  187. void __outb8(u8 val, unsigned int port)
  188. {
  189. /*
  190. * The SuperIO registers use sane addressing techniques...
  191. */
  192. if (SUPERIO_PORT(port))
  193. __raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2));
  194. else {
  195. void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
  196. /*
  197. * Shame nothing else does
  198. */
  199. if (port & 1)
  200. __raw_writel(val, a);
  201. else
  202. __raw_writeb(val, a);
  203. }
  204. }
  205. void __outb16(u8 val, unsigned int port)
  206. {
  207. unsigned int offset;
  208. /*
  209. * The SuperIO registers use sane addressing techniques...
  210. */
  211. if (SUPERIO_PORT(port))
  212. offset = port << 2;
  213. else
  214. offset = (port & ~1) << 1 | (port & 1);
  215. __raw_writeb(val, (void __iomem *)ISAIO_BASE + offset);
  216. }
  217. void __outw(u16 val, unsigned int port)
  218. {
  219. unsigned int offset;
  220. /*
  221. * The SuperIO registers use sane addressing techniques...
  222. */
  223. if (SUPERIO_PORT(port))
  224. offset = port << 2;
  225. else {
  226. offset = port << 1;
  227. BUG_ON(port & 1);
  228. }
  229. __raw_writew(val, (void __iomem *)ISAIO_BASE + offset);
  230. }
  231. void __outl(u32 val, unsigned int port)
  232. {
  233. BUG();
  234. }
  235. EXPORT_SYMBOL(__outb8);
  236. EXPORT_SYMBOL(__outb16);
  237. EXPORT_SYMBOL(__outw);
  238. EXPORT_SYMBOL(__outl);
  239. void outsb(unsigned int port, const void *from, int len)
  240. {
  241. u32 off;
  242. if (SUPERIO_PORT(port))
  243. off = port << 2;
  244. else {
  245. off = (port & ~1) << 1;
  246. if (port & 1)
  247. BUG();
  248. }
  249. __raw_writesb((void __iomem *)ISAIO_BASE + off, from, len);
  250. }
  251. void insb(unsigned int port, void *from, int len)
  252. {
  253. u32 off;
  254. if (SUPERIO_PORT(port))
  255. off = port << 2;
  256. else {
  257. off = (port & ~1) << 1;
  258. if (port & 1)
  259. BUG();
  260. }
  261. __raw_readsb((void __iomem *)ISAIO_BASE + off, from, len);
  262. }
  263. EXPORT_SYMBOL(outsb);
  264. EXPORT_SYMBOL(insb);
  265. void outsw(unsigned int port, const void *from, int len)
  266. {
  267. u32 off;
  268. if (SUPERIO_PORT(port))
  269. off = port << 2;
  270. else {
  271. off = (port & ~1) << 1;
  272. if (port & 1)
  273. BUG();
  274. }
  275. __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len);
  276. }
  277. void insw(unsigned int port, void *from, int len)
  278. {
  279. u32 off;
  280. if (SUPERIO_PORT(port))
  281. off = port << 2;
  282. else {
  283. off = (port & ~1) << 1;
  284. if (port & 1)
  285. BUG();
  286. }
  287. __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len);
  288. }
  289. EXPORT_SYMBOL(outsw);
  290. EXPORT_SYMBOL(insw);
  291. /*
  292. * We implement these as 16-bit insw/outsw, mainly for
  293. * 3c589 cards.
  294. */
  295. void outsl(unsigned int port, const void *from, int len)
  296. {
  297. u32 off = port << 1;
  298. if (SUPERIO_PORT(port) || port & 3)
  299. BUG();
  300. __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1);
  301. }
  302. void insl(unsigned int port, void *from, int len)
  303. {
  304. u32 off = port << 1;
  305. if (SUPERIO_PORT(port) || port & 3)
  306. BUG();
  307. __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1);
  308. }
  309. EXPORT_SYMBOL(outsl);
  310. EXPORT_SYMBOL(insl);