1 /* 2 * Marvel systems use the IO7 I/O chip provides PCI/PCIX/AGP access 3 * 4 * This file is based on: 5 * 6 * Marvel / EV7 System Programmer's Manual 7 * Revision 1.00 8 * 14 May 2001 9 */ 10 11 #ifndef __ALPHA_MARVEL__H__ 12 #define __ALPHA_MARVEL__H__ 13 14 #include <linux/types.h> 15 #include <linux/spinlock.h> 16 17 #include <asm/compiler.h> 18 19 #define MARVEL_MAX_PIDS 32 /* as long as we rely on 43-bit superpage */ 20 #define MARVEL_IRQ_VEC_PE_SHIFT (10) 21 #define MARVEL_IRQ_VEC_IRQ_MASK ((1 << MARVEL_IRQ_VEC_PE_SHIFT) - 1) 22 #define MARVEL_NR_IRQS \ 23 (16 + (MARVEL_MAX_PIDS * (1 << MARVEL_IRQ_VEC_PE_SHIFT))) 24 25 /* 26 * EV7 RBOX Registers 27 */ 28 typedef struct { 29 volatile unsigned long csr __attribute__((aligned(16))); 30 } ev7_csr; 31 32 typedef struct { 33 ev7_csr RBOX_CFG; /* 0x0000 */ 34 ev7_csr RBOX_NSVC; 35 ev7_csr RBOX_EWVC; 36 ev7_csr RBOX_WHAMI; 37 ev7_csr RBOX_TCTL; /* 0x0040 */ 38 ev7_csr RBOX_INT; 39 ev7_csr RBOX_IMASK; 40 ev7_csr RBOX_IREQ; 41 ev7_csr RBOX_INTQ; /* 0x0080 */ 42 ev7_csr RBOX_INTA; 43 ev7_csr RBOX_IT; 44 ev7_csr RBOX_SCRATCH1; 45 ev7_csr RBOX_SCRATCH2; /* 0x00c0 */ 46 ev7_csr RBOX_L_ERR; 47 } ev7_csrs; 48 49 /* 50 * EV7 CSR addressing macros 51 */ 52 #define EV7_MASK40(addr) ((addr) & ((1UL << 41) - 1)) 53 #define EV7_KERN_ADDR(addr) ((void *)(IDENT_ADDR | EV7_MASK40(addr))) 54 55 #define EV7_PE_MASK 0x1ffUL /* 9 bits ( 256 + mem/io ) */ 56 #define EV7_IPE(pe) ((~((long)(pe)) & EV7_PE_MASK) << 35) 57 58 #define EV7_CSR_PHYS(pe, off) (EV7_IPE(pe) | (0x7FFCUL << 20) | (off)) 59 #define EV7_CSRS_PHYS(pe) (EV7_CSR_PHYS(pe, 0UL)) 60 61 #define EV7_CSR_KERN(pe, off) (EV7_KERN_ADDR(EV7_CSR_PHYS(pe, off))) 62 #define EV7_CSRS_KERN(pe) (EV7_KERN_ADDR(EV7_CSRS_PHYS(pe))) 63 64 #define EV7_CSR_OFFSET(name) ((unsigned long)&((ev7_csrs *)NULL)->name.csr) 65 66 /* 67 * IO7 registers 68 */ 69 typedef struct { 70 volatile unsigned long csr __attribute__((aligned(64))); 71 } io7_csr; 72 73 typedef struct { 74 /* I/O Port Control Registers */ 75 io7_csr POx_CTRL; /* 0x0000 */ 76 io7_csr POx_CACHE_CTL; 77 io7_csr POx_TIMER; 78 io7_csr POx_IO_ADR_EXT; 79 io7_csr POx_MEM_ADR_EXT; /* 0x0100 */ 80 io7_csr POx_XCAL_CTRL; 81 io7_csr rsvd1[2]; /* ?? spec doesn't show 0x180 */ 82 io7_csr POx_DM_SOURCE; /* 0x0200 */ 83 io7_csr POx_DM_DEST; 84 io7_csr POx_DM_SIZE; 85 io7_csr POx_DM_CTRL; 86 io7_csr rsvd2[4]; /* 0x0300 */ 87 88 /* AGP Control Registers -- port 3 only */ 89 io7_csr AGP_CAP_ID; /* 0x0400 */ 90 io7_csr AGP_STAT; 91 io7_csr AGP_CMD; 92 io7_csr rsvd3; 93 94 /* I/O Port Monitor Registers */ 95 io7_csr POx_MONCTL; /* 0x0500 */ 96 io7_csr POx_CTRA; 97 io7_csr POx_CTRB; 98 io7_csr POx_CTR56; 99 io7_csr POx_SCRATCH; /* 0x0600 */ 100 io7_csr POx_XTRA_A; 101 io7_csr POx_XTRA_TS; 102 io7_csr POx_XTRA_Z; 103 io7_csr rsvd4; /* 0x0700 */ 104 io7_csr POx_THRESHA; 105 io7_csr POx_THRESHB; 106 io7_csr rsvd5[33]; 107 108 /* System Address Space Window Control Registers */ 109 110 io7_csr POx_WBASE[4]; /* 0x1000 */ 111 io7_csr POx_WMASK[4]; 112 io7_csr POx_TBASE[4]; 113 io7_csr POx_SG_TBIA; 114 io7_csr POx_MSI_WBASE; 115 io7_csr rsvd6[50]; 116 117 /* I/O Port Error Registers */ 118 io7_csr POx_ERR_SUM; 119 io7_csr POx_FIRST_ERR; 120 io7_csr POx_MSK_HEI; 121 io7_csr POx_TLB_ERR; 122 io7_csr POx_SPL_COMPLT; 123 io7_csr POx_TRANS_SUM; 124 io7_csr POx_FRC_PCI_ERR; 125 io7_csr POx_MULT_ERR; 126 io7_csr rsvd7[8]; 127 128 /* I/O Port End of Interrupt Registers */ 129 io7_csr EOI_DAT; 130 io7_csr rsvd8[7]; 131 io7_csr POx_IACK_SPECIAL; 132 io7_csr rsvd9[103]; 133 } io7_ioport_csrs; 134 135 typedef struct { 136 io7_csr IO_ASIC_REV; /* 0x30.0000 */ 137 io7_csr IO_SYS_REV; 138 io7_csr SER_CHAIN3; 139 io7_csr PO7_RST1; 140 io7_csr PO7_RST2; /* 0x30.0100 */ 141 io7_csr POx_RST[4]; 142 io7_csr IO7_DWNH; 143 io7_csr IO7_MAF; 144 io7_csr IO7_MAF_TO; 145 io7_csr IO7_ACC_CLUMP; /* 0x30.0300 */ 146 io7_csr IO7_PMASK; 147 io7_csr IO7_IOMASK; 148 io7_csr IO7_UPH; 149 io7_csr IO7_UPH_TO; /* 0x30.0400 */ 150 io7_csr RBX_IREQ_OFF; 151 io7_csr RBX_INTA_OFF; 152 io7_csr INT_RTY; 153 io7_csr PO7_MONCTL; /* 0x30.0500 */ 154 io7_csr PO7_CTRA; 155 io7_csr PO7_CTRB; 156 io7_csr PO7_CTR56; 157 io7_csr PO7_SCRATCH; /* 0x30.0600 */ 158 io7_csr PO7_XTRA_A; 159 io7_csr PO7_XTRA_TS; 160 io7_csr PO7_XTRA_Z; 161 io7_csr PO7_PMASK; /* 0x30.0700 */ 162 io7_csr PO7_THRESHA; 163 io7_csr PO7_THRESHB; 164 io7_csr rsvd1[97]; 165 io7_csr PO7_ERROR_SUM; /* 0x30.2000 */ 166 io7_csr PO7_BHOLE_MASK; 167 io7_csr PO7_HEI_MSK; 168 io7_csr PO7_CRD_MSK; 169 io7_csr PO7_UNCRR_SYM; /* 0x30.2100 */ 170 io7_csr PO7_CRRCT_SYM; 171 io7_csr PO7_ERR_PKT[2]; 172 io7_csr PO7_UGBGE_SYM; /* 0x30.2200 */ 173 io7_csr rsbv2[887]; 174 io7_csr PO7_LSI_CTL[128]; /* 0x31.0000 */ 175 io7_csr rsvd3[123]; 176 io7_csr HLT_CTL; /* 0x31.3ec0 */ 177 io7_csr HPI_CTL; /* 0x31.3f00 */ 178 io7_csr CRD_CTL; 179 io7_csr STV_CTL; 180 io7_csr HEI_CTL; 181 io7_csr PO7_MSI_CTL[16]; /* 0x31.4000 */ 182 io7_csr rsvd4[240]; 183 184 /* 185 * Interrupt Diagnostic / Test 186 */ 187 struct { 188 io7_csr INT_PND; 189 io7_csr INT_CLR; 190 io7_csr INT_EOI; 191 io7_csr rsvd[29]; 192 } INT_DIAG[4]; 193 io7_csr rsvd5[125]; /* 0x31.a000 */ 194 io7_csr MISC_PND; /* 0x31.b800 */ 195 io7_csr rsvd6[31]; 196 io7_csr MSI_PND[16]; /* 0x31.c000 */ 197 io7_csr rsvd7[16]; 198 io7_csr MSI_CLR[16]; /* 0x31.c800 */ 199 } io7_port7_csrs; 200 201 /* 202 * IO7 DMA Window Base register (POx_WBASEx) 203 */ 204 #define wbase_m_ena 0x1 205 #define wbase_m_sg 0x2 206 #define wbase_m_dac 0x4 207 #define wbase_m_addr 0xFFF00000 208 union IO7_POx_WBASE { 209 struct { 210 unsigned ena : 1; /* <0> */ 211 unsigned sg : 1; /* <1> */ 212 unsigned dac : 1; /* <2> -- window 3 only */ 213 unsigned rsvd1 : 17; 214 unsigned addr : 12; /* <31:20> */ 215 unsigned rsvd2 : 32; 216 } bits; 217 unsigned as_long[2]; 218 unsigned as_quad; 219 }; 220 221 /* 222 * IO7 IID (Interrupt IDentifier) format 223 * 224 * For level-sensative interrupts, int_num is encoded as: 225 * 226 * bus/port slot/device INTx 227 * <7:5> <4:2> <1:0> 228 */ 229 union IO7_IID { 230 struct { 231 unsigned int_num : 9; /* <8:0> */ 232 unsigned tpu_mask : 4; /* <12:9> rsvd */ 233 unsigned msi : 1; /* 13 */ 234 unsigned ipe : 10; /* <23:14> */ 235 unsigned long rsvd : 40; 236 } bits; 237 unsigned int as_long[2]; 238 unsigned long as_quad; 239 }; 240 241 /* 242 * IO7 addressing macros 243 */ 244 #define IO7_KERN_ADDR(addr) (EV7_KERN_ADDR(addr)) 245 246 #define IO7_PORT_MASK 0x07UL /* 3 bits of port */ 247 248 #define IO7_IPE(pe) (EV7_IPE(pe)) 249 #define IO7_IPORT(port) ((~((long)(port)) & IO7_PORT_MASK) << 32) 250 251 #define IO7_HOSE(pe, port) (IO7_IPE(pe) | IO7_IPORT(port)) 252 253 #define IO7_MEM_PHYS(pe, port) (IO7_HOSE(pe, port) | 0x00000000UL) 254 #define IO7_CONF_PHYS(pe, port) (IO7_HOSE(pe, port) | 0xFE000000UL) 255 #define IO7_IO_PHYS(pe, port) (IO7_HOSE(pe, port) | 0xFF000000UL) 256 #define IO7_CSR_PHYS(pe, port, off) \ 257 (IO7_HOSE(pe, port) | 0xFF800000UL | (off)) 258 #define IO7_CSRS_PHYS(pe, port) (IO7_CSR_PHYS(pe, port, 0UL)) 259 #define IO7_PORT7_CSRS_PHYS(pe) (IO7_CSR_PHYS(pe, 7, 0x300000UL)) 260 261 #define IO7_MEM_KERN(pe, port) (IO7_KERN_ADDR(IO7_MEM_PHYS(pe, port))) 262 #define IO7_CONF_KERN(pe, port) (IO7_KERN_ADDR(IO7_CONF_PHYS(pe, port))) 263 #define IO7_IO_KERN(pe, port) (IO7_KERN_ADDR(IO7_IO_PHYS(pe, port))) 264 #define IO7_CSR_KERN(pe, port, off) (IO7_KERN_ADDR(IO7_CSR_PHYS(pe,port,off))) 265 #define IO7_CSRS_KERN(pe, port) (IO7_KERN_ADDR(IO7_CSRS_PHYS(pe, port))) 266 #define IO7_PORT7_CSRS_KERN(pe) (IO7_KERN_ADDR(IO7_PORT7_CSRS_PHYS(pe))) 267 268 #define IO7_PLL_RNGA(pll) (((pll) >> 3) & 0x7) 269 #define IO7_PLL_RNGB(pll) (((pll) >> 6) & 0x7) 270 271 #define IO7_MEM_SPACE (2UL * 1024 * 1024 * 1024) /* 2GB MEM */ 272 #define IO7_IO_SPACE (8UL * 1024 * 1024) /* 8MB I/O */ 273 274 275 /* 276 * Offset between ram physical addresses and pci64 DAC addresses 277 */ 278 #define IO7_DAC_OFFSET (1UL << 49) 279 280 /* 281 * This is needed to satisify the IO() macro used in initializing the machvec 282 */ 283 #define MARVEL_IACK_SC \ 284 ((unsigned long) \ 285 (&(((io7_ioport_csrs *)IO7_CSRS_KERN(0, 0))->POx_IACK_SPECIAL))) 286 287 #ifdef __KERNEL__ 288 289 /* 290 * IO7 structs 291 */ 292 #define IO7_NUM_PORTS 4 293 #define IO7_AGP_PORT 3 294 295 struct io7_port { 296 struct io7 *io7; 297 struct pci_controller *hose; 298 299 int enabled; 300 unsigned int port; 301 io7_ioport_csrs *csrs; 302 303 unsigned long saved_wbase[4]; 304 unsigned long saved_wmask[4]; 305 unsigned long saved_tbase[4]; 306 }; 307 308 struct io7 { 309 struct io7 *next; 310 311 unsigned int pe; 312 io7_port7_csrs *csrs; 313 struct io7_port ports[IO7_NUM_PORTS]; 314 315 raw_spinlock_t irq_lock; 316 }; 317 318 #ifndef __EXTERN_INLINE 319 # define __EXTERN_INLINE extern inline 320 # define __IO_EXTERN_INLINE 321 #endif 322 323 /* 324 * I/O functions. All access through linear space. 325 */ 326 327 /* 328 * Memory functions. All accesses through linear space. 329 */ 330 331 #define vucp volatile unsigned char __force * 332 #define vusp volatile unsigned short __force * 333 334 extern unsigned int marvel_ioread8(void __iomem *); 335 extern void marvel_iowrite8(u8 b, void __iomem *); 336 337 __EXTERN_INLINE unsigned int marvel_ioread16(void __iomem *addr) 338 { 339 return __kernel_ldwu(*(vusp)addr); 340 } 341 342 __EXTERN_INLINE void marvel_iowrite16(u16 b, void __iomem *addr) 343 { 344 __kernel_stw(b, *(vusp)addr); 345 } 346 347 extern void __iomem *marvel_ioremap(unsigned long addr, unsigned long size); 348 extern void marvel_iounmap(volatile void __iomem *addr); 349 extern void __iomem *marvel_ioportmap (unsigned long addr); 350 351 __EXTERN_INLINE int marvel_is_ioaddr(unsigned long addr) 352 { 353 return (addr >> 40) & 1; 354 } 355 356 extern int marvel_is_mmio(const volatile void __iomem *); 357 358 #undef vucp 359 #undef vusp 360 361 #undef __IO_PREFIX 362 #define __IO_PREFIX marvel 363 #define marvel_trivial_rw_bw 1 364 #define marvel_trivial_rw_lq 1 365 #define marvel_trivial_io_bw 0 366 #define marvel_trivial_io_lq 1 367 #define marvel_trivial_iounmap 0 368 #include <asm/io_trivial.h> 369 370 #ifdef __IO_EXTERN_INLINE 371 # undef __EXTERN_INLINE 372 # undef __IO_EXTERN_INLINE 373 #endif 374 375 #endif /* __KERNEL__ */ 376 377 #endif /* __ALPHA_MARVEL__H__ */ 378