1/* 2 * linux/arch/alpha/kernel/sys_sio.c 3 * 4 * Copyright (C) 1995 David A Rusling 5 * Copyright (C) 1996 Jay A Estabrook 6 * Copyright (C) 1998, 1999 Richard Henderson 7 * 8 * Code for all boards that route the PCI interrupts through the SIO 9 * PCI/ISA bridge. This includes Noname (AXPpci33), Multia (UDB), 10 * Kenetics's Platform 2000, Avanti (AlphaStation), XL, and AlphaBook1. 11 */ 12 13#include <linux/config.h> 14#include <linux/kernel.h> 15#include <linux/types.h> 16#include <linux/mm.h> 17#include <linux/sched.h> 18#include <linux/pci.h> 19#include <linux/init.h> 20#include <linux/tty.h> 21 22#include <asm/compiler.h> 23#include <asm/ptrace.h> 24#include <asm/system.h> 25#include <asm/dma.h> 26#include <asm/irq.h> 27#include <asm/mmu_context.h> 28#include <asm/io.h> 29#include <asm/pgtable.h> 30#include <asm/core_apecs.h> 31#include <asm/core_lca.h> 32 33#include "proto.h" 34#include "irq_impl.h" 35#include "pci_impl.h" 36#include "machvec_impl.h" 37 38 39static void __init 40sio_init_irq(void) 41{ 42 if (alpha_using_srm) 43 alpha_mv.device_interrupt = srm_device_interrupt; 44 45 init_i8259a_irqs(); 46 common_init_isa_dma(); 47} 48 49static inline void __init 50alphabook1_init_arch(void) 51{ 52 /* The AlphaBook1 has LCD video fixed at 800x600, 53 37 rows and 100 cols. */ 54 screen_info.orig_y = 37; 55 screen_info.orig_video_cols = 100; 56 screen_info.orig_video_lines = 37; 57 58 lca_init_arch(); 59} 60 61 62/* 63 * sio_route_tab selects irq routing in PCI/ISA bridge so that: 64 * PIRQ0 -> irq 15 65 * PIRQ1 -> irq 9 66 * PIRQ2 -> irq 10 67 * PIRQ3 -> irq 11 68 * 69 * This probably ought to be configurable via MILO. For 70 * example, sound boards seem to like using IRQ 9. 71 * 72 * This is NOT how we should do it. PIRQ0-X should have 73 * their own IRQ's, the way intel uses the IO-APIC irq's. 74 */ 75 76static void __init 77sio_pci_route(void) 78{ 79 pcibios_write_config_dword(0, PCI_DEVFN(7, 0), 0x60, 80 alpha_mv.sys.sio.route_tab); 81} 82 83static unsigned int __init 84sio_collect_irq_levels(void) 85{ 86 unsigned int level_bits = 0; 87 struct pci_dev *dev; 88 89 /* Iterate through the devices, collecting IRQ levels. */ 90 pci_for_each_dev(dev) { 91 if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) && 92 (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA)) 93 continue; 94 95 if (dev->irq) 96 level_bits |= (1 << dev->irq); 97 } 98 return level_bits; 99} 100 101static void __init 102sio_fixup_irq_levels(unsigned int level_bits) 103{ 104 unsigned int old_level_bits; 105 106 /* 107 * Now, make all PCI interrupts level sensitive. Notice: 108 * these registers must be accessed byte-wise. inw()/outw() 109 * don't work. 110 * 111 * Make sure to turn off any level bits set for IRQs 9,10,11,15, 112 * so that the only bits getting set are for devices actually found. 113 * Note that we do preserve the remainder of the bits, which we hope 114 * will be set correctly by ARC/SRM. 115 * 116 * Note: we at least preserve any level-set bits on AlphaBook1 117 */ 118 old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8); 119 120 level_bits |= (old_level_bits & 0x71ff); 121 122 outb((level_bits >> 0) & 0xff, 0x4d0); 123 outb((level_bits >> 8) & 0xff, 0x4d1); 124} 125 126static inline int __init 127noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 128{ 129 /* 130 * The Noname board has 5 PCI slots with each of the 4 131 * interrupt pins routed to different pins on the PCI/ISA 132 * bridge (PIRQ0-PIRQ3). The table below is based on 133 * information available at: 134 * 135 * http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt 136 * 137 * I have no information on the Avanti interrupt routing, but 138 * the routing seems to be identical to the Noname except 139 * that the Avanti has an additional slot whose routing I'm 140 * unsure of. 141 * 142 * pirq_tab[0] is a fake entry to deal with old PCI boards 143 * that have the interrupt pin number hardwired to 0 (meaning 144 * that they use the default INTA line, if they are interrupt 145 * driven at all). 146 */ 147 static char irq_tab[][5] __initdata = { 148 /*INT A B C D */ 149 { 3, 3, 3, 3, 3}, /* idsel 6 (53c810) */ 150 {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */ 151 { 2, 2, -1, -1, -1}, /* idsel 8 (Hack: slot closest ISA) */ 152 {-1, -1, -1, -1, -1}, /* idsel 9 (unused) */ 153 {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */ 154 { 0, 0, 2, 1, 0}, /* idsel 11 KN25_PCI_SLOT0 */ 155 { 1, 1, 0, 2, 1}, /* idsel 12 KN25_PCI_SLOT1 */ 156 { 2, 2, 1, 0, 2}, /* idsel 13 KN25_PCI_SLOT2 */ 157 { 0, 0, 0, 0, 0}, /* idsel 14 AS255 TULIP */ 158 }; 159 const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5; 160 int irq = COMMON_TABLE_LOOKUP, tmp; 161 tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq); 162 return irq >= 0 ? tmp : -1; 163} 164 165static inline int __init 166p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 167{ 168 static char irq_tab[][5] __initdata = { 169 /*INT A B C D */ 170 { 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */ 171 {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */ 172 { 1, 1, 2, 3, 0}, /* idsel 8 (slot A) */ 173 { 2, 2, 3, 0, 1}, /* idsel 9 (slot B) */ 174 {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */ 175 {-1, -1, -1, -1, -1}, /* idsel 11 (unused) */ 176 { 3, 3, -1, -1, -1}, /* idsel 12 (CMD0646) */ 177 }; 178 const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5; 179 int irq = COMMON_TABLE_LOOKUP, tmp; 180 tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq); 181 return irq >= 0 ? tmp : -1; 182} 183 184static inline void __init 185noname_init_pci(void) 186{ 187 common_init_pci(); 188 sio_pci_route(); 189 sio_fixup_irq_levels(sio_collect_irq_levels()); 190 ns87312_enable_ide(0x26e); 191} 192 193static inline void __init 194alphabook1_init_pci(void) 195{ 196 struct pci_dev *dev; 197 unsigned char orig, config; 198 199 common_init_pci(); 200 sio_pci_route(); 201 202 /* 203 * On the AlphaBook1, the PCMCIA chip (Cirrus 6729) 204 * is sensitive to PCI bus bursts, so we must DISABLE 205 * burst mode for the NCR 8xx SCSI... :-( 206 * 207 * Note that the NCR810 SCSI driver must preserve the 208 * setting of the bit in order for this to work. At the 209 * moment (2.0.29), ncr53c8xx.c does NOT do this, but 210 * 53c7,8xx.c DOES. 211 */ 212 213 dev = NULL; 214 while ((dev = pci_find_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) { 215 if (dev->device == PCI_DEVICE_ID_NCR_53C810 216 || dev->device == PCI_DEVICE_ID_NCR_53C815 217 || dev->device == PCI_DEVICE_ID_NCR_53C820 218 || dev->device == PCI_DEVICE_ID_NCR_53C825) { 219 unsigned long io_port; 220 unsigned char ctest4; 221 222 io_port = dev->resource[0].start; 223 ctest4 = inb(io_port+0x21); 224 if (!(ctest4 & 0x80)) { 225 printk("AlphaBook1 NCR init: setting" 226 " burst disable\n"); 227 outb(ctest4 | 0x80, io_port+0x21); 228 } 229 } 230 } 231 232 /* Do not set *ANY* level triggers for AlphaBook1. */ 233 sio_fixup_irq_levels(0); 234 235 outb(0x0f, 0x3ce); orig = inb(0x3cf); 236 outb(0x0f, 0x3ce); outb(0x05, 0x3cf); 237 outb(0x0b, 0x3ce); config = inb(0x3cf); 238 if ((config & 0xc0) != 0xc0) { 239 printk("AlphaBook1 VGA init: setting 1Mb memory\n"); 240 config |= 0xc0; 241 outb(0x0b, 0x3ce); outb(config, 0x3cf); 242 } 243 outb(0x0f, 0x3ce); outb(orig, 0x3cf); 244} 245 246 247/* 248 * The System Vectors 249 */ 250 251#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_BOOK1) 252struct alpha_machine_vector alphabook1_mv __initmv = { 253 vector_name: "AlphaBook1", 254 DO_EV4_MMU, 255 DO_DEFAULT_RTC, 256 DO_LCA_IO, 257 DO_LCA_BUS, 258 machine_check: lca_machine_check, 259 max_dma_address: ALPHA_MAX_DMA_ADDRESS, 260 min_io_address: DEFAULT_IO_BASE, 261 min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE, 262 263 nr_irqs: 16, 264 device_interrupt: isa_device_interrupt, 265 266 init_arch: alphabook1_init_arch, 267 init_irq: sio_init_irq, 268 init_rtc: common_init_rtc, 269 init_pci: alphabook1_init_pci, 270 kill_arch: NULL, 271 pci_map_irq: noname_map_irq, 272 pci_swizzle: common_swizzle, 273 274 sys: { sio: { 275 /* NCR810 SCSI is 14, PCMCIA controller is 15. */ 276 route_tab: 0x0e0f0a0a, 277 }} 278}; 279ALIAS_MV(alphabook1) 280#endif 281 282#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_AVANTI) 283struct alpha_machine_vector avanti_mv __initmv = { 284 vector_name: "Avanti", 285 DO_EV4_MMU, 286 DO_DEFAULT_RTC, 287 DO_APECS_IO, 288 DO_APECS_BUS, 289 machine_check: apecs_machine_check, 290 max_dma_address: ALPHA_MAX_DMA_ADDRESS, 291 min_io_address: DEFAULT_IO_BASE, 292 min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE, 293 294 nr_irqs: 16, 295 device_interrupt: isa_device_interrupt, 296 297 init_arch: apecs_init_arch, 298 init_irq: sio_init_irq, 299 init_rtc: common_init_rtc, 300 init_pci: noname_init_pci, 301 pci_map_irq: noname_map_irq, 302 pci_swizzle: common_swizzle, 303 304 sys: { sio: { 305 route_tab: 0x0b0a0e0f, 306 }} 307}; 308ALIAS_MV(avanti) 309#endif 310 311#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_NONAME) 312struct alpha_machine_vector noname_mv __initmv = { 313 vector_name: "Noname", 314 DO_EV4_MMU, 315 DO_DEFAULT_RTC, 316 DO_LCA_IO, 317 DO_LCA_BUS, 318 machine_check: lca_machine_check, 319 max_dma_address: ALPHA_MAX_DMA_ADDRESS, 320 min_io_address: DEFAULT_IO_BASE, 321 min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE, 322 323 nr_irqs: 16, 324 device_interrupt: srm_device_interrupt, 325 326 init_arch: lca_init_arch, 327 init_irq: sio_init_irq, 328 init_rtc: common_init_rtc, 329 init_pci: noname_init_pci, 330 pci_map_irq: noname_map_irq, 331 pci_swizzle: common_swizzle, 332 333 sys: { sio: { 334 /* For UDB, the only available PCI slot must not map to IRQ 9, 335 since that's the builtin MSS sound chip. That PCI slot 336 will map to PIRQ1 (for INTA at least), so we give it IRQ 15 337 instead. 338 339 Unfortunately we have to do this for NONAME as well, since 340 they are co-indicated when the platform type "Noname" is 341 selected... :-( */ 342 343 route_tab: 0x0b0a0f0d, 344 }} 345}; 346ALIAS_MV(noname) 347#endif 348 349#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_P2K) 350struct alpha_machine_vector p2k_mv __initmv = { 351 vector_name: "Platform2000", 352 DO_EV4_MMU, 353 DO_DEFAULT_RTC, 354 DO_LCA_IO, 355 DO_LCA_BUS, 356 machine_check: lca_machine_check, 357 max_dma_address: ALPHA_MAX_DMA_ADDRESS, 358 min_io_address: DEFAULT_IO_BASE, 359 min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE, 360 361 nr_irqs: 16, 362 device_interrupt: srm_device_interrupt, 363 364 init_arch: lca_init_arch, 365 init_irq: sio_init_irq, 366 init_rtc: common_init_rtc, 367 init_pci: noname_init_pci, 368 pci_map_irq: p2k_map_irq, 369 pci_swizzle: common_swizzle, 370 371 sys: { sio: { 372 route_tab: 0x0b0a090f, 373 }} 374}; 375ALIAS_MV(p2k) 376#endif 377 378#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XL) 379struct alpha_machine_vector xl_mv __initmv = { 380 vector_name: "XL", 381 DO_EV4_MMU, 382 DO_DEFAULT_RTC, 383 DO_APECS_IO, 384 BUS(apecs), 385 machine_check: apecs_machine_check, 386 max_dma_address: ALPHA_XL_MAX_DMA_ADDRESS, 387 min_io_address: DEFAULT_IO_BASE, 388 min_mem_address: XL_DEFAULT_MEM_BASE, 389 390 nr_irqs: 16, 391 device_interrupt: isa_device_interrupt, 392 393 init_arch: apecs_init_arch, 394 init_irq: sio_init_irq, 395 init_rtc: common_init_rtc, 396 init_pci: noname_init_pci, 397 pci_map_irq: noname_map_irq, 398 pci_swizzle: common_swizzle, 399 400 sys: { sio: { 401 route_tab: 0x0b0a090f, 402 }} 403}; 404ALIAS_MV(xl) 405#endif 406