raw_io.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * linux/include/asm-m68k/raw_io.h
  4. *
  5. * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace
  6. *
  7. */
  8. #ifndef _RAW_IO_H
  9. #define _RAW_IO_H
  10. #ifdef __KERNEL__
  11. #include <asm/byteorder.h>
  12. /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
  13. * two accesses to memory, which may be undesirable for some devices.
  14. */
  15. #define in_8(addr) \
  16. ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; })
  17. #define in_be16(addr) \
  18. ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
  19. #define in_be32(addr) \
  20. ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; })
  21. #define in_le16(addr) \
  22. ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; })
  23. #define in_le32(addr) \
  24. ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; })
  25. #define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b))
  26. #define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w))
  27. #define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l))
  28. #define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w))
  29. #define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l))
  30. #define raw_inb in_8
  31. #define raw_inw in_be16
  32. #define raw_inl in_be32
  33. #define __raw_readb in_8
  34. #define __raw_readw in_be16
  35. #define __raw_readl in_be32
  36. #define raw_outb(val,port) out_8((port),(val))
  37. #define raw_outw(val,port) out_be16((port),(val))
  38. #define raw_outl(val,port) out_be32((port),(val))
  39. #define __raw_writeb(val,addr) out_8((addr),(val))
  40. #define __raw_writew(val,addr) out_be16((addr),(val))
  41. #define __raw_writel(val,addr) out_be32((addr),(val))
  42. /*
  43. * Atari ROM port (cartridge port) ISA adapter, used for the EtherNEC NE2000
  44. * network card driver.
  45. * The ISA adapter connects address lines A9-A13 to ISA address lines A0-A4,
  46. * and hardwires the rest of the ISA addresses for a base address of 0x300.
  47. *
  48. * Data lines D8-D15 are connected to ISA data lines D0-D7 for reading.
  49. * For writes, address lines A1-A8 are latched to ISA data lines D0-D7
  50. * (meaning the bit pattern on A1-A8 can be read back as byte).
  51. *
  52. * Read and write operations are distinguished by the base address used:
  53. * reads are from the ROM A side range, writes are through the B side range
  54. * addresses (A side base + 0x10000).
  55. *
  56. * Reads and writes are byte only.
  57. *
  58. * 16 bit reads and writes are necessary for the NetUSBee adapter's USB
  59. * chipset - 16 bit words are read straight off the ROM port while 16 bit
  60. * reads are split into two byte writes. The low byte is latched to the
  61. * NetUSBee buffer by a read from the _read_ window (with the data pattern
  62. * asserted as A1-A8 address pattern). The high byte is then written to the
  63. * write range as usual, completing the write cycle.
  64. */
  65. #if defined(CONFIG_ATARI_ROM_ISA)
  66. #define rom_in_8(addr) \
  67. ({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
  68. #define rom_in_be16(addr) \
  69. ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
  70. #define rom_in_le16(addr) \
  71. ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
  72. #define rom_out_8(addr, b) \
  73. ({u8 __w, __v = (b); u32 _addr = ((u32) (addr)); \
  74. __w = ((*(__force volatile u8 *) ((_addr | 0x10000) + (__v<<1)))); })
  75. #define rom_out_be16(addr, w) \
  76. ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
  77. __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \
  78. __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); })
  79. #define rom_out_le16(addr, w) \
  80. ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
  81. __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \
  82. __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); })
  83. #define raw_rom_inb rom_in_8
  84. #define raw_rom_inw rom_in_be16
  85. #define raw_rom_outb(val, port) rom_out_8((port), (val))
  86. #define raw_rom_outw(val, port) rom_out_be16((port), (val))
  87. #endif /* CONFIG_ATARI_ROM_ISA */
  88. static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
  89. {
  90. unsigned int i;
  91. for (i = 0; i < len; i++)
  92. *buf++ = in_8(port);
  93. }
  94. static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf,
  95. unsigned int len)
  96. {
  97. unsigned int i;
  98. for (i = 0; i < len; i++)
  99. out_8(port, *buf++);
  100. }
  101. static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)
  102. {
  103. unsigned int tmp;
  104. if (nr & 15) {
  105. tmp = (nr & 15) - 1;
  106. asm volatile (
  107. "1: movew %2@,%0@+; dbra %1,1b"
  108. : "=a" (buf), "=d" (tmp)
  109. : "a" (port), "0" (buf),
  110. "1" (tmp));
  111. }
  112. if (nr >> 4) {
  113. tmp = (nr >> 4) - 1;
  114. asm volatile (
  115. "1: "
  116. "movew %2@,%0@+; "
  117. "movew %2@,%0@+; "
  118. "movew %2@,%0@+; "
  119. "movew %2@,%0@+; "
  120. "movew %2@,%0@+; "
  121. "movew %2@,%0@+; "
  122. "movew %2@,%0@+; "
  123. "movew %2@,%0@+; "
  124. "movew %2@,%0@+; "
  125. "movew %2@,%0@+; "
  126. "movew %2@,%0@+; "
  127. "movew %2@,%0@+; "
  128. "movew %2@,%0@+; "
  129. "movew %2@,%0@+; "
  130. "movew %2@,%0@+; "
  131. "movew %2@,%0@+; "
  132. "dbra %1,1b"
  133. : "=a" (buf), "=d" (tmp)
  134. : "a" (port), "0" (buf),
  135. "1" (tmp));
  136. }
  137. }
  138. static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf,
  139. unsigned int nr)
  140. {
  141. unsigned int tmp;
  142. if (nr & 15) {
  143. tmp = (nr & 15) - 1;
  144. asm volatile (
  145. "1: movew %0@+,%2@; dbra %1,1b"
  146. : "=a" (buf), "=d" (tmp)
  147. : "a" (port), "0" (buf),
  148. "1" (tmp));
  149. }
  150. if (nr >> 4) {
  151. tmp = (nr >> 4) - 1;
  152. asm volatile (
  153. "1: "
  154. "movew %0@+,%2@; "
  155. "movew %0@+,%2@; "
  156. "movew %0@+,%2@; "
  157. "movew %0@+,%2@; "
  158. "movew %0@+,%2@; "
  159. "movew %0@+,%2@; "
  160. "movew %0@+,%2@; "
  161. "movew %0@+,%2@; "
  162. "movew %0@+,%2@; "
  163. "movew %0@+,%2@; "
  164. "movew %0@+,%2@; "
  165. "movew %0@+,%2@; "
  166. "movew %0@+,%2@; "
  167. "movew %0@+,%2@; "
  168. "movew %0@+,%2@; "
  169. "movew %0@+,%2@; "
  170. "dbra %1,1b"
  171. : "=a" (buf), "=d" (tmp)
  172. : "a" (port), "0" (buf),
  173. "1" (tmp));
  174. }
  175. }
  176. static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr)
  177. {
  178. unsigned int tmp;
  179. if (nr & 15) {
  180. tmp = (nr & 15) - 1;
  181. asm volatile (
  182. "1: movel %2@,%0@+; dbra %1,1b"
  183. : "=a" (buf), "=d" (tmp)
  184. : "a" (port), "0" (buf),
  185. "1" (tmp));
  186. }
  187. if (nr >> 4) {
  188. tmp = (nr >> 4) - 1;
  189. asm volatile (
  190. "1: "
  191. "movel %2@,%0@+; "
  192. "movel %2@,%0@+; "
  193. "movel %2@,%0@+; "
  194. "movel %2@,%0@+; "
  195. "movel %2@,%0@+; "
  196. "movel %2@,%0@+; "
  197. "movel %2@,%0@+; "
  198. "movel %2@,%0@+; "
  199. "movel %2@,%0@+; "
  200. "movel %2@,%0@+; "
  201. "movel %2@,%0@+; "
  202. "movel %2@,%0@+; "
  203. "movel %2@,%0@+; "
  204. "movel %2@,%0@+; "
  205. "movel %2@,%0@+; "
  206. "movel %2@,%0@+; "
  207. "dbra %1,1b"
  208. : "=a" (buf), "=d" (tmp)
  209. : "a" (port), "0" (buf),
  210. "1" (tmp));
  211. }
  212. }
  213. static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf,
  214. unsigned int nr)
  215. {
  216. unsigned int tmp;
  217. if (nr & 15) {
  218. tmp = (nr & 15) - 1;
  219. asm volatile (
  220. "1: movel %0@+,%2@; dbra %1,1b"
  221. : "=a" (buf), "=d" (tmp)
  222. : "a" (port), "0" (buf),
  223. "1" (tmp));
  224. }
  225. if (nr >> 4) {
  226. tmp = (nr >> 4) - 1;
  227. asm volatile (
  228. "1: "
  229. "movel %0@+,%2@; "
  230. "movel %0@+,%2@; "
  231. "movel %0@+,%2@; "
  232. "movel %0@+,%2@; "
  233. "movel %0@+,%2@; "
  234. "movel %0@+,%2@; "
  235. "movel %0@+,%2@; "
  236. "movel %0@+,%2@; "
  237. "movel %0@+,%2@; "
  238. "movel %0@+,%2@; "
  239. "movel %0@+,%2@; "
  240. "movel %0@+,%2@; "
  241. "movel %0@+,%2@; "
  242. "movel %0@+,%2@; "
  243. "movel %0@+,%2@; "
  244. "movel %0@+,%2@; "
  245. "dbra %1,1b"
  246. : "=a" (buf), "=d" (tmp)
  247. : "a" (port), "0" (buf),
  248. "1" (tmp));
  249. }
  250. }
  251. static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf,
  252. unsigned int nr)
  253. {
  254. if ((nr) % 8)
  255. __asm__ __volatile__
  256. ("\tmovel %0,%/a0\n\t"
  257. "movel %1,%/a1\n\t"
  258. "movel %2,%/d6\n\t"
  259. "subql #1,%/d6\n"
  260. "1:\tmovew %/a0@,%/d0\n\t"
  261. "rolw #8,%/d0\n\t"
  262. "movew %/d0,%/a1@+\n\t"
  263. "dbra %/d6,1b"
  264. :
  265. : "g" (port), "g" (buf), "g" (nr)
  266. : "d0", "a0", "a1", "d6");
  267. else
  268. __asm__ __volatile__
  269. ("movel %0,%/a0\n\t"
  270. "movel %1,%/a1\n\t"
  271. "movel %2,%/d6\n\t"
  272. "lsrl #3,%/d6\n\t"
  273. "subql #1,%/d6\n"
  274. "1:\tmovew %/a0@,%/d0\n\t"
  275. "rolw #8,%/d0\n\t"
  276. "movew %/d0,%/a1@+\n\t"
  277. "movew %/a0@,%/d0\n\t"
  278. "rolw #8,%/d0\n\t"
  279. "movew %/d0,%/a1@+\n\t"
  280. "movew %/a0@,%/d0\n\t"
  281. "rolw #8,%/d0\n\t"
  282. "movew %/d0,%/a1@+\n\t"
  283. "movew %/a0@,%/d0\n\t"
  284. "rolw #8,%/d0\n\t"
  285. "movew %/d0,%/a1@+\n\t"
  286. "movew %/a0@,%/d0\n\t"
  287. "rolw #8,%/d0\n\t"
  288. "movew %/d0,%/a1@+\n\t"
  289. "movew %/a0@,%/d0\n\t"
  290. "rolw #8,%/d0\n\t"
  291. "movew %/d0,%/a1@+\n\t"
  292. "movew %/a0@,%/d0\n\t"
  293. "rolw #8,%/d0\n\t"
  294. "movew %/d0,%/a1@+\n\t"
  295. "movew %/a0@,%/d0\n\t"
  296. "rolw #8,%/d0\n\t"
  297. "movew %/d0,%/a1@+\n\t"
  298. "dbra %/d6,1b"
  299. :
  300. : "g" (port), "g" (buf), "g" (nr)
  301. : "d0", "a0", "a1", "d6");
  302. }
  303. static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
  304. unsigned int nr)
  305. {
  306. if ((nr) % 8)
  307. __asm__ __volatile__
  308. ("movel %0,%/a0\n\t"
  309. "movel %1,%/a1\n\t"
  310. "movel %2,%/d6\n\t"
  311. "subql #1,%/d6\n"
  312. "1:\tmovew %/a1@+,%/d0\n\t"
  313. "rolw #8,%/d0\n\t"
  314. "movew %/d0,%/a0@\n\t"
  315. "dbra %/d6,1b"
  316. :
  317. : "g" (port), "g" (buf), "g" (nr)
  318. : "d0", "a0", "a1", "d6");
  319. else
  320. __asm__ __volatile__
  321. ("movel %0,%/a0\n\t"
  322. "movel %1,%/a1\n\t"
  323. "movel %2,%/d6\n\t"
  324. "lsrl #3,%/d6\n\t"
  325. "subql #1,%/d6\n"
  326. "1:\tmovew %/a1@+,%/d0\n\t"
  327. "rolw #8,%/d0\n\t"
  328. "movew %/d0,%/a0@\n\t"
  329. "movew %/a1@+,%/d0\n\t"
  330. "rolw #8,%/d0\n\t"
  331. "movew %/d0,%/a0@\n\t"
  332. "movew %/a1@+,%/d0\n\t"
  333. "rolw #8,%/d0\n\t"
  334. "movew %/d0,%/a0@\n\t"
  335. "movew %/a1@+,%/d0\n\t"
  336. "rolw #8,%/d0\n\t"
  337. "movew %/d0,%/a0@\n\t"
  338. "movew %/a1@+,%/d0\n\t"
  339. "rolw #8,%/d0\n\t"
  340. "movew %/d0,%/a0@\n\t"
  341. "movew %/a1@+,%/d0\n\t"
  342. "rolw #8,%/d0\n\t"
  343. "movew %/d0,%/a0@\n\t"
  344. "movew %/a1@+,%/d0\n\t"
  345. "rolw #8,%/d0\n\t"
  346. "movew %/d0,%/a0@\n\t"
  347. "movew %/a1@+,%/d0\n\t"
  348. "rolw #8,%/d0\n\t"
  349. "movew %/d0,%/a0@\n\t"
  350. "dbra %/d6,1b"
  351. :
  352. : "g" (port), "g" (buf), "g" (nr)
  353. : "d0", "a0", "a1", "d6");
  354. }
  355. #if defined(CONFIG_ATARI_ROM_ISA)
  356. static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
  357. {
  358. unsigned int i;
  359. for (i = 0; i < len; i++)
  360. *buf++ = rom_in_8(port);
  361. }
  362. static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf,
  363. unsigned int len)
  364. {
  365. unsigned int i;
  366. for (i = 0; i < len; i++)
  367. rom_out_8(port, *buf++);
  368. }
  369. static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf,
  370. unsigned int nr)
  371. {
  372. unsigned int i;
  373. for (i = 0; i < nr; i++)
  374. *buf++ = rom_in_be16(port);
  375. }
  376. static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf,
  377. unsigned int nr)
  378. {
  379. unsigned int i;
  380. for (i = 0; i < nr; i++)
  381. rom_out_be16(port, *buf++);
  382. }
  383. static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf,
  384. unsigned int nr)
  385. {
  386. unsigned int i;
  387. for (i = 0; i < nr; i++)
  388. *buf++ = rom_in_le16(port);
  389. }
  390. static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
  391. unsigned int nr)
  392. {
  393. unsigned int i;
  394. for (i = 0; i < nr; i++)
  395. rom_out_le16(port, *buf++);
  396. }
  397. #endif /* CONFIG_ATARI_ROM_ISA */
  398. #endif /* __KERNEL__ */
  399. #endif /* _RAW_IO_H */