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