From owner-p4-projects@FreeBSD.ORG Wed Oct 25 07:55:30 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DC1D916A47C; Wed, 25 Oct 2006 07:55:29 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9CA9D16A417 for ; Wed, 25 Oct 2006 07:55:29 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 37E7A43D64 for ; Wed, 25 Oct 2006 07:55:29 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k9P7tTjR009783 for ; Wed, 25 Oct 2006 07:55:29 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k9P7tScW009780 for perforce@freebsd.org; Wed, 25 Oct 2006 07:55:28 GMT (envelope-from imp@freebsd.org) Date: Wed, 25 Oct 2006 07:55:28 GMT Message-Id: <200610250755.k9P7tScW009780@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 108392 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Oct 2006 07:55:30 -0000 http://perforce.freebsd.org/chv.cgi?CH=108392 Change 108392 by imp@imp_lighthouse on 2006/10/25 07:54:28 Merge in preliminary write support. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91_ssc.c#12 edit .. //depot/projects/arm/src/sys/arm/at91/at91_sscreg.h#7 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91_ssc.c#12 (text+ko) ==== @@ -23,7 +23,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/arm/at91/at91_ssc.c,v 1.3 2006/10/20 07:08:59 imp Exp $"); +__FBSDID("$FreeBSD: src/sys/arm/at91/at91_ssc.c,v 1.2 2006/07/14 22:30:44 imp Exp $"); #include #include @@ -34,9 +34,13 @@ #include #include #include +#include #include #include +#include + +#define MAX_BUF 1024 struct at91_ssc_softc { @@ -48,6 +52,11 @@ struct cdev *cdev; int flags; #define OPENED 1 + bus_dma_tag_t tag; /* bus dma tag */ + bus_dmamap_t tx_map; + int txdone; + uint8_t rx_buf[MAX_BUF]; + bus_dmamap_t rx_map; }; static inline uint32_t @@ -129,6 +138,22 @@ AT91_SSC_LOCK_DESTROY(sc); goto out; } + + /* + * Allocate DMA tags and maps + */ + err = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, + BUS_SPACE_MAXADDR, NULL, NULL, 2048, 1, 2048, BUS_DMA_ALLOCNOW, + NULL, NULL, &sc->tag); + if (err != 0) + goto out; + err = bus_dmamap_create(sc->tag, 0, &sc->tx_map); + if (err != 0) + goto out; + err = bus_dmamap_create(sc->tag, 0, &sc->rx_map); + if (err != 0) + goto out; + sc->cdev = make_dev(&at91_ssc_cdevsw, device_get_unit(dev), UID_ROOT, GID_WHEEL, 0600, "ssc%d", device_get_unit(dev)); if (sc->cdev == NULL) { @@ -149,7 +174,7 @@ WR4(sc, SSC_TFMR, 0x1f | SSC_TFMR_DATDEF | SSC_TFMR_MSFBF | SSC_TFMR_FSOS_NEG_PULSE); -out:; +out: if (err) at91_ssc_deactivate(dev); return (err); @@ -209,16 +234,19 @@ at91_ssc_intr(void *xsc) { struct at91_ssc_softc *sc = xsc; -#if 0 uint32_t status; /* Reading the status also clears the interrupt */ status = RD4(sc, SSC_SR); if (status == 0) return; + if (status & SSC_SR_ENDTX) { + WR4(sc, SSC_IDR, SSC_SR_ENDTX); + sc->txdone++; + wakeup(&sc->txdone); + } AT91_SSC_LOCK(sc); AT91_SSC_UNLOCK(sc); -#endif wakeup(sc); return; } @@ -232,9 +260,6 @@ AT91_SSC_LOCK(sc); if (!(sc->flags & OPENED)) { sc->flags |= OPENED; -#if 0 - // Enable interrupts -#endif } AT91_SSC_UNLOCK(sc); return (0); @@ -248,13 +273,23 @@ sc = CDEV2SOFTC(dev); AT91_SSC_LOCK(sc); sc->flags &= ~OPENED; -#if 0 - // Disable interrupts -#endif AT91_SSC_UNLOCK(sc); return (0); } +static void +at91_ssc_loadwrite(void *arg, bus_dma_segment_t *segs, int nsegs, + bus_size_t size, int error) +{ + struct at91_ssc_softc *sc; + + sc = arg; + if (error != 0) + return; + WR4(sc, PDC_TPR, segs[0].ds_addr); + WR4(sc, PDC_TCR, size); +} + static int at91_ssc_read(struct cdev *dev, struct uio *uio, int flag) { @@ -264,7 +299,29 @@ static int at91_ssc_write(struct cdev *dev, struct uio *uio, int flag) { - return EIO; + struct at91_ssc_softc *sc; + int err, txdone; + + sc = CDEV2SOFTC(dev); + // must write a multiple of 4 bytes + if ((uio->uio_resid & 0x3) != 0 || uio->uio_resid > MAX_BUF) + return (EINVAL); + WR4(sc, SSC_CR, SSC_CR_TXDIS); + WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS); + err = bus_dmamap_load_uio(sc->tag, sc->tx_map, uio, at91_ssc_loadwrite, + sc, 0); + if (err != 0) + return (err); + WR4(sc, SSC_IER, SSC_SR_ENDTX); + WR4(sc, SSC_CR, SSC_CR_TXEN); + WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN); + txdone = sc->txdone; + do { + err = msleep(&sc->txdone, NULL, PCATCH | PZERO, "sscwr", hz); + } while (txdone == sc->txdone && err != EINTR); + if (err == 0) + uio->uio_resid = 0; + return err; } static device_method_t at91_ssc_methods[] = { ==== //depot/projects/arm/src/sys/arm/at91/at91_sscreg.h#7 (text+ko) ==== @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $FreeBSD: src/sys/arm/at91/at91_sscreg.h,v 1.2 2006/10/20 07:08:15 imp Exp $ */ +/* $FreeBSD: src/sys/arm/at91/at91_sscreg.h,v 1.1 2006/03/24 07:42:33 imp Exp $ */ #ifndef ARM_AT91_AT91_SSCREG_H #define ARM_AT91_AT91_SSCREG_H @@ -132,4 +132,18 @@ #define SSC_TFMR_DATDEF (1u << 5) /* DATDEF: Data Default Value */ #define SSC_TFMR_DATLEN (0x1fu << 0) /* DATLEN: Data Length */ +/* SSC_SR */ +#define SSC_SR_TXRDY (1u << 0) +#define SSC_SR_TXEMPTY (1u << 1) +#define SSC_SR_ENDTX (1u << 2) +#define SSC_SR_TXBUFE (1u << 3) +#define SSC_SR_RXRDY (1u << 4) +#define SSC_SR_OVRUN (1u << 5) +#define SSC_SR_ENDRX (1u << 6) +#define SSC_SR_RXBUFF (1u << 7) +#define SSC_SR_TXSYN (1u << 10) +#define SSC_SR_RSSYN (1u << 11) +#define SSC_SR_TXEN (1u << 16) +#define SSC_SR_RXEN (1u << 17) + #endif /* ARM_AT91_AT91_SSCREG_H */