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