Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __ALPHA_LCA__H__
0003 #define __ALPHA_LCA__H__
0004 
0005 #include <asm/compiler.h>
0006 #include <asm/mce.h>
0007 
0008 /*
0009  * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
0010  * for example).
0011  *
0012  * This file is based on:
0013  *
0014  *  DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
0015  *  Hardware Reference Manual; Digital Equipment Corp.; May 1994;
0016  *  Maynard, MA; Order Number: EC-N2681-71.
0017  */
0018 
0019 /*
0020  * NOTE: The LCA uses a Host Address Extension (HAE) register to access
0021  *   PCI addresses that are beyond the first 27 bits of address
0022  *   space.  Updating the HAE requires an external cycle (and
0023  *   a memory barrier), which tends to be slow.  Instead of updating
0024  *   it on each sparse memory access, we keep the current HAE value
0025  *   cached in variable cache_hae.  Only if the cached HAE differs
0026  *   from the desired HAE value do we actually updated HAE register.
0027  *   The HAE register is preserved by the interrupt handler entry/exit
0028  *   code, so this scheme works even in the presence of interrupts.
0029  *
0030  * Dense memory space doesn't require the HAE, but is restricted to
0031  * aligned 32 and 64 bit accesses.  Special Cycle and Interrupt
0032  * Acknowledge cycles may also require the use of the HAE.  The LCA
0033  * limits I/O address space to the bottom 24 bits of address space,
0034  * but this easily covers the 16 bit ISA I/O address space.
0035  */
0036 
0037 /*
0038  * NOTE 2! The memory operations do not set any memory barriers, as
0039  * it's not needed for cases like a frame buffer that is essentially
0040  * memory-like.  You need to do them by hand if the operations depend
0041  * on ordering.
0042  *
0043  * Similarly, the port I/O operations do a "mb" only after a write
0044  * operation: if an mb is needed before (as in the case of doing
0045  * memory mapped I/O first, and then a port I/O operation to the same
0046  * device), it needs to be done by hand.
0047  *
0048  * After the above has bitten me 100 times, I'll give up and just do
0049  * the mb all the time, but right now I'm hoping this will work out.
0050  * Avoiding mb's may potentially be a noticeable speed improvement,
0051  * but I can't honestly say I've tested it.
0052  *
0053  * Handling interrupts that need to do mb's to synchronize to
0054  * non-interrupts is another fun race area.  Don't do it (because if
0055  * you do, I'll have to do *everything* with interrupts disabled,
0056  * ugh).
0057  */
0058 
0059 /*
0060  * Memory Controller registers:
0061  */
0062 #define LCA_MEM_BCR0        (IDENT_ADDR + 0x120000000UL)
0063 #define LCA_MEM_BCR1        (IDENT_ADDR + 0x120000008UL)
0064 #define LCA_MEM_BCR2        (IDENT_ADDR + 0x120000010UL)
0065 #define LCA_MEM_BCR3        (IDENT_ADDR + 0x120000018UL)
0066 #define LCA_MEM_BMR0        (IDENT_ADDR + 0x120000020UL)
0067 #define LCA_MEM_BMR1        (IDENT_ADDR + 0x120000028UL)
0068 #define LCA_MEM_BMR2        (IDENT_ADDR + 0x120000030UL)
0069 #define LCA_MEM_BMR3        (IDENT_ADDR + 0x120000038UL)
0070 #define LCA_MEM_BTR0        (IDENT_ADDR + 0x120000040UL)
0071 #define LCA_MEM_BTR1        (IDENT_ADDR + 0x120000048UL)
0072 #define LCA_MEM_BTR2        (IDENT_ADDR + 0x120000050UL)
0073 #define LCA_MEM_BTR3        (IDENT_ADDR + 0x120000058UL)
0074 #define LCA_MEM_GTR     (IDENT_ADDR + 0x120000060UL)
0075 #define LCA_MEM_ESR     (IDENT_ADDR + 0x120000068UL)
0076 #define LCA_MEM_EAR     (IDENT_ADDR + 0x120000070UL)
0077 #define LCA_MEM_CAR     (IDENT_ADDR + 0x120000078UL)
0078 #define LCA_MEM_VGR     (IDENT_ADDR + 0x120000080UL)
0079 #define LCA_MEM_PLM     (IDENT_ADDR + 0x120000088UL)
0080 #define LCA_MEM_FOR     (IDENT_ADDR + 0x120000090UL)
0081 
0082 /*
0083  * I/O Controller registers:
0084  */
0085 #define LCA_IOC_HAE     (IDENT_ADDR + 0x180000000UL)
0086 #define LCA_IOC_CONF        (IDENT_ADDR + 0x180000020UL)
0087 #define LCA_IOC_STAT0       (IDENT_ADDR + 0x180000040UL)
0088 #define LCA_IOC_STAT1       (IDENT_ADDR + 0x180000060UL)
0089 #define LCA_IOC_TBIA        (IDENT_ADDR + 0x180000080UL)
0090 #define LCA_IOC_TB_ENA      (IDENT_ADDR + 0x1800000a0UL)
0091 #define LCA_IOC_SFT_RST     (IDENT_ADDR + 0x1800000c0UL)
0092 #define LCA_IOC_PAR_DIS     (IDENT_ADDR + 0x1800000e0UL)
0093 #define LCA_IOC_W_BASE0     (IDENT_ADDR + 0x180000100UL)
0094 #define LCA_IOC_W_BASE1     (IDENT_ADDR + 0x180000120UL)
0095 #define LCA_IOC_W_MASK0     (IDENT_ADDR + 0x180000140UL)
0096 #define LCA_IOC_W_MASK1     (IDENT_ADDR + 0x180000160UL)
0097 #define LCA_IOC_T_BASE0     (IDENT_ADDR + 0x180000180UL)
0098 #define LCA_IOC_T_BASE1     (IDENT_ADDR + 0x1800001a0UL)
0099 #define LCA_IOC_TB_TAG0     (IDENT_ADDR + 0x188000000UL)
0100 #define LCA_IOC_TB_TAG1     (IDENT_ADDR + 0x188000020UL)
0101 #define LCA_IOC_TB_TAG2     (IDENT_ADDR + 0x188000040UL)
0102 #define LCA_IOC_TB_TAG3     (IDENT_ADDR + 0x188000060UL)
0103 #define LCA_IOC_TB_TAG4     (IDENT_ADDR + 0x188000070UL)
0104 #define LCA_IOC_TB_TAG5     (IDENT_ADDR + 0x1880000a0UL)
0105 #define LCA_IOC_TB_TAG6     (IDENT_ADDR + 0x1880000c0UL)
0106 #define LCA_IOC_TB_TAG7     (IDENT_ADDR + 0x1880000e0UL)
0107 
0108 /*
0109  * Memory spaces:
0110  */
0111 #define LCA_IACK_SC     (IDENT_ADDR + 0x1a0000000UL)
0112 #define LCA_CONF        (IDENT_ADDR + 0x1e0000000UL)
0113 #define LCA_IO          (IDENT_ADDR + 0x1c0000000UL)
0114 #define LCA_SPARSE_MEM      (IDENT_ADDR + 0x200000000UL)
0115 #define LCA_DENSE_MEM       (IDENT_ADDR + 0x300000000UL)
0116 
0117 /*
0118  * Bit definitions for I/O Controller status register 0:
0119  */
0120 #define LCA_IOC_STAT0_CMD       0xf
0121 #define LCA_IOC_STAT0_ERR       (1<<4)
0122 #define LCA_IOC_STAT0_LOST      (1<<5)
0123 #define LCA_IOC_STAT0_THIT      (1<<6)
0124 #define LCA_IOC_STAT0_TREF      (1<<7)
0125 #define LCA_IOC_STAT0_CODE_SHIFT    8
0126 #define LCA_IOC_STAT0_CODE_MASK     0x7
0127 #define LCA_IOC_STAT0_P_NBR_SHIFT   13
0128 #define LCA_IOC_STAT0_P_NBR_MASK    0x7ffff
0129 
0130 #define LCA_HAE_ADDRESS     LCA_IOC_HAE
0131 
0132 /* LCA PMR Power Management register defines */
0133 #define LCA_PMR_ADDR    (IDENT_ADDR + 0x120000098UL)
0134 #define LCA_PMR_PDIV    0x7                     /* Primary clock divisor */
0135 #define LCA_PMR_ODIV    0x38                    /* Override clock divisor */
0136 #define LCA_PMR_INTO    0x40                    /* Interrupt override */
0137 #define LCA_PMR_DMAO    0x80                    /* DMA override */
0138 #define LCA_PMR_OCCEB   0xffff0000L             /* Override cycle counter - even bits */
0139 #define LCA_PMR_OCCOB   0xffff000000000000L     /* Override cycle counter - even bits */
0140 #define LCA_PMR_PRIMARY_MASK    0xfffffffffffffff8L
0141 
0142 /* LCA PMR Macros */
0143 
0144 #define LCA_READ_PMR        (*(volatile unsigned long *)LCA_PMR_ADDR)
0145 #define LCA_WRITE_PMR(d)    (*((volatile unsigned long *)LCA_PMR_ADDR) = (d))
0146 
0147 #define LCA_GET_PRIMARY(r)  ((r) & LCA_PMR_PDIV)
0148 #define LCA_GET_OVERRIDE(r) (((r) >> 3) & LCA_PMR_PDIV)
0149 #define LCA_SET_PRIMARY_CLOCK(r, c) ((r) = (((r) & LCA_PMR_PRIMARY_MASK)|(c)))
0150 
0151 /* LCA PMR Divisor values */
0152 #define LCA_PMR_DIV_1   0x0
0153 #define LCA_PMR_DIV_1_5 0x1
0154 #define LCA_PMR_DIV_2   0x2
0155 #define LCA_PMR_DIV_4   0x3
0156 #define LCA_PMR_DIV_8   0x4
0157 #define LCA_PMR_DIV_16  0x5
0158 #define LCA_PMR_DIV_MIN DIV_1
0159 #define LCA_PMR_DIV_MAX DIV_16
0160 
0161 
0162 /*
0163  * Data structure for handling LCA machine checks.  Correctable errors
0164  * result in a short logout frame, uncorrectable ones in a long one.
0165  */
0166 struct el_lca_mcheck_short {
0167     struct el_common    h;      /* common logout header */
0168     unsigned long       esr;        /* error-status register */
0169     unsigned long       ear;        /* error-address register */
0170     unsigned long       dc_stat;    /* dcache status register */
0171     unsigned long       ioc_stat0;  /* I/O controller status register 0 */
0172     unsigned long       ioc_stat1;  /* I/O controller status register 1 */
0173 };
0174 
0175 struct el_lca_mcheck_long {
0176     struct el_common    h;      /* common logout header */
0177     unsigned long       pt[31];     /* PAL temps */
0178     unsigned long       exc_addr;   /* exception address */
0179     unsigned long       pad1[3];
0180     unsigned long       pal_base;   /* PALcode base address */
0181     unsigned long       hier;       /* hw interrupt enable */
0182     unsigned long       hirr;       /* hw interrupt request */
0183     unsigned long       mm_csr;     /* MMU control & status */
0184     unsigned long       dc_stat;    /* data cache status */
0185     unsigned long       dc_addr;    /* data cache addr register */
0186     unsigned long       abox_ctl;   /* address box control register */
0187     unsigned long       esr;        /* error status register */
0188     unsigned long       ear;        /* error address register */
0189     unsigned long       car;        /* cache control register */
0190     unsigned long       ioc_stat0;  /* I/O controller status register 0 */
0191     unsigned long       ioc_stat1;  /* I/O controller status register 1 */
0192     unsigned long       va;     /* virtual address register */
0193 };
0194 
0195 union el_lca {
0196     struct el_common *      c;
0197     struct el_lca_mcheck_long * l;
0198     struct el_lca_mcheck_short *    s;
0199 };
0200 
0201 #ifdef __KERNEL__
0202 
0203 #ifndef __EXTERN_INLINE
0204 #define __EXTERN_INLINE extern inline
0205 #define __IO_EXTERN_INLINE
0206 #endif
0207 
0208 /*
0209  * I/O functions:
0210  *
0211  * Unlike Jensen, the Noname machines have no concept of local
0212  * I/O---everything goes over the PCI bus.
0213  *
0214  * There is plenty room for optimization here.  In particular,
0215  * the Alpha's insb/insw/extb/extw should be useful in moving
0216  * data to/from the right byte-lanes.
0217  */
0218 
0219 #define vip volatile int __force *
0220 #define vuip    volatile unsigned int __force *
0221 #define vulp    volatile unsigned long __force *
0222 
0223 #define LCA_SET_HAE                     \
0224     do {                            \
0225         if (addr >= (1UL << 24)) {          \
0226             unsigned long msb = addr & 0xf8000000;  \
0227             addr -= msb;                \
0228             set_hae(msb);               \
0229         }                       \
0230     } while (0)
0231 
0232 
0233 __EXTERN_INLINE unsigned int lca_ioread8(const void __iomem *xaddr)
0234 {
0235     unsigned long addr = (unsigned long) xaddr;
0236     unsigned long result, base_and_type;
0237 
0238     if (addr >= LCA_DENSE_MEM) {
0239         addr -= LCA_DENSE_MEM;
0240         LCA_SET_HAE;
0241         base_and_type = LCA_SPARSE_MEM + 0x00;
0242     } else {
0243         addr -= LCA_IO;
0244         base_and_type = LCA_IO + 0x00;
0245     }
0246 
0247     result = *(vip) ((addr << 5) + base_and_type);
0248     return __kernel_extbl(result, addr & 3);
0249 }
0250 
0251 __EXTERN_INLINE void lca_iowrite8(u8 b, void __iomem *xaddr)
0252 {
0253     unsigned long addr = (unsigned long) xaddr;
0254     unsigned long w, base_and_type;
0255 
0256     if (addr >= LCA_DENSE_MEM) {
0257         addr -= LCA_DENSE_MEM;
0258         LCA_SET_HAE;
0259         base_and_type = LCA_SPARSE_MEM + 0x00;
0260     } else {
0261         addr -= LCA_IO;
0262         base_and_type = LCA_IO + 0x00;
0263     }
0264 
0265     w = __kernel_insbl(b, addr & 3);
0266     *(vuip) ((addr << 5) + base_and_type) = w;
0267 }
0268 
0269 __EXTERN_INLINE unsigned int lca_ioread16(const void __iomem *xaddr)
0270 {
0271     unsigned long addr = (unsigned long) xaddr;
0272     unsigned long result, base_and_type;
0273 
0274     if (addr >= LCA_DENSE_MEM) {
0275         addr -= LCA_DENSE_MEM;
0276         LCA_SET_HAE;
0277         base_and_type = LCA_SPARSE_MEM + 0x08;
0278     } else {
0279         addr -= LCA_IO;
0280         base_and_type = LCA_IO + 0x08;
0281     }
0282 
0283     result = *(vip) ((addr << 5) + base_and_type);
0284     return __kernel_extwl(result, addr & 3);
0285 }
0286 
0287 __EXTERN_INLINE void lca_iowrite16(u16 b, void __iomem *xaddr)
0288 {
0289     unsigned long addr = (unsigned long) xaddr;
0290     unsigned long w, base_and_type;
0291 
0292     if (addr >= LCA_DENSE_MEM) {
0293         addr -= LCA_DENSE_MEM;
0294         LCA_SET_HAE;
0295         base_and_type = LCA_SPARSE_MEM + 0x08;
0296     } else {
0297         addr -= LCA_IO;
0298         base_and_type = LCA_IO + 0x08;
0299     }
0300 
0301     w = __kernel_inswl(b, addr & 3);
0302     *(vuip) ((addr << 5) + base_and_type) = w;
0303 }
0304 
0305 __EXTERN_INLINE unsigned int lca_ioread32(const void __iomem *xaddr)
0306 {
0307     unsigned long addr = (unsigned long) xaddr;
0308     if (addr < LCA_DENSE_MEM)
0309         addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
0310     return *(vuip)addr;
0311 }
0312 
0313 __EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
0314 {
0315     unsigned long addr = (unsigned long) xaddr;
0316     if (addr < LCA_DENSE_MEM)
0317         addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
0318     *(vuip)addr = b;
0319 }
0320 
0321 __EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
0322 {
0323     return (void __iomem *)(addr + LCA_IO);
0324 }
0325 
0326 __EXTERN_INLINE void __iomem *lca_ioremap(unsigned long addr,
0327                       unsigned long size)
0328 {
0329     return (void __iomem *)(addr + LCA_DENSE_MEM);
0330 }
0331 
0332 __EXTERN_INLINE int lca_is_ioaddr(unsigned long addr)
0333 {
0334     return addr >= IDENT_ADDR + 0x120000000UL;
0335 }
0336 
0337 __EXTERN_INLINE int lca_is_mmio(const volatile void __iomem *addr)
0338 {
0339     return (unsigned long)addr >= LCA_DENSE_MEM;
0340 }
0341 
0342 #undef vip
0343 #undef vuip
0344 #undef vulp
0345 
0346 #undef __IO_PREFIX
0347 #define __IO_PREFIX     lca
0348 #define lca_trivial_rw_bw   2
0349 #define lca_trivial_rw_lq   1
0350 #define lca_trivial_io_bw   0
0351 #define lca_trivial_io_lq   0
0352 #define lca_trivial_iounmap 1
0353 #include <asm/io_trivial.h>
0354 
0355 #ifdef __IO_EXTERN_INLINE
0356 #undef __EXTERN_INLINE
0357 #undef __IO_EXTERN_INLINE
0358 #endif
0359 
0360 #endif /* __KERNEL__ */
0361 
0362 #endif /* __ALPHA_LCA__H__ */