1 1.59 thorpej /* $NetBSD: pci_kn20aa.c,v 1.59 2021/07/04 22:42:36 thorpej Exp $ */ 2 1.1 cgd 3 1.1 cgd /* 4 1.5 cgd * Copyright (c) 1995, 1996 Carnegie-Mellon University. 5 1.1 cgd * All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Author: Chris G. Demetriou 8 1.53 matt * 9 1.1 cgd * Permission to use, copy, modify and distribute this software and 10 1.1 cgd * its documentation is hereby granted, provided that both the copyright 11 1.1 cgd * notice and this permission notice appear in all copies of the 12 1.1 cgd * software, derivative works or modified versions, and any portions 13 1.1 cgd * thereof, and that both notices appear in supporting documentation. 14 1.53 matt * 15 1.53 matt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 1.53 matt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17 1.1 cgd * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 1.53 matt * 19 1.1 cgd * Carnegie Mellon requests users of this software to return to 20 1.1 cgd * 21 1.1 cgd * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 22 1.1 cgd * School of Computer Science 23 1.1 cgd * Carnegie Mellon University 24 1.1 cgd * Pittsburgh PA 15213-3890 25 1.1 cgd * 26 1.1 cgd * any improvements or extensions that they make and grant Carnegie the 27 1.1 cgd * rights to redistribute these changes. 28 1.1 cgd */ 29 1.22 cgd 30 1.23 cgd #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 31 1.23 cgd 32 1.59 thorpej __KERNEL_RCSID(0, "$NetBSD: pci_kn20aa.c,v 1.59 2021/07/04 22:42:36 thorpej Exp $"); 33 1.1 cgd 34 1.1 cgd #include <sys/types.h> 35 1.1 cgd #include <sys/param.h> 36 1.1 cgd #include <sys/time.h> 37 1.1 cgd #include <sys/systm.h> 38 1.1 cgd #include <sys/errno.h> 39 1.1 cgd #include <sys/device.h> 40 1.1 cgd #include <sys/syslog.h> 41 1.1 cgd 42 1.7 cgd #include <machine/autoconf.h> 43 1.56 thorpej #include <machine/rpb.h> 44 1.7 cgd 45 1.1 cgd #include <dev/pci/pcireg.h> 46 1.1 cgd #include <dev/pci/pcivar.h> 47 1.1 cgd 48 1.1 cgd #include <alpha/pci/ciareg.h> 49 1.1 cgd #include <alpha/pci/ciavar.h> 50 1.1 cgd 51 1.1 cgd #include "sio.h" 52 1.37 thorpej #if NSIO > 0 || NPCEB > 0 53 1.1 cgd #include <alpha/pci/siovar.h> 54 1.1 cgd #endif 55 1.1 cgd 56 1.55 thorpej static int dec_kn20aa_intr_map(const struct pci_attach_args *, 57 1.55 thorpej pci_intr_handle_t *); 58 1.1 cgd 59 1.1 cgd #define KN20AA_PCEB_IRQ 31 60 1.1 cgd #define KN20AA_MAX_IRQ 32 61 1.1 cgd #define PCI_STRAY_MAX 5 62 1.1 cgd 63 1.55 thorpej static void kn20aa_enable_intr(pci_chipset_tag_t pc, int irq); 64 1.55 thorpej static void kn20aa_disable_intr(pci_chipset_tag_t pc, int irq); 65 1.1 cgd 66 1.56 thorpej static void 67 1.56 thorpej pci_kn20aa_pickintr(void *core, bus_space_tag_t iot, bus_space_tag_t memt, 68 1.56 thorpej pci_chipset_tag_t pc) 69 1.1 cgd { 70 1.1 cgd int i; 71 1.1 cgd 72 1.56 thorpej pc->pc_intr_v = core; 73 1.53 matt pc->pc_intr_map = dec_kn20aa_intr_map; 74 1.55 thorpej pc->pc_intr_string = alpha_pci_generic_intr_string; 75 1.55 thorpej pc->pc_intr_evcnt = alpha_pci_generic_intr_evcnt; 76 1.55 thorpej pc->pc_intr_establish = alpha_pci_generic_intr_establish; 77 1.55 thorpej pc->pc_intr_disestablish = alpha_pci_generic_intr_disestablish; 78 1.29 thorpej 79 1.30 mjacob /* Not supported on KN20AA. */ 80 1.29 thorpej pc->pc_pciide_compat_intr_establish = NULL; 81 1.1 cgd 82 1.57 thorpej pc->pc_intr_desc = "kn20aa"; 83 1.55 thorpej pc->pc_vecbase = 0x900; 84 1.55 thorpej pc->pc_nirq = KN20AA_MAX_IRQ; 85 1.55 thorpej 86 1.55 thorpej pc->pc_intr_enable = kn20aa_enable_intr; 87 1.55 thorpej pc->pc_intr_disable = kn20aa_disable_intr; 88 1.55 thorpej 89 1.39 thorpej for (i = 0; i < KN20AA_MAX_IRQ; i++) { 90 1.58 thorpej kn20aa_disable_intr(pc, i); 91 1.58 thorpej } 92 1.21 cgd 93 1.58 thorpej alpha_pci_intr_alloc(pc, PCI_STRAY_MAX); 94 1.39 thorpej 95 1.37 thorpej #if NSIO > 0 || NPCEB > 0 96 1.27 thorpej sio_intr_setup(pc, iot); 97 1.55 thorpej kn20aa_enable_intr(pc, KN20AA_PCEB_IRQ); 98 1.1 cgd #endif 99 1.1 cgd } 100 1.56 thorpej ALPHA_PCI_INTR_INIT(ST_DEC_KN20AA, pci_kn20aa_pickintr) 101 1.1 cgd 102 1.55 thorpej static int 103 1.52 dyoung dec_kn20aa_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp) 104 1.1 cgd { 105 1.41 sommerfe pcitag_t bustag = pa->pa_intrtag; 106 1.41 sommerfe int buspin = pa->pa_intrpin; 107 1.41 sommerfe pci_chipset_tag_t pc = pa->pa_pc; 108 1.1 cgd int device; 109 1.9 cgd int kn20aa_irq; 110 1.1 cgd 111 1.31 thorpej if (buspin == 0) { 112 1.31 thorpej /* No IRQ used. */ 113 1.31 thorpej return 1; 114 1.31 thorpej } 115 1.55 thorpej if (buspin < 0 || buspin > 4) { 116 1.31 thorpej printf("dec_kn20aa_intr_map: bad interrupt pin %d\n", buspin); 117 1.31 thorpej return 1; 118 1.31 thorpej } 119 1.1 cgd 120 1.1 cgd /* 121 1.1 cgd * Slot->interrupt translation. Appears to work, though it 122 1.1 cgd * may not hold up forever. 123 1.1 cgd * 124 1.1 cgd * The DEC engineers who did this hardware obviously engaged 125 1.1 cgd * in random drug testing. 126 1.1 cgd */ 127 1.43 thorpej pci_decompose_tag(pc, bustag, NULL, &device, NULL); 128 1.3 cgd switch (device) { 129 1.1 cgd case 11: 130 1.1 cgd case 12: 131 1.9 cgd kn20aa_irq = ((device - 11) + 0) * 4; 132 1.1 cgd break; 133 1.1 cgd 134 1.1 cgd case 7: 135 1.9 cgd kn20aa_irq = 8; 136 1.1 cgd break; 137 1.1 cgd 138 1.10 cgd case 9: 139 1.10 cgd kn20aa_irq = 12; 140 1.14 cgd break; 141 1.14 cgd 142 1.15 cgd case 6: /* 21040 on AlphaStation 500 */ 143 1.14 cgd kn20aa_irq = 13; 144 1.10 cgd break; 145 1.10 cgd 146 1.1 cgd case 8: 147 1.9 cgd kn20aa_irq = 16; 148 1.1 cgd break; 149 1.1 cgd 150 1.1 cgd default: 151 1.53 matt printf("dec_kn20aa_intr_map: weird device number %d\n", 152 1.1 cgd device); 153 1.53 matt return 1; 154 1.1 cgd } 155 1.1 cgd 156 1.9 cgd kn20aa_irq += buspin - 1; 157 1.1 cgd if (kn20aa_irq > KN20AA_MAX_IRQ) 158 1.44 provos panic("dec_kn20aa_intr_map: kn20aa_irq too large (%d)", 159 1.1 cgd kn20aa_irq); 160 1.1 cgd 161 1.55 thorpej alpha_pci_intr_handle_init(ihp, kn20aa_irq, 0); 162 1.9 cgd return (0); 163 1.3 cgd } 164 1.3 cgd 165 1.55 thorpej static void 166 1.55 thorpej kn20aa_enable_intr(pci_chipset_tag_t pc __unused, int irq) 167 1.1 cgd { 168 1.1 cgd 169 1.1 cgd /* 170 1.8 cgd * From disassembling small bits of the OSF/1 kernel: 171 1.1 cgd * the following appears to enable a given interrupt request. 172 1.1 cgd * "blech." I'd give valuable body parts for better docs or 173 1.1 cgd * for a good decompiler. 174 1.1 cgd */ 175 1.6 cgd alpha_mb(); 176 1.1 cgd REGVAL(0x8780000000L + 0x40L) |= (1 << irq); /* XXX */ 177 1.8 cgd alpha_mb(); 178 1.8 cgd } 179 1.8 cgd 180 1.55 thorpej static void 181 1.55 thorpej kn20aa_disable_intr(pci_chipset_tag_t pc __unused, int irq) 182 1.8 cgd { 183 1.8 cgd 184 1.8 cgd alpha_mb(); 185 1.8 cgd REGVAL(0x8780000000L + 0x40L) &= ~(1 << irq); /* XXX */ 186 1.6 cgd alpha_mb(); 187 1.1 cgd } 188