jensen.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ALPHA_JENSEN_H
  3. #define __ALPHA_JENSEN_H
  4. #include <asm/compiler.h>
  5. /*
  6. * Defines for the AlphaPC EISA IO and memory address space.
  7. */
  8. /*
  9. * NOTE! The memory operations do not set any memory barriers, as it's
  10. * not needed for cases like a frame buffer that is essentially memory-like.
  11. * You need to do them by hand if the operations depend on ordering.
  12. *
  13. * Similarly, the port IO operations do a "mb" only after a write operation:
  14. * if an mb is needed before (as in the case of doing memory mapped IO
  15. * first, and then a port IO operation to the same device), it needs to be
  16. * done by hand.
  17. *
  18. * After the above has bitten me 100 times, I'll give up and just do the
  19. * mb all the time, but right now I'm hoping this will work out. Avoiding
  20. * mb's may potentially be a noticeable speed improvement, but I can't
  21. * honestly say I've tested it.
  22. *
  23. * Handling interrupts that need to do mb's to synchronize to non-interrupts
  24. * is another fun race area. Don't do it (because if you do, I'll have to
  25. * do *everything* with interrupts disabled, ugh).
  26. */
  27. /*
  28. * EISA Interrupt Acknowledge address
  29. */
  30. #define EISA_INTA (IDENT_ADDR + 0x100000000UL)
  31. /*
  32. * FEPROM addresses
  33. */
  34. #define EISA_FEPROM0 (IDENT_ADDR + 0x180000000UL)
  35. #define EISA_FEPROM1 (IDENT_ADDR + 0x1A0000000UL)
  36. /*
  37. * VL82C106 base address
  38. */
  39. #define EISA_VL82C106 (IDENT_ADDR + 0x1C0000000UL)
  40. /*
  41. * EISA "Host Address Extension" address (bits 25-31 of the EISA address)
  42. */
  43. #define EISA_HAE (IDENT_ADDR + 0x1D0000000UL)
  44. /*
  45. * "SYSCTL" register address
  46. */
  47. #define EISA_SYSCTL (IDENT_ADDR + 0x1E0000000UL)
  48. /*
  49. * "spare" register address
  50. */
  51. #define EISA_SPARE (IDENT_ADDR + 0x1F0000000UL)
  52. /*
  53. * EISA memory address offset
  54. */
  55. #define EISA_MEM (IDENT_ADDR + 0x200000000UL)
  56. /*
  57. * EISA IO address offset
  58. */
  59. #define EISA_IO (IDENT_ADDR + 0x300000000UL)
  60. #ifdef __KERNEL__
  61. #ifndef __EXTERN_INLINE
  62. #define __EXTERN_INLINE extern inline
  63. #define __IO_EXTERN_INLINE
  64. #endif
  65. /*
  66. * Handle the "host address register". This needs to be set
  67. * to the high 7 bits of the EISA address. This is also needed
  68. * for EISA IO addresses, which are only 16 bits wide (the
  69. * hae needs to be set to 0).
  70. *
  71. * HAE isn't needed for the local IO operations, though.
  72. */
  73. #define JENSEN_HAE_ADDRESS EISA_HAE
  74. #define JENSEN_HAE_MASK 0x1ffffff
  75. __EXTERN_INLINE void jensen_set_hae(unsigned long addr)
  76. {
  77. /* hae on the Jensen is bits 31:25 shifted right */
  78. addr >>= 25;
  79. if (addr != alpha_mv.hae_cache)
  80. set_hae(addr);
  81. }
  82. #define vuip volatile unsigned int *
  83. /*
  84. * IO functions
  85. *
  86. * The "local" functions are those that don't go out to the EISA bus,
  87. * but instead act on the VL82C106 chip directly.. This is mainly the
  88. * keyboard, RTC, printer and first two serial lines..
  89. *
  90. * The local stuff makes for some complications, but it seems to be
  91. * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
  92. * convinced that I need one of the newer machines.
  93. */
  94. static inline unsigned int jensen_local_inb(unsigned long addr)
  95. {
  96. return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
  97. }
  98. static inline void jensen_local_outb(u8 b, unsigned long addr)
  99. {
  100. *(vuip)((addr << 9) + EISA_VL82C106) = b;
  101. mb();
  102. }
  103. static inline unsigned int jensen_bus_inb(unsigned long addr)
  104. {
  105. long result;
  106. jensen_set_hae(0);
  107. result = *(volatile int *)((addr << 7) + EISA_IO + 0x00);
  108. return __kernel_extbl(result, addr & 3);
  109. }
  110. static inline void jensen_bus_outb(u8 b, unsigned long addr)
  111. {
  112. jensen_set_hae(0);
  113. *(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
  114. mb();
  115. }
  116. /*
  117. * It seems gcc is not very good at optimizing away logical
  118. * operations that result in operations across inline functions.
  119. * Which is why this is a macro.
  120. */
  121. #define jensen_is_local(addr) ( \
  122. /* keyboard */ (addr == 0x60 || addr == 0x64) || \
  123. /* RTC */ (addr == 0x170 || addr == 0x171) || \
  124. /* mb COM2 */ (addr >= 0x2f8 && addr <= 0x2ff) || \
  125. /* mb LPT1 */ (addr >= 0x3bc && addr <= 0x3be) || \
  126. /* mb COM2 */ (addr >= 0x3f8 && addr <= 0x3ff))
  127. __EXTERN_INLINE u8 jensen_inb(unsigned long addr)
  128. {
  129. if (jensen_is_local(addr))
  130. return jensen_local_inb(addr);
  131. else
  132. return jensen_bus_inb(addr);
  133. }
  134. __EXTERN_INLINE void jensen_outb(u8 b, unsigned long addr)
  135. {
  136. if (jensen_is_local(addr))
  137. jensen_local_outb(b, addr);
  138. else
  139. jensen_bus_outb(b, addr);
  140. }
  141. __EXTERN_INLINE u16 jensen_inw(unsigned long addr)
  142. {
  143. long result;
  144. jensen_set_hae(0);
  145. result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
  146. result >>= (addr & 3) * 8;
  147. return 0xffffUL & result;
  148. }
  149. __EXTERN_INLINE u32 jensen_inl(unsigned long addr)
  150. {
  151. jensen_set_hae(0);
  152. return *(vuip) ((addr << 7) + EISA_IO + 0x60);
  153. }
  154. __EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
  155. {
  156. jensen_set_hae(0);
  157. *(vuip) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
  158. mb();
  159. }
  160. __EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
  161. {
  162. jensen_set_hae(0);
  163. *(vuip) ((addr << 7) + EISA_IO + 0x60) = b;
  164. mb();
  165. }
  166. /*
  167. * Memory functions.
  168. */
  169. __EXTERN_INLINE u8 jensen_readb(const volatile void __iomem *xaddr)
  170. {
  171. unsigned long addr = (unsigned long) xaddr;
  172. long result;
  173. jensen_set_hae(addr);
  174. addr &= JENSEN_HAE_MASK;
  175. result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
  176. result >>= (addr & 3) * 8;
  177. return 0xffUL & result;
  178. }
  179. __EXTERN_INLINE u16 jensen_readw(const volatile void __iomem *xaddr)
  180. {
  181. unsigned long addr = (unsigned long) xaddr;
  182. long result;
  183. jensen_set_hae(addr);
  184. addr &= JENSEN_HAE_MASK;
  185. result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
  186. result >>= (addr & 3) * 8;
  187. return 0xffffUL & result;
  188. }
  189. __EXTERN_INLINE u32 jensen_readl(const volatile void __iomem *xaddr)
  190. {
  191. unsigned long addr = (unsigned long) xaddr;
  192. jensen_set_hae(addr);
  193. addr &= JENSEN_HAE_MASK;
  194. return *(vuip) ((addr << 7) + EISA_MEM + 0x60);
  195. }
  196. __EXTERN_INLINE u64 jensen_readq(const volatile void __iomem *xaddr)
  197. {
  198. unsigned long addr = (unsigned long) xaddr;
  199. unsigned long r0, r1;
  200. jensen_set_hae(addr);
  201. addr &= JENSEN_HAE_MASK;
  202. addr = (addr << 7) + EISA_MEM + 0x60;
  203. r0 = *(vuip) (addr);
  204. r1 = *(vuip) (addr + (4 << 7));
  205. return r1 << 32 | r0;
  206. }
  207. __EXTERN_INLINE void jensen_writeb(u8 b, volatile void __iomem *xaddr)
  208. {
  209. unsigned long addr = (unsigned long) xaddr;
  210. jensen_set_hae(addr);
  211. addr &= JENSEN_HAE_MASK;
  212. *(vuip) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
  213. }
  214. __EXTERN_INLINE void jensen_writew(u16 b, volatile void __iomem *xaddr)
  215. {
  216. unsigned long addr = (unsigned long) xaddr;
  217. jensen_set_hae(addr);
  218. addr &= JENSEN_HAE_MASK;
  219. *(vuip) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
  220. }
  221. __EXTERN_INLINE void jensen_writel(u32 b, volatile void __iomem *xaddr)
  222. {
  223. unsigned long addr = (unsigned long) xaddr;
  224. jensen_set_hae(addr);
  225. addr &= JENSEN_HAE_MASK;
  226. *(vuip) ((addr << 7) + EISA_MEM + 0x60) = b;
  227. }
  228. __EXTERN_INLINE void jensen_writeq(u64 b, volatile void __iomem *xaddr)
  229. {
  230. unsigned long addr = (unsigned long) xaddr;
  231. jensen_set_hae(addr);
  232. addr &= JENSEN_HAE_MASK;
  233. addr = (addr << 7) + EISA_MEM + 0x60;
  234. *(vuip) (addr) = b;
  235. *(vuip) (addr + (4 << 7)) = b >> 32;
  236. }
  237. __EXTERN_INLINE void __iomem *jensen_ioportmap(unsigned long addr)
  238. {
  239. return (void __iomem *)addr;
  240. }
  241. __EXTERN_INLINE void __iomem *jensen_ioremap(unsigned long addr,
  242. unsigned long size)
  243. {
  244. return (void __iomem *)(addr + 0x100000000ul);
  245. }
  246. __EXTERN_INLINE int jensen_is_ioaddr(unsigned long addr)
  247. {
  248. return (long)addr >= 0;
  249. }
  250. __EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
  251. {
  252. return (unsigned long)addr >= 0x100000000ul;
  253. }
  254. /* New-style ioread interface. All the routines are so ugly for Jensen
  255. that it doesn't make sense to merge them. */
  256. #define IOPORT(OS, NS) \
  257. __EXTERN_INLINE unsigned int jensen_ioread##NS(void __iomem *xaddr) \
  258. { \
  259. if (jensen_is_mmio(xaddr)) \
  260. return jensen_read##OS(xaddr - 0x100000000ul); \
  261. else \
  262. return jensen_in##OS((unsigned long)xaddr); \
  263. } \
  264. __EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr) \
  265. { \
  266. if (jensen_is_mmio(xaddr)) \
  267. jensen_write##OS(b, xaddr - 0x100000000ul); \
  268. else \
  269. jensen_out##OS(b, (unsigned long)xaddr); \
  270. }
  271. IOPORT(b, 8)
  272. IOPORT(w, 16)
  273. IOPORT(l, 32)
  274. #undef IOPORT
  275. #undef vuip
  276. #undef __IO_PREFIX
  277. #define __IO_PREFIX jensen
  278. #define jensen_trivial_rw_bw 0
  279. #define jensen_trivial_rw_lq 0
  280. #define jensen_trivial_io_bw 0
  281. #define jensen_trivial_io_lq 0
  282. #define jensen_trivial_iounmap 1
  283. #include <asm/io_trivial.h>
  284. #ifdef __IO_EXTERN_INLINE
  285. #undef __EXTERN_INLINE
  286. #undef __IO_EXTERN_INLINE
  287. #endif
  288. #endif /* __KERNEL__ */
  289. #endif /* __ALPHA_JENSEN_H */