1 /* $NetBSD: gtsc.c,v 1.38 2008/06/13 08:13:37 cegger 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.38 2008/06/13 08:13:37 cegger 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 <dev/scsipi/scsi_all.h> 77 #include <dev/scsipi/scsipi_all.h> 78 #include <dev/scsipi/scsiconf.h> 79 #include <amiga/amiga/custom.h> 80 #include <amiga/amiga/cc.h> 81 #include <amiga/amiga/device.h> 82 #include <amiga/amiga/isr.h> 83 #include <amiga/dev/dmavar.h> 84 #include <amiga/dev/sbicreg.h> 85 #include <amiga/dev/sbicvar.h> 86 #include <amiga/dev/gtscreg.h> 87 #include <amiga/dev/zbusvar.h> 88 #include <amiga/dev/gvpbusvar.h> 89 90 void gtscattach(struct device *, struct device *, void *); 91 int gtscmatch(struct device *, struct cfdata *, void *); 92 93 void gtsc_enintr(struct sbic_softc *); 94 void gtsc_dmastop(struct sbic_softc *); 95 int gtsc_dmanext(struct sbic_softc *); 96 int gtsc_dmaintr(void *); 97 int gtsc_dmago(struct sbic_softc *, char *, int, int); 98 99 #ifdef DEBUG 100 void gtsc_dump(void); 101 #endif 102 103 int gtsc_maxdma = 0; /* Maximum size per DMA transfer */ 104 int gtsc_dmamask = 0; 105 int gtsc_dmabounce = 0; 106 int gtsc_clock_override = 0; 107 108 #ifdef DEBUG 109 int gtsc_debug = 0; 110 #endif 111 112 CFATTACH_DECL(gtsc, sizeof(struct sbic_softc), 113 gtscmatch, gtscattach, NULL, NULL); 114 115 int 116 gtscmatch(struct device *pdp, struct cfdata *cfp, void *auxp) 117 { 118 struct gvpbus_args *gap; 119 120 gap = auxp; 121 if (gap->flags & GVP_SCSI) 122 return(1); 123 return(0); 124 } 125 126 /* 127 * attach all devices on our board. 128 */ 129 void 130 gtscattach(struct device *pdp, struct device *dp, void *auxp) 131 { 132 volatile struct sdmac *rp; 133 struct gvpbus_args *gap; 134 struct sbic_softc *sc = (struct sbic_softc *)dp; 135 struct scsipi_adapter *adapt = &sc->sc_adapter; 136 struct scsipi_channel *chan = &sc->sc_channel; 137 138 gap = auxp; 139 sc->sc_cregs = rp = gap->zargs.va; 140 141 /* 142 * disable ints and reset bank register 143 */ 144 rp->CNTR = 0; 145 if ((gap->flags & GVP_NOBANK) == 0) 146 rp->bank = 0; 147 148 sc->sc_dmago = gtsc_dmago; 149 sc->sc_enintr = gtsc_enintr; 150 sc->sc_dmanext = gtsc_dmanext; 151 sc->sc_dmastop = gtsc_dmastop; 152 sc->sc_dmacmd = 0; 153 154 sc->sc_flags |= SBICF_BADDMA; 155 if (gtsc_dmamask) 156 sc->sc_dmamask = gtsc_dmamask; 157 else if (gap->flags & GVP_24BITDMA) 158 sc->sc_dmamask = ~0x00ffffff; 159 else if (gap->flags & GVP_25BITDMA) 160 sc->sc_dmamask = ~0x01ffffff; 161 else 162 sc->sc_dmamask = ~0x07ffffff; 163 printf(": dmamask 0x%lx", ~sc->sc_dmamask); 164 165 if ((gap->flags & GVP_NOBANK) == 0) 166 sc->gtsc_bankmask = (~sc->sc_dmamask >> 18) & 0x01c0; 167 168 #if 0 169 /* 170 * if the user requests a bounce buffer or 171 * the users kva space is not ztwo and DMA needs it 172 * try and allocate a bounce buffer. If we allocate 173 * one and it is in ztwo space leave maxdma to user 174 * setting or default to MAXPHYS else the address must 175 * be on the chip bus so decrease it to either the users 176 * setting or 1024 bytes. 177 * 178 * XXX this needs to change if we move to multiple memory segments. 179 */ 180 if (gtsc_dmabounce || kvtop(sc) & sc->sc_dmamask) { 181 sc->sc_dmabuffer = (char *) alloc_z2mem(MAXPHYS * 8); /* XXX */ 182 if (isztwomem(sc->sc_dmabuffer)) 183 printf(" bounce pa 0x%x", kvtop(sc->sc_dmabuffer)); 184 else if (gtsc_maxdma == 0) { 185 gtsc_maxdma = 1024; 186 printf(" bounce pa 0x%x", 187 PREP_DMA_MEM(sc->sc_dmabuffer)); 188 } 189 } 190 #endif 191 if (gtsc_maxdma == 0) 192 gtsc_maxdma = MAXPHYS; 193 194 printf(" flags %x", gap->flags); 195 printf(" maxdma %d\n", gtsc_maxdma); 196 197 sc->sc_sbic.sbic_asr_p = (volatile unsigned char *)rp + 0x61; 198 sc->sc_sbic.sbic_value_p = (volatile unsigned char *)rp + 0x63; 199 200 sc->sc_clkfreq = gtsc_clock_override ? gtsc_clock_override : 201 ((gap->flags & GVP_14MHZ) ? 143 : 72); 202 printf("sc_clkfreg: %ld.%ld MHz\n", sc->sc_clkfreq / 10, sc->sc_clkfreq % 10); 203 204 /* 205 * Fill in the scsipi_adapter. 206 */ 207 memset(adapt, 0, sizeof(*adapt)); 208 adapt->adapt_dev = &sc->sc_dev; 209 adapt->adapt_nchannels = 1; 210 adapt->adapt_openings = 7; 211 adapt->adapt_max_periph = 1; 212 adapt->adapt_request = sbic_scsipi_request; 213 adapt->adapt_minphys = sbic_minphys; 214 215 /* 216 * Fill in the scsipi_channel. 217 */ 218 memset(chan, 0, sizeof(*chan)); 219 chan->chan_adapter = adapt; 220 chan->chan_bustype = &scsi_bustype; 221 chan->chan_channel = 0; 222 chan->chan_ntargets = 8; 223 chan->chan_nluns = 8; 224 chan->chan_id = 7; 225 226 sbicinit(sc); 227 228 sc->sc_isr.isr_intr = gtsc_dmaintr; 229 sc->sc_isr.isr_arg = sc; 230 sc->sc_isr.isr_ipl = 2; 231 add_isr(&sc->sc_isr); 232 233 /* 234 * attach all scsi units on us 235 */ 236 config_found(dp, chan, scsiprint); 237 } 238 239 void 240 gtsc_enintr(struct sbic_softc *dev) 241 { 242 volatile struct sdmac *sdp; 243 244 sdp = dev->sc_cregs; 245 246 dev->sc_flags |= SBICF_INTR; 247 sdp->CNTR = GVP_CNTR_INTEN; 248 } 249 250 int 251 gtsc_dmago(struct sbic_softc *dev, char *addr, int count, int flags) 252 { 253 volatile struct sdmac *sdp; 254 255 sdp = dev->sc_cregs; 256 /* 257 * Set up the command word based on flags 258 */ 259 dev->sc_dmacmd = GVP_CNTR_INTEN; 260 if ((flags & DMAGO_READ) == 0) 261 dev->sc_dmacmd |= GVP_CNTR_DDIR; 262 263 #ifdef DEBUG 264 if (gtsc_debug & DDB_IO) 265 printf("gtsc_dmago: cmd %x\n", dev->sc_dmacmd); 266 #endif 267 dev->sc_flags |= SBICF_INTR; 268 sdp->CNTR = dev->sc_dmacmd; 269 if((u_int)dev->sc_cur->dc_addr & dev->sc_dmamask) { 270 #if 1 271 printf("gtsc_dmago: pa %p->%lx dmacmd %x", 272 dev->sc_cur->dc_addr, 273 (u_int)dev->sc_cur->dc_addr & ~dev->sc_dmamask, 274 dev->sc_dmacmd); 275 #endif 276 sdp->ACR = 0x00f80000; /***********************************/ 277 } else 278 sdp->ACR = (u_int) dev->sc_cur->dc_addr; 279 if (dev->gtsc_bankmask) 280 sdp->bank = 281 dev->gtsc_bankmask & (((u_int)dev->sc_cur->dc_addr) >> 18); 282 sdp->ST_DMA = 1; 283 284 /* 285 * restrict transfer count to maximum 286 */ 287 if (dev->sc_tcnt > gtsc_maxdma) 288 dev->sc_tcnt = gtsc_maxdma; 289 #if 1 290 if((u_int)dev->sc_cur->dc_addr & dev->sc_dmamask) 291 printf(" tcnt %ld\n", dev->sc_tcnt); 292 #endif 293 return(dev->sc_tcnt); 294 } 295 296 void 297 gtsc_dmastop(struct sbic_softc *dev) 298 { 299 volatile struct sdmac *sdp; 300 int s; 301 302 sdp = dev->sc_cregs; 303 304 #ifdef DEBUG 305 if (gtsc_debug & DDB_FOLLOW) 306 printf("gtsc_dmastop()\n"); 307 #endif 308 if (dev->sc_dmacmd) { 309 /* 310 * clear possible interrupt and stop DMA 311 */ 312 s = splbio(); 313 sdp->CNTR &= ~GVP_CNTR_INT_P; 314 sdp->SP_DMA = 1; 315 dev->sc_dmacmd = 0; 316 splx(s); 317 } 318 } 319 320 int 321 gtsc_dmaintr(void *arg) 322 { 323 struct sbic_softc *dev = arg; 324 volatile struct sdmac *sdp; 325 int stat; 326 327 sdp = dev->sc_cregs; 328 stat = sdp->CNTR; 329 if ((stat & GVP_CNTR_INT_P) == 0) 330 return (0); 331 #ifdef DEBUG 332 if (gtsc_debug & DDB_FOLLOW) 333 printf("%s: dmaintr 0x%x\n", dev->sc_dev.dv_xname, stat); 334 #endif 335 if (dev->sc_flags & SBICF_INTR) 336 if (sbicintr(dev)) 337 return (1); 338 return(0); 339 } 340 341 342 int 343 gtsc_dmanext(struct sbic_softc *dev) 344 { 345 volatile struct sdmac *sdp; 346 347 sdp = dev->sc_cregs; 348 349 if (dev->sc_cur > dev->sc_last) { 350 /* shouldn't happen !! */ 351 printf("gtsc_dmanext at end !!!\n"); 352 gtsc_dmastop(dev); 353 return(0); 354 } 355 /* 356 * clear possible interrupt and stop DMA 357 */ 358 sdp->CNTR &= ~GVP_CNTR_INT_P; 359 sdp->SP_DMA = 1; 360 361 sdp->CNTR = dev->sc_dmacmd; 362 sdp->ACR = (u_int) dev->sc_cur->dc_addr; 363 if (dev->gtsc_bankmask) 364 sdp->bank = 365 dev->gtsc_bankmask & ((u_int)dev->sc_cur->dc_addr >> 18); 366 sdp->ST_DMA = 1; 367 368 dev->sc_tcnt = dev->sc_cur->dc_count << 1; 369 if (dev->sc_tcnt > gtsc_maxdma) 370 dev->sc_tcnt = gtsc_maxdma; 371 #ifdef DEBUG 372 if (gtsc_debug & DDB_FOLLOW) 373 printf("gtsc_dmanext ret: %ld\n", dev->sc_tcnt); 374 #endif 375 return(dev->sc_tcnt); 376 } 377 378 #ifdef DEBUG 379 void 380 gtsc_dump(void) 381 { 382 extern struct cfdriver gtsc_cd; 383 struct sbic_softc *sc; 384 int i; 385 386 for (i = 0; i < gtsc_cd.cd_ndevs; ++i) { 387 sc = device_lookup_private(>sc_cd, i); 388 if (sc != NULL) 389 sbic_dump(sc); 390 } 391 } 392 #endif 393