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); }