PERFORCE change 108392 for review
Warner Losh
imp at FreeBSD.org
Wed Oct 25 00:55:30 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=108392
Change 108392 by imp at 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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/systm.h>
@@ -34,9 +34,13 @@
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/rman.h>
+#include <sys/uio.h>
#include <machine/bus.h>
#include <arm/at91/at91_sscreg.h>
+#include <arm/at91/at91_pdcreg.h>
+
+#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 */
More information about the p4-projects
mailing list