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 */ 28typedef struct { 29 volatile unsigned long csr __attribute__((aligned(16))); 30} ev7_csr; 31 32typedef 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 */ 69typedef struct { 70 volatile unsigned long csr __attribute__((aligned(64))); 71} io7_csr; 72 73typedef 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 135typedef 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 208union 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 */ 229union 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 295struct 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 308struct 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 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 334extern unsigned int marvel_ioread8(void __iomem *); 335extern 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 347extern void __iomem *marvel_ioremap(unsigned long addr, unsigned long size); 348extern void marvel_iounmap(volatile void __iomem *addr); 349extern 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 356extern 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