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

   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  * Translate physical memory address as seen on (PCI) bus into
  60  * a kernel virtual address and vv.
  61  */
  62 extern inline unsigned long virt_to_bus(void * address)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64         return virt_to_phys(address) + LCA_DMA_WIN_BASE;
  65 }
  66 
  67 extern inline void * bus_to_virt(unsigned long address)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         return phys_to_virt(address - LCA_DMA_WIN_BASE);
  70 }
  71 
  72 /*
  73  * Memory Controller registers:
  74  */
  75 #define LCA_MEM_BCR0            (IDENT_ADDR + 0x120000000UL)
  76 #define LCA_MEM_BCR1            (IDENT_ADDR + 0x120000008UL)
  77 #define LCA_MEM_BCR2            (IDENT_ADDR + 0x120000010UL)
  78 #define LCA_MEM_BCR3            (IDENT_ADDR + 0x120000018UL)
  79 #define LCA_MEM_BMR0            (IDENT_ADDR + 0x120000020UL)
  80 #define LCA_MEM_BMR1            (IDENT_ADDR + 0x120000028UL)
  81 #define LCA_MEM_BMR2            (IDENT_ADDR + 0x120000030UL)
  82 #define LCA_MEM_BMR3            (IDENT_ADDR + 0x120000038UL)
  83 #define LCA_MEM_BTR0            (IDENT_ADDR + 0x120000040UL)
  84 #define LCA_MEM_BTR1            (IDENT_ADDR + 0x120000048UL)
  85 #define LCA_MEM_BTR2            (IDENT_ADDR + 0x120000050UL)
  86 #define LCA_MEM_BTR3            (IDENT_ADDR + 0x120000058UL)
  87 #define LCA_MEM_GTR             (IDENT_ADDR + 0x120000060UL)
  88 #define LCA_MEM_ESR             (IDENT_ADDR + 0x120000068UL)
  89 #define LCA_MEM_EAR             (IDENT_ADDR + 0x120000070UL)
  90 #define LCA_MEM_CAR             (IDENT_ADDR + 0x120000078UL)
  91 #define LCA_MEM_VGR             (IDENT_ADDR + 0x120000080UL)
  92 #define LCA_MEM_PLM             (IDENT_ADDR + 0x120000088UL)
  93 #define LCA_MEM_FOR             (IDENT_ADDR + 0x120000090UL)
  94 
  95 /*
  96  * I/O Controller registers:
  97  */
  98 #define LCA_IOC_HAE             (IDENT_ADDR + 0x180000000UL)
  99 #define LCA_IOC_CONF            (IDENT_ADDR + 0x180000020UL)
 100 #define LCA_IOC_STAT0           (IDENT_ADDR + 0x180000040UL)
 101 #define LCA_IOC_STAT1           (IDENT_ADDR + 0x180000060UL)
 102 #define LCA_IOC_TBIA            (IDENT_ADDR + 0x180000080UL)
 103 #define LCA_IOC_TB_ENA          (IDENT_ADDR + 0x1800000a0UL)
 104 #define LCA_IOC_SFT_RST         (IDENT_ADDR + 0x1800000c0UL)
 105 #define LCA_IOC_PAR_DIS         (IDENT_ADDR + 0x1800000e0UL)
 106 #define LCA_IOC_W_BASE0         (IDENT_ADDR + 0x180000100UL)
 107 #define LCA_IOC_W_BASE1         (IDENT_ADDR + 0x180000120UL)
 108 #define LCA_IOC_W_MASK0         (IDENT_ADDR + 0x180000140UL)
 109 #define LCA_IOC_W_MASK1         (IDENT_ADDR + 0x180000160UL)
 110 #define LCA_IOC_T_BASE0         (IDENT_ADDR + 0x180000180UL)
 111 #define LCA_IOC_T_BASE1         (IDENT_ADDR + 0x1800001a0UL)
 112 #define LCA_IOC_TB_TAG0         (IDENT_ADDR + 0x188000000UL)
 113 #define LCA_IOC_TB_TAG1         (IDENT_ADDR + 0x188000020UL)
 114 #define LCA_IOC_TB_TAG2         (IDENT_ADDR + 0x188000040UL)
 115 #define LCA_IOC_TB_TAG3         (IDENT_ADDR + 0x188000060UL)
 116 #define LCA_IOC_TB_TAG4         (IDENT_ADDR + 0x188000070UL)
 117 #define LCA_IOC_TB_TAG5         (IDENT_ADDR + 0x1880000a0UL)
 118 #define LCA_IOC_TB_TAG6         (IDENT_ADDR + 0x1880000c0UL)
 119 #define LCA_IOC_TB_TAG7         (IDENT_ADDR + 0x1880000e0UL)
 120 
 121 /*
 122  * Memory spaces:
 123  */
 124 #define LCA_IACK_SC             (IDENT_ADDR + 0x1a0000000UL)
 125 #define LCA_CONF                (IDENT_ADDR + 0x1e0000000UL)
 126 #define LCA_IO                  (IDENT_ADDR + 0x1c0000000UL)
 127 #define LCA_SPARSE_MEM          (IDENT_ADDR + 0x200000000UL)
 128 #define LCA_DENSE_MEM           (IDENT_ADDR + 0x300000000UL)
 129 
 130 /*
 131  * Bit definitions for I/O Controller status register 0:
 132  */
 133 #define LCA_IOC_STAT0_CMD               0xf
 134 #define LCA_IOC_STAT0_ERR               (1<<4)
 135 #define LCA_IOC_STAT0_LOST              (1<<5)
 136 #define LCA_IOC_STAT0_THIT              (1<<6)
 137 #define LCA_IOC_STAT0_TREF              (1<<7)
 138 #define LCA_IOC_STAT0_CODE_SHIFT        8
 139 #define LCA_IOC_STAT0_CODE_MASK         0x7
 140 #define LCA_IOC_STAT0_P_NBR_SHIFT       13
 141 #define LCA_IOC_STAT0_P_NBR_MASK        0x7ffff
 142 
 143 #define HAE_ADDRESS     LCA_IOC_HAE
 144 
 145 /*
 146  * I/O functions:
 147  *
 148  * Unlike Jensen, the Noname machines have no concept of local
 149  * I/O---everything goes over the PCI bus.
 150  *
 151  * There is plenty room for optimization here.  In particular,
 152  * the Alpha's insb/insw/extb/extw should be useful in moving
 153  * data to/from the right byte-lanes.
 154  */
 155 
 156 #define vuip    volatile unsigned int *
 157 
 158 extern inline unsigned int __inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         long result = *(vuip) ((addr << 5) + LCA_IO + 0x00);
 161         result >>= (addr & 3) * 8;
 162         return 0xffUL & result;
 163 }
 164 
 165 extern inline void __outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167         unsigned int w;
 168 
 169         asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 170         *(vuip) ((addr << 5) + LCA_IO + 0x00) = w;
 171         mb();
 172 }
 173 
 174 extern inline unsigned int __inw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176         long result = *(vuip) ((addr << 5) + LCA_IO + 0x08);
 177         result >>= (addr & 3) * 8;
 178         return 0xffffUL & result;
 179 }
 180 
 181 extern inline void __outw(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183         unsigned int w;
 184 
 185         asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 186         *(vuip) ((addr << 5) + LCA_IO + 0x08) = w;
 187         mb();
 188 }
 189 
 190 extern inline unsigned int __inl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192         return *(vuip) ((addr << 5) + LCA_IO + 0x18);
 193 }
 194 
 195 extern inline void __outl(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 196 {
 197         *(vuip) ((addr << 5) + LCA_IO + 0x18) = b;
 198         mb();
 199 }
 200 
 201 
 202 /*
 203  * Memory functions.  64-bit and 32-bit accesses are done through
 204  * dense memory space, everything else through sparse space.
 205  */
 206 extern inline unsigned long __readb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208         unsigned long result, shift, msb;
 209 
 210         shift = (addr & 0x3) * 8;
 211         if (addr >= (1UL << 24)) {
 212                 msb = addr & 0xf8000000;
 213                 addr -= msb;
 214                 if (msb != hae.cache) {
 215                         set_hae(msb);
 216                 }
 217         }
 218         result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00);
 219         result >>= shift;
 220         return 0xffUL & result;
 221 }
 222 
 223 extern inline unsigned long __readw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 224 {
 225         unsigned long result, shift, msb;
 226 
 227         shift = (addr & 0x3) * 8;
 228         if (addr >= (1UL << 24)) {
 229                 msb = addr & 0xf8000000;
 230                 addr -= msb;
 231                 if (msb != hae.cache) {
 232                         set_hae(msb);
 233                 }
 234         }
 235         result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08);
 236         result >>= shift;
 237         return 0xffffUL & result;
 238 }
 239 
 240 extern inline unsigned long __readl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 241 {
 242         return *(vuip) (addr + LCA_DENSE_MEM);
 243 }
 244 
 245 extern inline void __writeb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247         unsigned long msb;
 248 
 249         if (addr >= (1UL << 24)) {
 250                 msb = addr & 0xf8000000;
 251                 addr -= msb;
 252                 if (msb != hae.cache) {
 253                         set_hae(msb);
 254                 }
 255         }
 256         *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = b * 0x01010101;
 257 }
 258 
 259 extern inline void __writew(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 260 {
 261         unsigned long msb;
 262 
 263         if (addr >= (1UL << 24)) {
 264                 msb = addr & 0xf8000000;
 265                 addr -= msb;
 266                 if (msb != hae.cache) {
 267                         set_hae(msb);
 268                 }
 269         }
 270         *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = b * 0x00010001;
 271 }
 272 
 273 extern inline void __writel(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 274 {
 275         *(vuip) (addr + LCA_DENSE_MEM) = b;
 276 }
 277 
 278 /*
 279  * Most of the above have so much overhead that it probably doesn't
 280  * make sense to have them inlined (better icache behavior).
 281  */
 282 extern unsigned int inb(unsigned long addr);
 283 extern unsigned int inw(unsigned long addr);
 284 extern unsigned int inl(unsigned long addr);
 285 
 286 extern void outb(unsigned char b, unsigned long addr);
 287 extern void outw(unsigned short b, unsigned long addr);
 288 extern void outl(unsigned int b, unsigned long addr);
 289 
 290 extern unsigned long readb(unsigned long addr);
 291 extern unsigned long readw(unsigned long addr);
 292 
 293 extern void writeb(unsigned short b, unsigned long addr);
 294 extern void writew(unsigned short b, unsigned long addr);
 295 
 296 #define inb(port) \
 297 (__builtin_constant_p((port))?__inb(port):(inb)(port))
 298 
 299 #define outb(x, port) \
 300 (__builtin_constant_p((port))?__outb((x),(port)):(outb)((x),(port)))
 301 
 302 #define inb_p inb
 303 #define outb_p outb
 304 
 305 #define readl(addr)     __readl(addr)
 306 #define writel(b,addr)  __writel(b,addr)
 307 
 308 #undef vuip
 309 
 310 extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end);
 311 
 312 #endif

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