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 #include <asm/system.h>
  56 
  57 #define LCA_DMA_WIN_BASE        (1024*1024*1024)
  58 #define LCA_DMA_WIN_SIZE        (1024*1024*1024)
  59 
  60 /*
  61  * Memory Controller registers:
  62  */
  63 #define LCA_MEM_BCR0            (IDENT_ADDR + 0x120000000UL)
  64 #define LCA_MEM_BCR1            (IDENT_ADDR + 0x120000008UL)
  65 #define LCA_MEM_BCR2            (IDENT_ADDR + 0x120000010UL)
  66 #define LCA_MEM_BCR3            (IDENT_ADDR + 0x120000018UL)
  67 #define LCA_MEM_BMR0            (IDENT_ADDR + 0x120000020UL)
  68 #define LCA_MEM_BMR1            (IDENT_ADDR + 0x120000028UL)
  69 #define LCA_MEM_BMR2            (IDENT_ADDR + 0x120000030UL)
  70 #define LCA_MEM_BMR3            (IDENT_ADDR + 0x120000038UL)
  71 #define LCA_MEM_BTR0            (IDENT_ADDR + 0x120000040UL)
  72 #define LCA_MEM_BTR1            (IDENT_ADDR + 0x120000048UL)
  73 #define LCA_MEM_BTR2            (IDENT_ADDR + 0x120000050UL)
  74 #define LCA_MEM_BTR3            (IDENT_ADDR + 0x120000058UL)
  75 #define LCA_MEM_GTR             (IDENT_ADDR + 0x120000060UL)
  76 #define LCA_MEM_ESR             (IDENT_ADDR + 0x120000068UL)
  77 #define LCA_MEM_EAR             (IDENT_ADDR + 0x120000070UL)
  78 #define LCA_MEM_CAR             (IDENT_ADDR + 0x120000078UL)
  79 #define LCA_MEM_VGR             (IDENT_ADDR + 0x120000080UL)
  80 #define LCA_MEM_PLM             (IDENT_ADDR + 0x120000088UL)
  81 #define LCA_MEM_FOR             (IDENT_ADDR + 0x120000090UL)
  82 
  83 /*
  84  * I/O Controller registers:
  85  */
  86 #define LCA_IOC_HAE             (IDENT_ADDR + 0x180000000UL)
  87 #define LCA_IOC_CONF            (IDENT_ADDR + 0x180000020UL)
  88 #define LCA_IOC_STAT0           (IDENT_ADDR + 0x180000040UL)
  89 #define LCA_IOC_STAT1           (IDENT_ADDR + 0x180000060UL)
  90 #define LCA_IOC_TBIA            (IDENT_ADDR + 0x180000080UL)
  91 #define LCA_IOC_TB_ENA          (IDENT_ADDR + 0x1800000a0UL)
  92 #define LCA_IOC_SFT_RST         (IDENT_ADDR + 0x1800000c0UL)
  93 #define LCA_IOC_PAR_DIS         (IDENT_ADDR + 0x1800000e0UL)
  94 #define LCA_IOC_W_BASE0         (IDENT_ADDR + 0x180000100UL)
  95 #define LCA_IOC_W_BASE1         (IDENT_ADDR + 0x180000120UL)
  96 #define LCA_IOC_W_MASK0         (IDENT_ADDR + 0x180000140UL)
  97 #define LCA_IOC_W_MASK1         (IDENT_ADDR + 0x180000160UL)
  98 #define LCA_IOC_T_BASE0         (IDENT_ADDR + 0x180000180UL)
  99 #define LCA_IOC_T_BASE1         (IDENT_ADDR + 0x1800001a0UL)
 100 #define LCA_IOC_TB_TAG0         (IDENT_ADDR + 0x188000000UL)
 101 #define LCA_IOC_TB_TAG1         (IDENT_ADDR + 0x188000020UL)
 102 #define LCA_IOC_TB_TAG2         (IDENT_ADDR + 0x188000040UL)
 103 #define LCA_IOC_TB_TAG3         (IDENT_ADDR + 0x188000060UL)
 104 #define LCA_IOC_TB_TAG4         (IDENT_ADDR + 0x188000070UL)
 105 #define LCA_IOC_TB_TAG5         (IDENT_ADDR + 0x1880000a0UL)
 106 #define LCA_IOC_TB_TAG6         (IDENT_ADDR + 0x1880000c0UL)
 107 #define LCA_IOC_TB_TAG7         (IDENT_ADDR + 0x1880000e0UL)
 108 
 109 /*
 110  * Memory spaces:
 111  */
 112 #define LCA_IACK_SC             (IDENT_ADDR + 0x1a0000000UL)
 113 #define LCA_CONF                (IDENT_ADDR + 0x1e0000000UL)
 114 #define LCA_IO                  (IDENT_ADDR + 0x1c0000000UL)
 115 #define LCA_SPARSE_MEM          (IDENT_ADDR + 0x200000000UL)
 116 #define LCA_DENSE_MEM           (IDENT_ADDR + 0x300000000UL)
 117 
 118 /*
 119  * Bit definitions for I/O Controller status register 0:
 120  */
 121 #define LCA_IOC_STAT0_CMD               0xf
 122 #define LCA_IOC_STAT0_ERR               (1<<4)
 123 #define LCA_IOC_STAT0_LOST              (1<<5)
 124 #define LCA_IOC_STAT0_THIT              (1<<6)
 125 #define LCA_IOC_STAT0_TREF              (1<<7)
 126 #define LCA_IOC_STAT0_CODE_SHIFT        8
 127 #define LCA_IOC_STAT0_CODE_MASK         0x7
 128 #define LCA_IOC_STAT0_P_NBR_SHIFT       13
 129 #define LCA_IOC_STAT0_P_NBR_MASK        0x7ffff
 130 
 131 #define HAE_ADDRESS     LCA_IOC_HAE
 132 
 133 #ifdef __KERNEL__
 134 
 135 /*
 136  * Translate physical memory address as seen on (PCI) bus into
 137  * a kernel virtual address and vv.
 138  */
 139 extern inline unsigned long virt_to_bus(void * address)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141         return virt_to_phys(address) + LCA_DMA_WIN_BASE;
 142 }
 143 
 144 extern inline void * bus_to_virt(unsigned long address)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146         /*
 147          * This check is a sanity check but also ensures that bus
 148          * address 0 maps to virtual address 0 which is useful to
 149          * detect null "pointers" (the NCR driver is much simpler if
 150          * NULL pointers are preserved).
 151          */
 152         if (address < LCA_DMA_WIN_BASE)
 153                 return 0;
 154         return phys_to_virt(address - LCA_DMA_WIN_BASE);
 155 }
 156 
 157 /*
 158  * I/O functions:
 159  *
 160  * Unlike Jensen, the Noname machines have no concept of local
 161  * I/O---everything goes over the PCI bus.
 162  *
 163  * There is plenty room for optimization here.  In particular,
 164  * the Alpha's insb/insw/extb/extw should be useful in moving
 165  * data to/from the right byte-lanes.
 166  */
 167 
 168 #define vuip    volatile unsigned int *
 169 
 170 extern inline unsigned int __inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172         long result = *(vuip) ((addr << 5) + LCA_IO + 0x00);
 173         result >>= (addr & 3) * 8;
 174         return 0xffUL & result;
 175 }
 176 
 177 extern inline void __outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         unsigned int w;
 180 
 181         asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 182         *(vuip) ((addr << 5) + LCA_IO + 0x00) = w;
 183         mb();
 184 }
 185 
 186 extern inline unsigned int __inw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         long result = *(vuip) ((addr << 5) + LCA_IO + 0x08);
 189         result >>= (addr & 3) * 8;
 190         return 0xffffUL & result;
 191 }
 192 
 193 extern inline void __outw(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195         unsigned int w;
 196 
 197         asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 198         *(vuip) ((addr << 5) + LCA_IO + 0x08) = w;
 199         mb();
 200 }
 201 
 202 extern inline unsigned int __inl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204         return *(vuip) ((addr << 5) + LCA_IO + 0x18);
 205 }
 206 
 207 extern inline void __outl(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209         *(vuip) ((addr << 5) + LCA_IO + 0x18) = b;
 210         mb();
 211 }
 212 
 213 
 214 /*
 215  * Memory functions.  64-bit and 32-bit accesses are done through
 216  * dense memory space, everything else through sparse space.
 217  */
 218 extern inline unsigned long __readb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220         unsigned long result, shift, msb;
 221 
 222         shift = (addr & 0x3) * 8;
 223         if (addr >= (1UL << 24)) {
 224                 msb = addr & 0xf8000000;
 225                 addr -= msb;
 226                 if (msb != hae.cache) {
 227                         set_hae(msb);
 228                 }
 229         }
 230         result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00);
 231         result >>= shift;
 232         return 0xffUL & result;
 233 }
 234 
 235 extern inline unsigned long __readw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 236 {
 237         unsigned long result, shift, msb;
 238 
 239         shift = (addr & 0x3) * 8;
 240         if (addr >= (1UL << 24)) {
 241                 msb = addr & 0xf8000000;
 242                 addr -= msb;
 243                 if (msb != hae.cache) {
 244                         set_hae(msb);
 245                 }
 246         }
 247         result = *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08);
 248         result >>= shift;
 249         return 0xffffUL & result;
 250 }
 251 
 252 extern inline unsigned long __readl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 253 {
 254         return *(vuip) (addr + LCA_DENSE_MEM);
 255 }
 256 
 257 extern inline void __writeb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 258 {
 259         unsigned long msb;
 260         unsigned int w;
 261 
 262         if (addr >= (1UL << 24)) {
 263                 msb = addr & 0xf8000000;
 264                 addr -= msb;
 265                 if (msb != hae.cache) {
 266                         set_hae(msb);
 267                 }
 268         }
 269         asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 270         *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x00) = w;
 271 }
 272 
 273 extern inline void __writew(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 274 {
 275         unsigned long msb;
 276         unsigned int w;
 277 
 278         if (addr >= (1UL << 24)) {
 279                 msb = addr & 0xf8000000;
 280                 addr -= msb;
 281                 if (msb != hae.cache) {
 282                         set_hae(msb);
 283                 }
 284         }
 285         asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
 286         *(vuip) ((addr << 5) + LCA_SPARSE_MEM + 0x08) = w;
 287 }
 288 
 289 extern inline void __writel(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 290 {
 291         *(vuip) (addr + LCA_DENSE_MEM) = b;
 292 }
 293 
 294 /*
 295  * Most of the above have so much overhead that it probably doesn't
 296  * make sense to have them inlined (better icache behavior).
 297  */
 298 
 299 #define inb(port) \
 300 (__builtin_constant_p((port))?__inb(port):_inb(port))
 301 
 302 #define outb(x, port) \
 303 (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
 304 
 305 #define readl(a)        __readl((unsigned long)(a))
 306 #define writel(v,a)     __writel((v),(unsigned long)(a))
 307 
 308 #undef vuip
 309 
 310 extern unsigned long lca_init (unsigned long mem_start, unsigned long mem_end);
 311 
 312 #endif /* __KERNEL__ */
 313 
 314 /*
 315  * Data structure for handling LCA machine checks.  Correctable errors
 316  * result in a short logout frame, uncorrectably ones in a long one.
 317  */
 318 struct el_lca_mcheck_short {
 319         struct el_common        h;              /* common logout header */
 320         unsigned long           reason;         /* reason for machine check */
 321         unsigned long           esr;            /* error-status register */
 322         unsigned long           ear;            /* error-address register */
 323         unsigned long           dc_stat;        /* dcache status register */
 324         unsigned long           ioc_stat0;      /* I/O controller status register 0 */
 325         unsigned long           ioc_stat1;      /* I/O controller status register 1 */
 326 };
 327 
 328 struct el_lca_mcheck_long {
 329         struct el_common        h;              /* common logout header */
 330         unsigned long           pt[32];         /* PAL temps (pt[0] is reason) */
 331         unsigned long           exc_addr;       /* exception address */
 332         unsigned long           pad1[3];
 333         unsigned long           pal_base;       /* PALcode base address */
 334         unsigned long           hier;           /* hw interrupt enable */
 335         unsigned long           hirr;           /* hw interrupt request */
 336         unsigned long           mm_csr;         /* MMU control & status */
 337         unsigned long           dc_stat;        /* data cache status */
 338         unsigned long           dc_addr;        /* data cache addr register */
 339         unsigned long           abox_ctl;       /* address box control register */
 340         unsigned long           esr;            /* error status register */
 341         unsigned long           ear;            /* error address register */
 342         unsigned long           car;            /* cache control register */
 343         unsigned long           ioc_stat0;      /* I/O controller status register 0 */
 344         unsigned long           ioc_stat1;      /* I/O controller status register 1 */
 345         unsigned long           va;             /* virtual address register */
 346 };
 347 
 348 union el_lca {
 349         struct el_common *              c;
 350         struct el_lca_mcheck_long *     l;
 351         struct el_lca_mcheck_short *    s;
 352 };
 353 
 354 #define RTC_PORT(x)     (0x70 + (x))
 355 #define RTC_ADDR(x)     (0x80 | (x))
 356 #define RTC_ALWAYS_BCD  0
 357 
 358 #endif /* __ALPHA_LCA__H__ */

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