1 1.33 thorpej /* $NetBSD: pci_1000a.c,v 1.33 2021/07/04 22:42:36 thorpej Exp $ */ 2 1.1 ross 3 1.1 ross /* 4 1.1 ross * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 1.1 ross * All rights reserved. 6 1.1 ross * 7 1.1 ross * This code is based on pci_kn20aa.c, written by Chris G. Demetriou at 8 1.1 ross * Carnegie-Mellon University. Platform support for Noritake, Pintake, and 9 1.1 ross * Corelle by Ross Harvey with copyright assignment by permission of Avalon 10 1.1 ross * Computer Systems, Inc. 11 1.1 ross * 12 1.1 ross * Redistribution and use in source and binary forms, with or without 13 1.1 ross * modification, are permitted provided that the following conditions 14 1.1 ross * are met: 15 1.1 ross * 1. Redistributions of source code must retain the above copyright 16 1.1 ross * notice, this list of conditions and the following disclaimer. 17 1.1 ross * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 ross * notice, this list of conditions and the following disclaimer in the 19 1.1 ross * documentation and/or other materials provided with the distribution. 20 1.1 ross * 21 1.1 ross * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 1.1 ross * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 1.1 ross * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 1.1 ross * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 1.1 ross * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 ross * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 ross * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 ross * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 ross * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 ross * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 1.1 ross * POSSIBILITY OF SUCH DAMAGE. 32 1.1 ross */ 33 1.1 ross 34 1.1 ross /* 35 1.1 ross * Copyright (c) 1995, 1996 Carnegie-Mellon University. 36 1.1 ross * All rights reserved. 37 1.1 ross * 38 1.1 ross * Author: Chris G. Demetriou 39 1.26 matt * 40 1.1 ross * Permission to use, copy, modify and distribute this software and 41 1.1 ross * its documentation is hereby granted, provided that both the copyright 42 1.1 ross * notice and this permission notice appear in all copies of the 43 1.1 ross * software, derivative works or modified versions, and any portions 44 1.1 ross * thereof, and that both notices appear in supporting documentation. 45 1.26 matt * 46 1.26 matt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 47 1.26 matt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 48 1.1 ross * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 49 1.26 matt * 50 1.1 ross * Carnegie Mellon requests users of this software to return to 51 1.1 ross * 52 1.1 ross * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 53 1.1 ross * School of Computer Science 54 1.1 ross * Carnegie Mellon University 55 1.1 ross * Pittsburgh PA 15213-3890 56 1.1 ross * 57 1.1 ross * any improvements or extensions that they make and grant Carnegie the 58 1.1 ross * rights to redistribute these changes. 59 1.1 ross */ 60 1.1 ross 61 1.1 ross #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 62 1.1 ross 63 1.33 thorpej __KERNEL_RCSID(0, "$NetBSD: pci_1000a.c,v 1.33 2021/07/04 22:42:36 thorpej Exp $"); 64 1.1 ross 65 1.1 ross #include <sys/types.h> 66 1.1 ross #include <sys/param.h> 67 1.1 ross #include <sys/time.h> 68 1.1 ross #include <sys/systm.h> 69 1.1 ross #include <sys/errno.h> 70 1.1 ross #include <sys/device.h> 71 1.1 ross #include <sys/syslog.h> 72 1.1 ross 73 1.1 ross #include <machine/autoconf.h> 74 1.30 thorpej #include <machine/rpb.h> 75 1.1 ross 76 1.1 ross #include <dev/pci/pcireg.h> 77 1.1 ross #include <dev/pci/pcivar.h> 78 1.1 ross 79 1.1 ross #include "sio.h" 80 1.9 thorpej #if NSIO > 0 || NPCEB > 0 81 1.1 ross #include <alpha/pci/siovar.h> 82 1.1 ross #endif 83 1.1 ross 84 1.11 thorpej #define PCI_NIRQ 32 85 1.11 thorpej #define PCI_STRAY_MAX 5 86 1.2 ross 87 1.1 ross #define IMR2IRQ(bn) ((bn) - 1) 88 1.1 ross #define IRQ2IMR(irq) ((irq) + 1) 89 1.1 ross 90 1.1 ross static bus_space_tag_t mystery_icu_iot; 91 1.1 ross static bus_space_handle_t mystery_icu_ioh[2]; 92 1.1 ross 93 1.29 thorpej static int dec_1000a_intr_map(const struct pci_attach_args *, 94 1.29 thorpej pci_intr_handle_t *); 95 1.29 thorpej 96 1.29 thorpej static void dec_1000a_enable_intr(pci_chipset_tag_t, int irq); 97 1.29 thorpej static void dec_1000a_disable_intr(pci_chipset_tag_t, int irq); 98 1.29 thorpej static void pci_1000a_imi(void); 99 1.1 ross 100 1.30 thorpej static void 101 1.30 thorpej pci_1000a_pickintr(void *core, bus_space_tag_t iot, bus_space_tag_t memt, 102 1.30 thorpej pci_chipset_tag_t pc) 103 1.1 ross { 104 1.2 ross 105 1.1 ross mystery_icu_iot = iot; 106 1.1 ross 107 1.1 ross if (bus_space_map(iot, 0x54a, 2, 0, mystery_icu_ioh + 0) 108 1.1 ross || bus_space_map(iot, 0x54c, 2, 0, mystery_icu_ioh + 1)) 109 1.1 ross panic("pci_1000a_pickintr"); 110 1.29 thorpej 111 1.26 matt pc->pc_intr_v = core; 112 1.26 matt pc->pc_intr_map = dec_1000a_intr_map; 113 1.29 thorpej pc->pc_intr_string = alpha_pci_generic_intr_string; 114 1.29 thorpej pc->pc_intr_evcnt = alpha_pci_generic_intr_evcnt; 115 1.29 thorpej pc->pc_intr_establish = alpha_pci_generic_intr_establish; 116 1.29 thorpej pc->pc_intr_disestablish = alpha_pci_generic_intr_disestablish; 117 1.1 ross 118 1.1 ross pc->pc_pciide_compat_intr_establish = NULL; 119 1.1 ross 120 1.31 thorpej pc->pc_intr_desc = "dec 1000a"; 121 1.29 thorpej pc->pc_vecbase = 0x900; 122 1.29 thorpej pc->pc_nirq = PCI_NIRQ; 123 1.29 thorpej 124 1.29 thorpej pc->pc_intr_enable = dec_1000a_enable_intr; 125 1.29 thorpej pc->pc_intr_disable = dec_1000a_disable_intr; 126 1.29 thorpej 127 1.32 thorpej pci_1000a_imi(); 128 1.32 thorpej 129 1.32 thorpej alpha_pci_intr_alloc(pc, PCI_STRAY_MAX); 130 1.11 thorpej 131 1.9 thorpej #if NSIO > 0 || NPCEB > 0 132 1.1 ross sio_intr_setup(pc, iot); 133 1.1 ross #endif 134 1.1 ross } 135 1.30 thorpej ALPHA_PCI_INTR_INIT(ST_DEC_1000A, pci_1000a_pickintr) 136 1.1 ross 137 1.26 matt int 138 1.25 dyoung dec_1000a_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp) 139 1.1 ross { 140 1.13 sommerfe pcitag_t bustag = pa->pa_intrtag; 141 1.13 sommerfe int buspin = pa->pa_intrpin; 142 1.13 sommerfe pci_chipset_tag_t pc = pa->pa_pc; 143 1.27 skrll int imrbit, device = 0; /* XXX gcc */ 144 1.1 ross /* 145 1.1 ross * Get bit number in mystery ICU imr 146 1.1 ross */ 147 1.1 ross static const signed char imrmap[][4] = { 148 1.1 ross # define IRQSPLIT(o) { (o), (o)+1, (o)+16, (o)+16+1 } 149 1.1 ross # define IRQNONE { 0, 0, 0, 0 } 150 1.1 ross /* 0 */ { 1, 0, 0, 0 }, /* Noritake and Pintake */ 151 1.1 ross /* 1 */ IRQSPLIT(8), 152 1.1 ross /* 2 */ IRQSPLIT(10), 153 1.1 ross /* 3 */ IRQSPLIT(12), 154 1.1 ross /* 4 */ IRQSPLIT(14), 155 1.1 ross /* 5 */ { 1, 0, 0, 0 }, /* Corelle */ 156 1.1 ross /* 6 */ { 10, 0, 0, 0 }, /* Corelle */ 157 1.1 ross /* 7 */ IRQNONE, 158 1.6 ross /* 8 */ { 1, 0, 0, 0 }, /* isp behind ppb */ 159 1.1 ross /* 9 */ IRQNONE, 160 1.1 ross /* 10 */ IRQNONE, 161 1.1 ross /* 11 */ IRQSPLIT(2), 162 1.1 ross /* 12 */ IRQSPLIT(4), 163 1.1 ross /* 13 */ IRQSPLIT(6), 164 1.1 ross /* 14 */ IRQSPLIT(8) /* Corelle */ 165 1.1 ross }; 166 1.1 ross 167 1.1 ross if (buspin == 0) /* No IRQ used. */ 168 1.1 ross return 1; 169 1.1 ross if (!(1 <= buspin && buspin <= 4)) 170 1.1 ross goto bad; 171 1.15 thorpej pci_decompose_tag(pc, bustag, NULL, &device, NULL); 172 1.1 ross if (0 <= device && device < sizeof imrmap / sizeof imrmap[0]) { 173 1.6 ross if (device == 0) 174 1.6 ross printf("dec_1000a_intr_map: ?! UNEXPECTED DEV 0\n"); 175 1.1 ross imrbit = imrmap[device][buspin - 1]; 176 1.1 ross if (imrbit) { 177 1.29 thorpej alpha_pci_intr_handle_init(ihp, IMR2IRQ(imrbit), 0); 178 1.1 ross return 0; 179 1.1 ross } 180 1.1 ross } 181 1.1 ross bad: printf("dec_1000a_intr_map: can't map dev %d pin %d\n", device, buspin); 182 1.1 ross return 1; 183 1.1 ross } 184 1.1 ross 185 1.1 ross /* 186 1.1 ross * Read and write the mystery ICU IMR registers 187 1.1 ross */ 188 1.1 ross 189 1.1 ross #define IR(h) bus_space_read_2(mystery_icu_iot, mystery_icu_ioh[h], 0) 190 1.1 ross #define IW(h, v) bus_space_write_2(mystery_icu_iot, mystery_icu_ioh[h], 0, (v)) 191 1.1 ross 192 1.1 ross /* 193 1.1 ross * Enable and disable interrupts at the ICU level 194 1.1 ross */ 195 1.1 ross 196 1.1 ross static void 197 1.29 thorpej dec_1000a_enable_intr(pci_chipset_tag_t pc __unused, int irq) 198 1.1 ross { 199 1.1 ross int imrval = IRQ2IMR(irq); 200 1.1 ross int i = imrval >= 16; 201 1.1 ross 202 1.1 ross IW(i, IR(i) | 1 << (imrval & 0xf)); 203 1.1 ross } 204 1.1 ross 205 1.1 ross static void 206 1.29 thorpej dec_1000a_disable_intr(pci_chipset_tag_t pc __unused, int irq) 207 1.1 ross { 208 1.1 ross int imrval = IRQ2IMR(irq); 209 1.1 ross int i = imrval >= 16; 210 1.1 ross 211 1.1 ross IW(i, IR(i) & ~(1 << (imrval & 0xf))); 212 1.1 ross } 213 1.29 thorpej 214 1.1 ross /* 215 1.1 ross * Initialize mystery ICU 216 1.1 ross */ 217 1.1 ross static void 218 1.26 matt pci_1000a_imi(void) 219 1.1 ross { 220 1.1 ross IW(0, IR(0) & 1); 221 1.1 ross IW(1, IR(0) & 3); 222 1.1 ross } 223