1 /* $NetBSD: amd756.c,v 1.1 2001/04/19 17:32:40 uch Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1999, by UCHIYAMA Yasushi 42 * All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. The name of the developer may NOT be used to endorse or promote products 50 * derived from this software without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 */ 64 65 /* 66 * Support for the Advanced Micro Devices AMD756 Peripheral Bus Controller. 67 */ 68 69 #include <sys/param.h> 70 #include <sys/systm.h> 71 #include <sys/device.h> 72 #include <sys/malloc.h> 73 74 #include <machine/intr.h> 75 #include <machine/bus.h> 76 77 #include <dev/pci/pcivar.h> 78 #include <dev/pci/pcireg.h> 79 #include <dev/pci/pcidevs.h> 80 81 #include <i386/pci/pci_intr_fixup.h> 82 #include <i386/pci/amd756reg.h> 83 84 struct amd756_handle { 85 bus_space_tag_t ph_iot; 86 bus_space_handle_t ph_regs_ioh; 87 pci_chipset_tag_t ph_pc; 88 pcitag_t ph_tag; 89 }; 90 91 int amd756_getclink __P((pciintr_icu_handle_t, int, int *)); 92 int amd756_get_intr __P((pciintr_icu_handle_t, int, int *)); 93 int amd756_set_intr __P((pciintr_icu_handle_t, int, int)); 94 int amd756_get_trigger __P((pciintr_icu_handle_t, int, int *)); 95 int amd756_set_trigger __P((pciintr_icu_handle_t, int, int)); 96 #ifdef AMD756_DEBUG 97 static void amd756_pir_dump __P((struct amd756_handle *)); 98 #endif 99 100 const struct pciintr_icu amd756_pci_icu = { 101 amd756_getclink, 102 amd756_get_intr, 103 amd756_set_intr, 104 amd756_get_trigger, 105 amd756_set_trigger, 106 }; 107 108 109 int 110 amd756_init(pc, iot, tag, ptagp, phandp) 111 pci_chipset_tag_t pc; 112 bus_space_tag_t iot; 113 pcitag_t tag; 114 pciintr_icu_tag_t *ptagp; 115 pciintr_icu_handle_t *phandp; 116 { 117 struct amd756_handle *ph; 118 119 ph = malloc(sizeof(*ph), M_DEVBUF, M_NOWAIT); 120 if (ph == NULL) 121 return (1); 122 123 ph->ph_iot = iot; 124 ph->ph_pc = pc; 125 ph->ph_tag = tag; 126 127 *ptagp = &amd756_pci_icu; 128 *phandp = ph; 129 130 #ifdef AMD756_DEBUG 131 amd756_pir_dump(ph); 132 #endif 133 134 return (0); 135 } 136 137 int 138 amd756_getclink(v, link, clinkp) 139 pciintr_icu_handle_t v; 140 int link, *clinkp; 141 { 142 if (AMD756_LEGAL_LINK(link - 1) == 0) 143 return (1); 144 145 *clinkp = link - 1; 146 147 return (0); 148 } 149 150 int 151 amd756_get_intr(v, clink, irqp) 152 pciintr_icu_handle_t v; 153 int clink, *irqp; 154 { 155 struct amd756_handle *ph = v; 156 pcireg_t reg; 157 int val; 158 159 if (AMD756_LEGAL_LINK(clink) == 0) 160 return (1); 161 162 reg = AMD756_GET_PIIRQSEL(ph); 163 val = (reg >> (4 * clink)) & 0x0f; 164 *irqp = (val == 0) ? 165 I386_PCI_INTERRUPT_LINE_NO_CONNECTION : val; 166 167 return (0); 168 } 169 170 int 171 amd756_set_intr(v, clink, irq) 172 pciintr_icu_handle_t v; 173 int clink, irq; 174 { 175 struct amd756_handle *ph = v; 176 int val; 177 pcireg_t reg; 178 179 if (AMD756_LEGAL_LINK(clink) == 0 || AMD756_LEGAL_IRQ(irq) == 0) 180 return (1); 181 182 reg = AMD756_GET_PIIRQSEL(ph); 183 amd756_get_intr(v, clink, &val); 184 reg &= ~(0x000f << (4 * clink)); 185 reg |= irq << (4 * clink); 186 AMD756_SET_PIIRQSEL(ph, reg); 187 188 return (0); 189 } 190 191 int 192 amd756_get_trigger(v, irq, triggerp) 193 pciintr_icu_handle_t v; 194 int irq, *triggerp; 195 { 196 struct amd756_handle *ph = v; 197 int i, pciirq; 198 pcireg_t reg; 199 200 if (AMD756_LEGAL_IRQ(irq) == 0) 201 return (1); 202 203 for (i = 0; i <= 3; i++) { 204 amd756_get_intr(v, i, &pciirq); 205 if (pciirq == irq) { 206 reg = AMD756_GET_EDGESEL(ph); 207 if (reg & (1 << i)) 208 *triggerp = IST_EDGE; 209 else 210 *triggerp = IST_LEVEL; 211 break; 212 } 213 } 214 215 return (0); 216 } 217 218 int 219 amd756_set_trigger(v, irq, trigger) 220 pciintr_icu_handle_t v; 221 int irq, trigger; 222 { 223 struct amd756_handle *ph = v; 224 int i, pciirq; 225 pcireg_t reg; 226 227 if (AMD756_LEGAL_IRQ(irq) == 0) 228 return (1); 229 230 for (i = 0; i <= 3; i++) { 231 amd756_get_intr(v, i, &pciirq); 232 if (pciirq == irq) { 233 reg = AMD756_GET_PIIRQSEL(ph); 234 if (trigger == IST_LEVEL) 235 reg &= ~(1 << (4 * i)); 236 else 237 reg |= 1 << (4 * i); 238 AMD756_SET_PIIRQSEL(ph, reg); 239 break; 240 } 241 } 242 243 return (0); 244 } 245 246 #ifdef AMD756_DEBUG 247 static void 248 amd756_pir_dump(ph) 249 struct amd756_handle *ph; 250 { 251 int a, b; 252 253 printf ("AMD756 PCI INTERRUPT ROUTING REGISTERS:\n"); 254 255 a = AMD756_GET_EDGESEL(ph); 256 b = AMD756_GET_PIIRQSEL(ph); 257 258 printf ("TRIGGER: %02x, ROUTING: %04x\n", a, b); 259 } 260 #endif 261