Module Name:    src
Committed By:   nonaka
Date:           Tue Apr  6 15:55:46 UTC 2010

Modified Files:
        src/sys/arch/arm/xscale: pxa2x0_mci.c

Log Message:
Enable DMA transfer.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/xscale/pxa2x0_mci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/xscale/pxa2x0_mci.c
diff -u src/sys/arch/arm/xscale/pxa2x0_mci.c:1.4 src/sys/arch/arm/xscale/pxa2x0_mci.c:1.5
--- src/sys/arch/arm/xscale/pxa2x0_mci.c:1.4	Sat Mar 13 12:28:44 2010
+++ src/sys/arch/arm/xscale/pxa2x0_mci.c	Tue Apr  6 15:55:46 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pxa2x0_mci.c,v 1.4 2010/03/13 12:28:44 nonaka Exp $	*/
+/*	$NetBSD: pxa2x0_mci.c,v 1.5 2010/04/06 15:55:46 nonaka Exp $	*/
 /*	$OpenBSD: pxa2x0_mmc.c,v 1.5 2009/02/23 18:09:55 miod Exp $	*/
 
 /*
@@ -18,7 +18,7 @@
  */
 
 /*-
- * Copyright (c) 2007-2009 NONAKA Kimihiro <non...@netbsd.org>
+ * Copyright (c) 2007-2010 NONAKA Kimihiro <non...@netbsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pxa2x0_mci.c,v 1.4 2010/03/13 12:28:44 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pxa2x0_mci.c,v 1.5 2010/04/06 15:55:46 nonaka Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -79,18 +79,18 @@
 #include <arm/xscale/pxa2x0_mci.h>
 
 #ifdef PXAMCI_DEBUG
-int pxamci_debug = 1;
+int pxamci_debug = 9;
 #define DPRINTF(n,s)	do { if ((n) <= pxamci_debug) printf s; } while (0)
 #else
 #define DPRINTF(n,s)	do {} while (0)
 #endif
 
-#ifndef DEBUG
-#define	STOPCLK_TIMO	2	/* ms */
-#define	EXECCMD_TIMO	2	/* ms */
+#ifndef PXAMCI_DEBUG
+#define	STOPCLK_TIMO	2	/* sec */
+#define	EXECCMD_TIMO	2	/* sec */
 #else
-#define	STOPCLK_TIMO	2	/* ms */
-#define	EXECCMD_TIMO	5	/* ms */
+#define	STOPCLK_TIMO	2	/* sec */
+#define	EXECCMD_TIMO	5	/* sec */
 #endif
 
 static int	pxamci_host_reset(sdmmc_chipset_handle_t);
@@ -155,6 +155,14 @@
 #define CSR_CLR_4(sc, reg, val) \
 	CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(val))
 
+#if 0	/* XXX */
+#define	DMA_ALIGNED(addr) \
+	(((u_long)(addr) & 0x7) == 0 || !CPU_IS_PXA250)
+#else
+#define	DMA_ALIGNED(addr) \
+	(((u_long)(addr) & 0x1f) == 0)
+#endif
+
 static void
 pxamci_enable_intr(struct pxamci_softc *sc, uint32_t mask)
 {
@@ -238,9 +246,6 @@
 	sc->sc_buswidth = 1;
 
 	/* setting DMA */
-#if 1	/* XXX */
-	SET(sc->sc_caps, PMC_CAPS_NO_DMA);	/* disable DMA */
-#endif
 	if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) {
 		aprint_normal_dev(sc->sc_dev, "using DMA transfer\n");
 
@@ -301,10 +306,8 @@
 	saa.saa_caps = 0;
 	if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA))
 		SET(saa.saa_caps, SMC_CAPS_DMA);
-#if notyet
 	if (CPU_IS_PXA270 && ISSET(sc->sc_caps, PMC_CAPS_4BIT))
 		SET(saa.saa_caps, SMC_CAPS_4BIT_MODE);
-#endif
 
 	sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL);
 	if (sc->sc_sdmmc == NULL) {
@@ -612,9 +615,12 @@
 		cmdat |= CMDAT_DATA_EN;
 
 		/* setting DMA */
-		if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) {
+		if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
+		 && DMA_ALIGNED(cmd->c_data)) {
 			struct dmac_xfer_desc *dx_desc;
 
+			DPRINTF(1,("%s: using DMA\n",device_xname(sc->sc_dev)));
+
 			cmdat |= CMDAT_MMC_DMA_EN;
 
 			if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
@@ -641,6 +647,8 @@
 				goto err;
 			}
 		} else {
+			DPRINTF(1,("%s: using PIO\n",device_xname(sc->sc_dev)));
+
 			cmd->c_resid = cmd->c_datalen;
 			cmd->c_buf = cmd->c_data;
 
@@ -739,7 +747,7 @@
 	ostatus =
 #endif
 	status = CSR_READ_4(sc, MMC_I_REG) & ~CSR_READ_4(sc, MMC_I_MASK);
-	DPRINTF(9,("%s: intr status = %08x\n", device_xname(sc->sc_dev),
+	DPRINTF(10,("%s: intr status = %08x\n", device_xname(sc->sc_dev),
 	    status));
 
 	/*
@@ -762,7 +770,8 @@
 		pxamci_disable_intr(sc, MMC_I_RES_ERR);
 		CLR(status, MMC_I_RES_ERR|MMC_I_END_CMD_RES);
 		if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
-		 && (sc->sc_cmd->c_datalen > 0)) {
+		 && (sc->sc_cmd->c_datalen > 0)
+		 && DMA_ALIGNED(sc->sc_cmd->c_data)) {
 			if (ISSET(sc->sc_cmd->c_flags, SCF_CMD_READ)) {
 				pxa2x0_dmac_abort_xfer(sc->sc_rxdx);
 			} else {
@@ -796,7 +805,8 @@
 		pxamci_intr_done(sc);
 		pxamci_disable_intr(sc, MMC_I_DAT_ERR);
 		CLR(status, MMC_I_DAT_ERR);
-		if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) {
+		if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
+		 && DMA_ALIGNED(sc->sc_cmd->c_data)) {
 			if (ISSET(sc->sc_cmd->c_flags, SCF_CMD_READ)) {
 				pxa2x0_dmac_abort_xfer(sc->sc_rxdx);
 			} else {
@@ -820,7 +830,7 @@
 	}
 
 	if (ISSET(status, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ)) {
-		DPRINTF(9,("%s: handling MMC_I_xxFIFO_xx_REQ\n",
+		DPRINTF(10,("%s: handling MMC_I_xxFIFO_xx_REQ\n",
 		    device_xname(sc->sc_dev)));
 		pxamci_intr_data(sc);
 		CLR(status, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ);
@@ -920,18 +930,20 @@
 		cmd->c_error = EIO;
 
 	if (cmd->c_error == 0 && cmd->c_datalen > 0) {
-		/* workaround for erratum #91 */
 		if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
-		 && CPU_IS_PXA270
-		 && !ISSET(cmd->c_flags, SCF_CMD_READ)) {
-			error = pxa2x0_dmac_start_xfer(sc->sc_txdx);
-			if (error) {
-				aprint_error_dev(sc->sc_dev,
-				    "couldn't start dma xfer. (error=%d)\n",
-				    error);
-				cmd->c_error = EIO;
-				pxamci_intr_done(sc);
-				return;
+		 && DMA_ALIGNED(cmd->c_data)) {
+			/* workaround for erratum #91 */
+			if (CPU_IS_PXA270
+			 && !ISSET(cmd->c_flags, SCF_CMD_READ)) {
+				error = pxa2x0_dmac_start_xfer(sc->sc_txdx);
+				if (error) {
+					aprint_error_dev(sc->sc_dev,
+					    "couldn't start dma xfer."
+					    " (error=%d)\n", error);
+					cmd->c_error = EIO;
+					pxamci_intr_done(sc);
+					return;
+				}
 			}
 			pxamci_enable_intr(sc,
 			    MMC_I_DATA_TRAN_DONE|MMC_I_DAT_ERR);
@@ -948,7 +960,7 @@
 	int intr;
 	int n;
 
-	DPRINTF(1,("%s: pxamci_intr_data: cmd = %p, resid = %d\n",
+	DPRINTF(10,("%s: pxamci_intr_data: cmd = %p, resid = %d\n",
 	    device_xname(sc->sc_dev), cmd, cmd->c_resid));
 
 	n = MIN(32, cmd->c_resid);
@@ -998,6 +1010,9 @@
 {
 	struct pxamci_softc *sc = dx->dx_cookie;
 
+	DPRINTF(1,("%s: pxamci_dmac_iintr: status = %#x\n",
+	    device_xname(sc->sc_dev), status));
+
 	if (status) {
 		aprint_error_dev(sc->sc_dev, "pxamci_dmac_iintr: "
 		    "non-zero completion status %d\n", status);
@@ -1009,7 +1024,14 @@
 {
 	struct pxamci_softc *sc = dx->dx_cookie;
 
-	if (status) {
+	DPRINTF(1,("%s: pxamci_dmac_ointr: status = %#x\n",
+	    device_xname(sc->sc_dev), status));
+
+	if (status == 0) {
+		if (sc->sc_cmd != NULL && (sc->sc_cmd->c_datalen & 31) != 0) {
+			CSR_WRITE_4(sc, MMC_PRTBUF, 1);
+		}
+	} else {
 		aprint_error_dev(sc->sc_dev, "pxamci_dmac_ointr: "
 		    "non-zero completion status %d\n", status);
 	}

Reply via email to