root/include/asm-alpha/lca.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. virt_to_bus
  2. bus_to_virt
  3. __inb
  4. __outb
  5. __inw
  6. __outw
  7. __inl
  8. __outl
  9. __readb
  10. __readw
  11. __readl
  12. __writeb
  13. __writew
  14. __writel
  15. readl
  16. writel

   1 #ifndef __ALPHA_LCA__H
   2 #define __ALPHA_LCA__H
   3 
   4 /*
   5  * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
   6  * for example).
   7  *
   8  * This file is based on:
   9  *
  10  *      DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
  11  *      Hardware Reference Manual; Digital Equipment Corp.; May 1994;
  12  *      Maynard, MA; Order Number: EC-N2681-71.
  13  */
  14 
  15 /*
  16  * NOTE: The LCA uses a Host Address Extension (HAE) register to access
  17  *       PCI addresses that are beyond the first 27 bits of address
  18  *       space.  Updating the HAE requires an external cycle (and
  19  *       a memory barrier), which tends to be slow.  Instead of updating
  20  *       it on each sparse memory access, we keep the current HAE value
  21  *       cached in variable cache_hae.  Only if the cached HAE differs
  22  *       from the desired HAE value do we actually updated HAE register.
  23  *       The HAE register is preserved by the interrupt handler entry/exit
  24  *       code, so this scheme works even in the presence of interrupts.
  25  *
  26  * Dense memory space doesn't require the HAE, but is restricted to
  27  * aligned 32 and 64 bit accesses.  Special Cycle and Interrupt
  28  * Acknowledge cycles may also require the use of the HAE.  The LCA
  29  * limits I/O address space to the bottom 24 bits of address space,
  30  * but this easily covers the 16 bit ISA I/O address space.
  31  */
  32 
  33 /*
  34  * NOTE 2! The memory operations do not set any memory barriers, as
  35  * it's not needed for cases like a frame buffer that is essentially
  36  * memory-like.  You need to do them by hand if the operations depend
  37  * on ordering.
  38  *
  39  * Similarly, the port I/O operations do a "mb" only after a write
  40  * operation: if an mb is needed before (as in the case of doing
  41  * memory mapped I/O first, and then a port I/O operation to the same
  42  * device), it needs to be done by hand.
  43  *
  44  * After the above has bitten me 100 times, I'll give up and just do
  45  * the mb all the time, but right now I'm hoping this will work out.
  46  * Avoiding mb's may potentially be a noticeable speed improvement,
  47  * but I can't honestly say I've tested it.
  48  *
  49  * Handling interrupts that need to do mb's to synchronize to
  50  * non-interrupts is another fun race area.  Don't do it (because if
  51  * you do, I'll have to do *everything* with interrupts disabled,
  52  * ugh).
  53  */
  54 
  55 #define LCA_DMA_WIN_BASE        (1024*1024*1024)
  56 #define LCA_DMA_WIN_SIZE        (1024*1024*1024)
  57 
  58 /*
  59  * Memory Controller registers:
  60  */
  61 #define LCA_MEM_BCR0            (IDENT_ADDR + 0x120000000UL)
  62 #define LCA_MEM_BCR1            (IDENT_ADDR + 0x120000008UL)
  63 #define LCA_MEM_BCR2            (IDENT_ADDR + 0x120000010UL)
  64 #define LCA_MEM_BCR3            (IDENT_ADDR + 0x120000018UL)
  65 #define LCA_MEM_BMR0            (IDENT_ADDR + 0x120000020UL)
  66 #define LCA_MEM_BMR1            (IDENT_ADDR + 0x120000028UL)
  67 #define LCA_MEM_BMR2            (IDENT_ADDR + 0x120000030UL)
  68 #define LCA_MEM_BMR3            (IDENT_ADDR + 0x120000038UL)
  69 #define LCA_MEM_BTR0            (IDENT_ADDR + 0x120000040UL)
  70 #define LCA_MEM_BTR1            (IDENT_ADDR + 0x120000048UL)
  71 #define LCA_MEM_BTR2            (IDENT_ADDR + 0x120000050UL)
  72 #define LCA_MEM_BTR3            (IDENT_ADDR + 0x120000058UL)
  73 #define LCA_MEM_GTR             (IDENT_ADDR + 0x120000060UL)
  74 #define LCA_MEM_ESR             (IDENT_ADDR + 0x120000068UL)
  75 #define LCA_MEM_EAR             (IDENT_ADDR + 0x120000070UL)
  76 #define LCA_MEM_CAR             (IDENT_ADDR + 0x120000078UL)
  77 #define LCA_MEM_VGR             (IDENT_ADDR + 0x120000080UL)
  78 #define LCA_MEM_PLM             (IDENT_ADDR + 0x120000088UL)
  79 #define LCA_MEM_FOR             (IDENT_ADDR + 0x120000090UL)
  80 
  81 /*
  82  * I/O Controller registers:
  83  */
  84 #define LCA_IOC_HAE             (IDENT_ADDR + 0x180000000UL)
  85 #define LCA_IOC_CONF            (IDENT_ADDR + 0x180000020UL)
  86 #define LCA_IOC_STAT0           (IDENT_ADDR + 0x180000040UL)
  87 #define LCA_IOC_STAT1           (IDENT_ADDR + 0x180000060UL)
  88 #define LCA_IOC_TBIA            (IDENT_ADDR + 0x180000080UL)
  89 #define LCA_IOC_TB_ENA          (IDENT_ADDR + 0x1800000a0UL)
  90 #define LCA_IOC_SFT_RST         (IDENT_ADDR + 0x1800000c0UL)
  91 #define LCA_IOC_PAR_DIS         (IDENT_ADDR + 0x1800000e0UL)
  92 #define LCA_IOC_W_BASE0         (IDENT_ADDR + 0x180000100UL)
  93 #define LCA_IOC_W_BASE1         (IDENT_ADDR + 0x180000120UL)
  94 #define LCA_IOC_W_MASK0         (IDENT_ADDR + 0x180000140UL)
  95 #define LCA_IOC_W_MASK1         (IDENT_ADDR + 0x180000160UL)
  96 #define LCA_IOC_T_BASE0         (IDENT_ADDR + 0x180000180UL)
  97 #define LCA_IOC_T_BASE1         (IDENT_ADDR + 0x1800001a0UL)
  98 #define LCA_IOC_TB_TAG0         (IDENT_ADDR + 0x188000000UL)
  99 #define LCA_IOC_TB_TAG1         (IDENT_ADDR + 0x188000020UL)
 100 #define LCA_IOC_TB_TAG2         (IDENT_ADDR + 0x188000040UL)
 101 #define LCA_IOC_TB_TAG3         (IDENT_ADDR + 0x188000060UL)
 102 #define LCA_IOC_TB_TAG4         (IDENT_ADDR + 0x188000070UL)
 103 #define LCA_IOC_TB_TAG5         (IDENT_ADDR + 0x1880000a0UL)
 104 #define LCA_IOC_TB_TAG6         (IDENT_ADDR + 0x1880000c0UL)
 105 #define LCA_IOC_TB_TAG7         (IDENT_ADDR + 0x1880000e0UL)
 106 
 107 /*
 108  * Memory spaces:
 109  */
 110 #define LCA_IACK_SC             (IDENT_ADDR + 0x1a0000000UL)
 111 #define LCA_CONF                (IDENT_ADDR + 0x1e0000000UL)
 112 #define LCA_IO                  (IDENT_ADDR + 0x1c0000000UL)
 113 #define LCA_SPARSE_MEM          (IDENT_ADDR + 0x200000000UL)
 114 #define LCA_DENSE_MEM           (IDENT_ADDR + 0x300000000UL)
 115 
 116 /*
 117  * Bit definitions for I/O Controller status register 0:
 118  */
 119 #define LCA_IOC_STAT0_CMD               0xf
 120 #define LCA_IOC_STAT0_ERR               (1<<4)
 121 #define LCA_IOC_STAT0_LOST              (1<<5)
 122 #define LCA_IOC_STAT0_THIT              (1<<6)
 123 #define LCA_IOC_STAT0_TREF              (1<<7)
 124 #define LCA_IOC_STAT0_CODE_SHIFT        8
 125 #define LCA_IOC_STAT0_CODE_MASK         0x7
 126 #define LCA_IOC_STAT0_P_NBR_SHIFT       13
 127 #define LCA_IOC_STAT0_P_NBR_MASK        0x7ffff
 128 
 129 #define HAE_ADDRESS     LCA_IOC_HAE
 130 
 131 #ifdef __KERNEL__
 132 
 133 /*
 134  * Translate physical memory address as seen on (PCI) bus into
 135  * a kernel virtual address and vv.
 136  */
 137 extern inline unsigned long virt_to_bus(void * address)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139         return virt_to_phys(address) + LCA_DMA_WIN_BASE;
 140 }
 141 
 142 extern inline void * bus_to_virt(unsigned long address)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144         return phys_to_virt(address - LCA_DMA_WIN_BASE);
 145 }
 146 
 147 /*
 148  * I/O functions:
 149  *
 150  * Unlike Jensen, the Noname machines have no concept of local
 151  * I/O---everything goes over the PCI bus.
 152  *
 153  * There is plenty room for optimization here.  In particular,
 154  * the Alpha's insb/insw/extb/extw should be useful in moving
 155  * data to/from the right byte-lanes.
 156  */
 157 
 158 #define vuip    volatile unsigned int *
 159 
 160 extern inline unsigned int __inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         long result = *(vuip) ((addr << 5) + LCA_IO + 0x00);
 163         result >>= (addr & 3) * 8;
 164         return 0xffUL & result;
 165 }
 166 
 167 extern inline void __outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169         unsigned int w;
 170 
 171         asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 172         *(vuip) ((addr << 5) + LCA_IO + 0x00) = w;
 173         mb();
 174 }
 175 
 176 extern inline unsigned int __inw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         long result = *(vuip) ((addr << 5) + LCA_IO + 0x08);
 179         result >>= (addr & 3) * 8;
 180         return 0xffffUL & result;
 181 }
 182 
 183 extern inline void __outw(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 184 {
 185         unsigned int w;
 186 
 187         asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 188         *(vuip) ((addr << 5) + LCA_IO + 0x08) = w;
 189         mb();
 190 }
 191 
 192 extern inline unsigned int __inl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194         return *(vuip) ((addr << 5) + LCA_IO + 0x18);
 195 }
 196 
 197 extern inline void __outl(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         *(vuip) ((addr << 5) + LCA_IO + 0x18) = b;
 200         mb();
 201 }
 202 
 203 
 204 /*
 205  * Memory functions.  64-bit and 32-bit accesses are done through
 206  * dense memory space, everything else through sparse space.
 207  */
 208 extern inline unsigned long __readb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210         unsigned long result, shift, msb;
 211 
 212         shift = (addr & 0x3) * 8;
 213         if (addr >= (1UL << 24)) {
 214                 msb = addr & 0xf8000000;
 215                 addr -= msb;
 216                 if (msb != hae.cache) {
 217                         set_hae(msb);
 218                 }
 219         }
 220         result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00);
 221         result >>= shift;
 222         return 0xffUL & result;
 223 }
 224 
 225 extern inline unsigned long __readw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227         unsigned long result, shift, msb;
 228 
 229         shift = (addr & 0x3) * 8;
 230         if (addr >= (1UL << 24)) {
 231                 msb = addr & 0xf8000000;
 232                 addr -= msb;
 233                 if (msb != hae.cache) {
 234                         set_hae(msb);
 235                 }
 236         }
 237         result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08);
 238         result >>= shift;
 239         return 0xffffUL & result;
 240 }
 241 
 242 extern inline unsigned long __readl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 243 {
 244         return *(vuip) (addr + LCA_DENSE_MEM);
 245 }
 246 
 247 extern inline void __writeb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249         unsigned long msb;
 250 
 251         if (addr >= (1UL << 24)) {
 252                 msb = addr & 0xf8000000;
 253                 addr -= msb;
 254                 if (msb != hae.cache) {
 255                         set_hae(msb);
 256                 }
 257         }
 258         *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = b * 0x01010101;
 259 }
 260 
 261 extern inline void __writew(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 262 {
 263         unsigned long msb;
 264 
 265         if (addr >= (1UL << 24)) {
 266                 msb = addr & 0xf8000000;
 267                 addr -= msb;
 268                 if (msb != hae.cache) {
 269                         set_hae(msb);
 270                 }
 271         }
 272         *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = b * 0x00010001;
 273 }
 274 
 275 extern inline void __writel(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277         *(vuip) (addr + LCA_DENSE_MEM) = b;
 278 }
 279 
 280 /*
 281  * Most of the above have so much overhead that it probably doesn't
 282  * make sense to have them inlined (better icache behavior).
 283  */
 284 extern unsigned int inb(unsigned long addr);
 285 extern unsigned int inw(unsigned long addr);
 286 extern unsigned int inl(unsigned long addr);
 287 
 288 extern void outb(unsigned char b, unsigned long addr);
 289 extern void outw(unsigned short b, unsigned long addr);
 290 extern void outl(unsigned int b, unsigned long addr);
 291 
 292 extern unsigned long readb(unsigned long addr);
 293 extern unsigned long readw(unsigned long addr);
 294 
 295 extern void writeb(unsigned char b, unsigned long addr);
 296 extern void writew(unsigned short b, unsigned long addr);
 297 
 298 #define inb(port) \
 299 (__builtin_constant_p((port))?__inb(port):(inb)(port))
 300 
 301 #define outb(x, port) \
 302 (__builtin_constant_p((port))?__outb((x),(port)):(outb)((x),(port)))
 303 
 304 #define inb_p inb
 305 #define outb_p outb
 306 
 307 extern inline unsigned long readl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 308 {
 309         return __readl(addr);
 310 }
 311 
 312 extern inline void writel(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 313 {
 314         __writel(b, addr);
 315 }
 316 
 317 #undef vuip
 318 
 319 extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end);
 320 
 321 #endif /* __KERNEL__ */
 322 
 323 #define RTC_PORT(x) (0x70 + (x))
 324 #define RTC_ADDR(x) (0x80 | (x))
 325 #define RTC_ALWAYS_BCD 0
 326 
 327 #endif /* __ALPHA_LCA__H */

/* [previous][next][first][last][top][bottom][index][help] */