home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-alpha / jensen.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  8.3 KB  |  347 lines

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