1*c7fb772bSthorpej /* $NetBSD: ptsc.c,v 1.21 2021/08/07 16:18:40 thorpej Exp $ */
2aad01611Sagc
3aad01611Sagc /*
4aad01611Sagc * Copyright (c) 1982, 1990 The Regents of the University of California.
5aad01611Sagc * All rights reserved.
6aad01611Sagc *
7aad01611Sagc * Redistribution and use in source and binary forms, with or without
8aad01611Sagc * modification, are permitted provided that the following conditions
9aad01611Sagc * are met:
10aad01611Sagc * 1. Redistributions of source code must retain the above copyright
11aad01611Sagc * notice, this list of conditions and the following disclaimer.
12aad01611Sagc * 2. Redistributions in binary form must reproduce the above copyright
13aad01611Sagc * notice, this list of conditions and the following disclaimer in the
14aad01611Sagc * documentation and/or other materials provided with the distribution.
15aad01611Sagc * 3. Neither the name of the University nor the names of its contributors
16aad01611Sagc * may be used to endorse or promote products derived from this software
17aad01611Sagc * without specific prior written permission.
18aad01611Sagc *
19aad01611Sagc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20aad01611Sagc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21aad01611Sagc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22aad01611Sagc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23aad01611Sagc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24aad01611Sagc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25aad01611Sagc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26aad01611Sagc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27aad01611Sagc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28aad01611Sagc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29aad01611Sagc * SUCH DAMAGE.
30aad01611Sagc *
31aad01611Sagc * @(#)ptsc.c
32aad01611Sagc */
337d4a1addSreinoud
347d4a1addSreinoud /*
357d4a1addSreinoud * Copyright (c) 1995 Scott Stevens
367d4a1addSreinoud * Copyright (c) 1995 Daniel Widenfalk
377d4a1addSreinoud * Copyright (c) 1994 Christian E. Hopps
387d4a1addSreinoud *
397d4a1addSreinoud * Redistribution and use in source and binary forms, with or without
407d4a1addSreinoud * modification, are permitted provided that the following conditions
417d4a1addSreinoud * are met:
427d4a1addSreinoud * 1. Redistributions of source code must retain the above copyright
437d4a1addSreinoud * notice, this list of conditions and the following disclaimer.
447d4a1addSreinoud * 2. Redistributions in binary form must reproduce the above copyright
457d4a1addSreinoud * notice, this list of conditions and the following disclaimer in the
467d4a1addSreinoud * documentation and/or other materials provided with the distribution.
477d4a1addSreinoud * 3. All advertising materials mentioning features or use of this software
487d4a1addSreinoud * must display the following acknowledgement:
497d4a1addSreinoud * This product includes software developed by the University of
507d4a1addSreinoud * California, Berkeley and its contributors.
517d4a1addSreinoud * 4. Neither the name of the University nor the names of its contributors
527d4a1addSreinoud * may be used to endorse or promote products derived from this software
537d4a1addSreinoud * without specific prior written permission.
547d4a1addSreinoud *
557d4a1addSreinoud * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
567d4a1addSreinoud * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
577d4a1addSreinoud * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
587d4a1addSreinoud * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
597d4a1addSreinoud * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
607d4a1addSreinoud * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
617d4a1addSreinoud * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
627d4a1addSreinoud * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
637d4a1addSreinoud * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
647d4a1addSreinoud * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
657d4a1addSreinoud * SUCH DAMAGE.
667d4a1addSreinoud *
677d4a1addSreinoud * @(#)ptsc.c
687d4a1addSreinoud */
697d4a1addSreinoud
707d4a1addSreinoud /*
717d4a1addSreinoud * Power-tec SCSI-2 driver uses SFAS216 generic driver
727d4a1addSreinoud *
737d4a1addSreinoud * Thanks to Alsystems for loaning a development card and providing
747d4a1addSreinoud * programming information.
757d4a1addSreinoud */
767d4a1addSreinoud
771b7326b5Slukem #include <sys/cdefs.h>
78*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: ptsc.c,v 1.21 2021/08/07 16:18:40 thorpej Exp $");
791b7326b5Slukem
807d4a1addSreinoud #include <sys/param.h>
817d4a1addSreinoud #include <sys/systm.h>
827d4a1addSreinoud #include <sys/kernel.h>
837d4a1addSreinoud #include <sys/device.h>
8489a25a09Sthorpej
8589a25a09Sthorpej #include <uvm/uvm_extern.h>
8689a25a09Sthorpej
877d4a1addSreinoud #include <dev/scsipi/scsi_all.h>
887d4a1addSreinoud #include <dev/scsipi/scsipi_all.h>
897d4a1addSreinoud #include <dev/scsipi/scsiconf.h>
907d4a1addSreinoud #include <machine/io.h>
91ce1401feSthorpej #include <machine/intr.h>
927d4a1addSreinoud #include <machine/bootconfig.h>
937d4a1addSreinoud #include <acorn32/podulebus/podulebus.h>
947d4a1addSreinoud #include <acorn32/podulebus/sfasreg.h>
957d4a1addSreinoud #include <acorn32/podulebus/sfasvar.h>
967d4a1addSreinoud #include <acorn32/podulebus/ptscreg.h>
977d4a1addSreinoud #include <acorn32/podulebus/ptscvar.h>
987d4a1addSreinoud #include <dev/podulebus/podules.h>
997d4a1addSreinoud #include <dev/podulebus/powerromreg.h>
1007d4a1addSreinoud
101a8c167faSmatt int ptscmatch(device_t, cfdata_t, void *);
102a8c167faSmatt void ptscattach(device_t, device_t, void *);
1037d4a1addSreinoud
104cbab9cadSchs CFATTACH_DECL_NEW(ptsc, sizeof(struct ptsc_softc),
1055a9ddc14Sthorpej ptscmatch, ptscattach, NULL, NULL);
1067d4a1addSreinoud
107ecdf1b40Schs int ptsc_intr(void *);
108ecdf1b40Schs int ptsc_setup_dma(void *, void *, int, int);
109ecdf1b40Schs int ptsc_build_dma_chain(void *, void *, void *, int);
110ecdf1b40Schs int ptsc_need_bump(void *, void *, int);
111ecdf1b40Schs void ptsc_led(void *, int);
112ecdf1b40Schs
113ecdf1b40Schs void ptsc_set_dma_adr(struct sfas_softc *, void *);
114ecdf1b40Schs void ptsc_set_dma_tc(struct sfas_softc *, unsigned int);
115ecdf1b40Schs void ptsc_set_dma_mode(struct sfas_softc *, int);
1167d4a1addSreinoud
1177d4a1addSreinoud /*
1187d4a1addSreinoud * if we are a Power-tec SCSI-2 card
1197d4a1addSreinoud */
1207d4a1addSreinoud int
ptscmatch(device_t parent,cfdata_t cf,void * aux)121a8c167faSmatt ptscmatch(device_t parent, cfdata_t cf, void *aux)
1227d4a1addSreinoud {
123a8c167faSmatt struct podule_attach_args *pa = aux;
1247d4a1addSreinoud
1257d4a1addSreinoud /* Look for the card */
1267d4a1addSreinoud
1277d4a1addSreinoud /*
1287d4a1addSreinoud * All Power-tec cards effectively have PowerROMS. Note,
1297d4a1addSreinoud * though, that here, if we fail to initialise the loader, we
1307d4a1addSreinoud * assume this _is_ the right kind of card.
1317d4a1addSreinoud */
1327d4a1addSreinoud if (pa->pa_product == PODULE_ALSYSTEMS_SCSI &&
1337d4a1addSreinoud (podulebus_initloader(pa) != 0 ||
1347d4a1addSreinoud podloader_callloader(pa, 0, 0) == PRID_POWERTEC))
1357d4a1addSreinoud return 1;
1367d4a1addSreinoud
1377d4a1addSreinoud return 0;
1387d4a1addSreinoud }
1397d4a1addSreinoud
1407d4a1addSreinoud void
ptscattach(device_t parent,device_t self,void * aux)141a8c167faSmatt ptscattach(device_t parent, device_t self, void *aux)
1427d4a1addSreinoud {
143a8c167faSmatt struct ptsc_softc *sc = device_private(self);
144a8c167faSmatt struct podule_attach_args *pa = aux;
1457d4a1addSreinoud ptsc_regmap_p rp = &sc->sc_regmap;
1467d4a1addSreinoud vu_char *fas;
1477d4a1addSreinoud
1487d4a1addSreinoud if (pa->pa_podule_number == -1)
1497d4a1addSreinoud panic("Podule has disappeared !");
1507d4a1addSreinoud
1517d4a1addSreinoud sc->sc_specific.sc_podule_number = pa->pa_podule_number;
1527d4a1addSreinoud sc->sc_specific.sc_podule = pa->pa_podule;
1537d4a1addSreinoud sc->sc_specific.sc_iobase =
1547d4a1addSreinoud (vu_char *)sc->sc_specific.sc_podule->fast_base;
1557d4a1addSreinoud
1567d4a1addSreinoud rp->chipreset = &sc->sc_specific.sc_iobase[PTSC_CONTROL_CHIPRESET];
1577d4a1addSreinoud rp->inten = &sc->sc_specific.sc_iobase[PTSC_CONTROL_INTEN];
1587d4a1addSreinoud rp->status = &sc->sc_specific.sc_iobase[PTSC_STATUS];
1597d4a1addSreinoud rp->term = &sc->sc_specific.sc_iobase[PTSC_CONTROL_TERM];
1607d4a1addSreinoud rp->led = &sc->sc_specific.sc_iobase[PTSC_CONTROL_LED];
1617d4a1addSreinoud fas = &sc->sc_specific.sc_iobase[PTSC_FASOFFSET_BASE];
1627d4a1addSreinoud
1637d4a1addSreinoud rp->FAS216.sfas_tc_low = &fas[PTSC_FASOFFSET_TCL];
1647d4a1addSreinoud rp->FAS216.sfas_tc_mid = &fas[PTSC_FASOFFSET_TCM];
1657d4a1addSreinoud rp->FAS216.sfas_fifo = &fas[PTSC_FASOFFSET_FIFO];
1667d4a1addSreinoud rp->FAS216.sfas_command = &fas[PTSC_FASOFFSET_COMMAND];
1677d4a1addSreinoud rp->FAS216.sfas_dest_id = &fas[PTSC_FASOFFSET_DESTID];
1687d4a1addSreinoud rp->FAS216.sfas_timeout = &fas[PTSC_FASOFFSET_TIMEOUT];
1697d4a1addSreinoud rp->FAS216.sfas_syncper = &fas[PTSC_FASOFFSET_PERIOD];
1707d4a1addSreinoud rp->FAS216.sfas_syncoff = &fas[PTSC_FASOFFSET_OFFSET];
1717d4a1addSreinoud rp->FAS216.sfas_config1 = &fas[PTSC_FASOFFSET_CONFIG1];
1727d4a1addSreinoud rp->FAS216.sfas_clkconv = &fas[PTSC_FASOFFSET_CLOCKCONV];
1737d4a1addSreinoud rp->FAS216.sfas_test = &fas[PTSC_FASOFFSET_TEST];
1747d4a1addSreinoud rp->FAS216.sfas_config2 = &fas[PTSC_FASOFFSET_CONFIG2];
1757d4a1addSreinoud rp->FAS216.sfas_config3 = &fas[PTSC_FASOFFSET_CONFIG3];
1767d4a1addSreinoud rp->FAS216.sfas_tc_high = &fas[PTSC_FASOFFSET_TCH];
1777d4a1addSreinoud rp->FAS216.sfas_fifo_bot = &fas[PTSC_FASOFFSET_FIFOBOTTOM];
1787d4a1addSreinoud
179cbab9cadSchs sc->sc_softc.sc_dev = self;
1807d4a1addSreinoud sc->sc_softc.sc_fas = (sfas_regmap_p)rp;
1817d4a1addSreinoud sc->sc_softc.sc_spec = &sc->sc_specific;
1827d4a1addSreinoud
1837d4a1addSreinoud sc->sc_softc.sc_led = ptsc_led;
1847d4a1addSreinoud
1857d4a1addSreinoud sc->sc_softc.sc_setup_dma = ptsc_setup_dma;
1867d4a1addSreinoud sc->sc_softc.sc_build_dma_chain = ptsc_build_dma_chain;
1877d4a1addSreinoud sc->sc_softc.sc_need_bump = ptsc_need_bump;
1887d4a1addSreinoud
1897d4a1addSreinoud sc->sc_softc.sc_clock_freq = 40; /* Power-Tec runs at 8MHz */
1907d4a1addSreinoud sc->sc_softc.sc_timeout = 250; /* Set default timeout to 250ms */
1917d4a1addSreinoud sc->sc_softc.sc_config_flags = SFAS_NO_DMA /*| SFAS_NF_DEBUG*/;
1927d4a1addSreinoud sc->sc_softc.sc_host_id = 7; /* Should check the jumpers */
1937d4a1addSreinoud
19489a25a09Sthorpej sc->sc_softc.sc_bump_sz = PAGE_SIZE;
1957d4a1addSreinoud sc->sc_softc.sc_bump_pa = 0x0;
1967d4a1addSreinoud
1977d4a1addSreinoud sfasinitialize((struct sfas_softc *)sc);
1987d4a1addSreinoud
199cbab9cadSchs sc->sc_softc.sc_adapter.adapt_dev = sc->sc_softc.sc_dev;
2007d4a1addSreinoud sc->sc_softc.sc_adapter.adapt_nchannels = 1;
2017d4a1addSreinoud sc->sc_softc.sc_adapter.adapt_openings = 7;
2027d4a1addSreinoud sc->sc_softc.sc_adapter.adapt_max_periph = 1;
2037d4a1addSreinoud sc->sc_softc.sc_adapter.adapt_ioctl = NULL;
2047d4a1addSreinoud sc->sc_softc.sc_adapter.adapt_minphys = sfas_minphys;
205ed8346a5Sbjh21 sc->sc_softc.sc_adapter.adapt_request = sfas_scsi_request;
2067d4a1addSreinoud
2077d4a1addSreinoud sc->sc_softc.sc_channel.chan_adapter = &sc->sc_softc.sc_adapter;
2087d4a1addSreinoud sc->sc_softc.sc_channel.chan_bustype = &scsi_bustype;
2097d4a1addSreinoud sc->sc_softc.sc_channel.chan_channel = 0;
2107d4a1addSreinoud sc->sc_softc.sc_channel.chan_ntargets = 8;
2117d4a1addSreinoud sc->sc_softc.sc_channel.chan_nluns = 8;
2127d4a1addSreinoud sc->sc_softc.sc_channel.chan_id = sc->sc_softc.sc_host_id;
2137d4a1addSreinoud
2147d4a1addSreinoud /* Provide an override for the host id */
2157d4a1addSreinoud (void)get_bootconf_option(boot_args, "ptsc.hostid",
2167d4a1addSreinoud BOOTOPT_TYPE_INT, &sc->sc_softc.sc_channel.chan_id);
2177d4a1addSreinoud
2187d4a1addSreinoud printf(": host=%d", sc->sc_softc.sc_channel.chan_id);
2197d4a1addSreinoud
2207d4a1addSreinoud /* initialise the card */
2217d4a1addSreinoud /* *rp->term = 0;*/
2227d4a1addSreinoud *rp->inten = (PTSC_POLL?0:1);
2237d4a1addSreinoud *rp->led = 0;
2247d4a1addSreinoud
2257d4a1addSreinoud #if PTSC_POLL == 0
2267d4a1addSreinoud evcnt_attach_dynamic(&sc->sc_softc.sc_intrcnt, EVCNT_TYPE_INTR, NULL,
227a8c167faSmatt device_xname(self), "intr");
2287d4a1addSreinoud sc->sc_softc.sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO,
2297d4a1addSreinoud ptsc_intr, &sc->sc_softc, &sc->sc_softc.sc_intrcnt);
2307d4a1addSreinoud if (sc->sc_softc.sc_ih == NULL)
231a8c167faSmatt panic("%s: Cannot install IRQ handler", device_xname(self));
2327d4a1addSreinoud #else
2337d4a1addSreinoud printf(" polling");
234ed8346a5Sbjh21 sc->sc_softc.sc_adapter.adapt_flags = SCSIPI_ADAPT_POLL_ONLY;
2357d4a1addSreinoud #endif
2367d4a1addSreinoud
2377d4a1addSreinoud printf("\n");
2387d4a1addSreinoud
2397d4a1addSreinoud /* attach all scsi units on us */
240*c7fb772bSthorpej config_found(self, &sc->sc_softc.sc_channel, scsiprint, CFARGS_NONE);
2417d4a1addSreinoud }
2427d4a1addSreinoud
2437d4a1addSreinoud
2447d4a1addSreinoud int
ptsc_intr(void * arg)245454af1c0Sdsl ptsc_intr(void *arg)
2467d4a1addSreinoud {
2477d4a1addSreinoud struct sfas_softc *dev = arg;
2487d4a1addSreinoud ptsc_regmap_p rp;
2497d4a1addSreinoud int quickints;
2507d4a1addSreinoud
2517d4a1addSreinoud rp = (ptsc_regmap_p)dev->sc_fas;
2527d4a1addSreinoud
2537d4a1addSreinoud if (*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING) {
2547d4a1addSreinoud quickints = 16;
2557d4a1addSreinoud do {
2567d4a1addSreinoud dev->sc_status = *rp->FAS216.sfas_status;
2577d4a1addSreinoud dev->sc_interrupt = *rp->FAS216.sfas_interrupt;
2587d4a1addSreinoud
2597d4a1addSreinoud if (dev->sc_interrupt & SFAS_INT_RESELECTED) {
2607d4a1addSreinoud dev->sc_resel[0] = *rp->FAS216.sfas_fifo;
2617d4a1addSreinoud dev->sc_resel[1] = *rp->FAS216.sfas_fifo;
2627d4a1addSreinoud }
2637d4a1addSreinoud
2647d4a1addSreinoud sfasintr(dev);
2657d4a1addSreinoud
2667d4a1addSreinoud } while((*rp->FAS216.sfas_status & SFAS_STAT_INTERRUPT_PENDING)
2677d4a1addSreinoud && --quickints);
2687d4a1addSreinoud }
2697d4a1addSreinoud
2707d4a1addSreinoud return(0); /* Pass interrupt on down the chain */
2717d4a1addSreinoud }
2727d4a1addSreinoud
2731ffa7b76Swiz /* Load transfer address into DMA register */
2747d4a1addSreinoud void
ptsc_set_dma_adr(struct sfas_softc * sc,void * ptr)275454af1c0Sdsl ptsc_set_dma_adr(struct sfas_softc *sc, void *ptr)
2767d4a1addSreinoud {
2777d4a1addSreinoud #if 0
2787d4a1addSreinoud ptsc_regmap_p rp;
2797d4a1addSreinoud unsigned int *p;
2807d4a1addSreinoud unsigned int d;
2817d4a1addSreinoud #endif
2827d4a1addSreinoud #if 0
2837d4a1addSreinoud printf("ptsc_set_dma_adr(sc = 0x%08x, ptr = 0x%08x)\n", (u_int)sc, (u_int)ptr);
2847d4a1addSreinoud #endif
2857d4a1addSreinoud return;
2867d4a1addSreinoud #if 0
2877d4a1addSreinoud rp = (ptsc_regmap_p)sc->sc_fas;
2887d4a1addSreinoud
2897d4a1addSreinoud d = (unsigned int)ptr;
2907d4a1addSreinoud p = (unsigned int *)((d & 0xFFFFFF) + (int)rp->dmabase);
2917d4a1addSreinoud
2927d4a1addSreinoud *rp->clear=0;
2937d4a1addSreinoud *p = d;
2947d4a1addSreinoud #endif
2957d4a1addSreinoud }
2967d4a1addSreinoud
2977d4a1addSreinoud /* Set DMA transfer counter */
2987d4a1addSreinoud void
ptsc_set_dma_tc(struct sfas_softc * sc,unsigned int len)299454af1c0Sdsl ptsc_set_dma_tc(struct sfas_softc *sc, unsigned int len)
3007d4a1addSreinoud {
3017d4a1addSreinoud printf("ptsc_set_dma_tc(sc, len = 0x%08x)", len);
3027d4a1addSreinoud
3037d4a1addSreinoud *sc->sc_fas->sfas_tc_low = len; len >>= 8;
3047d4a1addSreinoud *sc->sc_fas->sfas_tc_mid = len; len >>= 8;
3057d4a1addSreinoud *sc->sc_fas->sfas_tc_high = len;
3067d4a1addSreinoud }
3077d4a1addSreinoud
3087d4a1addSreinoud /* Set DMA mode */
3097d4a1addSreinoud void
ptsc_set_dma_mode(struct sfas_softc * sc,int mode)310454af1c0Sdsl ptsc_set_dma_mode(struct sfas_softc *sc, int mode)
3117d4a1addSreinoud {
3127d4a1addSreinoud #if 0
3137d4a1addSreinoud struct csc_specific *spec;
3147d4a1addSreinoud
3157d4a1addSreinoud spec = sc->sc_spec;
3167d4a1addSreinoud
3177d4a1addSreinoud spec->portbits = (spec->portbits & ~FLSC_PB_DMA_BITS) | mode;
3187d4a1addSreinoud *((flsc_regmap_p)sc->sc_fas)->hardbits = spec->portbits;
3197d4a1addSreinoud #endif
3207d4a1addSreinoud }
3217d4a1addSreinoud
3227d4a1addSreinoud /* Initialize DMA for transfer */
3237d4a1addSreinoud int
ptsc_setup_dma(void * v,void * ptr,int len,int mode)324454af1c0Sdsl ptsc_setup_dma(void *v, void *ptr, int len, int mode)
3257d4a1addSreinoud {
326ecdf1b40Schs return(0);
327ecdf1b40Schs
328ecdf1b40Schs #if 0
329ecdf1b40Schs struct sfas_softc *sc = v;
3307d4a1addSreinoud int retval;
3317d4a1addSreinoud
3327d4a1addSreinoud retval = 0;
3337d4a1addSreinoud
3347d4a1addSreinoud printf("ptsc_setup_dma(sc, ptr = 0x%08x, len = 0x%08x, mode = 0x%08x)\n", (u_int)ptr, len, mode);
3357d4a1addSreinoud
3367d4a1addSreinoud switch(mode) {
3377d4a1addSreinoud case SFAS_DMA_READ:
3387d4a1addSreinoud case SFAS_DMA_WRITE:
3397d4a1addSreinoud flsc_set_dma_adr(sc, ptr);
3407d4a1addSreinoud if (mode == SFAS_DMA_READ)
3417d4a1addSreinoud flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_READ);
3427d4a1addSreinoud else
3437d4a1addSreinoud flsc_set_dma_mode(sc,FLSC_PB_ENABLE_DMA | FLSC_PB_DMA_WRITE);
3447d4a1addSreinoud
3457d4a1addSreinoud flsc_set_dma_tc(sc, len);
3467d4a1addSreinoud break;
3477d4a1addSreinoud
3487d4a1addSreinoud case SFAS_DMA_CLEAR:
3497d4a1addSreinoud default:
3507d4a1addSreinoud flsc_set_dma_mode(sc, FLSC_PB_DISABLE_DMA);
3517d4a1addSreinoud flsc_set_dma_adr(sc, 0);
3527d4a1addSreinoud
3537d4a1addSreinoud retval = (*sc->sc_fas->sfas_tc_high << 16) |
3547d4a1addSreinoud (*sc->sc_fas->sfas_tc_mid << 8) |
3557d4a1addSreinoud *sc->sc_fas->sfas_tc_low;
3567d4a1addSreinoud
3577d4a1addSreinoud flsc_set_dma_tc(sc, 0);
3587d4a1addSreinoud break;
3597d4a1addSreinoud }
3607d4a1addSreinoud
3617d4a1addSreinoud return(retval);
3627d4a1addSreinoud #endif
3637d4a1addSreinoud }
3647d4a1addSreinoud
3657d4a1addSreinoud /* Check if address and len is ok for DMA transfer */
3667d4a1addSreinoud int
ptsc_need_bump(void * v,void * ptr,int len)367454af1c0Sdsl ptsc_need_bump(void *v, void *ptr, int len)
3687d4a1addSreinoud {
3697d4a1addSreinoud int p;
3707d4a1addSreinoud
3717d4a1addSreinoud p = (int)ptr & 0x03;
3727d4a1addSreinoud
3737d4a1addSreinoud if (p) {
3747d4a1addSreinoud p = 4-p;
3757d4a1addSreinoud
3767d4a1addSreinoud if (len < 256)
3777d4a1addSreinoud p = len;
3787d4a1addSreinoud }
3797d4a1addSreinoud
3807d4a1addSreinoud return(p);
3817d4a1addSreinoud }
3827d4a1addSreinoud
3837d4a1addSreinoud /* Interrupt driven routines */
3847d4a1addSreinoud int
ptsc_build_dma_chain(void * v1,void * v2,void * p,int l)385ecdf1b40Schs ptsc_build_dma_chain(void *v1, void *v2, void *p, int l)
3867d4a1addSreinoud {
3877d4a1addSreinoud #if 0
388d3d059aaSmatt vaddr_t pa, lastpa;
3897d4a1addSreinoud char *ptr;
3907d4a1addSreinoud int len, prelen, postlen, max_t, n;
3917d4a1addSreinoud #endif
3927d4a1addSreinoud #if 0
3937d4a1addSreinoud printf("ptsc_build_dma_chain()\n");
3947d4a1addSreinoud #endif
3957d4a1addSreinoud return(0);
3967d4a1addSreinoud
3977d4a1addSreinoud #if 0
3987d4a1addSreinoud if (l == 0)
3997d4a1addSreinoud return(0);
4007d4a1addSreinoud
4017d4a1addSreinoud #define set_link(n, p, l, f)\
4027d4a1addSreinoud do { chain[n].ptr = (p); chain[n].len = (l); chain[n++].flg = (f); } while(0)
4037d4a1addSreinoud
4047d4a1addSreinoud n = 0;
4057d4a1addSreinoud
4067d4a1addSreinoud if (l < 512)
407d3d059aaSmatt set_link(n, (vaddr_t)p, l, SFAS_CHAIN_BUMP);
4087d4a1addSreinoud else if (p >= (void *)0xFF000000) {
4097d4a1addSreinoud while(l != 0) {
4107d4a1addSreinoud len = ((l > sc->sc_bump_sz) ? sc->sc_bump_sz : l);
4117d4a1addSreinoud
412d3d059aaSmatt set_link(n, (vaddr_t)p, len, SFAS_CHAIN_BUMP);
4137d4a1addSreinoud
4147d4a1addSreinoud p += len;
4157d4a1addSreinoud l -= len;
4167d4a1addSreinoud }
4177d4a1addSreinoud } else {
4187d4a1addSreinoud ptr = p;
4197d4a1addSreinoud len = l;
4207d4a1addSreinoud
4217d4a1addSreinoud pa = kvtop(ptr);
4227d4a1addSreinoud prelen = ((int)ptr & 0x03);
4237d4a1addSreinoud
4247d4a1addSreinoud if (prelen) {
4257d4a1addSreinoud prelen = 4-prelen;
426d3d059aaSmatt set_link(n, (vaddr_t)ptr, prelen, SFAS_CHAIN_BUMP);
4277d4a1addSreinoud ptr += prelen;
4287d4a1addSreinoud len -= prelen;
4297d4a1addSreinoud }
4307d4a1addSreinoud
4317d4a1addSreinoud lastpa = 0;
4327d4a1addSreinoud while(len > 3) {
4337d4a1addSreinoud pa = kvtop(ptr);
43489a25a09Sthorpej max_t = PAGE_SIZE - (pa & PGOFSET);
4357d4a1addSreinoud if (max_t > len)
4367d4a1addSreinoud max_t = len;
4377d4a1addSreinoud
4387d4a1addSreinoud max_t &= ~3;
4397d4a1addSreinoud
4407d4a1addSreinoud if (lastpa == pa)
4417d4a1addSreinoud sc->sc_chain[n-1].len += max_t;
4427d4a1addSreinoud else
4437d4a1addSreinoud set_link(n, pa, max_t, SFAS_CHAIN_DMA);
4447d4a1addSreinoud
4457d4a1addSreinoud lastpa = pa+max_t;
4467d4a1addSreinoud
4477d4a1addSreinoud ptr += max_t;
4487d4a1addSreinoud len -= max_t;
4497d4a1addSreinoud }
4507d4a1addSreinoud
4517d4a1addSreinoud if (len)
452d3d059aaSmatt set_link(n, (vaddr_t)ptr, len, SFAS_CHAIN_BUMP);
4537d4a1addSreinoud }
4547d4a1addSreinoud
4557d4a1addSreinoud return(n);
4567d4a1addSreinoud #endif
4577d4a1addSreinoud }
4587d4a1addSreinoud
4597d4a1addSreinoud /* Turn on/off led */
4607d4a1addSreinoud void
ptsc_led(void * v,int mode)461ecdf1b40Schs ptsc_led(void *v, int mode)
4627d4a1addSreinoud {
463ecdf1b40Schs struct sfas_softc *sc = v;
4647d4a1addSreinoud ptsc_regmap_p rp;
4657d4a1addSreinoud
4667d4a1addSreinoud rp = (ptsc_regmap_p)sc->sc_fas;
4677d4a1addSreinoud
4687d4a1addSreinoud if (mode) {
4697d4a1addSreinoud sc->sc_led_status++;
4707d4a1addSreinoud } else {
4717d4a1addSreinoud if (sc->sc_led_status)
4727d4a1addSreinoud sc->sc_led_status--;
4737d4a1addSreinoud }
4747d4a1addSreinoud *rp->led = (sc->sc_led_status?1:0);
4757d4a1addSreinoud }
476