1 1.43 thorpej /* $NetBSD: gtsc.c,v 1.43 2021/08/07 16:18:41 thorpej Exp $ */ 2 1.7 cgd 3 1.1 chopps /* 4 1.1 chopps * Copyright (c) 1982, 1990 The Regents of the University of California. 5 1.1 chopps * All rights reserved. 6 1.1 chopps * 7 1.1 chopps * Redistribution and use in source and binary forms, with or without 8 1.1 chopps * modification, are permitted provided that the following conditions 9 1.1 chopps * are met: 10 1.1 chopps * 1. Redistributions of source code must retain the above copyright 11 1.1 chopps * notice, this list of conditions and the following disclaimer. 12 1.1 chopps * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 chopps * notice, this list of conditions and the following disclaimer in the 14 1.1 chopps * documentation and/or other materials provided with the distribution. 15 1.34 agc * 3. Neither the name of the University nor the names of its contributors 16 1.34 agc * may be used to endorse or promote products derived from this software 17 1.34 agc * without specific prior written permission. 18 1.34 agc * 19 1.34 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.34 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.34 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.34 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.34 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.34 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.34 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.34 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.34 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.34 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.34 agc * SUCH DAMAGE. 30 1.34 agc * 31 1.34 agc * @(#)dma.c 32 1.34 agc */ 33 1.34 agc 34 1.34 agc /* 35 1.34 agc * Copyright (c) 1994 Christian E. Hopps 36 1.34 agc * 37 1.34 agc * Redistribution and use in source and binary forms, with or without 38 1.34 agc * modification, are permitted provided that the following conditions 39 1.34 agc * are met: 40 1.34 agc * 1. Redistributions of source code must retain the above copyright 41 1.34 agc * notice, this list of conditions and the following disclaimer. 42 1.34 agc * 2. Redistributions in binary form must reproduce the above copyright 43 1.34 agc * notice, this list of conditions and the following disclaimer in the 44 1.34 agc * documentation and/or other materials provided with the distribution. 45 1.1 chopps * 3. All advertising materials mentioning features or use of this software 46 1.1 chopps * must display the following acknowledgement: 47 1.1 chopps * This product includes software developed by the University of 48 1.1 chopps * California, Berkeley and its contributors. 49 1.1 chopps * 4. Neither the name of the University nor the names of its contributors 50 1.1 chopps * may be used to endorse or promote products derived from this software 51 1.1 chopps * without specific prior written permission. 52 1.1 chopps * 53 1.1 chopps * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 1.1 chopps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 1.1 chopps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 1.1 chopps * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 1.1 chopps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 1.1 chopps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 1.1 chopps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 1.1 chopps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 1.1 chopps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 1.1 chopps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 1.1 chopps * SUCH DAMAGE. 64 1.1 chopps * 65 1.1 chopps * @(#)dma.c 66 1.1 chopps */ 67 1.30 aymeric 68 1.30 aymeric #include <sys/cdefs.h> 69 1.43 thorpej __KERNEL_RCSID(0, "$NetBSD: gtsc.c,v 1.43 2021/08/07 16:18:41 thorpej Exp $"); 70 1.30 aymeric 71 1.1 chopps #include <sys/param.h> 72 1.1 chopps #include <sys/systm.h> 73 1.1 chopps #include <sys/kernel.h> 74 1.1 chopps #include <sys/device.h> 75 1.37 ad #include <sys/intr.h> 76 1.40 phx #include <machine/cpu.h> 77 1.22 bouyer #include <dev/scsipi/scsi_all.h> 78 1.22 bouyer #include <dev/scsipi/scsipi_all.h> 79 1.22 bouyer #include <dev/scsipi/scsiconf.h> 80 1.1 chopps #include <amiga/amiga/custom.h> 81 1.1 chopps #include <amiga/amiga/cc.h> 82 1.1 chopps #include <amiga/amiga/device.h> 83 1.11 chopps #include <amiga/amiga/isr.h> 84 1.1 chopps #include <amiga/dev/dmavar.h> 85 1.1 chopps #include <amiga/dev/sbicreg.h> 86 1.1 chopps #include <amiga/dev/sbicvar.h> 87 1.1 chopps #include <amiga/dev/gtscreg.h> 88 1.9 chopps #include <amiga/dev/zbusvar.h> 89 1.1 chopps #include <amiga/dev/gvpbusvar.h> 90 1.1 chopps 91 1.41 chs void gtscattach(device_t, device_t, void *); 92 1.41 chs int gtscmatch(device_t, cfdata_t, void *); 93 1.1 chopps 94 1.29 aymeric void gtsc_enintr(struct sbic_softc *); 95 1.29 aymeric void gtsc_dmastop(struct sbic_softc *); 96 1.29 aymeric int gtsc_dmanext(struct sbic_softc *); 97 1.29 aymeric int gtsc_dmaintr(void *); 98 1.29 aymeric int gtsc_dmago(struct sbic_softc *, char *, int, int); 99 1.1 chopps 100 1.15 veego #ifdef DEBUG 101 1.29 aymeric void gtsc_dump(void); 102 1.15 veego #endif 103 1.15 veego 104 1.1 chopps int gtsc_maxdma = 0; /* Maximum size per DMA transfer */ 105 1.1 chopps int gtsc_dmamask = 0; 106 1.1 chopps int gtsc_dmabounce = 0; 107 1.12 chopps int gtsc_clock_override = 0; 108 1.1 chopps 109 1.1 chopps #ifdef DEBUG 110 1.1 chopps int gtsc_debug = 0; 111 1.1 chopps #endif 112 1.1 chopps 113 1.41 chs CFATTACH_DECL_NEW(gtsc, sizeof(struct sbic_softc), 114 1.32 thorpej gtscmatch, gtscattach, NULL, NULL); 115 1.14 thorpej 116 1.1 chopps int 117 1.41 chs gtscmatch(device_t parent, cfdata_t cf, void *aux) 118 1.1 chopps { 119 1.1 chopps struct gvpbus_args *gap; 120 1.1 chopps 121 1.41 chs gap = aux; 122 1.1 chopps if (gap->flags & GVP_SCSI) 123 1.1 chopps return(1); 124 1.1 chopps return(0); 125 1.1 chopps } 126 1.1 chopps 127 1.1 chopps /* 128 1.29 aymeric * attach all devices on our board. 129 1.1 chopps */ 130 1.1 chopps void 131 1.41 chs gtscattach(device_t parent, device_t self, void *aux) 132 1.1 chopps { 133 1.1 chopps volatile struct sdmac *rp; 134 1.1 chopps struct gvpbus_args *gap; 135 1.41 chs struct sbic_softc *sc = device_private(self); 136 1.28 bouyer struct scsipi_adapter *adapt = &sc->sc_adapter; 137 1.28 bouyer struct scsipi_channel *chan = &sc->sc_channel; 138 1.1 chopps 139 1.41 chs gap = aux; 140 1.41 chs sc->sc_dev = self; 141 1.29 aymeric sc->sc_cregs = rp = gap->zargs.va; 142 1.4 chopps 143 1.1 chopps /* 144 1.1 chopps * disable ints and reset bank register 145 1.1 chopps */ 146 1.1 chopps rp->CNTR = 0; 147 1.39 phx amiga_membarrier(); 148 1.39 phx if ((gap->flags & GVP_NOBANK) == 0) { 149 1.4 chopps rp->bank = 0; 150 1.39 phx amiga_membarrier(); 151 1.39 phx } 152 1.29 aymeric 153 1.1 chopps sc->sc_dmago = gtsc_dmago; 154 1.13 chopps sc->sc_enintr = gtsc_enintr; 155 1.1 chopps sc->sc_dmanext = gtsc_dmanext; 156 1.1 chopps sc->sc_dmastop = gtsc_dmastop; 157 1.1 chopps sc->sc_dmacmd = 0; 158 1.1 chopps 159 1.1 chopps sc->sc_flags |= SBICF_BADDMA; 160 1.1 chopps if (gtsc_dmamask) 161 1.1 chopps sc->sc_dmamask = gtsc_dmamask; 162 1.1 chopps else if (gap->flags & GVP_24BITDMA) 163 1.1 chopps sc->sc_dmamask = ~0x00ffffff; 164 1.1 chopps else if (gap->flags & GVP_25BITDMA) 165 1.1 chopps sc->sc_dmamask = ~0x01ffffff; 166 1.1 chopps else 167 1.1 chopps sc->sc_dmamask = ~0x07ffffff; 168 1.19 christos printf(": dmamask 0x%lx", ~sc->sc_dmamask); 169 1.29 aymeric 170 1.4 chopps if ((gap->flags & GVP_NOBANK) == 0) 171 1.4 chopps sc->gtsc_bankmask = (~sc->sc_dmamask >> 18) & 0x01c0; 172 1.1 chopps 173 1.12 chopps #if 0 174 1.1 chopps /* 175 1.29 aymeric * if the user requests a bounce buffer or 176 1.33 wiz * the users kva space is not ztwo and DMA needs it 177 1.1 chopps * try and allocate a bounce buffer. If we allocate 178 1.1 chopps * one and it is in ztwo space leave maxdma to user 179 1.1 chopps * setting or default to MAXPHYS else the address must 180 1.1 chopps * be on the chip bus so decrease it to either the users 181 1.1 chopps * setting or 1024 bytes. 182 1.1 chopps * 183 1.1 chopps * XXX this needs to change if we move to multiple memory segments. 184 1.1 chopps */ 185 1.1 chopps if (gtsc_dmabounce || kvtop(sc) & sc->sc_dmamask) { 186 1.12 chopps sc->sc_dmabuffer = (char *) alloc_z2mem(MAXPHYS * 8); /* XXX */ 187 1.1 chopps if (isztwomem(sc->sc_dmabuffer)) 188 1.19 christos printf(" bounce pa 0x%x", kvtop(sc->sc_dmabuffer)); 189 1.1 chopps else if (gtsc_maxdma == 0) { 190 1.1 chopps gtsc_maxdma = 1024; 191 1.29 aymeric printf(" bounce pa 0x%x", 192 1.1 chopps PREP_DMA_MEM(sc->sc_dmabuffer)); 193 1.1 chopps } 194 1.1 chopps } 195 1.12 chopps #endif 196 1.1 chopps if (gtsc_maxdma == 0) 197 1.1 chopps gtsc_maxdma = MAXPHYS; 198 1.1 chopps 199 1.19 christos printf(" flags %x", gap->flags); 200 1.19 christos printf(" maxdma %d\n", gtsc_maxdma); 201 1.1 chopps 202 1.24 is sc->sc_sbic.sbic_asr_p = (volatile unsigned char *)rp + 0x61; 203 1.24 is sc->sc_sbic.sbic_value_p = (volatile unsigned char *)rp + 0x63; 204 1.39 phx amiga_membarrier(); 205 1.24 is 206 1.12 chopps sc->sc_clkfreq = gtsc_clock_override ? gtsc_clock_override : 207 1.12 chopps ((gap->flags & GVP_14MHZ) ? 143 : 72); 208 1.36 lukem printf("sc_clkfreg: %ld.%ld MHz\n", sc->sc_clkfreq / 10, sc->sc_clkfreq % 10); 209 1.1 chopps 210 1.28 bouyer /* 211 1.28 bouyer * Fill in the scsipi_adapter. 212 1.28 bouyer */ 213 1.28 bouyer memset(adapt, 0, sizeof(*adapt)); 214 1.41 chs adapt->adapt_dev = self; 215 1.28 bouyer adapt->adapt_nchannels = 1; 216 1.28 bouyer adapt->adapt_openings = 7; 217 1.28 bouyer adapt->adapt_max_periph = 1; 218 1.28 bouyer adapt->adapt_request = sbic_scsipi_request; 219 1.28 bouyer adapt->adapt_minphys = sbic_minphys; 220 1.26 thorpej 221 1.28 bouyer /* 222 1.28 bouyer * Fill in the scsipi_channel. 223 1.28 bouyer */ 224 1.28 bouyer memset(chan, 0, sizeof(*chan)); 225 1.28 bouyer chan->chan_adapter = adapt; 226 1.28 bouyer chan->chan_bustype = &scsi_bustype; 227 1.29 aymeric chan->chan_channel = 0; 228 1.28 bouyer chan->chan_ntargets = 8; 229 1.28 bouyer chan->chan_nluns = 8; 230 1.28 bouyer chan->chan_id = 7; 231 1.12 chopps 232 1.12 chopps sbicinit(sc); 233 1.1 chopps 234 1.11 chopps sc->sc_isr.isr_intr = gtsc_dmaintr; 235 1.11 chopps sc->sc_isr.isr_arg = sc; 236 1.11 chopps sc->sc_isr.isr_ipl = 2; 237 1.11 chopps add_isr(&sc->sc_isr); 238 1.1 chopps 239 1.1 chopps /* 240 1.1 chopps * attach all scsi units on us 241 1.1 chopps */ 242 1.43 thorpej config_found(self, chan, scsiprint, CFARGS_NONE); 243 1.1 chopps } 244 1.1 chopps 245 1.1 chopps void 246 1.29 aymeric gtsc_enintr(struct sbic_softc *dev) 247 1.1 chopps { 248 1.1 chopps volatile struct sdmac *sdp; 249 1.1 chopps 250 1.1 chopps sdp = dev->sc_cregs; 251 1.1 chopps 252 1.13 chopps dev->sc_flags |= SBICF_INTR; 253 1.13 chopps sdp->CNTR = GVP_CNTR_INTEN; 254 1.39 phx amiga_membarrier(); 255 1.1 chopps } 256 1.1 chopps 257 1.1 chopps int 258 1.29 aymeric gtsc_dmago(struct sbic_softc *dev, char *addr, int count, int flags) 259 1.1 chopps { 260 1.1 chopps volatile struct sdmac *sdp; 261 1.1 chopps 262 1.1 chopps sdp = dev->sc_cregs; 263 1.1 chopps /* 264 1.1 chopps * Set up the command word based on flags 265 1.1 chopps */ 266 1.1 chopps dev->sc_dmacmd = GVP_CNTR_INTEN; 267 1.1 chopps if ((flags & DMAGO_READ) == 0) 268 1.1 chopps dev->sc_dmacmd |= GVP_CNTR_DDIR; 269 1.1 chopps 270 1.1 chopps #ifdef DEBUG 271 1.1 chopps if (gtsc_debug & DDB_IO) 272 1.19 christos printf("gtsc_dmago: cmd %x\n", dev->sc_dmacmd); 273 1.1 chopps #endif 274 1.1 chopps dev->sc_flags |= SBICF_INTR; 275 1.1 chopps sdp->CNTR = dev->sc_dmacmd; 276 1.39 phx amiga_membarrier(); 277 1.13 chopps if((u_int)dev->sc_cur->dc_addr & dev->sc_dmamask) { 278 1.13 chopps #if 1 279 1.19 christos printf("gtsc_dmago: pa %p->%lx dmacmd %x", 280 1.13 chopps dev->sc_cur->dc_addr, 281 1.13 chopps (u_int)dev->sc_cur->dc_addr & ~dev->sc_dmamask, 282 1.13 chopps dev->sc_dmacmd); 283 1.13 chopps #endif 284 1.13 chopps sdp->ACR = 0x00f80000; /***********************************/ 285 1.13 chopps } else 286 1.13 chopps sdp->ACR = (u_int) dev->sc_cur->dc_addr; 287 1.39 phx amiga_membarrier(); 288 1.39 phx if (dev->gtsc_bankmask) { 289 1.29 aymeric sdp->bank = 290 1.4 chopps dev->gtsc_bankmask & (((u_int)dev->sc_cur->dc_addr) >> 18); 291 1.39 phx amiga_membarrier(); 292 1.39 phx } 293 1.1 chopps sdp->ST_DMA = 1; 294 1.39 phx amiga_membarrier(); 295 1.1 chopps 296 1.1 chopps /* 297 1.1 chopps * restrict transfer count to maximum 298 1.1 chopps */ 299 1.1 chopps if (dev->sc_tcnt > gtsc_maxdma) 300 1.1 chopps dev->sc_tcnt = gtsc_maxdma; 301 1.13 chopps #if 1 302 1.13 chopps if((u_int)dev->sc_cur->dc_addr & dev->sc_dmamask) 303 1.19 christos printf(" tcnt %ld\n", dev->sc_tcnt); 304 1.13 chopps #endif 305 1.1 chopps return(dev->sc_tcnt); 306 1.1 chopps } 307 1.1 chopps 308 1.1 chopps void 309 1.29 aymeric gtsc_dmastop(struct sbic_softc *dev) 310 1.1 chopps { 311 1.1 chopps volatile struct sdmac *sdp; 312 1.1 chopps int s; 313 1.1 chopps 314 1.1 chopps sdp = dev->sc_cregs; 315 1.1 chopps 316 1.1 chopps #ifdef DEBUG 317 1.1 chopps if (gtsc_debug & DDB_FOLLOW) 318 1.19 christos printf("gtsc_dmastop()\n"); 319 1.1 chopps #endif 320 1.1 chopps if (dev->sc_dmacmd) { 321 1.29 aymeric /* 322 1.33 wiz * clear possible interrupt and stop DMA 323 1.1 chopps */ 324 1.1 chopps s = splbio(); 325 1.1 chopps sdp->CNTR &= ~GVP_CNTR_INT_P; 326 1.39 phx amiga_membarrier(); 327 1.1 chopps sdp->SP_DMA = 1; 328 1.39 phx amiga_membarrier(); 329 1.1 chopps dev->sc_dmacmd = 0; 330 1.1 chopps splx(s); 331 1.1 chopps } 332 1.1 chopps } 333 1.1 chopps 334 1.1 chopps int 335 1.29 aymeric gtsc_dmaintr(void *arg) 336 1.1 chopps { 337 1.15 veego struct sbic_softc *dev = arg; 338 1.1 chopps volatile struct sdmac *sdp; 339 1.11 chopps int stat; 340 1.1 chopps 341 1.11 chopps sdp = dev->sc_cregs; 342 1.11 chopps stat = sdp->CNTR; 343 1.39 phx amiga_membarrier(); 344 1.11 chopps if ((stat & GVP_CNTR_INT_P) == 0) 345 1.11 chopps return (0); 346 1.1 chopps #ifdef DEBUG 347 1.11 chopps if (gtsc_debug & DDB_FOLLOW) 348 1.41 chs printf("%s: dmaintr 0x%x\n", device_xname(dev->sc_dev), stat); 349 1.1 chopps #endif 350 1.11 chopps if (dev->sc_flags & SBICF_INTR) 351 1.11 chopps if (sbicintr(dev)) 352 1.11 chopps return (1); 353 1.11 chopps return(0); 354 1.1 chopps } 355 1.1 chopps 356 1.1 chopps 357 1.1 chopps int 358 1.29 aymeric gtsc_dmanext(struct sbic_softc *dev) 359 1.1 chopps { 360 1.1 chopps volatile struct sdmac *sdp; 361 1.1 chopps 362 1.1 chopps sdp = dev->sc_cregs; 363 1.1 chopps 364 1.1 chopps if (dev->sc_cur > dev->sc_last) { 365 1.1 chopps /* shouldn't happen !! */ 366 1.19 christos printf("gtsc_dmanext at end !!!\n"); 367 1.1 chopps gtsc_dmastop(dev); 368 1.1 chopps return(0); 369 1.1 chopps } 370 1.29 aymeric /* 371 1.33 wiz * clear possible interrupt and stop DMA 372 1.1 chopps */ 373 1.1 chopps sdp->CNTR &= ~GVP_CNTR_INT_P; 374 1.39 phx amiga_membarrier(); 375 1.1 chopps sdp->SP_DMA = 1; 376 1.39 phx amiga_membarrier(); 377 1.1 chopps 378 1.1 chopps sdp->CNTR = dev->sc_dmacmd; 379 1.39 phx amiga_membarrier(); 380 1.1 chopps sdp->ACR = (u_int) dev->sc_cur->dc_addr; 381 1.39 phx amiga_membarrier(); 382 1.39 phx if (dev->gtsc_bankmask) { 383 1.29 aymeric sdp->bank = 384 1.1 chopps dev->gtsc_bankmask & ((u_int)dev->sc_cur->dc_addr >> 18); 385 1.39 phx amiga_membarrier(); 386 1.39 phx } 387 1.1 chopps sdp->ST_DMA = 1; 388 1.39 phx amiga_membarrier(); 389 1.1 chopps 390 1.1 chopps dev->sc_tcnt = dev->sc_cur->dc_count << 1; 391 1.1 chopps if (dev->sc_tcnt > gtsc_maxdma) 392 1.1 chopps dev->sc_tcnt = gtsc_maxdma; 393 1.1 chopps #ifdef DEBUG 394 1.1 chopps if (gtsc_debug & DDB_FOLLOW) 395 1.19 christos printf("gtsc_dmanext ret: %ld\n", dev->sc_tcnt); 396 1.1 chopps #endif 397 1.1 chopps return(dev->sc_tcnt); 398 1.1 chopps } 399 1.1 chopps 400 1.1 chopps #ifdef DEBUG 401 1.1 chopps void 402 1.29 aymeric gtsc_dump(void) 403 1.1 chopps { 404 1.23 thorpej extern struct cfdriver gtsc_cd; 405 1.38 cegger struct sbic_softc *sc; 406 1.13 chopps int i; 407 1.1 chopps 408 1.38 cegger for (i = 0; i < gtsc_cd.cd_ndevs; ++i) { 409 1.38 cegger sc = device_lookup_private(>sc_cd, i); 410 1.38 cegger if (sc != NULL) 411 1.38 cegger sbic_dump(sc); 412 1.38 cegger } 413 1.1 chopps } 414 1.1 chopps #endif 415