linux/arch/alpha/include/asm/jensen.h
<<
>>
Prefs
   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
 113static inline unsigned int jensen_local_inb(unsigned long addr)
 114{
 115        return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
 116}
 117
 118static inline void jensen_local_outb(u8 b, unsigned long addr)
 119{
 120        *(vuip)((addr << 9) + EISA_VL82C106) = b;
 121        mb();
 122}
 123
 124static 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
 133static 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
 322IOPORT(b, 8)
 323IOPORT(w, 16)
 324IOPORT(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