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