raw_io.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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 *) (unsigned long)(addr)); __v; })
  17. #define in_be16(addr) \
  18. ({ u16 __v = (*(__force volatile u16 *) (unsigned long)(addr)); __v; })
  19. #define in_be32(addr) \
  20. ({ u32 __v = (*(__force volatile u32 *) (unsigned long)(addr)); __v; })
  21. #define in_le16(addr) \
  22. ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (unsigned long)(addr)); __v; })
  23. #define in_le32(addr) \
  24. ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (unsigned long)(addr)); __v; })
  25. #define out_8(addr,b) (void)((*(__force volatile u8 *) (unsigned long)(addr)) = (b))
  26. #define out_be16(addr,w) (void)((*(__force volatile u16 *) (unsigned long)(addr)) = (w))
  27. #define out_be32(addr,l) (void)((*(__force volatile u32 *) (unsigned long)(addr)) = (l))
  28. #define out_le16(addr,w) (void)((*(__force volatile __le16 *) (unsigned long)(addr)) = cpu_to_le16(w))
  29. #define out_le32(addr,l) (void)((*(__force volatile __le32 *) (unsigned long)(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. (void)({u8 __maybe_unused __w, __v = (b); u32 _addr = ((u32) (addr)); \
  74. __w = ((*(__force volatile u8 *) ((_addr | 0x10000) + (__v<<1)))); })
  75. #define rom_out_be16(addr, w) \
  76. (void)({u16 __maybe_unused __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. (void)({u16 __maybe_unused __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 nr)
  96. {
  97. unsigned int tmp;
  98. if (nr & 15) {
  99. tmp = (nr & 15) - 1;
  100. asm volatile (
  101. "1: moveb %0@+,%2@; dbra %1,1b"
  102. : "=a" (buf), "=d" (tmp)
  103. : "a" (port), "0" (buf),
  104. "1" (tmp));
  105. }
  106. if (nr >> 4) {
  107. tmp = (nr >> 4) - 1;
  108. asm volatile (
  109. "1: "
  110. "moveb %0@+,%2@; "
  111. "moveb %0@+,%2@; "
  112. "moveb %0@+,%2@; "
  113. "moveb %0@+,%2@; "
  114. "moveb %0@+,%2@; "
  115. "moveb %0@+,%2@; "
  116. "moveb %0@+,%2@; "
  117. "moveb %0@+,%2@; "
  118. "moveb %0@+,%2@; "
  119. "moveb %0@+,%2@; "
  120. "moveb %0@+,%2@; "
  121. "moveb %0@+,%2@; "
  122. "moveb %0@+,%2@; "
  123. "moveb %0@+,%2@; "
  124. "moveb %0@+,%2@; "
  125. "moveb %0@+,%2@; "
  126. "dbra %1,1b"
  127. : "=a" (buf), "=d" (tmp)
  128. : "a" (port), "0" (buf),
  129. "1" (tmp));
  130. }
  131. }
  132. static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)
  133. {
  134. unsigned int tmp;
  135. if (nr & 15) {
  136. tmp = (nr & 15) - 1;
  137. asm volatile (
  138. "1: movew %2@,%0@+; dbra %1,1b"
  139. : "=a" (buf), "=d" (tmp)
  140. : "a" (port), "0" (buf),
  141. "1" (tmp));
  142. }
  143. if (nr >> 4) {
  144. tmp = (nr >> 4) - 1;
  145. asm volatile (
  146. "1: "
  147. "movew %2@,%0@+; "
  148. "movew %2@,%0@+; "
  149. "movew %2@,%0@+; "
  150. "movew %2@,%0@+; "
  151. "movew %2@,%0@+; "
  152. "movew %2@,%0@+; "
  153. "movew %2@,%0@+; "
  154. "movew %2@,%0@+; "
  155. "movew %2@,%0@+; "
  156. "movew %2@,%0@+; "
  157. "movew %2@,%0@+; "
  158. "movew %2@,%0@+; "
  159. "movew %2@,%0@+; "
  160. "movew %2@,%0@+; "
  161. "movew %2@,%0@+; "
  162. "movew %2@,%0@+; "
  163. "dbra %1,1b"
  164. : "=a" (buf), "=d" (tmp)
  165. : "a" (port), "0" (buf),
  166. "1" (tmp));
  167. }
  168. }
  169. static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf,
  170. unsigned int nr)
  171. {
  172. unsigned int tmp;
  173. if (nr & 15) {
  174. tmp = (nr & 15) - 1;
  175. asm volatile (
  176. "1: movew %0@+,%2@; dbra %1,1b"
  177. : "=a" (buf), "=d" (tmp)
  178. : "a" (port), "0" (buf),
  179. "1" (tmp));
  180. }
  181. if (nr >> 4) {
  182. tmp = (nr >> 4) - 1;
  183. asm volatile (
  184. "1: "
  185. "movew %0@+,%2@; "
  186. "movew %0@+,%2@; "
  187. "movew %0@+,%2@; "
  188. "movew %0@+,%2@; "
  189. "movew %0@+,%2@; "
  190. "movew %0@+,%2@; "
  191. "movew %0@+,%2@; "
  192. "movew %0@+,%2@; "
  193. "movew %0@+,%2@; "
  194. "movew %0@+,%2@; "
  195. "movew %0@+,%2@; "
  196. "movew %0@+,%2@; "
  197. "movew %0@+,%2@; "
  198. "movew %0@+,%2@; "
  199. "movew %0@+,%2@; "
  200. "movew %0@+,%2@; "
  201. "dbra %1,1b"
  202. : "=a" (buf), "=d" (tmp)
  203. : "a" (port), "0" (buf),
  204. "1" (tmp));
  205. }
  206. }
  207. static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr)
  208. {
  209. unsigned int tmp;
  210. if (nr & 15) {
  211. tmp = (nr & 15) - 1;
  212. asm volatile (
  213. "1: movel %2@,%0@+; dbra %1,1b"
  214. : "=a" (buf), "=d" (tmp)
  215. : "a" (port), "0" (buf),
  216. "1" (tmp));
  217. }
  218. if (nr >> 4) {
  219. tmp = (nr >> 4) - 1;
  220. asm volatile (
  221. "1: "
  222. "movel %2@,%0@+; "
  223. "movel %2@,%0@+; "
  224. "movel %2@,%0@+; "
  225. "movel %2@,%0@+; "
  226. "movel %2@,%0@+; "
  227. "movel %2@,%0@+; "
  228. "movel %2@,%0@+; "
  229. "movel %2@,%0@+; "
  230. "movel %2@,%0@+; "
  231. "movel %2@,%0@+; "
  232. "movel %2@,%0@+; "
  233. "movel %2@,%0@+; "
  234. "movel %2@,%0@+; "
  235. "movel %2@,%0@+; "
  236. "movel %2@,%0@+; "
  237. "movel %2@,%0@+; "
  238. "dbra %1,1b"
  239. : "=a" (buf), "=d" (tmp)
  240. : "a" (port), "0" (buf),
  241. "1" (tmp));
  242. }
  243. }
  244. static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf,
  245. unsigned int nr)
  246. {
  247. unsigned int tmp;
  248. if (nr & 15) {
  249. tmp = (nr & 15) - 1;
  250. asm volatile (
  251. "1: movel %0@+,%2@; dbra %1,1b"
  252. : "=a" (buf), "=d" (tmp)
  253. : "a" (port), "0" (buf),
  254. "1" (tmp));
  255. }
  256. if (nr >> 4) {
  257. tmp = (nr >> 4) - 1;
  258. asm volatile (
  259. "1: "
  260. "movel %0@+,%2@; "
  261. "movel %0@+,%2@; "
  262. "movel %0@+,%2@; "
  263. "movel %0@+,%2@; "
  264. "movel %0@+,%2@; "
  265. "movel %0@+,%2@; "
  266. "movel %0@+,%2@; "
  267. "movel %0@+,%2@; "
  268. "movel %0@+,%2@; "
  269. "movel %0@+,%2@; "
  270. "movel %0@+,%2@; "
  271. "movel %0@+,%2@; "
  272. "movel %0@+,%2@; "
  273. "movel %0@+,%2@; "
  274. "movel %0@+,%2@; "
  275. "movel %0@+,%2@; "
  276. "dbra %1,1b"
  277. : "=a" (buf), "=d" (tmp)
  278. : "a" (port), "0" (buf),
  279. "1" (tmp));
  280. }
  281. }
  282. static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf,
  283. unsigned int nr)
  284. {
  285. if ((nr) % 8)
  286. __asm__ __volatile__
  287. ("\tmovel %0,%/a0\n\t"
  288. "movel %1,%/a1\n\t"
  289. "movel %2,%/d6\n\t"
  290. "subql #1,%/d6\n"
  291. "1:\tmovew %/a0@,%/d0\n\t"
  292. "rolw #8,%/d0\n\t"
  293. "movew %/d0,%/a1@+\n\t"
  294. "dbra %/d6,1b"
  295. :
  296. : "g" (port), "g" (buf), "g" (nr)
  297. : "d0", "a0", "a1", "d6");
  298. else
  299. __asm__ __volatile__
  300. ("movel %0,%/a0\n\t"
  301. "movel %1,%/a1\n\t"
  302. "movel %2,%/d6\n\t"
  303. "lsrl #3,%/d6\n\t"
  304. "subql #1,%/d6\n"
  305. "1:\tmovew %/a0@,%/d0\n\t"
  306. "rolw #8,%/d0\n\t"
  307. "movew %/d0,%/a1@+\n\t"
  308. "movew %/a0@,%/d0\n\t"
  309. "rolw #8,%/d0\n\t"
  310. "movew %/d0,%/a1@+\n\t"
  311. "movew %/a0@,%/d0\n\t"
  312. "rolw #8,%/d0\n\t"
  313. "movew %/d0,%/a1@+\n\t"
  314. "movew %/a0@,%/d0\n\t"
  315. "rolw #8,%/d0\n\t"
  316. "movew %/d0,%/a1@+\n\t"
  317. "movew %/a0@,%/d0\n\t"
  318. "rolw #8,%/d0\n\t"
  319. "movew %/d0,%/a1@+\n\t"
  320. "movew %/a0@,%/d0\n\t"
  321. "rolw #8,%/d0\n\t"
  322. "movew %/d0,%/a1@+\n\t"
  323. "movew %/a0@,%/d0\n\t"
  324. "rolw #8,%/d0\n\t"
  325. "movew %/d0,%/a1@+\n\t"
  326. "movew %/a0@,%/d0\n\t"
  327. "rolw #8,%/d0\n\t"
  328. "movew %/d0,%/a1@+\n\t"
  329. "dbra %/d6,1b"
  330. :
  331. : "g" (port), "g" (buf), "g" (nr)
  332. : "d0", "a0", "a1", "d6");
  333. }
  334. static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
  335. unsigned int nr)
  336. {
  337. if ((nr) % 8)
  338. __asm__ __volatile__
  339. ("movel %0,%/a0\n\t"
  340. "movel %1,%/a1\n\t"
  341. "movel %2,%/d6\n\t"
  342. "subql #1,%/d6\n"
  343. "1:\tmovew %/a1@+,%/d0\n\t"
  344. "rolw #8,%/d0\n\t"
  345. "movew %/d0,%/a0@\n\t"
  346. "dbra %/d6,1b"
  347. :
  348. : "g" (port), "g" (buf), "g" (nr)
  349. : "d0", "a0", "a1", "d6");
  350. else
  351. __asm__ __volatile__
  352. ("movel %0,%/a0\n\t"
  353. "movel %1,%/a1\n\t"
  354. "movel %2,%/d6\n\t"
  355. "lsrl #3,%/d6\n\t"
  356. "subql #1,%/d6\n"
  357. "1:\tmovew %/a1@+,%/d0\n\t"
  358. "rolw #8,%/d0\n\t"
  359. "movew %/d0,%/a0@\n\t"
  360. "movew %/a1@+,%/d0\n\t"
  361. "rolw #8,%/d0\n\t"
  362. "movew %/d0,%/a0@\n\t"
  363. "movew %/a1@+,%/d0\n\t"
  364. "rolw #8,%/d0\n\t"
  365. "movew %/d0,%/a0@\n\t"
  366. "movew %/a1@+,%/d0\n\t"
  367. "rolw #8,%/d0\n\t"
  368. "movew %/d0,%/a0@\n\t"
  369. "movew %/a1@+,%/d0\n\t"
  370. "rolw #8,%/d0\n\t"
  371. "movew %/d0,%/a0@\n\t"
  372. "movew %/a1@+,%/d0\n\t"
  373. "rolw #8,%/d0\n\t"
  374. "movew %/d0,%/a0@\n\t"
  375. "movew %/a1@+,%/d0\n\t"
  376. "rolw #8,%/d0\n\t"
  377. "movew %/d0,%/a0@\n\t"
  378. "movew %/a1@+,%/d0\n\t"
  379. "rolw #8,%/d0\n\t"
  380. "movew %/d0,%/a0@\n\t"
  381. "dbra %/d6,1b"
  382. :
  383. : "g" (port), "g" (buf), "g" (nr)
  384. : "d0", "a0", "a1", "d6");
  385. }
  386. #if defined(CONFIG_ATARI_ROM_ISA)
  387. static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
  388. {
  389. unsigned int i;
  390. for (i = 0; i < len; i++)
  391. *buf++ = rom_in_8(port);
  392. }
  393. static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf,
  394. unsigned int len)
  395. {
  396. unsigned int i;
  397. for (i = 0; i < len; i++)
  398. rom_out_8(port, *buf++);
  399. }
  400. static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf,
  401. unsigned int nr)
  402. {
  403. unsigned int i;
  404. for (i = 0; i < nr; i++)
  405. *buf++ = rom_in_be16(port);
  406. }
  407. static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf,
  408. unsigned int nr)
  409. {
  410. unsigned int i;
  411. for (i = 0; i < nr; i++)
  412. rom_out_be16(port, *buf++);
  413. }
  414. static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf,
  415. unsigned int nr)
  416. {
  417. unsigned int i;
  418. for (i = 0; i < nr; i++)
  419. *buf++ = rom_in_le16(port);
  420. }
  421. static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
  422. unsigned int nr)
  423. {
  424. unsigned int i;
  425. for (i = 0; i < nr; i++)
  426. rom_out_le16(port, *buf++);
  427. }
  428. #endif /* CONFIG_ATARI_ROM_ISA */
  429. #endif /* __KERNEL__ */
  430. #endif /* _RAW_IO_H */