1 1.40 thorpej /* $NetBSD: dma_sbus.c,v 1.40 2022/09/25 18:03:04 thorpej Exp $ */ 2 1.3 pk 3 1.3 pk /*- 4 1.3 pk * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 1.3 pk * All rights reserved. 6 1.3 pk * 7 1.3 pk * This code is derived from software contributed to The NetBSD Foundation 8 1.3 pk * by Paul Kranenburg. 9 1.3 pk * 10 1.3 pk * Redistribution and use in source and binary forms, with or without 11 1.3 pk * modification, are permitted provided that the following conditions 12 1.3 pk * are met: 13 1.3 pk * 1. Redistributions of source code must retain the above copyright 14 1.3 pk * notice, this list of conditions and the following disclaimer. 15 1.3 pk * 2. Redistributions in binary form must reproduce the above copyright 16 1.3 pk * notice, this list of conditions and the following disclaimer in the 17 1.3 pk * documentation and/or other materials provided with the distribution. 18 1.3 pk * 19 1.3 pk * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.3 pk * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.3 pk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.3 pk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.3 pk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.3 pk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.3 pk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.3 pk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.3 pk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.3 pk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.3 pk * POSSIBILITY OF SUCH DAMAGE. 30 1.3 pk */ 31 1.1 pk 32 1.1 pk /* 33 1.1 pk * Copyright (c) 1994 Peter Galbavy. All rights reserved. 34 1.1 pk * 35 1.1 pk * Redistribution and use in source and binary forms, with or without 36 1.1 pk * modification, are permitted provided that the following conditions 37 1.1 pk * are met: 38 1.1 pk * 1. Redistributions of source code must retain the above copyright 39 1.1 pk * notice, this list of conditions and the following disclaimer. 40 1.1 pk * 2. Redistributions in binary form must reproduce the above copyright 41 1.1 pk * notice, this list of conditions and the following disclaimer in the 42 1.1 pk * documentation and/or other materials provided with the distribution. 43 1.1 pk * 3. All advertising materials mentioning features or use of this software 44 1.1 pk * must display the following acknowledgement: 45 1.1 pk * This product includes software developed by Peter Galbavy. 46 1.1 pk * 4. The name of the author may not be used to endorse or promote products 47 1.1 pk * derived from this software without specific prior written permission. 48 1.1 pk * 49 1.1 pk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 50 1.1 pk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 51 1.1 pk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52 1.1 pk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 53 1.1 pk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 54 1.1 pk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 55 1.1 pk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 56 1.1 pk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 57 1.1 pk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 58 1.1 pk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 1.1 pk */ 60 1.7 lukem 61 1.7 lukem #include <sys/cdefs.h> 62 1.40 thorpej __KERNEL_RCSID(0, "$NetBSD: dma_sbus.c,v 1.40 2022/09/25 18:03:04 thorpej Exp $"); 63 1.1 pk 64 1.1 pk #include <sys/param.h> 65 1.1 pk #include <sys/systm.h> 66 1.1 pk #include <sys/kernel.h> 67 1.1 pk #include <sys/errno.h> 68 1.1 pk #include <sys/device.h> 69 1.1 pk 70 1.29 ad #include <sys/bus.h> 71 1.29 ad #include <sys/intr.h> 72 1.1 pk #include <machine/autoconf.h> 73 1.1 pk 74 1.1 pk #include <dev/sbus/sbusvar.h> 75 1.1 pk 76 1.1 pk #include <dev/ic/lsi64854reg.h> 77 1.1 pk #include <dev/ic/lsi64854var.h> 78 1.1 pk 79 1.1 pk struct dma_softc { 80 1.1 pk struct lsi64854_softc sc_lsi64854; /* base device */ 81 1.35 tsutsui /* possible sbus specific stuff here */ 82 1.1 pk }; 83 1.1 pk 84 1.31 tsutsui int dmamatch_sbus(device_t, cfdata_t, void *); 85 1.31 tsutsui void dmaattach_sbus(device_t, device_t, void *); 86 1.1 pk 87 1.24 perry int dmaprint_sbus(void *, const char *); 88 1.1 pk 89 1.24 perry void *dmabus_intr_establish( 90 1.1 pk bus_space_tag_t, 91 1.5 pk int, /*bus interrupt priority*/ 92 1.5 pk int, /*`device class' level*/ 93 1.24 perry int (*)(void *), /*handler*/ 94 1.17 pk void *, /*handler arg*/ 95 1.24 perry void (*) (void)); /*optional fast trap handler*/ 96 1.1 pk 97 1.31 tsutsui CFATTACH_DECL_NEW(dma_sbus, sizeof(struct dma_softc), 98 1.16 thorpej dmamatch_sbus, dmaattach_sbus, NULL, NULL); 99 1.1 pk 100 1.31 tsutsui CFATTACH_DECL_NEW(ledma, sizeof(struct dma_softc), 101 1.16 thorpej dmamatch_sbus, dmaattach_sbus, NULL, NULL); 102 1.1 pk 103 1.1 pk int 104 1.31 tsutsui dmaprint_sbus(void *aux, const char *busname) 105 1.1 pk { 106 1.1 pk struct sbus_attach_args *sa = aux; 107 1.1 pk bus_space_tag_t t = sa->sa_bustag; 108 1.1 pk struct dma_softc *sc = t->cookie; 109 1.1 pk 110 1.1 pk sa->sa_bustag = sc->sc_lsi64854.sc_bustag; /* XXX */ 111 1.1 pk sbus_print(aux, busname); /* XXX */ 112 1.1 pk sa->sa_bustag = t; /* XXX */ 113 1.31 tsutsui return UNCONF; 114 1.1 pk } 115 1.1 pk 116 1.1 pk int 117 1.34 cegger dmamatch_sbus(device_t parent, cfdata_t cf, void *aux) 118 1.1 pk { 119 1.1 pk struct sbus_attach_args *sa = aux; 120 1.1 pk 121 1.31 tsutsui return strcmp(cf->cf_name, sa->sa_name) == 0 || 122 1.31 tsutsui strcmp("espdma", sa->sa_name) == 0; 123 1.1 pk } 124 1.1 pk 125 1.1 pk void 126 1.31 tsutsui dmaattach_sbus(device_t parent, device_t self, void *aux) 127 1.1 pk { 128 1.31 tsutsui struct dma_softc *dsc = device_private(self); 129 1.31 tsutsui struct lsi64854_softc *sc = &dsc->sc_lsi64854; 130 1.1 pk struct sbus_attach_args *sa = aux; 131 1.31 tsutsui struct sbus_softc *sbsc = device_private(parent); 132 1.1 pk bus_space_tag_t sbt; 133 1.1 pk int sbusburst, burst; 134 1.1 pk int node; 135 1.1 pk 136 1.1 pk node = sa->sa_node; 137 1.1 pk 138 1.31 tsutsui sc->sc_dev = self; 139 1.1 pk sc->sc_bustag = sa->sa_bustag; 140 1.1 pk sc->sc_dmatag = sa->sa_dmatag; 141 1.1 pk 142 1.1 pk /* Map registers */ 143 1.11 eeh if (sa->sa_npromvaddrs) { 144 1.11 eeh sbus_promaddr_to_handle(sa->sa_bustag, 145 1.31 tsutsui sa->sa_promvaddrs[0], &sc->sc_regs); 146 1.11 eeh } else { 147 1.10 pk if (sbus_bus_map(sa->sa_bustag, 148 1.31 tsutsui sa->sa_slot, sa->sa_offset, sa->sa_size, 149 1.31 tsutsui 0, &sc->sc_regs) != 0) { 150 1.31 tsutsui aprint_error(": cannot map registers\n"); 151 1.1 pk return; 152 1.1 pk } 153 1.1 pk } 154 1.1 pk 155 1.1 pk /* 156 1.1 pk * Get transfer burst size from PROM and plug it into the 157 1.1 pk * controller registers. This is needed on the Sun4m; do 158 1.1 pk * others need it too? 159 1.1 pk */ 160 1.31 tsutsui sbusburst = sbsc->sc_burst; 161 1.1 pk if (sbusburst == 0) 162 1.1 pk sbusburst = SBUS_BURST_32 - 1; /* 1->16 */ 163 1.1 pk 164 1.21 pk burst = prom_getpropint(node,"burst-sizes", -1); 165 1.1 pk if (burst == -1) 166 1.1 pk /* take SBus burst sizes */ 167 1.1 pk burst = sbusburst; 168 1.1 pk 169 1.1 pk /* Clamp at parent's burst sizes */ 170 1.1 pk burst &= sbusburst; 171 1.1 pk sc->sc_burst = (burst & SBUS_BURST_32) ? 32 : 172 1.1 pk (burst & SBUS_BURST_16) ? 16 : 0; 173 1.1 pk 174 1.31 tsutsui if (device_is_a(self, "ledma")) { 175 1.1 pk char *cabletype; 176 1.31 tsutsui uint32_t csr; 177 1.1 pk /* 178 1.2 pk * Check to see which cable type is currently active and 179 1.2 pk * set the appropriate bit in the ledma csr so that it 180 1.2 pk * gets used. If we didn't netboot, the PROM won't have 181 1.2 pk * the "cable-selection" property; default to TP and then 182 1.2 pk * the user can change it via a "media" option to ifconfig. 183 1.1 pk */ 184 1.21 pk cabletype = prom_getpropstring(node, "cable-selection"); 185 1.1 pk csr = L64854_GCSR(sc); 186 1.1 pk if (strcmp(cabletype, "tpe") == 0) { 187 1.1 pk csr |= E_TP_AUI; 188 1.1 pk } else if (strcmp(cabletype, "aui") == 0) { 189 1.1 pk csr &= ~E_TP_AUI; 190 1.1 pk } else { 191 1.1 pk /* assume TP if nothing there */ 192 1.1 pk csr |= E_TP_AUI; 193 1.1 pk } 194 1.1 pk L64854_SCSR(sc, csr); 195 1.2 pk delay(20000); /* manual says we need a 20ms delay */ 196 1.2 pk sc->sc_channel = L64854_CHANNEL_ENET; 197 1.1 pk } else { 198 1.2 pk sc->sc_channel = L64854_CHANNEL_SCSI; 199 1.1 pk } 200 1.1 pk 201 1.23 pk if ((sbt = bus_space_tag_alloc(sc->sc_bustag, dsc)) == NULL) { 202 1.31 tsutsui aprint_error(": out of memory\n"); 203 1.23 pk return; 204 1.23 pk } 205 1.23 pk sbt->sparc_intr_establish = dmabus_intr_establish; 206 1.1 pk lsi64854_attach(sc); 207 1.1 pk 208 1.1 pk /* Attach children */ 209 1.39 thorpej devhandle_t selfh = device_handle(self); 210 1.1 pk for (node = firstchild(sa->sa_node); node; node = nextsibling(node)) { 211 1.25 christos struct sbus_attach_args sax; 212 1.31 tsutsui sbus_setup_attach_args(sbsc, sbt, sc->sc_dmatag, node, &sax); 213 1.36 thorpej (void)config_found(self, (void *)&sax, dmaprint_sbus, 214 1.39 thorpej CFARGS(.devhandle = prom_node_to_devhandle(selfh, node))); 215 1.25 christos sbus_destroy_attach_args(&sax); 216 1.1 pk } 217 1.1 pk } 218 1.1 pk 219 1.1 pk void * 220 1.31 tsutsui dmabus_intr_establish(bus_space_tag_t t, int pri, int level, 221 1.31 tsutsui int (*handler)(void *), void *arg, void (*fastvec)(void)) 222 1.1 pk { 223 1.1 pk struct lsi64854_softc *sc = t->cookie; 224 1.1 pk 225 1.2 pk /* XXX - for now only le; do esp later */ 226 1.2 pk if (sc->sc_channel == L64854_CHANNEL_ENET) { 227 1.1 pk sc->sc_intrchain = handler; 228 1.1 pk sc->sc_intrchainarg = arg; 229 1.1 pk handler = lsi64854_enet_intr; 230 1.1 pk arg = sc; 231 1.1 pk } 232 1.31 tsutsui return bus_intr_establish(sc->sc_bustag, pri, level, handler, arg); 233 1.1 pk } 234