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